2 #include "netinet/ipl.h"
6 #define IPF_ENTERPRISE 9932
8 * Enterprise number OID:
11 static u_char ipf_enterprise[] = { 6, 7, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c };
12 static u_char ipf_trap0_1[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 1 };
13 static u_char ipf_trap0_2[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 2 };
15 static int writeint __P((u_char *, int));
16 static int writelength __P((u_char *, u_int));
17 static int maketrap_v1 __P((char *, u_char *, int, u_char *, int, u_32_t,
19 static void snmpv1_destroy __P((void *));
20 static void *snmpv1_dup __P((void *));
21 static int snmpv1_match __P((void *, void *));
22 static void *snmpv1_parse __P((char **));
23 static void snmpv1_print __P((void *));
24 static int snmpv1_send __P((void *, ipmon_msg_t *));
26 typedef struct snmpv1_opts_s {
32 struct sockaddr_in6 sin6;
34 struct sockaddr_in sin;
37 ipmon_saver_t snmpv1saver = {
41 snmpv1_match, /* match */
49 snmpv1_match(ctx1, ctx2)
52 snmpv1_opts_t *s1 = ctx1, *s2 = ctx2;
57 if (strcmp(s1->community, s2->community))
62 if (memcmp(&s1->sin6, &s2->sin6, sizeof(s1->sin6)))
67 if (memcmp(&s1->sin, &s2->sin, sizeof(s1->sin)))
79 snmpv1_opts_t *s = ctx;
90 snmpv1_opts_t *snmpv1 = ctx;
92 printf("%s ", snmpv1->community);
94 if (snmpv1->v6 == 1) {
97 printf("%s", inet_ntop(AF_INET6, &snmpv1->sin6.sin6_addr, buf,
98 sizeof(snmpv1->sin6.sin6_addr)));
102 printf("%s", inet_ntoa(snmpv1->sin.sin_addr));
108 snmpv1_parse(char **strings)
115 if (strings[0] == NULL || strings[0][0] == '\0')
118 if (strchr(*strings, ' ') == NULL)
121 str = strdup(*strings);
123 ctx = calloc(1, sizeof(*ctx));
129 s = strchr(str, ' ');
131 ctx->community = str;
142 if (strchr(s, ':') == NULL) {
143 result = inet_pton(AF_INET, s, &ctx->sin.sin_addr);
145 ctx->fd = socket(AF_INET, SOCK_DGRAM, 0);
147 ctx->sin.sin_family = AF_INET;
148 ctx->sin.sin_port = htons(162);
150 (struct sockaddr *)&ctx->sin,
151 sizeof(ctx->sin)) != 0) {
158 result = inet_pton(AF_INET6, s, &ctx->sin6.sin6_addr);
161 ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0);
163 ctx->sin6.sin6_family = AF_INET6;
164 ctx->sin6.sin6_port = htons(162);
166 (struct sockaddr *)&ctx->sin6,
167 sizeof(ctx->sin6)) != 0) {
175 result = inet_aton(s, &ctx->sin.sin_addr);
177 ctx->fd = socket(AF_INET, SOCK_DGRAM, 0);
179 ctx->sin.sin_family = AF_INET;
180 ctx->sin.sin_port = htons(162);
181 if (connect(ctx->fd, (struct sockaddr *)&ctx->sin,
182 sizeof(ctx->sin)) != 0) {
206 snmpv1_opts_t *v1 = ctx;
221 snmpv1_send(ctx, msg)
225 snmpv1_opts_t *v1 = ctx;
227 return sendtrap_v1_0(v1->fd, v1->community,
228 msg->imm_msg, msg->imm_msglen, msg->imm_when);
231 static char def_community[] = "public"; /* ublic */
234 writelength(buffer, value)
238 u_int n = htonl(value);
245 if (value > 0xffffff)
247 else if (value > 0xffff)
249 else if (value > 0xff)
254 *buffer = 0x80 | len;
256 bcopy((u_char *)&n + 4 - len, buffer + 1, len);
263 writeint(buffer, value)
276 *s++ = 0x80 | (n / 4194304);
277 n -= 4194304 * (n / 4194304);
280 *s++ = 0x80 | (n / 32768);
281 n -= 32768 * (n / 327678);
284 *s++ = 0x80 | (n / 128);
285 n -= (n / 128) * 128;
295 * First style of traps is:
296 * 1.3.6.1.4.1.9932.1.1
299 maketrap_v1(community, buffer, bufsize, msg, msglen, ipaddr, when)
308 u_char *s = buffer, *t, *pdulen, *varlen;
317 if (community == NULL || *community == '\0')
318 community = def_community;
319 basesize += strlen(community) + msglen;
321 if (basesize + 8 > bufsize)
324 memset(buffer, 0xff, bufsize);
325 *s++ = 0x30; /* Sequence */
326 if (basesize - 1 >= 128) {
333 *s++ = 0x02; /* Integer32 */
334 *s++ = 0x01; /* length 1 */
335 *s++ = 0x00; /* version 1 */
336 *s++ = 0x04; /* octet string */
337 *s++ = strlen(community); /* length of "public" */
338 bcopy(community, s, s[-1]);
340 *s++ = 0xA4; /* PDU(4) */
342 if (basesize - (s - buffer) >= 128) {
351 bcopy(ipf_enterprise, s, sizeof(ipf_enterprise));
352 s += sizeof(ipf_enterprise);
357 bcopy(&ipaddr, s, 4);
360 /* Generic Trap code */
362 n = writeint(s + 1, 6);
368 /* Specific Trap code */
370 n = writeint(s + 1, 0);
377 *s++ = 0x43; /* TimeTicks */
378 *s++ = 0x04; /* TimeTicks */
386 * The trap0 message is "ipfilter_version" followed by the message
390 if (basesize - (s - buffer) >= 128) {
400 bcopy(ipf_trap0_1, t, sizeof(ipf_trap0_1));
401 t += sizeof(ipf_trap0_1);
403 *t++ = 0x2; /* Integer */
404 n = writeint(t + 1, IPFILTER_VERSION);
413 if (basesize - (s - buffer) >= 128) {
420 bcopy(ipf_trap0_2, t, sizeof(ipf_trap0_2));
421 t += sizeof(ipf_trap0_2);
423 *t++ = 0x4; /* Octet string */
424 n = writelength(t, msglen);
426 bcopy(msg, t, msglen);
429 len = t - s - trapmsglen;
432 len = t - varlen - varlensz;
433 writelength(varlen, len); /* pdu length */
435 len = t - pdulen - pdulensz;
436 writelength(pdulen, len); /* pdu length */
438 len = t - buffer - baselensz - 1;
439 writelength(buffer + 1, len); /* length of trap */
446 sendtrap_v1_0(fd, community, msg, msglen, when)
448 char *community, *msg;
456 n = maketrap_v1(community, buffer, sizeof(buffer),
457 (u_char *)msg, msglen, 0, when);
459 return send(fd, buffer, n, 0);