|
|
1.1 root 1: /* snmpd.c - SNMP agent for 4BSD/ISODE */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/snmp/RCS/snmpd.c,v 7.35 90/07/09 14:49:04 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/snmp/RCS/snmpd.c,v 7.35 90/07/09 14:49:04 mrose Exp $
9: *
10: * Contributed by NYSERNet Inc. This work was partially supported by the
11: * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
12: * Center of the U.S. Air Force Systems Command under contract number
13: * F30602-88-C-0016.
14: *
15: *
16: * $Log: snmpd.c,v $
17: * Revision 7.35 90/07/09 14:49:04 mrose
18: * sync
19: *
20: * Revision 7.34 90/07/01 21:07:26 mrose
21: * pepsy
22: *
23: * Revision 7.33 90/06/23 17:07:38 mrose
24: * loopback
25: *
26: * Revision 7.32 90/06/23 17:01:24 mrose
27: * update
28: *
29: * Revision 7.31 90/06/23 01:33:12 mrose
30: * proxy again
31: *
32: * Revision 7.30 90/06/21 21:27:14 mrose
33: * proxy and snmpt
34: *
35: * Revision 7.29 90/06/20 23:52:57 mrose
36: * again
37: *
38: * Revision 7.28 90/06/20 21:38:33 mrose
39: * update
40: *
41: * Revision 7.27 90/06/15 16:58:39 mrose
42: * update
43: *
44: * Revision 7.26 90/06/13 17:58:44 mrose
45: * defaultView
46: *
47: * Revision 7.25 90/06/12 05:19:03 mrose
48: * again
49: *
50: * Revision 7.24 90/06/12 02:21:43 mrose
51: * again
52: *
53: * Revision 7.23 90/06/12 02:05:33 mrose
54: * views ...
55: *
56: * Revision 7.22 90/06/05 20:47:10 mrose
57: * touch-up
58: *
59: * Revision 7.21 90/05/21 10:07:39 mrose
60: * bug-fix
61: *
62: * Revision 7.20 90/05/15 16:56:20 mrose
63: * bump COMM_RDWRITE
64: *
65: * Revision 7.19 90/05/14 19:55:48 mrose
66: * optimize views
67: *
68: * Revision 7.18 90/05/13 18:13:46 mrose
69: * update
70: *
71: * Revision 7.17 90/05/13 17:54:39 mrose
72: * views again
73: *
74: * Revision 7.16 90/05/13 16:18:17 mrose
75: * views
76: *
77: * Revision 7.15 90/04/18 08:51:53 mrose
78: * oid_normalize
79: *
80: * Revision 7.14 90/04/09 08:50:16 mrose
81: * update
82: *
83: * Revision 7.13 90/02/27 18:49:55 mrose
84: * unix stuff
85: *
86: * Revision 7.12 90/02/23 17:47:49 mrose
87: * update
88: *
89: * Revision 7.11 90/02/19 16:25:56 mrose
90: * typo
91: *
92: * Revision 7.10 90/02/19 15:38:50 mrose
93: * one more time
94: *
95: * Revision 7.9 90/02/17 17:18:48 mrose
96: * touch-up
97: *
98: * Revision 7.8 90/01/11 18:34:33 mrose
99: * real-sync
100: *
101: * Revision 7.7 89/12/19 22:01:52 mrose
102: * touch-up
103: *
104: * Revision 7.6 89/12/19 16:18:23 mrose
105: * dgram
106: *
107: * Revision 7.5 89/12/11 16:22:29 mrose
108: * more clts
109: *
110: * Revision 7.4 89/12/09 21:07:41 mrose
111: * touch-up
112: *
113: * Revision 7.3 89/12/08 14:20:27 mrose
114: * touch-up
115: *
116: * Revision 7.2 89/12/07 22:15:12 mrose
117: * touch-up
118: *
119: * Revision 7.1 89/12/01 10:42:15 mrose
120: * clts
121: *
122: * Revision 7.0 89/11/23 22:23:26 mrose
123: * Release 6.0
124: *
125: */
126:
127: /*
128: * NOTICE
129: *
130: * Acquisition, use, and distribution of this module and related
131: * materials are subject to the restrictions of a license agreement.
132: * Consult the Preface in the User's Manual for the full terms of
133: * this agreement.
134: *
135: */
136:
137:
138: #include <errno.h>
139: #include <signal.h>
140: #include <stdio.h>
141: #include <varargs.h>
142: #include "mib.h"
143: #include <sys/ioctl.h>
144: #ifdef BSD42
145: #include <sys/file.h>
146: #endif
147: #ifdef SYS5
148: #include <fcntl.h>
149: #endif
150: #include <sys/stat.h>
151: #include "tailor.h"
152:
153: #include "dgram.h"
154: #include "tsap.h"
155: #ifdef TCP
156: #define SMUX
157: #include "internet.h"
158: #endif
159: #ifdef X25
160: #include "x25.h"
161: #define COTS
162: #endif
163: #ifdef TP4
164: #include "tp4.h"
165: #if !defined(CLTS) && !defined(COTS)
166: #define COTS
167: #endif
168: #endif
169:
170: #ifdef SNMPT
171: #undef SMUX
172: #endif
173:
174:
175: #define IDLE_TIME (3 * 60)
176:
177: /* DATA */
178:
179: int debug = 0;
180: static int nbits = FD_SETSIZE;
181: #ifndef SNMPT
182: static int rflag = 0;
183: #endif
184:
185:
186: #define LLOG_XXX (LLOG_PDUS | LLOG_DEBUG)
187:
188: static LLog _pgm_log = {
189: #ifndef SNMPT
190: "snmpd.log",
191: #else
192: "snmpt.log",
193: #endif
194: NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
195: LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
196: };
197: static LLog *pgm_log = &_pgm_log;
198:
199: #ifndef SNMPT
200: static char *myname = "snmpd";
201: #else
202: static char *myname = "snmpt";
203: #endif
204:
205: static int tcpservice = 1;
206: static int x25service = 1;
207: static int tp4service = 1;
208:
209:
210: #define NTADDRS FD_SETSIZE
211:
212: static fd_set ifds;
213:
214: static struct TSAPaddr *tz;
215: static struct TSAPaddr tas[NTADDRS];
216:
217: #ifdef COTS
218: static fd_set cfds;
219: static struct TSAPaddr taddrs[FD_SETSIZE];
220: static struct timeval lru[FD_SETSIZE];
221: #endif
222: static char source[BUFSIZ];
223:
224:
225: void adios (), advise ();
226: void ts_advise ();
227:
228:
229: extern int errno;
230:
231: /* */
232:
233: int nd = NOTOK;
234:
235: #ifdef TCP
236: static int udp = NOTOK;
237: #ifndef SNMPT
238: static int udport;
239: static int traport;
240: #endif
241: #endif
242:
243: #ifdef CLTS
244: static int clts = NOTOK;
245: #endif
246:
247: /* */
248:
249: #ifndef SNMPT
250: int quantum = 0;
251:
252:
253: struct subtree {
254: struct subtree *s_forw; /* doubly-linked list */
255: struct subtree *s_back; /* doubly-linked list */
256:
257: OID s_subtree; /* subtree */
258: };
259:
260:
261: struct view {
262: struct view *v_forw; /* doubly-linked list */
263: struct view *v_back; /* .. */
264:
265: OID v_name; /* view name */
266: u_long v_mask; /* view mask */
267:
268: struct subtree v_subtree; /* list of subtrees */
269:
270: struct qbuf *v_community; /* for proxy, traps... */
271: struct sockaddr v_sa;
272: };
273:
274: static struct view viewque;
275: static struct view *VHead = &viewque;
276:
277: static int viewmask = 0x1;
278: static OID localAgent = NULLOID;
279: static OID rfc1157Domain = NULLOID;
280:
281:
282: struct community {
283: struct community *c_forw; /* doubly-linked list */
284: struct community *c_back; /* .. */
285:
286: char *c_name; /* community name */
287: struct NSAPaddr c_addr; /* network address */
288:
289: int c_permission; /* same as ot_access */
290: #define OT_YYY 0x08
291:
292: OID c_vu; /* associated view */
293: struct view *c_view; /* .. */
294:
295: unsigned int *c_instance; /* object instance */
296: int c_insize; /* .. */
297: struct community *c_next; /* next in lexi-order */
298: };
299:
300: static struct community commque;
301: static struct community *CHead = &commque;
302: static struct community *CLex;
303:
304: struct community *str2comm ();
305:
306:
307: struct trap {
308: struct trap *t_forw; /* doubly-linked list */
309: struct trap *t_back; /* .. */
310:
311: char *t_name; /* trap name */
312:
313: struct view t_vu; /* associated view */
314: struct view *t_view; /* .. */
315:
316: u_long t_generics; /* generic traps enabled */
317: };
318:
319: static struct trap trapque;
320: static struct trap *UHead = &trapque;
321:
322: static OID trapview = NULLOID;
323: #ifdef TCP
324: static struct type_SNMP_Message *trap = NULL;
325: #endif
326: #ifdef SMUX
327: static struct qbuf *loopback_addr = NULL;
328: #endif
329:
330:
331: #define NPQ 10
332:
333: static struct proxyque {
334: integer pq_quantum;
335: int pq_age;
336:
337: int pq_fd;
338: IFP pq_closefnx;
339: PS pq_ps;
340:
341: struct qbuf pq_community;
342: integer pq_request;
343: } pips[NPQ];
344:
345: static int pqs = 0;
346:
347: static struct proxyque *pqr = NULL;
348:
349: /* */
350:
351: struct snmpstat {
352: integer s_inpkts;
353: integer s_outpkts;
354: integer s_badversions;
355: integer s_badcommunitynames;
356: integer s_badcommunityuses;
357: integer s_asnparseerrs;
358: integer s_badtypes;
359: integer s_totalreqvars;
360: integer s_totalsetvars;
361: integer s_ingetrequests;
362: integer s_ingetnexts;
363: integer s_insetrequests;
364: integer s_ingetresponses;
365: integer s_intraps;
366: integer s_outgetresponses;
367: integer s_outtraps;
368: integer s_toobigs;
369: integer s_nosuchnames;
370: integer s_badvalues;
371: integer s_readonlys;
372: integer s_generrs;
373: integer s_enableauthtraps;
374: #define TRAPS_ENABLED 1 /* snmpEnableAuthTraps */
375: #define TRAPS_DISABLED 2 /* .. */
376: };
377:
378:
379: static struct snmpstat snmpstat;
380:
381:
382: static int unix_netstat = 1;
383:
384: #else /* SNMPT */
385:
386: /* */
387:
388: static PS audit = NULLPS;
389:
390: #endif /* SNMPT */
391:
392: /* */
393:
394: #ifdef SMUX
395: static int smux_enabled = 1;
396: static int smux = NOTOK;
397:
398: static fd_set sfds;
399:
400:
401: struct smuxPeer {
402: struct smuxPeer *pb_forw; /* doubly-linked list */
403: struct smuxPeer *pb_back; /* .. */
404:
405: int pb_fd; /* smuxPindex */
406: struct sockaddr_in pb_address;
407: char pb_source[30];
408:
409: OID pb_identity; /* smuxPidentity */
410: char *pb_description; /* smuxPdescription */
411:
412: PS pb_ps;
413:
414: int pb_priority; /* minimum allowed priority */
415: };
416:
417: static struct smuxPeer peerque;
418: static struct smuxPeer *PHead = &peerque;
419:
420:
421: struct smuxTree {
422: struct smuxTree *tb_forw; /* doubly-linked list */
423: struct smuxTree *tb_back; /* .. */
424:
425: #define TB_SIZE 30 /* object instance */
426: unsigned int tb_instance[TB_SIZE + 1];
427: int tb_insize;
428:
429: OT tb_subtree; /* smuxTsubtree */
430: int tb_priority; /* smuxTpriority */
431: struct smuxPeer *tb_peer; /* smuxTindex */
432:
433: struct smuxTree *tb_next; /* linked list for ot_smux */
434: };
435:
436: static struct smuxTree treeque;
437: static struct smuxTree *THead = &treeque;
438:
439: static struct smuxReserved {
440: char *rb_text;
441: OID rb_name;
442: } reserved[] = {
443: "snmp", NULLOID,
444: "smux", NULLOID,
445:
446: NULL
447: };
448: #endif
449:
450: /* MAIN */
451:
452: /* ARGSUSED */
453:
454: main (argc, argv, envp)
455: int argc;
456: char **argv,
457: **envp;
458: {
459: int failed,
460: listening,
461: nfds;
462: register struct TSAPaddr *ta;
463: struct TSAPdisconnect tds;
464: register struct TSAPdisconnect *td = &tds;
465:
466: arginit (argv);
467: envinit ();
468:
469: failed = listening = 0;
470: nfds = 0;
471: FD_ZERO (&ifds);
472:
473: for (ta = tas; ta < tz; ta++) {
474: if (ta -> ta_naddr == 0) {
475: if (!tp4service)
476: continue;
477: #ifdef CLTS
478: goto do_clts;
479: #endif
480: }
481: else {
482: register struct NSAPaddr *na = ta -> ta_addrs;
483:
484: switch (na -> na_stack) {
485: case NA_TCP:
486: if (!tcpservice)
487: continue;
488: #ifdef TCP
489: {
490: struct sockaddr_in lo_socket;
491: register struct sockaddr_in *lsock = &lo_socket;
492:
493: bzero ((char *) lsock, sizeof *lsock);
494: lsock -> sin_family = AF_INET;
495: lsock -> sin_port = na -> na_port;
496:
497: if ((udp = start_udp_server (lsock, 0, 0, 0))
498: == NOTOK) {
499: advise (LLOG_EXCEPTIONS, "failed",
500: "start_udp_server");
501: failed++;
502: continue;
503: }
504: if (udp >= nfds)
505: nfds = udp + 1;
506: FD_SET (udp, &ifds);
507: if (nd == NOTOK)
508: nd = udp;
509:
510: advise (LLOG_NOTICE, NULLCP,
511: "listening on UDP port %d",
512: (int) ntohs (na -> na_port));
513: listening++;
514: continue;
515: }
516: #else
517: advise (LLOG_EXCEPTIONS, NULLCP,
518: "UDP support not configured");
519: failed++;
520: continue;
521: #endif
522:
523: case NA_X25:
524: if (!x25service)
525: continue;
526: break;
527:
528: case NA_NSAP:
529: if (!tp4service)
530: continue;
531: #ifdef CLTS
532: do_clts: ;
533: {
534: union sockaddr_osi lo_socket;
535: register union sockaddr_osi *lsock = &lo_socket;
536:
537: (void) gen2tp4 (ta, lsock);
538: if ((clts = start_clts_server (lsock, 0, 0, 0))
539: == NOTOK) {
540: advise (LLOG_EXCEPTIONS, "failed",
541: "start_clts_server");
542: failed++;
543: continue;
544: }
545: if (clts >= nfds)
546: nfds = clts + 1;
547: FD_SET (clts, &ifds);
548: if (nd == NOTOK)
549: nd = clts;
550:
551: advise (LLOG_NOTICE, NULLCP,
552: "listening on %s", taddr2str (ta));
553: listening++;
554: continue;
555: }
556: #else
557: break;
558: #endif
559:
560: default:
561: adios (NULLCP, "unknown network type 0x%x", na -> na_stack);
562: /* NOT REACHED */
563: }
564: }
565:
566: advise (LLOG_NOTICE, NULLCP, "listening on %s", taddr2str (ta));
567:
568: if (TNetListen (ta, td) == NOTOK) {
569: ts_advise (td, LLOG_EXCEPTIONS, "listen failed");
570: failed++;
571: }
572: else
573: listening++;
574: }
575:
576: if (!listening)
577: adios (NULLCP, failed ? "no successful listens"
578: : "no network services selected");
579:
580: #ifndef SNMPT
581: do_trap (int_SNMP_generic__trap_coldStart, 0,
582: (struct type_SNMP_VarBindList *) 0);
583: #endif
584:
585: #ifdef SMUX
586: {
587: struct sockaddr_in lo_socket;
588: register struct sockaddr_in *lsock = &lo_socket;
589: register struct servent *sp;
590: register struct smuxReserved *sr;
591: OT ot;
592:
593: PHead -> pb_forw = PHead -> pb_back = PHead;
594: THead -> tb_forw = THead -> tb_back = THead;
595: for (sr = reserved; sr -> rb_text; sr++)
596: if (ot = text2obj (sr -> rb_text))
597: sr -> rb_name = ot -> ot_name;
598:
599: bzero ((char *) lsock, sizeof *lsock);
600: lsock -> sin_family = AF_INET;
601: lsock -> sin_port = (sp = getservbyname ("smux", "tcp"))
602: ? sp -> s_port
603: : htons ((u_short) 199);
604:
605: if (smux_enabled) {
606: if ((smux = start_tcp_server (lsock, SOMAXCONN, 0, 0)) == NOTOK)
607: adios ("failed", "start_tcp_server for SMUX");
608: if (smux >= nfds)
609: nfds = smux + 1;
610: FD_SET (smux, &ifds);
611: }
612: }
613:
614: FD_ZERO (&sfds);
615: #endif
616:
617: #ifdef COTS
618: FD_ZERO (&cfds);
619: #endif
620:
621: for (;;) {
622: int fd,
623: secs;
624: #ifdef COTS
625: struct timeval tvs;
626: register struct timeval *tv = &tvs;
627: #endif
628: int vecp;
629: fd_set rfds;
630: char *vec[4];
631:
632: secs = NOTOK;
633: #ifdef COTS
634: for (fd = 0; fd < nfds; fd++)
635: if (FD_ISSET (fd, &cfds)) {
636: secs = IDLE_TIME + 10;
637: break;
638: }
639: #endif
640:
641: rfds = ifds; /* struct copy */
642: if (TNetAcceptAux (&vecp, vec, &fd, NULLTA, nfds, &rfds, NULLFD,
643: NULLFD, secs, td) == NOTOK) {
644: ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed");
645: continue;
646: }
647:
648: #ifdef TCP
649: if (udp != NOTOK && FD_ISSET (udp, &rfds))
650: doit_udp (udp);
651: #endif
652:
653: #ifdef SMUX
654: if (smux != NOTOK
655: && FD_ISSET (smux, &rfds)
656: && (fd = start_smux ()) != NOTOK) {
657: if (fd >= nfds)
658: nfds = fd + 1;
659: FD_SET (fd, &ifds);
660: FD_SET (fd, &sfds);
661: }
662:
663: for (fd = 0; fd < nfds; fd++)
664: if (FD_ISSET (fd, &rfds) && FD_ISSET (fd, &sfds))
665: doit_smux (fd);
666: #endif
667:
668: #ifdef CLTS
669: if (clts != NOTOK && FD_ISSET (clts, &rfds))
670: doit_clts (clts);
671: #endif
672:
673: #ifdef COTS
674: if (vecp > 0 && (fd = start_tsap (vecp, vec)) != NOTOK) {
675: if (fd >= nfds)
676: nfds = fd + 1;
677: FD_SET (fd, &ifds);
678: FD_SET (fd, &cfds);
679: }
680:
681: for (fd = 0; fd < nfds; fd++)
682: if (FD_ISSET (fd, &rfds) && FD_ISSET (fd, &cfds))
683: doit_cots (fd);
684:
685: (void) gettimeofday (tv, (struct timezone *) 0);
686: tv -> tv_sec -= (long) IDLE_TIME;
687:
688: for (fd = 0; fd < nfds; fd++)
689: if (FD_ISSET (fd, &cfds)) {
690: if (timercmp (tv, &lru[fd], >)) {
691: advise (LLOG_EXCEPTIONS, NULLCP,
692: "clearing connection from %d: %s", fd,
693: taddr2str (taddrs + fd));
694: (void) TDiscRequest (fd, NULLCP, 0, td);
695:
696: FD_CLR (fd, &ifds);
697: FD_CLR (fd, &cfds);
698: proxy_clear (fd);
699: }
700: }
701:
702: for (fd = nfds - 1; fd >= 0; fd--)
703: if (FD_ISSET (fd, &ifds))
704: break;
705: nfds = fd + 1;
706: #endif
707: }
708: }
709:
710: /* */
711:
712: static void ts_advise (td, code, event)
713: register struct TSAPdisconnect *td;
714: int code;
715: char *event;
716: {
717: char buffer[BUFSIZ];
718:
719: if (td -> td_cc > 0)
720: (void) sprintf (buffer, "[%s] %*.*s",
721: TErrString (td -> td_reason),
722: td -> td_cc, td -> td_cc, td -> td_data);
723: else
724: (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
725:
726: advise (code, NULLCP, "%s: %s", event, buffer);
727: }
728:
729: /* DOIT */
730:
731: #ifdef TCP
732: static doit_udp (pd)
733: int pd;
734: {
735: int fd;
736: char *cp;
737: struct sockaddr_in in_socket;
738: register struct sockaddr_in *isock = &in_socket;
739: struct NSAPaddr nas;
740: register struct NSAPaddr *na = &nas;
741:
742: if ((fd = join_udp_client (pd, isock)) == NOTOK) {
743: if (errno == EWOULDBLOCK)
744: return;
745: adios ("failed", "join_udp_client");
746: }
747:
748: (void) sprintf (source, "Internet=%s+%d+2",
749: cp = inet_ntoa (isock -> sin_addr),
750: (int) ntohs (isock -> sin_port));
751:
752: bzero ((char *) na, sizeof *na);
753: na -> na_stack = NA_TCP;
754: na -> na_community = ts_comm_tcp_default;
755: (void) strncpy (na -> na_domain, cp, sizeof na -> na_domain - 1);
756: na -> na_port = isock -> sin_port;
757:
758: doit_aux (fd, na, read_udp_socket, write_udp_socket);
759: #ifndef SNMPT
760: if (pqr)
761: pqr -> pq_fd = fd, pqr -> pq_closefnx = close_udp_socket;
762: else
763: #endif
764: (void) close_udp_socket (fd);
765: }
766: #endif
767:
768: /* */
769:
770: #ifdef CLTS
771: static doit_clts (pd)
772: int pd;
773: {
774: int fd;
775: char *cp;
776: union sockaddr_osi in_socket;
777: register union sockaddr_osi *isock = &in_socket;
778: struct TSAPaddr tas;
779: register struct TSAPaddr *ta = &tas;
780:
781: if ((fd = join_clts_client (pd, isock)) == NOTOK) {
782: if (errno == EWOULDBLOCK)
783: return;
784: adios ("failed", "join_tcp_client");
785: }
786: (void) tp42gen (ta, isock);
787:
788: (void) strcpy (source, taddr2str (ta));
789:
790: doit_aux (fd, ta -> ta_addrs, read_clts_socket, write_clts_socket);
791: #ifndef SNMPT
792: if (pqr)
793: pqr -> pq_fd = fd, pqr -> pq_closefnx = close_clts_socket;
794: else
795: #endif
796: (void) close_clts_socket (fd);
797: }
798: #endif
799:
800: /* */
801:
802: #ifdef COTS
803: static int start_tsap (vecp, vec)
804: int vecp;
805: char **vec;
806: {
807: struct TSAPstart tss;
808: register struct TSAPstart *ts = &tss;
809: struct TSAPdisconnect tds;
810: register struct TSAPdisconnect *td = &tds;
811:
812: if (TInit (vecp, vec, ts, td) == NOTOK) {
813: ts_advise (td, LLOG_EXCEPTIONS, "T-CONNECT.INDICATION");
814: return NOTOK;
815: }
816:
817: advise (LLOG_XXX, NULLCP,
818: "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>",
819: ts -> ts_sd,
820: taddr2str (&ts -> ts_calling), taddr2str (&ts -> ts_called),
821: ts -> ts_expedited, ts -> ts_tsdusize);
822:
823: if (TConnResponse (ts -> ts_sd, NULLTA, 0, NULLCP, 0, NULLQOS, td)
824: == NOTOK) {
825: ts_advise (td, LLOG_EXCEPTIONS, "T-CONNECT.RESPONSE");
826: return NOTOK;
827: }
828:
829: taddrs[ts -> ts_sd] = ts -> ts_calling; /* struct copy */
830: (void) gettimeofday (lru + ts -> ts_sd, (struct timezone *) 0);
831:
832: return ts -> ts_sd;
833: }
834:
835: /* */
836:
837: static doit_cots (fd)
838: int fd;
839: {
840: (void) strcpy (source, taddr2str (taddrs + fd));
841: doit_aux (fd, &(taddrs[fd].ta_addrs[0]), ts_read, ts_write);
842: #ifndef SNMPT
843: if (pqr)
844: pqr -> pq_fd = fd, pqr -> pq_closefnx = NULLIFP;
845: #endif
846:
847: (void) gettimeofday (lru + fd, (struct timezone *) 0);
848: }
849: #endif
850:
851: /* */
852:
853: static doit_aux (fd, na, rfx, wfx)
854: int fd;
855: struct NSAPaddr *na;
856: IFP rfx,
857: wfx;
858: {
859: int result;
860: PE pe;
861: PS ps;
862: struct type_SNMP_Message *msg;
863:
864: result = NOTOK;
865: pe = NULLPE;
866: msg = NULL;
867: #ifndef SNMPT
868: pqr = NULL;
869: #endif
870: if ((ps = ps_alloc (dg_open)) == NULLPS
871: || dg_setup (ps, fd, MAXDGRAM, rfx, wfx) == NOTOK) {
872: if (ps == NULLPS)
873: advise (LLOG_EXCEPTIONS, NULLCP, "ps_alloc: out of memory (%s)",
874: source);
875: else
876: advise (LLOG_EXCEPTIONS, NULLCP, "dg_setup: %s (%s)",
877: ps_error (ps -> ps_errno), source);
878:
879: goto out;
880: }
881:
882: if ((pe = ps2pe (ps)) == NULLPE) {
883: #ifdef COTS
884: if (rfx == ts_read) {
885: FD_CLR (fd, &ifds);
886: FD_CLR (fd, &cfds);
887: proxy_clear (fd);
888:
889: if (ps -> ps_errno == PS_ERR_NONE) {
890: advise (LLOG_XXX, NULLCP,
891: "T-DISCONNECT.INDICATION: %d (%s)", fd, source);
892: goto out;
893: }
894: }
895: #endif
896: advise (LLOG_EXCEPTIONS, NULLCP, "ps2pe: %s (%s)",
897: ps_error (ps -> ps_errno), source);
898: #ifndef SNMPT
899: snmpstat.s_inpkts++;
900: snmpstat.s_asnparseerrs++;
901: #endif
902: goto out;
903: }
904: #ifdef COTS
905: if (rfx == ts_read)
906: advise (LLOG_XXX, NULLCP, "T-DATA.INDICATION: %d (%s)", fd, source);
907: else
908: #endif
909: advise (LLOG_XXX, NULLCP, "packet from %s", source);
910:
911: #ifndef SNMPT
912: snmpstat.s_inpkts++;
913: #endif
914:
915: if (decode_SNMP_Message (pe, 1, NULLIP, NULLVP, &msg) == NOTOK) {
916: advise (LLOG_EXCEPTIONS, NULLCP, "decode_SNMP_Message: %s (%s)",
917: PY_pepy, source);
918: #ifndef SNMPT
919: snmpstat.s_asnparseerrs++;
920: #endif
921: #ifdef COTS
922: if (rfx == ts_read) {
923: struct TSAPdisconnect tds;
924:
925: advise (LLOG_EXCEPTIONS, NULLCP,
926: "clearing connection from %d: %s", fd,
927: taddr2str (taddrs + fd));
928: (void) TDiscRequest (fd, NULLCP, 0, &tds);
929:
930: FD_CLR (fd, &ifds);
931: FD_CLR (fd, &cfds);
932: proxy_clear (fd);
933: }
934: #endif
935: goto out;
936: }
937:
938: PLOGP (pgm_log,SNMP_Message, pe, "Message", 1);
939:
940: result = process (ps, msg, na);
941:
942: out: ;
943: if (msg)
944: free_SNMP_Message (msg);
945: if (pe)
946: pe_free (pe);
947: if (result != OK && ps)
948: ps_free (ps);
949: }
950:
951: /* PROCESS */
952:
953: #ifndef SNMPT
954: static int process (ps, msg, na)
955: PS ps;
956: register struct type_SNMP_Message *msg;
957: struct NSAPaddr *na;
958: {
959: int result;
960: char *commname;
961: struct community *comm;
962: PE pe;
963:
964: if (msg -> version != int_SNMP_version_version__1) {
965: advise (LLOG_EXCEPTIONS, NULLCP, "badVersion: %d (%s)",
966: msg -> version, source);
967: snmpstat.s_badversions++;
968: return DONE;
969: }
970:
971: if ((commname = qb2str (msg -> community)) == NULLCP) {
972: advise (LLOG_EXCEPTIONS, NULLCP, "qb2str: out of memory (%s)", source);
973: return DONE;
974: }
975:
976: result = NOTOK;
977: if ((comm = str2comm (commname, na)) == NULL) {
978: advise (LLOG_EXCEPTIONS, NULLCP, "badCommunity: %s (%s)",
979: commname, source);
980: snmpstat.s_badcommunitynames++;
981: if (snmpstat.s_enableauthtraps == TRAPS_ENABLED)
982: do_trap (int_SNMP_generic__trap_authenticationFailure, 0,
983: (struct type_SNMP_VarBindList *) 0);
984: goto out;
985: }
986:
987: if ((result = do_operation (ps, msg, comm)) != DONE)
988: goto out;
989:
990: pe = NULLPE;
991:
992: if (encode_SNMP_Message (&pe, 1, 0, NULLCP, msg) != NOTOK) {
993: PLOGP (pgm_log,SNMP_Message, pe, "Message", 0);
994:
995: if (pe2ps (ps, pe) == NOTOK)
996: advise (LLOG_EXCEPTIONS, NULLCP, "pe2ps: %s (%s)",
997: ps_error (ps -> ps_errno), source);
998: else
999: snmpstat.s_outpkts++;
1000: }
1001: else
1002: advise (LLOG_EXCEPTIONS, NULLCP, "encode_SNMP_Message: %s (%s)",
1003: PY_pepy, source);
1004:
1005: if (pe)
1006: pe_free (pe);
1007:
1008: out: ;
1009: free (commname);
1010:
1011: return result;
1012: }
1013:
1014: /* */
1015:
1016: static int do_operation (ps, msg, comm)
1017: PS ps;
1018: struct type_SNMP_Message *msg;
1019: struct community *comm;
1020: {
1021: int idx,
1022: offset,
1023: status;
1024: object_instance ois;
1025: struct view *vu = comm -> c_view;
1026: register struct type_SNMP_PDUs *pdu = msg -> data;
1027: register struct type_SNMP_VarBindList *vp;
1028: register struct type_SNMP_GetResponse__PDU *parm = pdu -> un.get__response;
1029:
1030: idx = 0;
1031: switch (pdu -> offset) {
1032: case type_SNMP_PDUs_get__request:
1033: snmpstat.s_ingetrequests++;
1034: if (vu == NULL || !(comm -> c_permission & OT_RDONLY)) {
1035: access_denied: ;
1036: advise (LLOG_EXCEPTIONS, NULLCP,
1037: "authorizationFailure: %d (%s)", pdu -> offset,
1038: source);
1039: /* no trap for this... */
1040: idx = 0;
1041: offset = pdu -> offset;
1042: pdu -> offset = type_SNMP_PDUs_get__response;
1043: parm -> error__status = int_SNMP_error__status_noSuchName;
1044: goto out;
1045: }
1046: break;
1047: case type_SNMP_PDUs_get__next__request:
1048: snmpstat.s_ingetnexts++;
1049: if (vu == NULL || !(comm -> c_permission & OT_RDONLY))
1050: goto access_denied;
1051: break;
1052:
1053: case type_SNMP_PDUs_set__request:
1054: snmpstat.s_insetrequests++;
1055: if (vu == NULL || !(comm -> c_permission & OT_WRONLY))
1056: goto access_denied;
1057: break;
1058:
1059: case type_SNMP_PDUs_get__response:
1060: snmpstat.s_ingetresponses++;
1061: if (vu == NULL)
1062: goto access_denied;
1063: if ((comm -> c_permission & OT_YYY) && proxy2 (msg) != OK)
1064: return NOTOK;
1065: /* else fall... */
1066: case type_SNMP_PDUs_trap:
1067: snmpstat.s_intraps++;
1068: if (vu == NULL)
1069: goto access_denied;
1070: advise (LLOG_EXCEPTIONS, NULLCP,
1071: "unexpectedOperation: %d (%s)", pdu -> offset, source);
1072: snmpstat.s_badtypes++;
1073: return NOTOK;
1074:
1075: default:
1076: if (vu == NULL)
1077: goto access_denied;
1078: advise (LLOG_EXCEPTIONS, NULLCP,
1079: "badOperation: %d (%s)", pdu -> offset, source);
1080: snmpstat.s_badtypes++;
1081: return NOTOK;
1082: }
1083:
1084: if (vu -> v_community)
1085: return proxy1 (ps, msg, comm);
1086:
1087: offset = pdu -> offset;
1088: pdu -> offset = type_SNMP_PDUs_get__response;
1089:
1090: quantum++;
1091: for (vp = msg -> data -> un.get__request -> variable__bindings;
1092: vp;
1093: vp = vp -> next) {
1094: register OI oi;
1095: register OT ot;
1096: register struct type_SNMP_VarBind *v = vp -> VarBind;
1097:
1098: idx++;
1099:
1100: if (offset == type_SNMP_PDUs_get__next__request) {
1101: if ((oi = name2inst (v -> name)) == NULLOI
1102: && (oi = next2inst (v -> name)) == NULLOI)
1103: goto no_name;
1104:
1105: if ((ot = oi -> oi_type) -> ot_getfnx == NULLIFP
1106: && ot -> ot_smux == NULL)
1107: goto get_next;
1108: }
1109: else
1110: if ((oi = name2inst (v -> name)) == NULLOI
1111: || ((ot = oi -> oi_type) -> ot_getfnx == NULLIFP
1112: && ot -> ot_smux == NULL)) {
1113: no_name: ;
1114: parm -> error__status = int_SNMP_error__status_noSuchName;
1115: goto out;
1116: }
1117:
1118: try_again: ;
1119: switch (offset) {
1120: case type_SNMP_PDUs_get__request:
1121: if (!(vu -> v_mask & ot -> ot_views)) {
1122: snmpstat.s_badcommunityuses++;
1123: parm -> error__status = int_SNMP_error__status_noSuchName;
1124: goto out;
1125: }
1126: break;
1127:
1128: case type_SNMP_PDUs_get__next__request:
1129: if (!(vu -> v_mask & ot -> ot_views))
1130: goto get_next;
1131: break;
1132:
1133: case type_SNMP_PDUs_set__request:
1134: if (!(vu -> v_mask & ot -> ot_views)) {
1135: snmpstat.s_badcommunityuses++;
1136: parm -> error__status = int_SNMP_error__status_readOnly;
1137: goto out;
1138: }
1139: break;
1140: }
1141:
1142: #ifdef SMUX
1143: if (ot -> ot_smux)
1144: status = smux_getfnx (pdu, ot,
1145: ((struct smuxTree *) ot -> ot_smux)
1146: -> tb_peer,
1147: v, offset);
1148: else
1149: #endif
1150: status = (*ot -> ot_getfnx) (oi, v, offset);
1151:
1152: switch (status) {
1153: case NOTOK: /* get-next wants a bump */
1154: get_next: ;
1155: oi = &ois;
1156: for (;;) {
1157: if ((ot = ot -> ot_next) == NULLOT) {
1158: parm -> error__status =
1159: int_SNMP_error__status_noSuchName;
1160: goto out;
1161: }
1162: oi -> oi_name = (oi -> oi_type = ot) -> ot_name;
1163: if (ot -> ot_getfnx || ot -> ot_smux)
1164: goto try_again;
1165: }
1166:
1167: case int_SNMP_error__status_noError:
1168: break;
1169:
1170: default:
1171: parm -> error__status = status;
1172: goto out;
1173: }
1174: }
1175: idx = 0;
1176:
1177: out: ;
1178: parm -> error__index = idx;
1179: switch (parm -> error__status) {
1180: case int_SNMP_error__status_noError:
1181: idx = 0;
1182: for (vp = msg -> data -> un.get__request -> variable__bindings;
1183: vp;
1184: vp = vp -> next)
1185: idx++;
1186: switch (offset) {
1187: case type_SNMP_PDUs_get__request:
1188: case type_SNMP_PDUs_get__next__request:
1189: snmpstat.s_totalreqvars += idx;
1190: break;
1191:
1192: case type_SNMP_PDUs_set__request:
1193: snmpstat.s_totalsetvars += idx;
1194: break;
1195: }
1196: break;
1197:
1198: case int_SNMP_error__status_tooBig:
1199: snmpstat.s_toobigs++;
1200: break;
1201:
1202: case int_SNMP_error__status_noSuchName:
1203: snmpstat.s_nosuchnames++;
1204: break;
1205:
1206: case int_SNMP_error__status_badValue:
1207: snmpstat.s_badvalues++;
1208: break;
1209:
1210: case int_SNMP_error__status_readOnly:
1211: snmpstat.s_readonlys++;
1212: break;
1213:
1214: case int_SNMP_error__status_genErr:
1215: snmpstat.s_generrs++;
1216: break;
1217:
1218: default:
1219: break;
1220: }
1221: snmpstat.s_outgetresponses++;
1222:
1223: return DONE;
1224: }
1225:
1226: /* PROXY */
1227:
1228: static int proxy1 (psp, msg, comm)
1229: PS psp;
1230: struct type_SNMP_Message *msg;
1231: struct community *comm;
1232: {
1233: int result;
1234: register struct view *v = comm -> c_view;
1235: register struct proxyque *pq;
1236: PE pe;
1237: PS ps;
1238:
1239: if (qb_pullup (msg -> community) == NOTOK) {
1240: advise (LLOG_EXCEPTIONS, NULLCP, "qb_pullup: out of memory (proxy %s)",
1241: source);
1242: return NOTOK;
1243: }
1244: if (pqs >= NPQ) {
1245: register struct proxyque *qp;
1246:
1247: for (qp = (pq = pips) + NPQ; pq < qp; pq++)
1248: if (pq -> pq_age < quantum) {
1249: advise (LLOG_NOTICE, NULLCP, "proxy flush");
1250: if (pq -> pq_closefnx) {
1251: ps_free (pq -> pq_ps);
1252: (void) (*pq -> pq_closefnx) (pq -> pq_fd);
1253: }
1254: QBFREE (&pq -> pq_community);
1255: break;
1256: }
1257: if (pq >= qp) {
1258: advise (LLOG_EXCEPTIONS, NULLCP,
1259: "proxy for view %s, but no proxyque slots available (%s)",
1260: oid2ode (v -> v_name), source);
1261: return NOTOK;
1262: }
1263: }
1264: else
1265: pq = pips + pqs++;
1266:
1267: pq -> pq_quantum = quantum;
1268: pq -> pq_age = quantum + 20; /* who knows what a good value is?!? */
1269: pq -> pq_ps = psp;
1270: pq -> pq_community.qb_forw = pq -> pq_community.qb_back
1271: = &pq -> pq_community;
1272: insque (msg -> community -> qb_forw, &pq -> pq_community);
1273: free ((char *) msg -> community);
1274: pq -> pq_request = msg -> data -> un.get__request -> request__id;
1275:
1276: msg -> community = v -> v_community;
1277: msg -> data -> un.get__request -> request__id = pq -> pq_quantum;
1278:
1279: result = NOTOK;
1280: pe = NULLPE;
1281: if (encode_SNMP_Message (&pe, 1, 0, NULLCP, msg) == NOTOK) {
1282: advise (LLOG_EXCEPTIONS, NULLCP, "encode_SNMP_Message: %s (proxy %s)",
1283: PY_pepy, source);
1284: if (pe)
1285: pe_free (pe);
1286: goto out;
1287: }
1288: PLOGP (pgm_log,SNMP_Message, pe, "Message", 0);
1289:
1290: if ((ps = ps_alloc (dg_open)) == NULLPS
1291: || dg_setup (ps, udp, MAXDGRAM, read_udp_socket, write_udp_socket)
1292: == NOTOK) {
1293: if (ps == NULLPS)
1294: advise (LLOG_EXCEPTIONS, NULLCP,
1295: "ps_alloc: out of memory (proxy %s)", source);
1296: else
1297: advise (LLOG_EXCEPTIONS, NULLCP, "dg_setup: %s (proxy %s)",
1298: ps_error (ps -> ps_errno), source);
1299: }
1300: else
1301: if (hack_dgram_socket (udp, &v -> v_sa) == NOTOK)
1302: advise (LLOG_EXCEPTIONS, "failed",
1303: "hack_dgram_socket(1) (proxy %s)", source);
1304: else
1305: if (pe2ps (ps, pe) == NOTOK)
1306: advise (LLOG_EXCEPTIONS, NULLCP, "pe2ps: %s (proxy %s)",
1307: ps_error (ps -> ps_errno), source);
1308: else {
1309: result = OK;
1310:
1311: if (hack_dgram_socket (udp, (struct sockaddr *) NULL) == NOTOK)
1312: advise (LLOG_EXCEPTIONS, "failed",
1313: "hack_dgram_socket(2) (proxy %s)", source);
1314: }
1315:
1316: pe_free (pe);
1317:
1318: if (ps)
1319: ps_free (ps);
1320:
1321: out: ;
1322: msg -> community = NULL;
1323: if (result == NOTOK) {
1324: register struct proxyque *qp = pips + --pqs;
1325:
1326: if (pq -> pq_closefnx) {
1327: ps_free (pq -> pq_ps);
1328: (void) (*pq -> pq_closefnx) (pq -> pq_fd);
1329: }
1330: QBFREE (&pq -> pq_community);
1331:
1332: if (pq != qp)
1333: *pq = *qp; /* struct copy */
1334: }
1335: else
1336: pqr = pq;
1337:
1338: return result;
1339: }
1340:
1341: /* */
1342:
1343: static int proxy2 (msg)
1344: struct type_SNMP_Message *msg;
1345: {
1346: integer request;
1347: register struct proxyque *pq,
1348: *qp;
1349: PE pe;
1350:
1351: request = msg -> data -> un.get__request -> request__id;
1352: for (qp = (pq = pips) + pqs; pq < qp; pq++)
1353: if (pq -> pq_quantum == request)
1354: break;
1355: if (pq >= qp)
1356: return OK;
1357:
1358: qb_free (msg -> community);
1359: msg -> community = &pq -> pq_community;
1360: msg -> data -> un.get__request -> request__id = pq -> pq_request;
1361:
1362: pe = NULLPE;
1363: if (encode_SNMP_Message (&pe, 1, 0, NULLCP, msg) == NOTOK) {
1364: advise (LLOG_EXCEPTIONS, NULLCP, "encode_SNMP_Message: %s (proxy %s)",
1365: PY_pepy, source);
1366: if (pe)
1367: pe_free (pe);
1368: goto out;
1369: }
1370: PLOGP (pgm_log,SNMP_Message, pe, "Message", 0);
1371:
1372: if (pe2ps (pq -> pq_ps, pe) == NOTOK)
1373: advise (LLOG_EXCEPTIONS, NULLCP, "pe2ps: %s (proxy %s)",
1374: ps_error (pq -> pq_ps -> ps_errno), source);
1375: snmpstat.s_outgetresponses++;
1376:
1377: pe_free (pe);
1378:
1379: out: ;
1380: msg -> community = NULL;
1381:
1382: qp = pips + --pqs;
1383:
1384: if (pq -> pq_closefnx) {
1385: ps_free (pq -> pq_ps);
1386: (void) (*pq -> pq_closefnx) (pq -> pq_fd);
1387: }
1388: QBFREE (&pq -> pq_community);
1389:
1390: if (pq != qp)
1391: *pq = *qp; /* struct copy */
1392:
1393: return DONE;
1394: }
1395:
1396: /* */
1397:
1398: #ifdef COTS
1399: static proxy_clear (fd)
1400: int fd;
1401: {
1402: register struct proxyque *pq,
1403: *qp;
1404:
1405: again: ;
1406: for (qp = (pq = pips) + pqs; pq < qp; pq++)
1407: if (pq -> pq_fd == fd) {
1408: qp = pips + --pqs;
1409:
1410: if (pq -> pq_closefnx) {
1411: ps_free (pq -> pq_ps);
1412: (void) (*pq -> pq_closefnx) (pq -> pq_fd);
1413: }
1414: QBFREE (&pq -> pq_community);
1415:
1416: if (pq != qp)
1417: *pq = *qp;
1418: goto again;
1419: }
1420: }
1421: #endif
1422:
1423: /* SMUX */
1424:
1425: #ifdef SMUX
1426: #include "smux.h"
1427:
1428:
1429: static int start_smux ()
1430: {
1431: int fd;
1432: struct sockaddr_in in_socket;
1433: register struct sockaddr_in *isock = &in_socket;
1434: register struct smuxPeer *pb,
1435: *qb;
1436:
1437: if ((fd = join_tcp_client (smux, isock)) == NOTOK) {
1438: if (errno == EWOULDBLOCK)
1439: return NOTOK;
1440: adios ("failed", "join_tcp_client");
1441: }
1442:
1443: if ((pb = (struct smuxPeer *) calloc (1, sizeof *pb)) == NULL) {
1444: advise (LLOG_EXCEPTIONS, NULLCP, "doit_smux: out of memory");
1445: out: ;
1446: (void) close_tcp_socket (fd);
1447: return NOTOK;
1448: }
1449:
1450: pb -> pb_address = *isock; /* struct copy */
1451: (void) sprintf (pb -> pb_source, "%s/%d",
1452: inet_ntoa (pb -> pb_address.sin_addr),
1453: (int) ntohs (pb -> pb_address.sin_port));
1454: (void) strcpy (source, pb -> pb_source);
1455:
1456: if ((pb -> pb_ps = ps_alloc (fdx_open)) == NULLPS
1457: || fdx_setup (pb -> pb_ps, fd) == NOTOK) {
1458: if (pb -> pb_ps == NULLPS)
1459: advise (LLOG_EXCEPTIONS, NULLCP,
1460: "ps_alloc: out of memory (SMUX %s)", source);
1461: else
1462: advise (LLOG_EXCEPTIONS, NULLCP, "fdx_setup: %s (SMUX %s)",
1463: ps_error (pb -> pb_ps -> ps_errno), source);
1464:
1465: pb_free (pb);
1466: goto out;
1467: }
1468:
1469: for (qb = PHead -> pb_forw; qb != PHead; qb = qb -> pb_forw)
1470: if (qb -> pb_fd > fd)
1471: break;
1472: insque (pb, qb != PHead ? qb -> pb_forw : qb -> pb_back);
1473:
1474: return (pb -> pb_fd = fd);
1475: }
1476:
1477: /* */
1478:
1479: static int doit_smux (fd)
1480: int fd;
1481: {
1482: PE pe;
1483: register struct smuxPeer *pb;
1484: struct type_SNMP_SMUX__PDUs *pdu;
1485:
1486: for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw)
1487: if (pb -> pb_fd == fd)
1488: break;
1489: if (pb == PHead) {
1490: advise (LLOG_EXCEPTIONS, NULLCP, "lost smuxPeer block for %d", fd);
1491: FD_CLR (fd, &ifds);
1492: FD_CLR (fd, &sfds);
1493:
1494: return;
1495: }
1496:
1497: (void) strcpy (source, pb -> pb_source);
1498:
1499: if ((pe = ps2pe (pb -> pb_ps)) == NULLPE) {
1500: advise (LLOG_EXCEPTIONS, NULLCP, "ps2pe: %s (SMUX %s)",
1501: ps_error (pb -> pb_ps -> ps_errno), source);
1502:
1503: out: ;
1504: if (pe)
1505: pe_free (pe);
1506: pb_free (pb);
1507: return;
1508: }
1509:
1510: advise (LLOG_XXX, NULLCP, "SMUX packet from %s", source);
1511:
1512: pdu = NULL;
1513:
1514: if (decode_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) {
1515: advise (LLOG_EXCEPTIONS, NULLCP,
1516: "decode_SNMP_SMUX__PDUs: %s (SMUX %s)", PY_pepy, source);
1517: goto out;
1518: }
1519:
1520: PLOGP (pgm_log,SNMP_SMUX__PDUs, pe, "SMUX Message", 1);
1521:
1522: if (smux_process (pb, pdu) == NOTOK)
1523: pb_free (pb);
1524:
1525: if (pdu)
1526: free_SNMP_SMUX__PDUs (pdu);
1527: if (pe)
1528: pe_free (pe);
1529: }
1530:
1531: /* */
1532:
1533: static smux_process (pb, pdu)
1534: register struct smuxPeer *pb;
1535: struct type_SNMP_SMUX__PDUs *pdu;
1536: {
1537: int result = OK;
1538:
1539: switch (pdu -> offset) {
1540: case type_SNMP_SMUX__PDUs_simple:
1541: if (pb -> pb_identity)
1542: goto unexpected;
1543: {
1544: register struct type_SNMP_SimpleOpen *simple =
1545: pdu -> un.simple;
1546: register struct smuxEntry *se;
1547:
1548: if (simple -> version != int_SNMP_version_version__1) {
1549: advise (LLOG_EXCEPTIONS, NULLCP,
1550: "badVersion: %d (SMUX %s)",
1551: simple -> version, source);
1552: return NOTOK;
1553: }
1554:
1555: pb -> pb_identity = simple -> identity;
1556: simple -> identity = NULL;
1557:
1558: if ((pb -> pb_description = qb2str (simple -> description))
1559: == NULL) {
1560: advise (LLOG_EXCEPTIONS, NULLCP,
1561: "qb2str: out of memory (SMUX %s)", source);
1562: return NOTOK;
1563: }
1564:
1565: if (qb_pullup (simple -> password) == NOTOK) {
1566: advise (LLOG_EXCEPTIONS, NULLCP,
1567: "qb_pullup: out of memory (SMUX %s)", source);
1568: return NOTOK;
1569: }
1570:
1571: if ((se = getsmuxEntrybyidentity (pb -> pb_identity)) == NULL
1572: || strcmp (se -> se_password,
1573: simple -> password -> qb_forw -> qb_data)) {
1574: advise (LLOG_EXCEPTIONS, NULLCP,
1575: "%s: %s (SMUX %s)",
1576: se ? "badPassword" : "badIdentity",
1577: oid2ode (simple -> identity), source);
1578: if (snmpstat.s_enableauthtraps == TRAPS_ENABLED)
1579: do_trap (int_SNMP_generic__trap_authenticationFailure,
1580: 0, (struct type_SNMP_VarBindList *) 0);
1581: return NOTOK;
1582: }
1583:
1584: if ((pb -> pb_priority = se -> se_priority) < 0)
1585: pb -> pb_priority = 0;
1586:
1587: advise (LLOG_NOTICE, NULLCP,
1588: "SMUX open: %d %s \"%s\" (%s)",
1589: pb -> pb_fd, oid2ode (pb -> pb_identity),
1590: pb -> pb_description, source);
1591: }
1592: break;
1593:
1594: case type_SNMP_SMUX__PDUs_close:
1595: if (!pb -> pb_identity)
1596: goto unexpected;
1597: advise (LLOG_NOTICE, NULLCP,
1598: "SMUX close: %s (%s)",
1599: smux_error (pdu -> un.close -> parm), source);
1600: return NOTOK;
1601:
1602: case type_SNMP_SMUX__PDUs_registerRequest:
1603: if (!pb -> pb_identity)
1604: goto unexpected;
1605: {
1606: register struct type_SNMP_RReqPDU *rreq =
1607: pdu -> un.registerRequest;
1608: struct type_SNMP_RRspPDU rrsp;
1609: struct type_SNMP_SMUX__PDUs rsp;
1610: register struct smuxReserved *sr;
1611: register struct smuxTree *tb = NULL;
1612: register struct smuxTree *qb;
1613: register OID oid = rreq -> subtree;
1614: OT ot = NULLOT;
1615: PE pe;
1616:
1617: for (sr = reserved; sr -> rb_text; sr++)
1618: if (sr -> rb_name
1619: && bcmp ((char *) sr -> rb_name -> oid_elements,
1620: (char *) oid -> oid_elements,
1621: (sr -> rb_name -> oid_nelem
1622: <= oid -> oid_nelem
1623: ? sr -> rb_name -> oid_nelem
1624: : oid -> oid_nelem)
1625: * sizeof oid -> oid_elements[0])
1626: == 0) {
1627: advise (LLOG_EXCEPTIONS, NULLCP,
1628: "reservedSubTree: %s %s %s (SMUX %s)",
1629: oid2ode (oid),
1630: sr -> rb_name -> oid_nelem
1631: <= oid -> oid_nelem
1632: ? "under" : "contains",
1633: sr -> rb_text, source);
1634: goto no_dice;
1635: }
1636:
1637: if ((ot = name2obj (oid)) == NULLOT) {
1638: if (rreq -> operation == int_SNMP_operation_delete) {
1639: advise (LLOG_EXCEPTIONS, NULLCP,
1640: "noSuchSubTree: %s (SMUX %s)",
1641: oid2ode (oid), source);
1642: goto no_dice;
1643: }
1644:
1645: if ((ot = (OT) calloc (1, sizeof *ot)) == NULL
1646: || (ot -> ot_text = ot -> ot_id =
1647: strdup (sprintoid (oid)))
1648: == NULL) {
1649: advise (LLOG_EXCEPTIONS, NULLCP,
1650: "out of memory (SMUX %s)", source);
1651: if (ot)
1652: free ((char *) ot);
1653: return NOTOK;
1654: }
1655: ot -> ot_name = rreq -> subtree;
1656: rreq -> subtree = NULL;
1657: ot -> ot_access = rreq -> operation;
1658: ot -> ot_status = OT_OPTIONAL;
1659: export_view (ot);
1660:
1661: add_objects (ot);
1662: }
1663: else {
1664: if (rreq -> operation == int_SNMP_operation_delete) {
1665: for (tb = (struct smuxTree *) ot -> ot_smux;
1666: tb;
1667: tb = tb -> tb_next)
1668: if (tb -> tb_peer == pb
1669: && (rreq -> priority < 0
1670: || rreq -> priority
1671: == tb -> tb_priority))
1672: break;
1673: if (tb)
1674: tb_free (tb);
1675: else {
1676: advise (LLOG_EXCEPTIONS, NULLCP,
1677: "noSuchRegistration: %s (SMUX %s)",
1678: oid2ode (oid), source);
1679: ot = NULLOT;
1680: }
1681: goto no_dice;
1682: }
1683:
1684: if (ot -> ot_name -> oid_nelem > oid -> oid_nelem) {
1685: advise (LLOG_EXCEPTIONS, NULLCP,
1686: "badSubTree: %s (SMUX %s)",
1687: oid2ode (oid), source);
1688: ot = NULL;
1689: goto no_dice;
1690: }
1691: }
1692:
1693: if ((tb = (struct smuxTree *) calloc (1, sizeof *tb))
1694: == NULL) {
1695: advise (LLOG_EXCEPTIONS, NULLCP,
1696: "out of memory (SMUX %s)", source);
1697: return NOTOK;
1698: }
1699:
1700: if ((tb -> tb_priority = rreq -> priority) < pb -> pb_priority)
1701: tb -> tb_priority = pb -> pb_priority;
1702: for (qb = (struct smuxTree *) ot -> ot_smux;
1703: qb;
1704: qb = qb -> tb_next)
1705: if (qb -> tb_priority > tb -> tb_priority)
1706: break;
1707: else
1708: if (qb -> tb_priority == tb -> tb_priority)
1709: tb -> tb_priority++;
1710:
1711: tb -> tb_peer = pb;
1712:
1713: no_dice: ;
1714: bzero ((char *) &rsp, sizeof rsp);
1715: rsp.offset = type_SNMP_SMUX__PDUs_registerResponse;
1716: rsp.un.registerResponse = &rrsp;
1717:
1718: bzero ((char *) &rrsp, sizeof rrsp);
1719: rrsp.parm = tb ? tb -> tb_priority
1720: : int_SNMP_RRspPDU_failure;
1721:
1722: pe = NULLPE;
1723:
1724: if (encode_SNMP_SMUX__PDUs (&pe, 1, 0, NULLCP, &rsp)
1725: != NOTOK) {
1726: PLOGP (pgm_log,SNMP_SMUX__PDUs, pe, "SMUX Message", 0);
1727:
1728: if (pe2ps (pb -> pb_ps, pe) == NOTOK) {
1729: advise (LLOG_EXCEPTIONS, NULLCP, "pe2ps: %s (SMUX %s)",
1730: ps_error (pb -> pb_ps -> ps_errno), source);
1731: result = NOTOK;
1732: }
1733: else {
1734: if (ot)
1735: advise (LLOG_NOTICE, NULLCP,
1736: "SMUX register: %s %s in=%d out=%d (%s)",
1737: rreq -> operation
1738: == int_SNMP_operation_delete ? "delete"
1739: : rreq -> operation
1740: == int_SNMP_operation_readOnly
1741: ? "readOnly" : "readWrite",
1742: oid2ode (ot -> ot_name),
1743: rreq -> priority,
1744: tb ? tb -> tb_priority : -1, source);
1745:
1746: if (tb
1747: && rreq -> operation
1748: != int_SNMP_operation_delete) {
1749: register int i;
1750: register unsigned int *ip,
1751: *jp;
1752: register struct smuxTree **qpp;
1753:
1754: tb -> tb_subtree = ot;
1755:
1756: for (qb = ot -> ot_smux
1757: ? (struct smuxTree *) ot -> ot_smux
1758: : THead -> tb_forw;
1759: qb != THead;
1760: qb = qb -> tb_forw)
1761: if ((i = oid_cmp (qb -> tb_subtree -> ot_name,
1762: ot -> ot_name)) > 0
1763: || (i == 0
1764: && qb -> tb_priority
1765: > tb -> tb_priority))
1766: break;
1767: insque (tb, qb != THead ? qb -> tb_forw
1768: : qb -> tb_back);
1769:
1770: for (qpp = (struct smuxTree **) &ot -> ot_smux;
1771: qb = *qpp;
1772: qpp = &qb -> tb_next)
1773: if (qb -> tb_priority > tb -> tb_priority)
1774: break;
1775: tb -> tb_next = qb;
1776: *qpp = tb;
1777:
1778: ip = tb -> tb_instance;
1779: jp = ot -> ot_name -> oid_elements;
1780: for (*ip++ = (i = ot -> ot_name -> oid_nelem);
1781: i > 0;
1782: i--)
1783: *ip++ = *jp++;
1784: *ip++ = tb -> tb_priority;
1785: tb -> tb_insize = ip - tb -> tb_instance;
1786: }
1787: }
1788: }
1789: else {
1790: advise (LLOG_EXCEPTIONS, NULLCP,
1791: "encode_SNMP_SMUX__PDUs: %s (SMUX %s)",
1792: PY_pepy, source);
1793: result = NOTOK;
1794: }
1795:
1796: if (pe)
1797: pe_free (pe);
1798: }
1799: break;
1800:
1801: case type_SNMP_SMUX__PDUs_trap:
1802: if (!pb -> pb_identity)
1803: goto unexpected;
1804: {
1805: struct qbuf *qb;
1806: struct type_SNMP_Message msgs;
1807: register struct type_SNMP_Message *msg = &msgs;
1808: struct type_SNMP_PDUs datas;
1809: register struct type_SNMP_PDUs *data = &datas;
1810: register struct type_SNMP_Trap__PDU *parm = pdu -> un.trap;
1811:
1812: advise (LLOG_NOTICE, NULLCP,
1813: "SMUX trap: %d %d (%s)",
1814: parm -> generic__trap, parm -> specific__trap, source);
1815:
1816: bzero ((char *) msg, sizeof *msg);
1817: msg -> version = int_SNMP_version_version__1;
1818: msg -> data = data;
1819:
1820: bzero ((char *) data, sizeof *data);
1821: data -> offset = type_SNMP_PDUs_trap;
1822: data -> un.trap = parm;
1823:
1824: if (loopback_addr
1825: && qb_pullup (qb = parm -> agent__addr) != NOTOK
1826: && qb -> qb_len == loopback_addr -> qb_len
1827: && bcmp (qb -> qb_forw -> qb_data,
1828: loopback_addr -> qb_forw -> qb_data,
1829: qb -> qb_len) == 0)
1830: parm -> agent__addr = trap -> data -> un.trap->agent__addr;
1831: do_traps (msg, parm -> generic__trap, parm -> specific__trap);
1832: parm -> agent__addr = qb;
1833: }
1834: break;
1835:
1836: case type_SNMP_SMUX__PDUs_registerResponse:
1837: case type_SNMP_SMUX__PDUs_get__request:
1838: case type_SNMP_SMUX__PDUs_get__next__request:
1839: case type_SNMP_SMUX__PDUs_get__response:
1840: case type_SNMP_SMUX__PDUs_set__request:
1841: unexpected: ;
1842: advise (LLOG_EXCEPTIONS, NULLCP,
1843: "unexpectedOperation: %d (SMUX %s)", pdu -> offset,
1844: source);
1845: return NOTOK;
1846:
1847: default:
1848: advise (LLOG_EXCEPTIONS, NULLCP,
1849: "badOperation: %d (SMUX %s)", pdu -> offset, source);
1850: return NOTOK;
1851: }
1852:
1853: return result;
1854: }
1855:
1856: /* */
1857:
1858: static int smux_getfnx (pdu, ot, pb, v, offset)
1859: struct type_SNMP_PDUs *pdu;
1860: OT ot;
1861: register struct smuxPeer *pb;
1862: register struct type_SNMP_VarBind *v;
1863: int offset;
1864: {
1865: int status,
1866: orig_id;
1867: struct type_SNMP_VarBindList *orig_bindings,
1868: vps;
1869: struct type_SNMP_SMUX__PDUs req,
1870: *rsp;
1871: register struct type_SNMP_GetResponse__PDU *get;
1872: PE pe;
1873:
1874: status = int_SNMP_error__status_noError;
1875: orig_id = pdu -> un.get__request -> request__id;
1876: orig_bindings = pdu -> un.get__request -> variable__bindings;
1877:
1878: bzero ((char *) &req, sizeof req);
1879: req.offset = offset == type_SNMP_PDUs_get__request
1880: ? type_SNMP_SMUX__PDUs_get__request
1881: : type_SNMP_SMUX__PDUs_get__next__request;
1882: req.un.get__request = pdu -> un.get__request;
1883:
1884: pdu -> un.get__request -> request__id = quantum;
1885:
1886: bzero ((char *) &vps, sizeof vps);
1887: vps.VarBind = v;
1888: pdu -> un.get__request -> variable__bindings = &vps;
1889:
1890: pe = NULLPE;
1891:
1892: if (encode_SNMP_SMUX__PDUs (&pe, 1, 0, NULLCP, &req) != NOTOK) {
1893: PLOGP (pgm_log,SNMP_SMUX__PDUs, pe, "SMUX Message", 0);
1894:
1895: if (pe2ps (pb -> pb_ps, pe) == NOTOK) {
1896: advise (LLOG_EXCEPTIONS, NULLCP, "pe2ps: %s (%s, SMUX %s)",
1897: ps_error (pb -> pb_ps -> ps_errno), source,
1898: pb -> pb_source);
1899:
1900: lost_peer: ;
1901: pb_free (pb);
1902: status = int_SNMP_error__status_genErr;
1903: }
1904: }
1905: else {
1906: advise (LLOG_EXCEPTIONS, NULLCP,
1907: "encode_SNMP_SMUX__PDUs: %s (%s)", PY_pepy, source);
1908: status = int_SNMP_error__status_genErr;
1909: }
1910:
1911: if (pe)
1912: pe_free (pe);
1913:
1914: pdu -> un.get__request -> request__id = orig_id;
1915: pdu -> un.get__request -> variable__bindings = orig_bindings;
1916:
1917: if (status != int_SNMP_error__status_noError)
1918: return status;
1919:
1920: if ((pe = ps2pe (pb -> pb_ps)) == NULLPE) {
1921: advise (LLOG_EXCEPTIONS, NULLCP, "ps2pe: %s (%s, SMUX %s)",
1922: ps_error (pb -> pb_ps -> ps_errno), source,
1923: pb -> pb_source);
1924:
1925: goto lost_peer;
1926: }
1927:
1928:
1929: rsp = NULL;
1930:
1931: if (decode_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, &rsp) == NOTOK) {
1932: advise (LLOG_EXCEPTIONS, NULLCP,
1933: "decode_SNMP_SMUX__PDUs: %s (%s, SMUX %s)", PY_pepy, source,
1934: pb -> pb_source);
1935:
1936: lost_peer_again: ;
1937: pb_free (pb);
1938: status = int_SNMP_error__status_genErr;
1939: goto out;
1940: }
1941:
1942: PLOGP (pgm_log,SNMP_SMUX__PDUs, pe, "SMUX Message", 1);
1943:
1944: if (rsp -> offset != type_SNMP_SMUX__PDUs_get__response) {
1945: advise (LLOG_EXCEPTIONS, NULLCP,
1946: "unexpectedOperation: %d (%s, SMUX %s)", rsp -> offset,
1947: source, pb -> pb_source);
1948:
1949: goto lost_peer_again;
1950: }
1951: get = rsp -> un.get__response;
1952:
1953: switch (status = get -> error__status) {
1954: case int_SNMP_error__status_noError:
1955: {
1956: register struct type_SNMP_VarBindList *vp;
1957: register struct type_SNMP_VarBind *v2;
1958:
1959: if ((vp = get -> variable__bindings) == NULL) {
1960: advise (LLOG_EXCEPTIONS, NULLCP,
1961: "missing variable in get response (%s, SMUX %s)",
1962: source, pb -> pb_source);
1963:
1964: goto lost_peer_again;
1965: }
1966: v2 = vp -> VarBind;
1967:
1968: if (offset == type_SNMP_PDUs_get__next__request
1969: && (ot -> ot_name -> oid_nelem
1970: > v2 -> name -> oid_nelem
1971: || bcmp ((char *) ot -> ot_name ->oid_elements,
1972: (char *) v2 -> name -> oid_elements,
1973: ot -> ot_name -> oid_nelem
1974: * sizeof ot -> ot_name ->
1975: oid_elements[0]))) {
1976: status = NOTOK;
1977: break;
1978: }
1979: free_SNMP_ObjectName (v -> name);
1980: v -> name = v2 -> name;
1981: v2 -> name = NULL;
1982: free_SNMP_ObjectSyntax (v -> value);
1983: v -> value = v2 -> value;
1984: v2 -> value = NULL;
1985: }
1986: break;
1987:
1988: case int_SNMP_error__status_noSuchName:
1989: if (offset == type_SNMP_PDUs_get__next__request) {
1990: status = NOTOK;
1991: break;
1992: }
1993: /* else fall */
1994:
1995: default:
1996: break;
1997: }
1998:
1999: out: ;
2000: if (rsp)
2001: free_SNMP_SMUX__PDUs (rsp);
2002: if (pe)
2003: pe_free (pe);
2004:
2005: return status;
2006: }
2007:
2008: /* */
2009:
2010: static pb_free (pb)
2011: register struct smuxPeer *pb;
2012: {
2013: register struct smuxTree *tb,
2014: *ub;
2015:
2016: if (pb == NULL)
2017: return;
2018:
2019: for (tb = THead -> tb_forw; tb != THead; tb = ub) {
2020: ub = tb -> tb_forw;
2021:
2022: if (tb -> tb_peer == pb)
2023: tb_free (tb);
2024: }
2025:
2026: if (pb -> pb_ps)
2027: ps_free (pb -> pb_ps);
2028:
2029: if (pb -> pb_fd != NOTOK) {
2030: (void) close_tcp_socket (pb -> pb_fd);
2031: FD_CLR (pb -> pb_fd, &ifds);
2032: FD_CLR (pb -> pb_fd, &sfds);
2033: }
2034:
2035: if (pb -> pb_identity)
2036: oid_free (pb -> pb_identity);
2037: if (pb -> pb_description)
2038: free (pb -> pb_description);
2039:
2040: remque (pb);
2041:
2042: free ((char *) pb);
2043: }
2044:
2045: /* */
2046:
2047: static tb_free (tb)
2048: register struct smuxTree *tb;
2049: {
2050: register struct smuxTree *tp,
2051: **tpp;
2052:
2053: if (tb == NULL)
2054: return;
2055:
2056: for (tpp = (struct smuxTree **) &tb -> tb_subtree -> ot_smux;
2057: tp = *tpp;
2058: tpp = &tp -> tb_next)
2059: if (tp == tb) {
2060: *tpp = tb -> tb_next;
2061: break;
2062: }
2063:
2064: remque (tb);
2065:
2066: free ((char *) tb);
2067: }
2068: #endif
2069:
2070: /* SNMP GROUP */
2071:
2072: static init_snmp ()
2073: {
2074: register OT ot;
2075:
2076: if (ot = text2obj ("snmpInPkts"))
2077: ot -> ot_getfnx = o_generic,
2078: ot -> ot_info = (caddr_t) &snmpstat.s_inpkts;
2079: if (ot = text2obj ("snmpOutPkts"))
2080: ot -> ot_getfnx = o_generic,
2081: ot -> ot_info = (caddr_t) &snmpstat.s_outpkts;
2082: if (ot = text2obj ("snmpInBadVersions"))
2083: ot -> ot_getfnx = o_generic,
2084: ot -> ot_info = (caddr_t) &snmpstat.s_badversions;
2085: if (ot = text2obj ("snmpInBadCommunityNames"))
2086: ot -> ot_getfnx = o_generic,
2087: ot -> ot_info = (caddr_t) &snmpstat.s_badcommunitynames;
2088: if (ot = text2obj ("snmpInBadCommunityUses"))
2089: ot -> ot_getfnx = o_generic,
2090: ot -> ot_info = (caddr_t) &snmpstat.s_badcommunityuses;
2091: if (ot = text2obj ("snmpInASNParseErrs"))
2092: ot -> ot_getfnx = o_generic,
2093: ot -> ot_info = (caddr_t) &snmpstat.s_asnparseerrs;
2094: if (ot = text2obj ("snmpInBadTypes"))
2095: ot -> ot_getfnx = o_generic,
2096: ot -> ot_info = (caddr_t) &snmpstat.s_badtypes;
2097: if (ot = text2obj ("snmpInTotalReqVars"))
2098: ot -> ot_getfnx = o_generic,
2099: ot -> ot_info = (caddr_t) &snmpstat.s_totalreqvars;
2100: if (ot = text2obj ("snmpInTotalSetVars"))
2101: ot -> ot_getfnx = o_generic,
2102: ot -> ot_info = (caddr_t) &snmpstat.s_totalsetvars;
2103: if (ot = text2obj ("snmpInGetRequests"))
2104: ot -> ot_getfnx = o_generic,
2105: ot -> ot_info = (caddr_t) &snmpstat.s_ingetrequests;
2106: if (ot = text2obj ("snmpInGetNexts"))
2107: ot -> ot_getfnx = o_generic,
2108: ot -> ot_info = (caddr_t) &snmpstat.s_ingetnexts;
2109: if (ot = text2obj ("snmpInSetRequests"))
2110: ot -> ot_getfnx = o_generic,
2111: ot -> ot_info = (caddr_t) &snmpstat.s_insetrequests;
2112: if (ot = text2obj ("snmpInGetResponses"))
2113: ot -> ot_getfnx = o_generic,
2114: ot -> ot_info = (caddr_t) &snmpstat.s_ingetresponses;
2115: if (ot = text2obj ("snmpInTraps"))
2116: ot -> ot_getfnx = o_generic,
2117: ot -> ot_info = (caddr_t) &snmpstat.s_intraps;
2118: if (ot = text2obj ("snmpOutTooBigs"))
2119: ot -> ot_getfnx = o_generic,
2120: ot -> ot_info = (caddr_t) &snmpstat.s_toobigs;
2121: if (ot = text2obj ("snmpOutNoSuchNames"))
2122: ot -> ot_getfnx = o_generic,
2123: ot -> ot_info = (caddr_t) &snmpstat.s_nosuchnames;
2124: if (ot = text2obj ("snmpOutBadValues"))
2125: ot -> ot_getfnx = o_generic,
2126: ot -> ot_info = (caddr_t) &snmpstat.s_badvalues;
2127: if (ot = text2obj ("snmpOutReadOnlys"))
2128: ot -> ot_getfnx = o_generic,
2129: ot -> ot_info = (caddr_t) &snmpstat.s_readonlys;
2130: if (ot = text2obj ("snmpOutGenErrs"))
2131: ot -> ot_getfnx = o_generic,
2132: ot -> ot_info = (caddr_t) &snmpstat.s_generrs;
2133: if (ot = text2obj ("snmpOutGetResponses"))
2134: ot -> ot_getfnx = o_generic,
2135: ot -> ot_info = (caddr_t) &snmpstat.s_outgetresponses;
2136: if (ot = text2obj ("snmpOutTraps"))
2137: ot -> ot_getfnx = o_generic,
2138: ot -> ot_info = (caddr_t) &snmpstat.s_outtraps;
2139: if (ot = text2obj ("snmpEnableAuthTraps"))
2140: ot -> ot_getfnx = o_generic,
2141: ot -> ot_info = (caddr_t) &snmpstat.s_enableauthtraps;
2142:
2143: if (ot = text2obj ("unixNetstat"))
2144: ot -> ot_getfnx = o_generic,
2145: ot -> ot_info = (caddr_t) &unix_netstat;
2146: }
2147:
2148: /* SMUX GROUP */
2149:
2150: #ifdef SMUX
2151: #define smuxPindex 0
2152: #define smuxPidentity 1
2153: #define smuxPdescription 2
2154: #define smuxPstatus 3
2155:
2156: #define PB_VALID 1 /* smuxPstatus */
2157: #define PB_CONNECTING 2 /* .. */
2158:
2159:
2160: static int o_smuxPeer (oi, v, offset)
2161: OI oi;
2162: register struct type_SNMP_VarBind *v;
2163: int offset;
2164: {
2165: int ifnum,
2166: ifvar;
2167: register struct smuxPeer *pb;
2168: register OID oid = oi -> oi_name;
2169: register OT ot = oi -> oi_type;
2170:
2171: ifvar = (int) ot -> ot_info;
2172: switch (offset) {
2173: case type_SNMP_PDUs_get__request:
2174: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1)
2175: return int_SNMP_error__status_noSuchName;
2176: ifnum = oid -> oid_elements[oid -> oid_nelem - 1];
2177: for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw)
2178: if (pb -> pb_fd == ifnum)
2179: break;
2180: if (pb == PHead
2181: || ((ifvar == smuxPidentity || ifvar == smuxPdescription)
2182: && pb -> pb_identity == NULL))
2183: return int_SNMP_error__status_noSuchName;
2184: break;
2185:
2186: case type_SNMP_PDUs_get__next__request:
2187: again: ;
2188: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
2189: OID new;
2190:
2191: if ((pb = PHead -> pb_forw) == PHead)
2192: return NOTOK;
2193: ifnum = pb -> pb_fd;
2194:
2195: if ((new = oid_extend (oid, 1)) == NULLOID)
2196: return int_SNMP_error__status_genErr;
2197: new -> oid_elements[new -> oid_nelem - 1] = ifnum;
2198:
2199: if (v -> name)
2200: free_SNMP_ObjectName (v -> name);
2201: v -> name = new;
2202: }
2203: else {
2204: int i = ot -> ot_name -> oid_nelem;
2205:
2206: ifnum = oid -> oid_elements[i];
2207: for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw)
2208: if (pb -> pb_fd >= ifnum)
2209: break;
2210: if (pb == PHead
2211: || ((pb -> pb_fd == ifnum)
2212: && (pb = pb -> pb_forw) == PHead))
2213: return NOTOK;
2214: ifnum = pb -> pb_fd;
2215:
2216: oid -> oid_elements[i] = ifnum;
2217: oid -> oid_nelem = i + 1;
2218: }
2219: if ((ifvar == smuxPidentity || ifvar == smuxPdescription)
2220: && pb -> pb_identity == NULL)
2221: goto again;
2222: break;
2223:
2224: default:
2225: return int_SNMP_error__status_genErr;
2226: }
2227:
2228: switch (ifvar) {
2229: case smuxPindex:
2230: return o_integer (oi, v, pb -> pb_fd);
2231:
2232: case smuxPidentity:
2233: return o_specific (oi, v, (caddr_t) pb -> pb_identity);
2234:
2235: case smuxPdescription:
2236: return o_string (oi, v, pb -> pb_description,
2237: strlen (pb -> pb_description));
2238:
2239: case smuxPstatus:
2240: return o_integer (oi, v, pb -> pb_identity ? PB_VALID
2241: : PB_CONNECTING);
2242:
2243: default:
2244: return int_SNMP_error__status_noSuchName;
2245: }
2246: }
2247:
2248: /* */
2249:
2250: static struct smuxTree *get_tbent (ip, len, isnext)
2251: register unsigned int *ip;
2252: int len;
2253: int isnext;
2254: {
2255: register struct smuxTree *tb;
2256:
2257: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
2258: switch (elem_cmp (tb -> tb_instance, tb -> tb_insize, ip, len)) {
2259: case 0:
2260: if (!isnext)
2261: return tb;
2262: if ((tb = tb -> tb_forw) == THead)
2263: return NULL;
2264: /* else fall... */
2265:
2266: case 1:
2267: return (isnext ? tb : NULL);
2268: }
2269:
2270: return NULL;
2271: }
2272:
2273: /* */
2274:
2275: #define smuxTsubtree 0
2276: #define smuxTpriority 1
2277: #define smuxTindex 2
2278: #define smuxTstatus 3
2279:
2280: #define TB_VALID 1 /* smuxTstatus */
2281:
2282:
2283: static int o_smuxTree (oi, v, offset)
2284: OI oi;
2285: register struct type_SNMP_VarBind *v;
2286: int offset;
2287: {
2288: int ifvar;
2289: register int i;
2290: register unsigned int *ip,
2291: *jp;
2292: register struct smuxTree *tb;
2293: register OID oid = oi -> oi_name;
2294: register OT ot = oi -> oi_type;
2295:
2296: ifvar = (int) ot -> ot_info;
2297: switch (offset) {
2298: case type_SNMP_PDUs_get__request:
2299: if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
2300: return int_SNMP_error__status_noSuchName;
2301: if ((tb = get_tbent (oid -> oid_elements
2302: + ot -> ot_name -> oid_nelem,
2303: oid -> oid_nelem
2304: - ot -> ot_name -> oid_nelem, 0)) == NULL)
2305: return int_SNMP_error__status_noSuchName;
2306: break;
2307:
2308: case type_SNMP_PDUs_get__next__request:
2309: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
2310: OID new;
2311:
2312: if ((tb = THead -> tb_forw) == THead)
2313: return NOTOK;
2314:
2315: if ((new = oid_extend (oid, tb -> tb_insize)) == NULLOID)
2316: return int_SNMP_error__status_genErr;
2317: ip = new -> oid_elements + new -> oid_nelem - tb -> tb_insize;
2318: jp = tb -> tb_instance;
2319: for (i = tb -> tb_insize; i > 0; i--)
2320: *ip++ = *jp++;
2321:
2322: if (v -> name)
2323: free_SNMP_ObjectName (v -> name);
2324: v -> name = new;
2325: }
2326: else {
2327: int j;
2328:
2329: if ((tb = get_tbent (oid -> oid_elements
2330: + ot -> ot_name -> oid_nelem,
2331: j = oid -> oid_nelem
2332: - ot -> ot_name -> oid_nelem, 1))
2333: == NULL)
2334: return NOTOK;
2335:
2336: if ((i = j - tb -> tb_insize) < 0) {
2337: OID new;
2338:
2339: if ((new = oid_extend (oid, -i)) == NULLOID)
2340: return int_SNMP_error__status_genErr;
2341: if (v -> name)
2342: free_SNMP_ObjectName (v -> name);
2343: v -> name = new;
2344:
2345: oid = new;
2346: }
2347: else
2348: if (i > 0)
2349: oid -> oid_nelem -= i;
2350:
2351: ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
2352: jp = tb -> tb_instance;
2353: for (i = tb -> tb_insize; i > 0; i--)
2354: *ip++ = *jp++;
2355: }
2356: break;
2357:
2358: default:
2359: return int_SNMP_error__status_genErr;
2360: }
2361:
2362: switch (ifvar) {
2363: case smuxTsubtree:
2364: return o_specific (oi, v, (caddr_t) tb -> tb_subtree -> ot_name);
2365:
2366: case smuxTpriority:
2367: return o_integer (oi, v, tb -> tb_priority);
2368:
2369: case smuxTindex:
2370: return o_integer (oi, v, tb -> tb_peer -> pb_fd);
2371:
2372: case smuxTstatus:
2373: return o_integer (oi, v, TB_VALID);
2374:
2375: default:
2376: return int_SNMP_error__status_noSuchName;
2377: }
2378: }
2379:
2380: /* */
2381:
2382: static init_smux ()
2383: {
2384: register OT ot;
2385:
2386: if (ot = text2obj ("smuxPindex"))
2387: ot -> ot_getfnx = o_smuxPeer,
2388: ot -> ot_info = (caddr_t) smuxPindex;
2389: if (ot = text2obj ("smuxPidentity"))
2390: ot -> ot_getfnx = o_smuxPeer,
2391: ot -> ot_info = (caddr_t) smuxPidentity;
2392: if (ot = text2obj ("smuxPdescription"))
2393: ot -> ot_getfnx = o_smuxPeer,
2394: ot -> ot_info = (caddr_t) smuxPdescription;
2395: if (ot = text2obj ("smuxPstatus"))
2396: ot -> ot_getfnx = o_smuxPeer,
2397: ot -> ot_info = (caddr_t) smuxPstatus;
2398:
2399: if (ot = text2obj ("smuxTsubtree"))
2400: ot -> ot_getfnx = o_smuxTree,
2401: ot -> ot_info = (caddr_t) smuxTsubtree;
2402: if (ot = text2obj ("smuxTpriority"))
2403: ot -> ot_getfnx = o_smuxTree,
2404: ot -> ot_info = (caddr_t) smuxTpriority;
2405: if (ot = text2obj ("smuxTindex"))
2406: ot -> ot_getfnx = o_smuxTree,
2407: ot -> ot_info = (caddr_t) smuxTindex;
2408: if (ot = text2obj ("smuxTstatus"))
2409: ot -> ot_getfnx = o_smuxTree,
2410: ot -> ot_info = (caddr_t) smuxTstatus;
2411: }
2412: #endif
2413:
2414: /* VIEW MIB */
2415:
2416: #define viewPrimName 0
2417: #define viewPrimTDomain 1
2418: #define viewPrimTAddr 2
2419: #define viewPrimUser 3
2420: #define viewPrimCommunity 4
2421: #define viewPrimType 5
2422:
2423: #define P_VALID 1 /* viewPrimType */
2424:
2425:
2426: struct view *get_prent ();
2427:
2428:
2429: static int o_viewPrim (oi, v, offset)
2430: OI oi;
2431: register struct type_SNMP_VarBind *v;
2432: int offset;
2433: {
2434: int ifvar;
2435: register int i;
2436: register unsigned int *ip,
2437: *jp;
2438: register struct view *vu;
2439: register OID oid = oi -> oi_name;
2440: register OT ot = oi -> oi_type;
2441:
2442: ifvar = (int) ot -> ot_info;
2443: switch (offset) {
2444: case type_SNMP_PDUs_get__request:
2445: if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
2446: return int_SNMP_error__status_noSuchName;
2447: if ((vu = get_prent (oid -> oid_elements
2448: + ot -> ot_name -> oid_nelem,
2449: oid -> oid_nelem
2450: - ot -> ot_name -> oid_nelem, 0)) == NULL)
2451: return int_SNMP_error__status_noSuchName;
2452: break;
2453:
2454: case type_SNMP_PDUs_get__next__request:
2455: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
2456: OID new;
2457:
2458: if ((vu = VHead -> v_forw) == VHead)
2459: return NOTOK;
2460:
2461: i = vu -> v_name -> oid_nelem + 1;
2462: if ((new = oid_extend (oid, i)) == NULLOID)
2463: return int_SNMP_error__status_genErr;
2464: ip = new -> oid_elements + new -> oid_nelem - i;
2465: jp = vu -> v_name -> oid_elements;
2466: *ip++ = i;
2467: for (i--; i > 0; i--)
2468: *ip++ = *jp++;
2469:
2470: if (v -> name)
2471: free_SNMP_ObjectName (v -> name);
2472: v -> name = new;
2473: }
2474: else {
2475: int j,
2476: k;
2477:
2478: if ((vu = get_prent (oid -> oid_elements
2479: + ot -> ot_name -> oid_nelem,
2480: j = oid -> oid_nelem
2481: - ot -> ot_name -> oid_nelem, 1))
2482: == NULL)
2483: return NOTOK;
2484:
2485: k = vu -> v_name -> oid_nelem + 1;
2486: if ((i = j - k) < 0) {
2487: OID new;
2488:
2489: if ((new = oid_extend (oid, -i)) == NULLOID)
2490: return int_SNMP_error__status_genErr;
2491: if (v -> name)
2492: free_SNMP_ObjectName (v -> name);
2493: v -> name = new;
2494:
2495: oid = new;
2496: }
2497: else
2498: if (i > 0)
2499: oid -> oid_nelem -= i;
2500:
2501: ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
2502: jp = vu -> v_name -> oid_elements;
2503: *ip++ = k;
2504: for (k--; k > 0; k--)
2505: *ip++ = *jp++;
2506: }
2507: break;
2508:
2509: default:
2510: return int_SNMP_error__status_genErr;
2511: }
2512:
2513: switch (ifvar) {
2514: case viewPrimName:
2515: return o_specific (oi, v, (caddr_t) vu -> v_name);
2516:
2517: case viewPrimTDomain:
2518: return o_specific (oi, v,
2519: (caddr_t) (vu -> v_community ? rfc1157Domain
2520: : localAgent));
2521:
2522: case viewPrimTAddr:
2523: #ifdef TCP
2524: if (vu -> v_community) {
2525: struct sockaddr_in *sin = (struct sockaddr_in *) &vu -> v_sa;
2526:
2527: return o_string (oi, v, (char *) &sin -> sin_addr, 4);
2528: }
2529: else
2530: #endif
2531: return o_string (oi, v, NULLCP, 0);
2532:
2533: case viewPrimUser:
2534: #ifdef TCP
2535: if (vu -> v_community)
2536: return o_qbstring (oi, v,
2537: trap -> data -> un.trap -> agent__addr);
2538: else
2539: #endif
2540: return o_string (oi, v, NULLCP, 0);
2541:
2542: case viewPrimCommunity:
2543: if (vu -> v_community)
2544: return o_qbstring (oi, v, vu -> v_community);
2545: else
2546: return o_string (oi, v, NULLCP, 0);
2547:
2548: case viewPrimType:
2549: return o_integer (oi, v, P_VALID);
2550:
2551: default:
2552: return int_SNMP_error__status_noSuchName;
2553: }
2554: }
2555:
2556: /* */
2557:
2558: static struct view *get_prent (ip, len, isnext)
2559: register unsigned int *ip;
2560: int len;
2561: int isnext;
2562: {
2563: register struct view *v;
2564:
2565: ip++, len--;
2566: for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
2567: switch (elem_cmp (v -> v_name -> oid_elements,v -> v_name -> oid_nelem,
2568: ip, len)) {
2569: case 0:
2570: if (!isnext)
2571: return v;
2572: if ((v = v -> v_forw) == VHead)
2573: return NULL;
2574: /* else fall... */
2575:
2576: case 1:
2577: return (isnext ? v : NULL);
2578: }
2579:
2580: return NULL;
2581: }
2582:
2583: /* */
2584:
2585: #define viewAclView 0
2586: #define viewAclCommunity 1
2587: #define viewAclUser 2
2588: #define viewAclPrivileges 3
2589: #define viewAclType 4
2590:
2591: #define A_VALID 1 /* viewAclType */
2592:
2593:
2594: struct community *get_acent ();
2595:
2596:
2597: static int o_viewAcl (oi, v, offset)
2598: OI oi;
2599: register struct type_SNMP_VarBind *v;
2600: int offset;
2601: {
2602: int ifvar;
2603: register int i;
2604: register unsigned int *ip,
2605: *jp;
2606: register struct community *c;
2607: register OID oid = oi -> oi_name;
2608: register OT ot = oi -> oi_type;
2609:
2610: ifvar = (int) ot -> ot_info;
2611: switch (offset) {
2612: case type_SNMP_PDUs_get__request:
2613: if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
2614: return int_SNMP_error__status_noSuchName;
2615: if ((c = get_acent (oid -> oid_elements
2616: + ot -> ot_name -> oid_nelem,
2617: oid -> oid_nelem
2618: - ot -> ot_name -> oid_nelem, 0)) == NULL)
2619: return int_SNMP_error__status_noSuchName;
2620: break;
2621:
2622: case type_SNMP_PDUs_get__next__request:
2623: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
2624: OID new;
2625:
2626: if ((c = CLex) == NULL)
2627: return NOTOK;
2628:
2629: if ((new = oid_extend (oid, c -> c_insize)) == NULLOID)
2630: return int_SNMP_error__status_genErr;
2631: ip = new -> oid_elements + new -> oid_nelem - c -> c_insize;
2632: jp = c -> c_instance;
2633: for (i = c -> c_insize; i > 0; i--)
2634: *ip++ = *jp++;
2635:
2636: if (v -> name)
2637: free_SNMP_ObjectName (v -> name);
2638: v -> name = new;
2639: }
2640: else {
2641: int j;
2642:
2643: if ((c = get_acent (oid -> oid_elements
2644: + ot -> ot_name -> oid_nelem,
2645: j = oid -> oid_nelem
2646: - ot -> ot_name -> oid_nelem, 1))
2647: == NULL)
2648: return NOTOK;
2649:
2650: if ((i = j - c -> c_insize) < 0) {
2651: OID new;
2652:
2653: if ((new = oid_extend (oid, -i)) == NULLOID)
2654: return int_SNMP_error__status_genErr;
2655: if (v -> name)
2656: free_SNMP_ObjectName (v -> name);
2657: v -> name = new;
2658:
2659: oid = new;
2660: }
2661: else
2662: if (i > 0)
2663: oid -> oid_nelem -= i;
2664:
2665: ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
2666: jp = c -> c_instance;
2667: for (i = c -> c_insize; i > 0; i--)
2668: *ip++ = *jp++;
2669: }
2670: break;
2671:
2672: default:
2673: return int_SNMP_error__status_genErr;
2674: }
2675:
2676: switch (ifvar) {
2677: case viewAclView:
2678: return o_specific (oi, v, (caddr_t) c -> c_view -> v_name);
2679:
2680: case viewAclCommunity:
2681: return o_string (oi, v, c -> c_name, strlen (c -> c_name));
2682:
2683: case viewAclUser:
2684: switch (c -> c_addr.na_type) {
2685: case NA_TCP:
2686: { /* hard to believe this is the easiest way of doing it */
2687: register char *bp,
2688: *ep;
2689: char buf[4];
2690:
2691: ip = c -> c_instance + 1 + strlen (c -> c_name) + 1;
2692: for (ep = (bp = buf + sizeof buf); bp < ep; )
2693: *bp++ = *ip++ & 0xff;
2694:
2695: return o_string (oi, v, buf, sizeof buf);
2696: }
2697:
2698: case NA_X25:
2699: return o_string (oi, v, c -> c_addr.na_dte,
2700: (int) c -> c_addr.na_dtelen);
2701:
2702: case NA_NSAP:
2703: return o_string (oi, v, c -> c_addr.na_address,
2704: (int) c -> c_addr.na_addrlen);
2705:
2706: default:
2707: return o_string (oi, v, NULLCP, 0);
2708: }
2709:
2710: case viewAclPrivileges:
2711: return o_integer (oi, v,
2712: ((c -> c_permission & OT_RDONLY) ? 3 : 0)
2713: + ((c -> c_permission & OT_WRONLY) ? 8 : 0)
2714: + ((c -> c_permission & OT_YYY) ? 4 : 0));
2715:
2716: case viewAclType:
2717: return o_integer (oi, v, A_VALID);
2718:
2719: default:
2720: return int_SNMP_error__status_noSuchName;
2721: }
2722: }
2723:
2724: /* */
2725:
2726: static struct community *get_acent (ip, len, isnext)
2727: register unsigned int *ip;
2728: int len;
2729: int isnext;
2730: {
2731: register struct community *c;
2732:
2733: for (c = CLex; c; c = c -> c_next)
2734: switch (elem_cmp (c -> c_instance, c -> c_insize, ip, len)) {
2735: case 0:
2736: return (isnext ? c -> c_next : c);
2737:
2738: case 1:
2739: return (isnext ? c : NULL);
2740: }
2741:
2742: return NULL;
2743: }
2744:
2745: /* */
2746:
2747: #define viewTrapView 0
2748: #define viewTrapGenerics 1
2749: #define viewTrapSpecifics 2
2750: #define viewTrapType 3
2751:
2752: #define T_VALID 1 /* viewTrapType */
2753:
2754:
2755: struct trap *get_trent ();
2756:
2757:
2758: static int o_viewTrap (oi, v, offset)
2759: OI oi;
2760: register struct type_SNMP_VarBind *v;
2761: int offset;
2762: {
2763: int ifvar;
2764: register int i;
2765: register unsigned int *ip,
2766: *jp;
2767: register struct trap *t;
2768: register OID oid = oi -> oi_name;
2769: register OT ot = oi -> oi_type;
2770:
2771: ifvar = (int) ot -> ot_info;
2772: switch (offset) {
2773: case type_SNMP_PDUs_get__request:
2774: if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
2775: return int_SNMP_error__status_noSuchName;
2776: if ((t = get_trent (oid -> oid_elements
2777: + ot -> ot_name -> oid_nelem,
2778: oid -> oid_nelem
2779: - ot -> ot_name -> oid_nelem, 0)) == NULL)
2780: return int_SNMP_error__status_noSuchName;
2781: break;
2782:
2783: case type_SNMP_PDUs_get__next__request:
2784: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
2785: OID new;
2786:
2787: if ((t = UHead -> t_forw) == UHead)
2788: return NOTOK;
2789:
2790: i = t -> t_view -> v_name -> oid_nelem + 1;
2791: if ((new = oid_extend (oid, i)) == NULLOID)
2792: return int_SNMP_error__status_genErr;
2793: ip = new -> oid_elements + new -> oid_nelem - i;
2794: jp = t -> t_view -> v_name -> oid_elements;
2795: *ip++ = i;
2796: for (i--; i > 0; i--)
2797: *ip++ = *jp++;
2798:
2799: if (v -> name)
2800: free_SNMP_ObjectName (v -> name);
2801: v -> name = new;
2802: }
2803: else {
2804: int j,
2805: k;
2806:
2807: if ((t = get_trent (oid -> oid_elements
2808: + ot -> ot_name -> oid_nelem,
2809: j = oid -> oid_nelem
2810: - ot -> ot_name -> oid_nelem, 1))
2811: == NULL)
2812: return NOTOK;
2813:
2814: k = t -> t_view -> v_name -> oid_nelem + 1;
2815: if ((i = j - k) < 0) {
2816: OID new;
2817:
2818: if ((new = oid_extend (oid, -i)) == NULLOID)
2819: return int_SNMP_error__status_genErr;
2820: if (v -> name)
2821: free_SNMP_ObjectName (v -> name);
2822: v -> name = new;
2823:
2824: oid = new;
2825: }
2826: else
2827: if (i > 0)
2828: oid -> oid_nelem -= i;
2829:
2830: ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
2831: jp = t -> t_view -> v_name -> oid_elements;
2832: *ip++ = k;
2833: for (k--; k > 0; k--)
2834: *ip++ = *jp++;
2835: }
2836: break;
2837:
2838: default:
2839: return int_SNMP_error__status_genErr;
2840: }
2841:
2842: switch (ifvar) {
2843: case viewTrapView:
2844: return o_specific (oi, v, (caddr_t) t -> t_view -> v_name);
2845:
2846: case viewTrapGenerics:
2847: {
2848: char c = t -> t_generics & 0xff;
2849:
2850: return o_string (oi, v, &c, sizeof c);
2851: }
2852:
2853: case viewTrapSpecifics:
2854: return o_string (oi, v, NULLCP, 0);
2855:
2856: case viewTrapType:
2857: return o_integer (oi, v, T_VALID);
2858:
2859: default:
2860: return int_SNMP_error__status_noSuchName;
2861: }
2862: }
2863:
2864: /* */
2865:
2866: static struct trap *get_trent (ip, len, isnext)
2867: register unsigned int *ip;
2868: int len;
2869: int isnext;
2870: {
2871: register struct trap *t;
2872:
2873: ip++, len--;
2874: for (t = UHead -> t_forw; t != UHead; t = t -> t_forw)
2875: switch (elem_cmp (t -> t_view -> v_name -> oid_elements,
2876: t -> t_view -> v_name -> oid_nelem,
2877: ip, len)) {
2878: case 0:
2879: if (!isnext)
2880: return t;
2881: if ((t = t -> t_forw) == UHead)
2882: return NULL;
2883: /* else fall... */
2884:
2885: case 1:
2886: return (isnext ? t : NULL);
2887: }
2888:
2889: return NULL;
2890: }
2891:
2892: /* */
2893:
2894: static int view_compar (a, b)
2895: struct view **a,
2896: **b;
2897: {
2898: return oid_cmp ((*a) -> v_name, (*b) -> v_name);
2899:
2900: }
2901:
2902: static int comm_compar (a, b)
2903: struct community **a,
2904: **b;
2905: {
2906: return elem_cmp ((*a) -> c_instance, (*a) -> c_insize,
2907: (*b) -> c_instance, (*b) -> c_insize);
2908: }
2909:
2910: static int trap_compar (a, b)
2911: struct trap **a,
2912: **b;
2913: {
2914: return oid_cmp ((*a) -> t_view -> v_name, (*b) -> t_view -> v_name);
2915: }
2916:
2917:
2918: static init_view ()
2919: {
2920: register int i;
2921: register OT ot;
2922: register struct community *c;
2923: register struct view *v;
2924: register struct trap *t;
2925:
2926: if (ot = text2obj ("viewPrimName"))
2927: ot -> ot_getfnx = o_viewPrim,
2928: ot -> ot_info = (caddr_t) viewPrimName;
2929: if (ot = text2obj ("viewPrimTDomain"))
2930: ot -> ot_getfnx = o_viewPrim,
2931: ot -> ot_info = (caddr_t) viewPrimTDomain;
2932: if (ot = text2obj ("viewPrimTAddr"))
2933: ot -> ot_getfnx = o_viewPrim,
2934: ot -> ot_info = (caddr_t) viewPrimTAddr;
2935: if (ot = text2obj ("viewPrimUser"))
2936: ot -> ot_getfnx = o_viewPrim,
2937: ot -> ot_info = (caddr_t) viewPrimUser;
2938: if (ot = text2obj ("viewPrimCommunity"))
2939: ot -> ot_getfnx = o_viewPrim,
2940: ot -> ot_info = (caddr_t) viewPrimCommunity;
2941: if (ot = text2obj ("viewPrimType"))
2942: ot -> ot_getfnx = o_viewPrim,
2943: ot -> ot_info = (caddr_t) viewPrimType;
2944:
2945: if (ot = text2obj ("viewAclView"))
2946: ot -> ot_getfnx = o_viewAcl,
2947: ot -> ot_info = (caddr_t) viewAclView;
2948: if (ot = text2obj ("viewAclCommunity"))
2949: ot -> ot_getfnx = o_viewAcl,
2950: ot -> ot_info = (caddr_t) viewAclCommunity;
2951: if (ot = text2obj ("viewAclUser"))
2952: ot -> ot_getfnx = o_viewAcl,
2953: ot -> ot_info = (caddr_t) viewAclUser;
2954: if (ot = text2obj ("viewAclPrivileges"))
2955: ot -> ot_getfnx = o_viewAcl,
2956: ot -> ot_info = (caddr_t) viewAclPrivileges;
2957: if (ot = text2obj ("viewAclType"))
2958: ot -> ot_getfnx = o_viewAcl,
2959: ot -> ot_info = (caddr_t) viewAclType;
2960:
2961: if (ot = text2obj ("viewTrapView"))
2962: ot -> ot_getfnx = o_viewTrap,
2963: ot -> ot_info = (caddr_t) viewTrapView;
2964: if (ot = text2obj ("viewTrapGenerics"))
2965: ot -> ot_getfnx = o_viewTrap,
2966: ot -> ot_info = (caddr_t) viewTrapGenerics;
2967: if (ot = text2obj ("viewTrapSpecifics"))
2968: ot -> ot_getfnx = o_viewTrap,
2969: ot -> ot_info = (caddr_t) viewTrapSpecifics;
2970: if (ot = text2obj ("viewTrapType"))
2971: ot -> ot_getfnx = o_viewTrap,
2972: ot -> ot_info = (caddr_t) viewTrapType;
2973:
2974: i = 0;
2975: for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
2976: i++;
2977: if (i > 1) {
2978: register struct view **base,
2979: **bp,
2980: **ep;
2981:
2982: if ((base = (struct view **) malloc ((unsigned) (i * sizeof *base)))
2983: == NULL)
2984: adios (NULLCP, "out of memory");
2985: ep = base;
2986: for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
2987: remque (*ep++ = v);
2988: VHead -> v_forw = VHead -> v_back = VHead;
2989:
2990: qsort ((char *) base, i, sizeof *base, view_compar);
2991:
2992: bp = base;
2993: while (bp < ep)
2994: insque (*bp++, VHead -> v_back);
2995:
2996: free ((char *) base);
2997: }
2998:
2999: i = 0;
3000: for (c = CHead -> c_forw; c != CHead; c = c -> c_forw)
3001: i++;
3002: if (i > 0) {
3003: int j;
3004: register struct community **base,
3005: **bp,
3006: **ep;
3007:
3008: if ((base = (struct community **)
3009: malloc ((unsigned) (i * sizeof *base))) == NULL)
3010: adios (NULLCP, "out of memory");
3011: ep = base;
3012: for (c = CHead -> c_forw; c != CHead; c = c -> c_forw) {
3013: register char *cp,
3014: *dp;
3015: register unsigned int *ip;
3016:
3017: switch (c -> c_addr.na_stack) {
3018: case NA_TCP:
3019: j = 4;
3020: break;
3021:
3022: case NA_X25:
3023: j = c -> c_addr.na_dtelen;
3024: break;
3025:
3026: case NA_NSAP:
3027: j = c -> c_addr.na_addrlen;
3028: break;
3029:
3030: default:
3031: j = 0;
3032: break;
3033: }
3034:
3035: c -> c_insize = 1 + strlen (c -> c_name) + 1 + j;
3036: if ((c -> c_instance =
3037: (unsigned int *) calloc ((unsigned) c -> c_insize,
3038: sizeof *c -> c_instance)) == NULL)
3039: adios (NULLCP, "out of memory");
3040: ip = c -> c_instance;
3041:
3042: *ip++ = strlen (c -> c_name);
3043: for (cp = c -> c_name; *cp; cp++)
3044: *ip++ = *cp & 0xff;
3045:
3046: *ip++ = j;
3047: switch (c -> c_addr.na_stack) {
3048: case NA_TCP:
3049: (void) sscanf (c -> c_addr.na_domain, "%u.%u.%u.%u",
3050: ip, ip + 1, ip + 2, ip + 3);
3051: break;
3052:
3053: case NA_X25:
3054: dp = (cp = c -> c_addr.na_dte) + c -> c_addr.na_dtelen;
3055: goto stuff_it;
3056:
3057: case NA_NSAP:
3058: dp = (cp = c -> c_addr.na_address) + c ->c_addr.na_addrlen;
3059: stuff_it: ;
3060: while (cp < dp)
3061: *ip++ = *cp++ & 0xff;
3062: break;
3063:
3064: default:
3065: break;
3066: }
3067:
3068: *ep++ = c;
3069: }
3070:
3071: if (i > 1)
3072: qsort ((char *) base, i, sizeof *base, comm_compar);
3073:
3074: bp = base;
3075: c = CLex = *bp++;
3076: while (bp < ep) {
3077: c -> c_next = *bp;
3078: c = *bp++;
3079: }
3080: c -> c_next = NULL;
3081:
3082: free ((char *) base);
3083: }
3084: else
3085: CLex = NULL;
3086:
3087: i = 0;
3088: for (t = UHead -> t_forw; t != UHead; t = t -> t_forw)
3089: i++;
3090: if (i > 1) {
3091: register struct trap **base,
3092: **bp,
3093: **ep;
3094:
3095: if ((base = (struct trap **) malloc ((unsigned) (i * sizeof *base)))
3096: == NULL)
3097: adios (NULLCP, "out of memory");
3098: ep = base;
3099: for (t = UHead -> t_forw; t != UHead; t = t -> t_forw)
3100: remque (*ep++ = t);
3101: UHead -> t_forw = UHead -> t_back = UHead;
3102:
3103: qsort ((char *) base, i, sizeof *base, trap_compar);
3104:
3105: bp = base;
3106: while (bp < ep)
3107: insque (*bp++, UHead -> t_back);
3108:
3109: free ((char *) base);
3110: }
3111:
3112: if (debug) {
3113: fprintf (stderr, "///////\nprimitive view table\n");
3114: for (v = VHead -> v_forw; v != VHead; v = v -> v_forw) {
3115: fprintf (stderr, "name=%s ", sprintoid (v -> v_name));
3116: if (v -> v_community) {
3117: register char *cp,
3118: *ep;
3119: char *p;
3120: register struct qbuf *qb;
3121: #ifdef TCP
3122: struct qbuf *x = trap -> data -> un.trap -> agent__addr;
3123: struct sockaddr_in *sin = (struct sockaddr_in *) &v -> v_sa;
3124: #endif
3125:
3126: fprintf (stderr, "tDomain=%s tAddr=", sprintoid (rfc1157Domain));
3127: #ifdef TCP
3128: p = "0x";
3129: for (ep = (cp = (char *) &sin -> sin_addr) + 4; cp < ep; cp++) {
3130: fprintf (stderr, "%s%02x", p, *cp & 0xff);
3131: p = ":";
3132: }
3133: for (ep = (cp = (char *) &sin -> sin_port) + 2; cp < ep; cp++)
3134: fprintf (stderr, ":%02x", *cp & 0xff);
3135: #else
3136: fprintf (stderr, "\"\"");
3137: #endif
3138: fprintf (stderr, " user=");
3139: #ifdef TCP
3140: p = "0x";
3141: for (qb = x -> qb_forw; qb != x; qb = qb -> qb_forw)
3142: for (ep = (cp = qb -> qb_data) + qb -> qb_len; cp < ep; cp++) {
3143: fprintf (stderr, "%s%02x", p, *cp & 0xff);
3144: p = ":";
3145: }
3146: #else
3147: fprintf (stderr, "\"\"");
3148: #endif
3149: fprintf (stderr," community=\"");
3150: for (qb = v -> v_community -> qb_forw;
3151: qb != v -> v_community;
3152: qb = qb -> qb_forw)
3153: fprintf (stderr, "%*.*s", qb -> qb_len, qb -> qb_len,
3154: qb -> qb_data);
3155: fprintf (stderr, "\"");
3156: }
3157: else
3158: fprintf (stderr, "tDomain=%s ...", sprintoid (localAgent));
3159: fprintf (stderr, "\n");
3160: }
3161: fprintf(stderr,"\nview access table\n");
3162: for (c = CLex; c; c = c -> c_next) {
3163: OIDentifier oids;
3164: oids.oid_elements = c -> c_instance, oids.oid_nelem = c -> c_insize;
3165: fprintf (stderr,"acl=%s ", sprintoid (&oids));
3166: fprintf (stderr, "view=%s community=%s user=%s privileges=%d\n",
3167: sprintoid (c -> c_view -> v_name), c -> c_name,
3168: na2str (&c -> c_addr),
3169: ((c -> c_permission & OT_RDONLY) ? 3 : 0)
3170: + ((c -> c_permission & OT_WRONLY) ? 8 : 0)
3171: + ((c -> c_permission & OT_YYY) ? 4 : 0));
3172: }
3173: fprintf(stderr,"\ntrap table\n");
3174: for (t = UHead -> t_forw; t != UHead; t = t -> t_forw) {
3175: v = t -> t_view;
3176: fprintf (stderr, "view=%s generics=0x%x specifics=null\n",
3177: sprintoid (v -> v_name), t -> t_generics);
3178: }
3179: fprintf(stderr,"///////\n");
3180: compat_log -> ll_events |= LLOG_TRACE;
3181: compat_log -> ll_stat |= LLOGTTY;
3182: }
3183: }
3184:
3185: /* VIEWS */
3186:
3187: static initview () {
3188: register OT ot;
3189:
3190: for (ot = text2obj ("ccitt"); ot; ot = ot -> ot_next)
3191: if (ot -> ot_getfnx != NULL && ot -> ot_access != OT_NONE)
3192: export_view (ot);
3193: }
3194:
3195: /* */
3196:
3197: #define inSubtree(tree,object) \
3198: ((tree) -> oid_nelem <= (object) -> oid_nelem \
3199: && bcmp ((char *) (tree) -> oid_elements, \
3200: (char *) (object) -> oid_elements, \
3201: (tree) -> oid_nelem \
3202: * sizeof ((tree) -> oid_elements[0])) == 0)
3203:
3204:
3205: static export_view (ot)
3206: register OT ot;
3207: {
3208: register struct subtree *s;
3209: register struct view *v;
3210: OID name = ot -> ot_name;
3211:
3212: ot -> ot_views = 0;
3213: for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
3214: if ((s = v -> v_subtree.s_forw) != &v -> v_subtree) {
3215: for (; s != &v -> v_subtree; s = s -> s_forw)
3216: if (inSubtree (s -> s_subtree, name))
3217: goto mark_it;
3218: }
3219: else {
3220: mark_it: ;
3221: ot -> ot_views |= v -> v_mask;
3222: }
3223: }
3224:
3225: /* COMMUNITIES */
3226:
3227: struct community *str2comm (name, na)
3228: char *name;
3229: register struct NSAPaddr *na;
3230: {
3231: register struct community *c,
3232: *d;
3233:
3234: d = NULL;
3235: for (c = CHead -> c_forw; c != CHead; c = c -> c_forw)
3236: if (strcmp (c -> c_name, name) == 0) {
3237: if (c -> c_addr.na_stack == NA_TCP
3238: && strcmp (c -> c_addr.na_domain, "0.0.0.0") == 0) {
3239: d = c;
3240: continue;
3241: }
3242: else {
3243: if (c -> c_addr.na_stack != na -> na_stack)
3244: continue;
3245: switch (na -> na_stack) {
3246: case NA_TCP:
3247: if (strcmp (c -> c_addr.na_domain, na -> na_domain))
3248: continue;
3249: break;
3250:
3251: case NA_X25:
3252: if (c -> c_addr.na_dtelen != na -> na_dtelen
3253: || bcmp (c -> c_addr.na_dte,
3254: na -> na_dte, na -> na_dtelen))
3255: continue;
3256: break;
3257:
3258: case NA_NSAP:
3259: if (c -> c_addr.na_addrlen != na -> na_addrlen
3260: || bcmp (c -> c_addr.na_address,
3261: na -> na_address, na -> na_addrlen))
3262: continue;
3263: break;
3264:
3265: default:
3266: adios (NULLCP,
3267: "unknown network type (0x%x) for community \"%s\"",
3268: na -> na_stack, name);
3269: /* NOTREACHED */
3270: }
3271: }
3272:
3273: d = c;
3274: break;
3275: }
3276:
3277: if (d) {
3278: remque (d);
3279: insque (d, CHead);
3280: }
3281:
3282: return d;
3283: }
3284:
3285: /* TRAPS */
3286:
3287: static initrap () {
3288: #ifdef TCP
3289: char myhost[BUFSIZ];
3290: register struct hostent *hp;
3291: struct type_SNMP_Message *msg;
3292: register struct type_SNMP_PDUs *pdu;
3293: register struct type_SNMP_Trap__PDU *parm;
3294:
3295: if ((msg = (struct type_SNMP_Message *) calloc (1, sizeof *msg)) == NULL) {
3296: no_mem: ;
3297: advise (LLOG_EXCEPTIONS, NULLCP,
3298: "unable to initialize trap structure: out of memory");
3299: out: ;
3300: if (msg)
3301: free_SNMP_Message (msg);
3302:
3303: return;
3304: }
3305: msg -> version = int_SNMP_version_version__1;
3306:
3307: if ((pdu = (struct type_SNMP_PDUs *) calloc (1, sizeof *pdu)) == NULL)
3308: goto no_mem;
3309: msg -> data = pdu;
3310:
3311: pdu -> offset = type_SNMP_PDUs_trap;
3312:
3313: if ((parm = (struct type_SNMP_Trap__PDU *) calloc (1, sizeof *parm))
3314: == NULL)
3315: goto no_mem;
3316: pdu -> un.trap = parm;
3317:
3318: (void) strcpy (myhost, TLocalHostName ());
3319: if (hp = gethostbystring (myhost)) {
3320: struct sockaddr_in sin;
3321:
3322: inaddr_copy (hp, &sin);
3323: if ((parm -> agent__addr = str2qb ((char *) &sin.sin_addr, 4, 1))
3324: == NULL)
3325: goto no_mem;
3326: }
3327: else {
3328: advise (LLOG_EXCEPTIONS, NULLCP,
3329: "%s: unknown host, so no traps", myhost);
3330: goto out;
3331: }
3332:
3333: if ((parm -> time__stamp = (struct type_SNMP_TimeTicks *)
3334: calloc (1, sizeof *parm -> time__stamp)) == NULL)
3335: goto no_mem;
3336:
3337: trap = msg;
3338:
3339: #ifdef SMUX
3340: if (hp = gethostbystring ("localhost")) {
3341: struct sockaddr_in sin;
3342:
3343: inaddr_copy (hp, &sin);
3344: if ((loopback_addr = str2qb ((char *) &sin.sin_addr, 4, 1)) == NULL)
3345: advise (LLOG_EXCEPTIONS, NULLCP,
3346: "unable to initialize loopback address: out of memory");
3347: }
3348: #endif
3349: #endif
3350: }
3351:
3352: /* */
3353:
3354: #ifndef TCP
3355: /* ARGSUSED */
3356: #endif
3357:
3358: static do_trap (generic, specific, bindings)
3359: int generic,
3360: specific;
3361: struct type_SNMP_VarBindList *bindings;
3362: {
3363: #ifdef TCP
3364: struct type_SNMP_Message *msg;
3365: register struct type_SNMP_Trap__PDU *parm;
3366: OT ot;
3367:
3368: if ((msg = trap) == NULL)
3369: return;
3370: parm = msg -> data -> un.trap;
3371:
3372: if ((ot = text2obj ("sysObjectID")) == NULLOT) {
3373: advise (LLOG_EXCEPTIONS, NULLCP,
3374: "unable to send trap: no such object: \"%s\"",
3375: "sysObjectID");
3376: return;
3377: }
3378: if ((parm -> enterprise = (OID) ot -> ot_info) == NULLOID) {
3379: advise (LLOG_EXCEPTIONS, NULLCP,
3380: "unable to send trap: no value defined for object \"%s\"",
3381: "sysObjectID");
3382: return;
3383: }
3384:
3385: parm -> generic__trap = generic;
3386: parm -> specific__trap = specific;
3387: {
3388: struct timeval boottime,
3389: now;
3390:
3391: if (getkmem (nl + N_BOOTTIME, (caddr_t) &boottime, sizeof boottime)
3392: == NOTOK) {
3393: advise (LLOG_EXCEPTIONS, NULLCP,
3394: "unable to send trap: read of boottime failed");
3395: return;
3396: }
3397: if (gettimeofday (&now, (struct timezone *) 0) == NOTOK) {
3398: advise (LLOG_EXCEPTIONS, "failed", "gettimeofday");
3399: return;
3400: }
3401:
3402: parm -> time__stamp -> parm = (now.tv_sec - boottime.tv_sec) * 100
3403: + ((now.tv_usec - boottime.tv_usec)
3404: / 10000);
3405: }
3406: parm -> variable__bindings = bindings;
3407:
3408: do_traps (msg, generic, specific);
3409: #endif
3410: }
3411:
3412: /* */
3413:
3414: #ifdef TCP
3415: static do_traps (msg, generic, specific)
3416: register struct type_SNMP_Message *msg;
3417: int generic,
3418: specific;
3419: {
3420: int mask = 1 << 7 - generic;
3421: register struct trap *t;
3422:
3423: for (t = UHead -> t_forw; t != UHead; t = t -> t_forw) {
3424: register struct view *v = t -> t_view;
3425: PE pe;
3426: PS ps;
3427:
3428: if (specific == 0 && !(t -> t_generics & mask))
3429: continue;
3430:
3431: msg -> community = v -> v_community;
3432:
3433: pe = NULLPE;
3434: if (encode_SNMP_Message (&pe, 1, 0, NULLCP, msg) == NOTOK) {
3435: advise (LLOG_EXCEPTIONS, NULLCP,
3436: "encode_SNMP_Message: %s", PY_pepy);
3437: if (pe)
3438: pe_free (pe);
3439: continue;
3440: }
3441: PLOGP (pgm_log,SNMP_Message, pe, "Message", 0);
3442:
3443: if ((ps = ps_alloc (dg_open)) == NULLPS
3444: || dg_setup (ps, udp, MAXDGRAM, read_udp_socket,
3445: write_udp_socket) == NOTOK) {
3446: if (ps == NULLPS)
3447: advise (LLOG_EXCEPTIONS, NULLCP, "ps_alloc: out of memory");
3448: else
3449: advise (LLOG_EXCEPTIONS, NULLCP, "dg_setup: %s",
3450: ps_error (ps -> ps_errno));
3451: }
3452: else
3453: if (hack_dgram_socket (udp, &v -> v_sa)
3454: == NOTOK)
3455: advise (LLOG_EXCEPTIONS, "failed", "hack_dgram_socket(1)");
3456: else
3457: if (pe2ps (ps, pe) == NOTOK)
3458: advise (LLOG_EXCEPTIONS, NULLCP, "pe2ps: %s",
3459: ps_error (ps -> ps_errno));
3460: else {
3461: snmpstat.s_outpkts++, snmpstat.s_outtraps++;
3462:
3463: if (hack_dgram_socket (udp, (struct sockaddr *) NULL)
3464: == NOTOK)
3465: advise (LLOG_EXCEPTIONS, "failed",
3466: "hack_dgram_socket(2)");
3467: }
3468:
3469: pe_free (pe);
3470:
3471: if (ps)
3472: ps_free (ps);
3473: else
3474: break;
3475: }
3476: }
3477: #endif
3478: #else /* SNMPT */
3479:
3480: /* */
3481:
3482: /* ARGSUSED */
3483:
3484: static int process (ps, msg, na)
3485: PS ps;
3486: register struct type_SNMP_Message *msg;
3487: struct NSAPaddr *na;
3488: {
3489: char *cp;
3490: long now;
3491: PE pe,
3492: p;
3493: register struct type_SNMP_PDUs *pdu = msg -> data;
3494: register struct tm *tm;
3495: struct UTCtime uts;
3496: register struct UTCtime *ut = &uts;
3497: register struct type_SNMP_Audit *au;
3498:
3499: if (msg -> version != int_SNMP_version_version__1) {
3500: advise (LLOG_EXCEPTIONS, NULLCP, "badVersion: %d (%s)",
3501: msg -> version, source);
3502: return NOTOK;
3503: }
3504:
3505: if (pdu -> offset != type_SNMP_PDUs_trap) {
3506: advise (LLOG_EXCEPTIONS, NULLCP,
3507: "unexpectedOperation: %d (%s)", pdu -> offset, source);
3508: return NOTOK;
3509: }
3510:
3511: pe = p = NULLPE;
3512: au = NULL;
3513:
3514: if (encode_SNMP_Message (&p, 1, 0, NULLCP, msg) == NOTOK) {
3515: advise (LLOG_EXCEPTIONS, NULLCP, "encode_SNMP_Message: %s (%s)",
3516: PY_pepy, source);
3517: goto out;
3518: }
3519:
3520: if ((au = (struct type_SNMP_Audit *) calloc (1, sizeof *au)) == NULL)
3521: goto no_mem;
3522: au -> sizeOfEncodingWhichFollows = ps_get_abs (p);
3523:
3524: if ((au -> source = str2qb (source, strlen (source), 1)) == NULL) {
3525: no_mem: ;
3526: advise (LLOG_EXCEPTIONS, NULLCP, "out of memory for audit (%s)",
3527: source);
3528: goto out;
3529: }
3530: (void) time (&now);
3531:
3532: if (tm = gmtime (&now))
3533: tm2ut (tm, ut);
3534: else {
3535: advise (LLOG_EXCEPTIONS, NULLCP, "gmtime failed");
3536:
3537: bzero ((char *) ut, sizeof *ut);
3538: }
3539:
3540: if ((cp = gent2str (ut)) == NULL
3541: || (au -> dateAndTime = str2qb (cp, strlen (cp), 1)) == NULL)
3542: goto no_mem;
3543:
3544: if (encode_SNMP_Audit (&pe, 1, 0, NULLCP, au) != NOTOK) {
3545: PLOGP (pgm_log,SNMP_Audit, pe, "Audit", 0);
3546: PLOGP (pgm_log,SNMP_Message, p, "Message", 0);
3547:
3548: if (pe2ps (audit, pe) == NOTOK || pe2ps (audit, p) == NOTOK)
3549: advise (LLOG_EXCEPTIONS, NULLCP, "pe2ps: %s (%s)",
3550: ps_error (audit -> ps_errno), source);
3551:
3552: (void) ps_flush (audit);
3553: }
3554: else
3555: advise (LLOG_EXCEPTIONS, NULLCP, "encode_SNMP_Audit: %s (%s)",
3556: PY_pepy, source);
3557:
3558: out: ;
3559: if (au)
3560: free_SNMP_Audit (au);
3561: if (pe)
3562: pe_free (pe);
3563: if (p)
3564: pe_free (p);
3565:
3566: return DONE;
3567: }
3568: #endif /* SNMPT */
3569:
3570: /* MISCELLANY */
3571:
3572: static arginit (vec)
3573: char **vec;
3574: {
3575: register char *ap;
3576: #ifdef SNMPT
3577: char *file = "snmp.traps";
3578: FILE *fp;
3579: #endif
3580: #ifdef TCP
3581: int port;
3582: struct NSAPaddr *tcp_na;
3583: register struct servent *sp;
3584: #endif
3585: #ifdef X25
3586: struct NSAPaddr *x25_na;
3587: #endif
3588:
3589: if (myname = rindex (*vec, '/'))
3590: myname++;
3591: if (myname == NULL || *myname == NULL)
3592: myname = *vec;
3593:
3594: isodetailor (myname, 0);
3595: ll_hdinit (pgm_log, myname);
3596:
3597: bzero ((char *) tas, sizeof tas);
3598: tz = tas;
3599:
3600: #ifdef TCP
3601: if (!(ts_stacks & TS_TCP))
3602: tcpservice = 0;
3603: if ((sp = getservbyname ("snmp", "udp")) == NULL)
3604: advise (LLOG_EXCEPTIONS, NULLCP, "udp/snmp: unknown service");
3605:
3606: tcp_na = tz -> ta_addrs;
3607: tcp_na -> na_stack = NA_TCP;
3608: tcp_na -> na_community = ts_comm_tcp_default;
3609: tcp_na -> na_domain[0] = NULL;
3610: #ifndef SNMPT
3611: tcp_na -> na_port = sp ? sp -> s_port : htons ((u_short) 161);
3612: udport = tcp_na -> na_port;
3613: #endif
3614: tz -> ta_naddr = 1;
3615:
3616: tz++;
3617:
3618: if ((sp = getservbyname ("snmp-trap", "udp")) == NULL)
3619: advise (LLOG_EXCEPTIONS, NULLCP, "udp/snmp-trap: unknown service");
3620: #ifndef SNMPT
3621: traport = sp ? sp -> s_port : htons ((u_short) 162);
3622: #else
3623: tcp_na -> na_port = sp ? sp -> s_port : htons ((u_short) 162);
3624: #endif
3625: #endif
3626:
3627: #ifdef COTS
3628: bzero ((char *) taddrs, sizeof taddrs);
3629: bzero ((char *) lru, sizeof lru);
3630: #endif
3631:
3632: #ifdef X25
3633: if (!(ts_stacks & TS_X25))
3634: x25service = 0;
3635:
3636: x25_na = tz -> ta_addrs;
3637: x25_na -> na_stack = NA_X25;
3638: x25_na -> na_community = ts_c_x25_default;
3639: if (x25_local_dte && *x25_local_dte) {
3640: (void) strcpy (x25_na -> na_dte, x25_local_dte);
3641: x25_na -> na_dtelen = strlen (x25_na -> na_dte);
3642: }
3643: #ifndef SNMPT
3644: x25_na -> na_pidlen = str2sel ("03018200", -1, x25_na -> na_pid, NPSIZE);
3645: #else
3646: x25_na -> na_pidlen = str2sel ("03019000", -1, x25_na -> na_pid, NPSIZE);
3647: #endif
3648: tz -> ta_naddr = 1;
3649:
3650: tz++;
3651: #endif
3652:
3653: #ifdef TP4
3654: if (!(ts_stacks & TS_TP4))
3655: tp4service = 0;
3656:
3657: #ifndef SNMPT
3658: bcopy ("snmp", tz -> ta_selector, tz -> ta_selectlen = sizeof "snmp" - 1);
3659: #else
3660: bcopy ("snmp-trap", tz -> ta_selector,
3661: tz -> ta_selectlen = sizeof "snmp-trap" - 1);
3662: #endif
3663: tz -> ta_naddr = 0;
3664:
3665: tz++;
3666: #endif
3667:
3668: for (vec++; ap = *vec; vec++) {
3669: if (*ap == '-')
3670: switch (*++ap) {
3671: case 'd':
3672: debug++;
3673: continue;
3674:
3675: #ifndef SNMPT
3676: case 's':
3677: #ifdef SMUX
3678: smux_enabled = 0;
3679: #endif
3680: continue;
3681: #endif
3682:
3683: case 't':
3684: ts_stacks = TS_TCP;
3685: tcpservice = 1;
3686: x25service = tp4service = 0;
3687: continue;
3688:
3689: case 'x':
3690: ts_stacks = TS_X25;
3691: x25service = 1;
3692: tcpservice = tp4service = 0;
3693: continue;
3694:
3695: case 'z':
3696: ts_stacks = TS_TP4;
3697: tp4service = 1;
3698: tcpservice = x25service = 0;
3699: continue;
3700:
3701: #ifndef SNMPT
3702: case 'r':
3703: rflag = 1;
3704: continue;
3705: #else
3706: case 'f':
3707: if ((file = *++vec) == NULL || *file == '-')
3708: adios (NULLCP, "usage: %s -f audit-file", myname);
3709: continue;
3710: #endif
3711:
3712: #ifdef TCP
3713: case 'p':
3714: if ((ap = *++vec) == NULL
3715: || *ap == '-'
3716: || (port = atoi (ap)) <= 0)
3717: adios (NULLCP, "usage: %s -p portno", myname);
3718: tcp_na -> na_port = htons ((u_short) port);
3719: continue;
3720: #endif
3721:
3722: #ifdef X25
3723: /* This permits listening on a specific subaddress. */
3724: case 'a':
3725: if ((ap = *++vec) == NULL || *ap == '-')
3726: adios (NULLCP, "usage: %s -a x121address", myname);
3727: (void) strcpy (x25_na -> na_dte, ap);
3728: x25_na -> na_dtelen = strlen (ap);
3729: continue;
3730:
3731: /* This permits listening on a specific protocol id.
3732: In fact, SunLink X.25 lets you listen on a protocol
3733: id mask, but let's keep it simple. */
3734: case 'i':
3735: if ((ap = *++vec) == NULL || *ap == '-' )
3736: adios (NULLCP, "usage: %s -i pid", myname);
3737: x25_na -> na_pidlen =
3738: str2sel (ap, -1, x25_na -> na_pid, NPSIZE);
3739: continue;
3740: #endif
3741:
3742: default:
3743: adios (NULLCP, "-%s: unknown switch", ap);
3744: }
3745:
3746: adios (NULLCP, "usage: %s [switches]", myname);
3747: }
3748:
3749: ps_len_strategy = PS_LEN_LONG;
3750:
3751: #ifdef SNMPT
3752: file = _isodefile (isodelogpath, file);
3753: if ((fp = fopen (file, "a")) == NULL)
3754: adios (file, "unable to append to");
3755: if ((audit = ps_alloc (std_open)) == NULLPS)
3756: adios (NULLCP, "ps_alloc(std_open): you lose");
3757: if (std_setup (audit, fp) == NOTOK)
3758: adios (NULLCP, "std_setup: %s", ps_error (audit -> ps_errno));
3759: #endif
3760: }
3761:
3762: /* */
3763:
3764: static envinit () {
3765: int i,
3766: sd;
3767: char file[BUFSIZ];
3768: FILE *fp;
3769:
3770: nbits = getdtablesize ();
3771:
3772: if (debug == 0 && !(debug = isatty (2))) {
3773: for (i = 0; i < 5; i++) {
3774: switch (fork ()) {
3775: case NOTOK:
3776: sleep (5);
3777: continue;
3778:
3779: case OK:
3780: break;
3781:
3782: default:
3783: _exit (0);
3784: }
3785: break;
3786: }
3787:
3788: (void) chdir ("/");
3789:
3790: if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
3791: adios ("/dev/null", "unable to read");
3792: if (sd != 0)
3793: (void) dup2 (sd, 0), (void) close (sd);
3794: (void) dup2 (0, 1);
3795: (void) dup2 (0, 2);
3796:
3797: #ifdef SETSID
3798: if (setsid () == NOTOK)
3799: advise (LLOG_EXCEPTIONS, "failed", "setsid");
3800: #endif
3801: #ifdef TIOCNOTTY
3802: if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
3803: (void) ioctl (sd, TIOCNOTTY, NULLCP);
3804: (void) close (sd);
3805: }
3806: #else
3807: #ifdef SYS5
3808: (void) setpgrp ();
3809: (void) signal (SIGINT, SIG_IGN);
3810: (void) signal (SIGQUIT, SIG_IGN);
3811: #endif
3812: #endif
3813: }
3814: else
3815: ll_dbinit (pgm_log, myname);
3816:
3817: #ifndef sun /* damn YP... */
3818: for (sd = 3; sd < nbits; sd++)
3819: if (pgm_log -> ll_fd != sd)
3820: (void) close (sd);
3821: #endif
3822:
3823: (void) signal (SIGPIPE, SIG_IGN);
3824:
3825: ll_hdinit (pgm_log, myname);
3826:
3827: #ifndef SNMPT
3828: if (readobjects ("snmpd.defs") == NOTOK)
3829: adios (NULLCP, "readobjects: %s", PY_pepy);
3830:
3831: readmib ();
3832: readconfig ();
3833:
3834: init_snmp ();
3835: #ifdef SMUX
3836: init_smux ();
3837: #endif
3838: init_view ();
3839:
3840: initrap ();
3841: initview ();
3842: checkmib ();
3843:
3844: o_advise = (IFP) advise;
3845: #endif
3846:
3847: (void) sprintf (file, "/etc/%s.pid", myname);
3848: if (fp = fopen (file, "w")) {
3849: (void) fprintf (fp, "%d\n", getpid ());
3850: (void) fclose (fp);
3851: }
3852:
3853: advise (LLOG_NOTICE, NULLCP, "starting");
3854: }
3855:
3856: /* CONFIG */
3857:
3858: #ifndef SNMPT
3859:
3860: int f_community (), f_logging (), f_proxy (), f_trap (), f_variable (),
3861: f_view ();
3862:
3863: static struct pair {
3864: char *p_name; /* runcom directive */
3865: IFP p_handler; /* dispatch */
3866: } pairs[] = {
3867: "community", f_community,
3868: "logging", f_logging,
3869: "proxy", f_proxy,
3870: "trap", f_trap,
3871: "variable", f_variable,
3872: "view", f_view,
3873:
3874: NULL
3875: };
3876:
3877:
3878: static struct wired {
3879: char *w_args1;
3880: char *w_args2;
3881: } wired[] = {
3882: "defViewWholeRW", NULL,
3883: "defViewWholeRO", NULL,
3884: "defViewStandardRW", "mgmt",
3885: "defViewStandardRO", "mgmt",
3886:
3887: NULL
3888: };
3889:
3890: static readconfig () {
3891: register char *cp;
3892: char buffer[BUFSIZ],
3893: line[BUFSIZ],
3894: *vec[NVEC + NSLACK + 1];
3895: register struct community *c;
3896: register struct view *v;
3897: register struct pair *p;
3898: register struct wired *w;
3899: struct stat st;
3900: FILE *fp;
3901:
3902: CHead -> c_forw = CHead -> c_back = CHead;
3903: UHead -> t_forw = UHead -> t_back = UHead;
3904: VHead -> v_forw = VHead -> v_back = VHead;
3905:
3906: if ((localAgent = text2oid ("localAgent")) == NULLOID)
3907: adios (NULLCP, "unknown OID \"localAgent\"");
3908: if ((rfc1157Domain = text2oid ("rfc1157Domain")) == NULLOID)
3909: adios (NULLCP, "unknown OID \"rfc1157Domain\"");
3910:
3911: vec[0] = "view";
3912: for (w = wired; w -> w_args1; w++) {
3913: vec[1] = w -> w_args1;
3914: if (vec[2] = w -> w_args2)
3915: vec[3] = NULL;
3916:
3917: if (f_view (vec) == NOTOK)
3918: adios (NULLCP, "you lose");
3919: }
3920:
3921: (void) strcpy (buffer, "defViewTrapDest.0");
3922: if ((trapview = text2oid (buffer)) == NULLOID)
3923: adios (NULLCP, "unknown OID \"defViewTrapDest.0\" for traps");
3924: trapview -> oid_nelem--;
3925:
3926: bzero ((char *) &snmpstat, sizeof snmpstat);
3927: snmpstat.s_enableauthtraps = TRAPS_ENABLED;
3928:
3929: if ((fp = fopen (cp = "snmpd.rc", "r")) == NULL
3930: && (fp = fopen (cp = isodefile ("snmpd.rc", 0), "r")) == NULL)
3931: adios (cp, "unable to read");
3932:
3933: if (!rflag
3934: && getuid () == 0
3935: && fstat (fileno (fp), &st) != NOTOK
3936: && st.st_uid != 0)
3937: adios (NULLCP, "%s not owned by root", cp);
3938:
3939: while (fgets (buffer, sizeof buffer, fp)) {
3940: if (*buffer == '#')
3941: continue;
3942: if (cp = index (buffer, '\n'))
3943: *cp = NULL;
3944: (void) strcpy (line, buffer);
3945:
3946: bzero ((char *) vec, sizeof vec);
3947: if (str2vec (buffer, vec) < 1)
3948: continue;
3949: for (p = pairs; p -> p_name; p++)
3950: if (lexequ (p -> p_name, vec[0]) == 0) {
3951: if ((*p -> p_handler) (vec) == NOTOK)
3952: advise (LLOG_EXCEPTIONS, NULLCP,
3953: "malformed directive: \"%s\"", line);
3954: break;
3955: }
3956: if (!p -> p_name)
3957: advise (LLOG_EXCEPTIONS, NULLCP, "unknown directive: \"%s\"",
3958: line);
3959: }
3960:
3961: (void) fclose (fp);
3962:
3963: if (CHead -> c_forw == CHead) {
3964: vec[0] = "community";
3965: vec[1] = "public";
3966: vec[2] = NULL;
3967:
3968: (void) f_community (vec);
3969: }
3970:
3971: for (c = CHead -> c_forw; c != CHead; c = c -> c_forw) {
3972: for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
3973: if (oid_cmp (v -> v_name, c -> c_vu) == 0) {
3974: c -> c_view = v;
3975: break;
3976: }
3977: if (v == VHead)
3978: advise (LLOG_EXCEPTIONS, NULLCP,
3979: "no such view as %s for community \"%s\"",
3980: sprintoid (c -> c_vu), c -> c_name);
3981: }
3982: }
3983:
3984: /* */
3985:
3986: static int f_community (vec)
3987: char **vec;
3988: {
3989: register struct community *c;
3990: register struct NSAPaddr *na;
3991:
3992: vec++;
3993:
3994: if ((c = (struct community *) calloc (1, sizeof *c)) == NULL
3995: || (c -> c_name = strdup (*vec)) == NULL)
3996: adios (NULLCP, "out of memory");
3997: vec++;
3998:
3999: na = &c -> c_addr;
4000: if (*vec) {
4001: if (str2sa (*vec, na, (struct sockaddr *) NULL, 0) == NOTOK)
4002: adios (NULLCP, "unknown address \"%s\" for community \"%s\"",
4003: *vec, c -> c_name);
4004:
4005: vec++;
4006: }
4007: else {
4008: na -> na_stack = NA_TCP;
4009: na -> na_community = ts_comm_tcp_default;
4010: (void) strcpy (na -> na_domain, "0.0.0.0");
4011: }
4012:
4013: if (*vec) {
4014: if (lexequ (*vec, "readOnly") == 0)
4015: c -> c_permission = OT_RDONLY;
4016: else
4017: if (lexequ (*vec, "readWrite") == 0)
4018: c -> c_permission = OT_RDWRITE;
4019: else
4020: if (lexequ (*vec, "writeOnly") == 0)
4021: c -> c_permission = OT_WRONLY;
4022: else
4023: if (lexequ (*vec, "none")) {
4024: advise (LLOG_EXCEPTIONS, NULLCP,
4025: "invalid access mode \"%s\"", *vec);
4026: goto you_lose;
4027: }
4028:
4029: vec++;
4030: }
4031: else
4032: c -> c_permission = OT_RDONLY;
4033:
4034: if (*vec) {
4035: char buffer[BUFSIZ];
4036:
4037: (void) strcpy (buffer, *vec);
4038: if ((c -> c_vu = text2oid (buffer)) == NULLOID) {
4039: advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
4040: goto you_lose;
4041: }
4042:
4043: if (*++vec)
4044: goto you_lose;
4045: }
4046: else
4047: if ((c -> c_vu = text2oid ("defViewWholeRO")) == NULL) {
4048: advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"defViewWholeRO\"");
4049: goto you_lose;
4050: }
4051:
4052: insque (c, CHead -> c_back);
4053:
4054: return OK;
4055:
4056: you_lose: ;
4057: free (c -> c_name);
4058: free ((char *) c);
4059:
4060: return NOTOK;
4061: }
4062:
4063: /* */
4064:
4065: static int f_logging (vec)
4066: char **vec;
4067: {
4068: register char **vp;
4069:
4070: for (vp = ++vec; *vp; vp++)
4071: continue;
4072:
4073: log_tai (pgm_log, vec, vp - vec);
4074:
4075: return OK;
4076: }
4077:
4078: /* */
4079:
4080: static int f_proxy (vec)
4081: char **vec;
4082: {
4083: char buffer[BUFSIZ];
4084: register struct community *c;
4085: register struct view *v,
4086: *u;
4087: register struct NSAPaddr *na;
4088:
4089: if ((v = (struct view *) calloc (1, sizeof *v)) == NULL)
4090: adios (NULLCP, "out of memory");
4091: v -> v_subtree.s_forw = v -> v_subtree.s_back = &v -> v_subtree;
4092: if ((c = (struct community *) calloc (1, sizeof *c)) == NULL)
4093: adios (NULLCP, "out of memory");
4094: c -> c_permission = OT_YYY;
4095: vec++;
4096:
4097: (void) strcpy (buffer, *vec);
4098: if ((v -> v_name = text2oid (buffer)) == NULL) {
4099: advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
4100: goto you_lose;
4101: }
4102: c -> c_vu = v -> v_name;
4103: if (trapview && inSubtree (trapview, v -> v_name)) {
4104: advise (LLOG_EXCEPTIONS, NULLCP, "view \"%s\" is for traps", *vec);
4105: goto you_lose;
4106: }
4107: for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
4108: if (oid_cmp (u -> v_name, v -> v_name) == 0) {
4109: advise (LLOG_EXCEPTIONS, NULLCP, "duplicate view \"%s\"", *vec);
4110: goto you_lose;
4111: }
4112: vec++;
4113:
4114: if (lexequ (*vec, "rfc1157")) {
4115: advise (LLOG_EXCEPTIONS, NULLCP, "unsupported proxy domain \"%s\"",
4116: *vec);
4117: goto you_lose;
4118: }
4119: vec++;
4120:
4121: na = &c -> c_addr;
4122: if (*vec) {
4123: if (str2sa (*vec, na, &v -> v_sa, 1) == NOTOK)
4124: adios (NULLCP, "unknown address \"%s\" for proxy %s",
4125: *vec, oid2ode (v -> v_name));
4126:
4127: vec++;
4128: }
4129: else
4130: goto you_lose;
4131:
4132: if (*vec) {
4133: if ((v -> v_community = str2qb (*vec, strlen (*vec), 1)) == NULL)
4134: adios (NULLCP, "out of memory");
4135: if ((c -> c_name = strdup (*vec)) == NULL)
4136: adios (NULLCP, "out of memory");
4137:
4138: if (*++vec)
4139: goto you_lose;
4140: }
4141: else
4142: goto you_lose;
4143:
4144: insque (v, VHead -> v_back);
4145: insque (c, CHead -> c_back);
4146:
4147: return OK;
4148:
4149: you_lose: ;
4150: if (c -> c_name)
4151: free (c -> c_name);
4152: free ((char *) c);
4153: if (v -> v_name)
4154: oid_free (v -> v_name);
4155: if (v -> v_community)
4156: qb_free (v -> v_community);
4157: free ((char *) v);
4158:
4159: return NOTOK;
4160: }
4161:
4162: /* */
4163:
4164: static int f_trap (vec)
4165: char **vec;
4166: {
4167: register struct trap *t;
4168: register struct view *v;
4169: struct NSAPaddr nas;
4170: register struct NSAPaddr *na = &nas;
4171: static int trapno = 1;
4172:
4173: vec++;
4174:
4175: if ((t = (struct trap *) calloc (1, sizeof *t)) == NULL
4176: || (t -> t_name = strdup (*vec)) == NULL)
4177: adios (NULLCP, "out of memory");
4178: v = t -> t_view = &t -> t_vu;
4179: v -> v_subtree.s_forw = v -> v_subtree.s_back = &v -> v_subtree;
4180: t -> t_generics = 0xfe;
4181: vec++;
4182:
4183: trapview -> oid_elements[trapview -> oid_nelem++] = trapno;
4184: v -> v_name = oid_cpy (trapview);
4185: trapview -> oid_nelem--;
4186: if (v -> v_name == NULLOID)
4187: adios (NULLCP, "out of memory");
4188:
4189: if ((v -> v_community = str2qb (t -> t_name, strlen (t -> t_name), 1))
4190: == NULL)
4191: adios (NULLCP, "out of memory");
4192:
4193: bzero ((char *) na, sizeof *na);
4194: if (*vec) {
4195: if (str2sa (*vec, na, &v -> v_sa, 0) == NOTOK)
4196: adios (NULLCP, "unknown address \"%s\" for trap sink \"%s\"",
4197: *vec, t -> t_name);
4198:
4199: vec++;
4200: }
4201: else
4202: goto you_lose;
4203:
4204: if (*vec) {
4205: char buffer[BUFSIZ];
4206: OID name;
4207: register struct view *u;
4208:
4209: (void) strcpy (buffer, *vec);
4210: if ((name = text2oid (buffer)) == NULL) {
4211: advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
4212: goto you_lose;
4213: }
4214: oid_free (v -> v_name);
4215: v -> v_name = name;
4216:
4217: for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
4218: if (oid_cmp (u -> v_name, v -> v_name) == 0) {
4219: advise (LLOG_EXCEPTIONS, NULLCP,
4220: "duplicate view \"%s\" for trap sink \"%s\"",
4221: *vec, t -> t_name);
4222: goto you_lose;
4223: }
4224:
4225: vec++;
4226: }
4227: else
4228: trapno++;
4229:
4230: if (*vec) {
4231: if (sscanf (*vec, "%lx", &t -> t_generics) != 1)
4232: goto you_lose;
4233:
4234: if (*++vec)
4235: goto you_lose;
4236: }
4237:
4238: insque (t, UHead -> t_back);
4239: insque (v, VHead -> v_back);
4240:
4241: return OK;
4242:
4243: you_lose: ;
4244: oid_free (v -> v_name);
4245: qb_free (v -> v_community);
4246: free (t -> t_name);
4247: free ((char *) t);
4248:
4249: return NOTOK;
4250: }
4251:
4252: /* */
4253:
4254: static int f_variable (vec)
4255: char **vec;
4256: {
4257: if (*++vec == NULL)
4258: return NOTOK;
4259:
4260: if (lexequ (*vec, "interface") == 0) {
4261: char *name;
4262:
4263: if ((name = *++vec) == NULL)
4264: return NOTOK;
4265: for (vec++; *vec; vec++)
4266: if (index (*vec, '='))
4267: set_interface (name, *vec);
4268: else
4269: return NOTOK;
4270:
4271: return OK;
4272: }
4273:
4274: if (lexequ (*vec, "snmpEnableAuthTraps") == 0) {
4275: ++vec;
4276:
4277: if (lexequ (*vec, "enabled") == 0)
4278: snmpstat.s_enableauthtraps = TRAPS_ENABLED;
4279: else
4280: if (lexequ (*vec, "disabled") == 0)
4281: snmpstat.s_enableauthtraps = TRAPS_DISABLED;
4282:
4283: return OK;
4284: }
4285:
4286: if (!vec[0] || !vec[1] || vec[2])
4287: return NOTOK;
4288:
4289: set_variable (vec[0], vec[1]);
4290:
4291: return OK;
4292: }
4293:
4294: /* */
4295:
4296: static int f_view (vec)
4297: char **vec;
4298: {
4299: char buffer[BUFSIZ];
4300: register struct subtree *s,
4301: *x,
4302: *y;
4303: register struct view *v,
4304: *u;
4305:
4306: if (viewmask == 0) {
4307: advise (LLOG_EXCEPTIONS, NULLCP,
4308: "too many views starting with \"%s\"", *vec);
4309: return NOTOK;
4310: }
4311:
4312: if ((v = (struct view *) calloc (1, sizeof *v)) == NULL)
4313: adios (NULLCP, "out of memory");
4314: s = &v -> v_subtree;
4315: v -> v_subtree.s_forw = v -> v_subtree.s_back = s;
4316: vec++;
4317:
4318: (void) strcpy (buffer, *vec);
4319: if ((v -> v_name = text2oid (buffer)) == NULL) {
4320: advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
4321: goto you_lose;
4322: }
4323: if (trapview && inSubtree (trapview, v -> v_name)) {
4324: advise (LLOG_EXCEPTIONS, NULLCP, "view \"%s\" is for traps", *vec);
4325: goto you_lose;
4326: }
4327: for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
4328: if (oid_cmp (u -> v_name, v -> v_name) == 0) {
4329: advise (LLOG_EXCEPTIONS, NULLCP, "duplicate view \"%s\"", *vec);
4330: goto you_lose;
4331: }
4332:
4333: for (vec++; *vec; vec++) {
4334: register struct subtree *z;
4335: OID name;
4336:
4337: (void) strcpy (buffer, *vec);
4338: if ((name = text2oid (buffer)) == NULLOID) {
4339: advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
4340: goto you_lose;
4341: }
4342:
4343: for (x = s -> s_forw; x != s; x = y) {
4344: register int i,
4345: j;
4346: y = x -> s_forw;
4347:
4348: if (bcmp ((char *) x -> s_subtree -> oid_elements,
4349: (char *) name -> oid_elements,
4350: ((i = x -> s_subtree -> oid_nelem)
4351: <= (j = name -> oid_nelem) ? i : j)
4352: * sizeof name -> oid_elements[0]) == 0) {
4353: advise (LLOG_EXCEPTIONS, NULLCP,
4354: "%s %s %s",
4355: *vec,
4356: i <= j ? "already under" : "superceding",
4357: oid2ode (x -> s_subtree));
4358: if (i <= j)
4359: goto another;
4360:
4361: remque (x);
4362: oid_free (x -> s_subtree);
4363: free ((char *) x);
4364: }
4365: }
4366:
4367: if ((z = (struct subtree *) calloc (1, sizeof *z)) == NULL)
4368: adios (NULLCP, "out of memory");
4369: z -> s_subtree = name;
4370:
4371: insque (z, s -> s_back);
4372: another: ;
4373: }
4374:
4375: v -> v_mask = viewmask;
4376: viewmask <<= 1;
4377: insque (v, VHead -> v_back);
4378:
4379: return OK;
4380:
4381: you_lose: ;
4382: for (x = s -> s_forw; x != s; x = y) {
4383: y = x -> s_forw;
4384:
4385: remque (x);
4386: oid_free (x -> s_subtree);
4387: free ((char *) x);
4388: }
4389: if (v -> v_name)
4390: oid_free (v -> v_name);
4391: free ((char *) v);
4392:
4393: return NOTOK;
4394: }
4395:
4396: /* */
4397:
4398: static int str2sa (s, na, sock, proxy)
4399: char *s;
4400: struct NSAPaddr *na;
4401: struct sockaddr *sock;
4402: int proxy;
4403: {
4404: #ifdef TCP
4405: register struct hostent *hp;
4406: #endif
4407: struct TSAPaddr *ta;
4408:
4409: #ifdef TCP
4410: if (hp = gethostbystring (s)) {
4411: struct sockaddr_in sin;
4412:
4413: na -> na_stack = NA_TCP;
4414: na -> na_community = ts_comm_tcp_default;
4415: inaddr_copy (hp, &sin);
4416: (void) strncpy (na -> na_domain, inet_ntoa (sin.sin_addr),
4417: sizeof na -> na_domain - 1);
4418: }
4419: else
4420: #endif
4421: if ((ta = str2taddr (s)) && ta -> ta_naddr > 0) {
4422: *na = ta -> ta_addrs[0]; /* struct copy */
4423: }
4424: else
4425: return NOTOK;
4426:
4427: if (sock == NULL)
4428: return OK;
4429:
4430: switch (na -> na_stack) {
4431: #ifdef TCP
4432: case NA_TCP:
4433: if (!tcpservice)
4434: goto you_lose;
4435: {
4436: struct sockaddr_in sin;
4437:
4438: sin.sin_port = na -> na_port ? na -> na_port
4439: : proxy ? udport : traport;
4440:
4441: if ((hp = gethostbystring (na -> na_domain)) == NULL)
4442: return NOTOK;
4443:
4444: sin.sin_family = hp -> h_addrtype;
4445: inaddr_copy (hp, &sin);
4446:
4447: *((struct sockaddr_in *) sock) = sin; /* struct copy */
4448: }
4449: break;
4450: #endif
4451:
4452: default:
4453: you_lose: ;
4454: advise (LLOG_EXCEPTIONS, NULLCP, "address type unsupported");
4455: return NOTOK;
4456: }
4457:
4458: return OK;
4459: }
4460: #endif /* SNMPT */
4461:
4462: /* ERRORS */
4463:
4464: #ifndef lint
4465: void adios (va_alist)
4466: va_dcl
4467: {
4468: va_list ap;
4469:
4470: va_start (ap);
4471:
4472: _ll_log (pgm_log, LLOG_FATAL, ap);
4473:
4474: va_end (ap);
4475:
4476: _exit (1);
4477: }
4478: #else
4479: /* VARARGS */
4480:
4481: void adios (what, fmt)
4482: char *what,
4483: *fmt;
4484: {
4485: adios (what, fmt);
4486: }
4487: #endif
4488:
4489:
4490: #ifndef lint
4491: void advise (va_alist)
4492: va_dcl
4493: {
4494: int code;
4495: va_list ap;
4496:
4497: va_start (ap);
4498:
4499: code = va_arg (ap, int);
4500:
4501: _ll_log (pgm_log, code, ap);
4502:
4503: va_end (ap);
4504: }
4505: #else
4506: /* VARARGS */
4507:
4508: void advise (code, what, fmt)
4509: char *what,
4510: *fmt;
4511: int code;
4512: {
4513: advise (code, what, fmt);
4514: }
4515: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.