} data;
};
+enum snmp_request {
+ REQUEST_GET = 0,
+ REQUEST_GETNEXT = 1,
+ REQUEST_RESPONSE = 2,
+ REQUEST_SET = 3,
+ REQUEST_TRAP = 4,
+ REQUEST_GETBULK = 5,
+ REQUEST_INFORM = 6,
+ REQUEST_TRAPV2 = 7,
+ REQUEST_REPORT = 8
+};
+
+
extern int verbose;
extern char *axsocket;
extern char *hostname;
#define MIB_SUBAGENT_UNREGISTER MIB_SUBAGENTS, 4
#define MIB_SUBAGENT_BACKEND MIB_SUBAGENTS, 5
#define MIB_SUBAGENT_SNMP MIB_SUBAGENTS, 6
+#define MIB_SUBAGENT_TRANSPORT MIB_SUBAGENTS, 7
/* Region used for registration testing */
#define MIB_REGISTER MIB_OPENBSD_REGRESS, 2
#define MIB_UNREGISTER MIB_OPENBSD_REGRESS, 3
#define MIB_BACKEND MIB_OPENBSD_REGRESS, 4
#define MIB_SNMP MIB_OPENBSD_REGRESS, 5
+#define MIB_TRANSPORT MIB_OPENBSD_REGRESS, 6
#define SYSORTABLE 1, 3, 6, 1, 2, 1, 1, 9
int32_t snmpv2_getnext(int, const char *, int32_t, struct varbind *, size_t);
int32_t snmpv2_getbulk(int, const char *, int32_t, int32_t, int32_t,
struct varbind *, size_t);
+struct ber_element *snmpv2_build(const char *, enum snmp_request, int32_t,
+ int32_t, int32_t, struct varbind *, size_t);
void snmpv2_response_validate(int, int, const char *, int32_t, int32_t, int32_t,
struct varbind *, size_t);
void snmp_timeout(int, int);
+void smi_debug_elements(struct ber_element *);
void backend_get_integer(void);
void backend_get_octetstring(void);
void backend_error_getbulk_firstrepetition(void);
void backend_error_getbulk_secondrepetition(void);
void snmp_v3_usm_noauthpriv(void);
+void transport_tcp_get(void);
+void transport_tcp_disconnect(void);
+void transport_tcp_double_get_disconnect(void);
EXCEPTION_ENDOFMIBVIEW = 2
};
-enum snmp_request {
- REQUEST_GET = 0,
- REQUEST_GETNEXT = 1,
- REQUEST_RESPONSE = 2,
- REQUEST_SET = 3,
- REQUEST_TRAP = 4,
- REQUEST_GETBULK = 5,
- REQUEST_INFORM = 6,
- REQUEST_TRAPV2 = 7,
- REQUEST_REPORT = 8
-};
-
enum security_model {
SM_USM = 3,
SM_TSM = 4
unsigned int smi_application(struct ber_element *);
char *smi_oid2string(struct ber_oid *, char *, size_t);
char *smi_print_element(struct ber_element *);
-void smi_debug_elements(struct ber_element *);
struct ber_element *v2cmps(struct ber_element *, const char *);
void snmp_pdu_validate(struct ber_element *, enum snmp_request, int32_t,
int32_t, int32_t, struct varbind *, size_t);
maxrep, varbindlist, nvarbind);
}
+struct ber_element *
+snmpv2_build(const char *community, enum snmp_request request,
+ int32_t requestid, int32_t error, int32_t index,
+ struct varbind *varbindlist, size_t nvarbind)
+{
+ struct ber_element *message;
+
+ if (community == NULL)
+ community = SNMP_R_COMMUNITY;
+ message = ober_printf_elements(NULL, "{dse}", 1, community,
+ snmp_pdu(request, requestid, error, index, varbindlist, nvarbind));
+ if (message == NULL)
+ err(1, NULL);
+
+ return message;
+}
+
int32_t
snmpv2_send(int s, const char *community, enum snmp_request request,
int32_t requestid, int32_t error, int32_t index,
void *buf;
ssize_t buflen, writelen;
- if (community == NULL)
- community = SNMP_R_COMMUNITY;
while (requestid == 0)
requestid = arc4random();
- message = ober_printf_elements(NULL, "{dse}", 1, community,
- snmp_pdu(request, requestid, error, index, varbindlist, nvarbind));
- if (message == NULL)
- err(1, NULL);
+
+ message = snmpv2_build(community, request, requestid, error, index,
+ varbindlist,nvarbind);
if (ober_write_elements(&ber, message) == -1)
err(1, "ober_write_elements");
--- /dev/null
+#include <sys/socket.h>
+
+#include <ber.h>
+#include <err.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "regress.h"
+
+#define MIB_SUBAGENT_TRANSPORT_TCP MIB_SUBAGENT_TRANSPORT, 1
+#define MIB_TRANSPORT_TCP MIB_TRANSPORT, 1
+
+void
+transport_tcp_get(void)
+{
+ struct sockaddr_storage ss;
+ struct sockaddr *sa = (struct sockaddr *)&ss;
+ socklen_t salen;
+ int snmp_s, ax_s;
+ uint32_t sessionid;
+ struct varbind varbind = {
+ .type = TYPE_NULL,
+ .name = OID_STRUCT(MIB_TRANSPORT_TCP, 1, 0),
+ .data.int32 = 1
+ };
+ int32_t requestid;
+ char buf[1024];
+ size_t n;
+
+ ax_s = agentx_connect(axsocket);
+ sessionid = agentx_open(ax_s, 0, 0,
+ OID_ARG(MIB_SUBAGENT_TRANSPORT_TCP, 1), __func__);
+ agentx_register(ax_s, sessionid, 0, 0, 127, 0,
+ OID_ARG(MIB_TRANSPORT_TCP, 1), 0);
+
+ salen = snmp_resolve(SOCK_STREAM, hostname, servname, sa);
+ snmp_s = snmp_connect(SOCK_STREAM, sa, salen);
+ requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1);
+
+ n = agentx_read(ax_s, buf, sizeof(buf), 1000);
+ agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1);
+
+ varbind.type = TYPE_INTEGER;
+ agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1);
+
+ snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0,
+ &varbind, 1);
+}
+
+void
+transport_tcp_disconnect(void)
+{
+ struct sockaddr_storage ss;
+ struct sockaddr *sa = (struct sockaddr *)&ss;
+ socklen_t salen;
+ int snmp_s, ax_s;
+ uint32_t sessionid;
+ struct varbind varbind = {
+ .type = TYPE_NULL,
+ .name = OID_STRUCT(MIB_TRANSPORT_TCP, 2, 0),
+ .data.int32 = 1
+ };
+ int32_t requestid;
+ char buf[1024];
+ size_t n;
+
+ ax_s = agentx_connect(axsocket);
+ sessionid = agentx_open(ax_s, 0, 0,
+ OID_ARG(MIB_SUBAGENT_TRANSPORT_TCP, 2), __func__);
+ agentx_register(ax_s, sessionid, 0, 0, 127, 0,
+ OID_ARG(MIB_TRANSPORT_TCP, 2), 0);
+
+ salen = snmp_resolve(SOCK_STREAM, hostname, servname, sa);
+ snmp_s = snmp_connect(SOCK_STREAM, sa, salen);
+ requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1);
+
+ close(snmp_s);
+
+ n = agentx_read(ax_s, buf, sizeof(buf), 1000);
+ agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1);
+
+ varbind.type = TYPE_INTEGER;
+ agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1);
+}
+
+void
+transport_tcp_double_get_disconnect(void)
+{
+ struct sockaddr_storage ss;
+ struct sockaddr *sa = (struct sockaddr *)&ss;
+ socklen_t salen;
+ int snmp_s, ax_s;
+ uint32_t sessionid;
+ struct varbind varbind = {
+ .type = TYPE_NULL,
+ .name = OID_STRUCT(MIB_TRANSPORT_TCP, 2, 0),
+ .data.int32 = 1
+ };
+ struct ber_element *message;
+ struct ber ber = {};
+ char buf[1024];
+ ssize_t buflen, writelen;
+ void *ptr;
+ size_t n;
+
+ ax_s = agentx_connect(axsocket);
+ sessionid = agentx_open(ax_s, 0, 0,
+ OID_ARG(MIB_SUBAGENT_TRANSPORT_TCP, 2), __func__);
+ agentx_register(ax_s, sessionid, 0, 0, 127, 0,
+ OID_ARG(MIB_TRANSPORT_TCP, 2), 0);
+
+ salen = snmp_resolve(SOCK_STREAM, hostname, servname, sa);
+ snmp_s = snmp_connect(SOCK_STREAM, sa, salen);
+
+ message = snmpv2_build(community, REQUEST_GET, 0, 0, 0, &varbind, 1);
+
+ if (ober_write_elements(&ber, message) == -1)
+ err(1, "ober_write_elements");
+
+ buflen = ober_get_writebuf(&ber, &ptr);
+ /* send two copies in a single window */
+ memcpy(buf, ptr, buflen);
+ memcpy(buf + buflen, ptr, buflen);
+
+ if ((writelen = write(snmp_s, buf, buflen * 2)) == -1)
+ err(1, "write");
+ if (writelen != buflen * 2)
+ errx(1, "write: short write");
+
+ if (verbose) {
+ printf("SNMP send(%d):\n", snmp_s);
+ smi_debug_elements(message);
+ }
+ ober_free_elements(message);
+ ober_free(&ber);
+
+ close(snmp_s);
+
+ n = agentx_read(ax_s, buf, sizeof(buf), 1000);
+ agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1);
+
+ varbind.type = TYPE_INTEGER;
+ agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1);
+
+ n = agentx_read(ax_s, buf, sizeof(buf), 1000);
+ agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1);
+ agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1);
+}