|
|
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.