Annotation of 43BSDReno/contrib/isode-beta/snmp/snmpd.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.