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

1.1       root        1: /* udp.c - MIB realization of the UDP group */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/snmp/RCS/udp.c,v 7.3 90/04/23 00:08:20 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/snmp/RCS/udp.c,v 7.3 90/04/23 00:08:20 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:       udp.c,v $
                     17:  * Revision 7.3  90/04/23  00:08:20  mrose
                     18:  * touch-up
                     19:  * 
                     20:  * Revision 7.2  90/04/18  08:52:09  mrose
                     21:  * oid_normalize
                     22:  * 
                     23:  * Revision 7.1  90/02/27  18:50:10  mrose
                     24:  * unix stuff
                     25:  * 
                     26:  * Revision 7.0  89/11/23  22:23:38  mrose
                     27:  * Release 6.0
                     28:  * 
                     29:  */
                     30: 
                     31: /*
                     32:  *                               NOTICE
                     33:  *
                     34:  *    Acquisition, use, and distribution of this module and related
                     35:  *    materials are subject to the restrictions of a license agreement.
                     36:  *    Consult the Preface in the User's Manual for the full terms of
                     37:  *    this agreement.
                     38:  *
                     39:  */
                     40: 
                     41: 
                     42: #include <stdio.h>
                     43: #include "mib.h"
                     44: 
                     45: #include "internet.h"
                     46: #ifdef BSD44
                     47: #include <machine/machparam.h>
                     48: #endif
                     49: #include <net/route.h>
                     50: #include <sys/socketvar.h>
                     51: #include <netinet/in_systm.h>
                     52: #include <netinet/ip.h>
                     53: #include <netinet/in_pcb.h>
                     54: #include <netinet/ip_var.h>
                     55: #include <netinet/udp.h>
                     56: #include <netinet/udp_var.h>
                     57: 
                     58: /*  */
                     59: 
                     60: static struct udpstat udpstat;
                     61: 
                     62: /*  */
                     63: 
                     64: #ifdef BSD44
                     65: #define        udpInDatagrams  1
                     66: #define        udpNoPorts      2
                     67: #endif
                     68: #define        udpInErrors     3
                     69: #ifdef BSD44
                     70: #define        udpOutDatagrams 4
                     71: #endif
                     72: 
                     73: 
                     74: static int  o_udp (oi, v, offset)
                     75: OI     oi;
                     76: register struct type_SNMP_VarBind *v;
                     77: int    offset;
                     78: {
                     79:     int            ifvar;
                     80:     register struct udpstat *udps = &udpstat;
                     81:     register OID    oid = oi -> oi_name;
                     82:     register OT            ot = oi -> oi_type;
                     83:     static   int lastq = -1;
                     84: 
                     85:     ifvar = (int) ot -> ot_info;
                     86:     switch (offset) {
                     87:        case type_SNMP_PDUs_get__request:
                     88:            if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
                     89:                    || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
                     90:                return int_SNMP_error__status_noSuchName;
                     91:            break;
                     92: 
                     93:        case type_SNMP_PDUs_get__next__request:
                     94:            if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
                     95:                OID     new;
                     96: 
                     97:                if ((new = oid_extend (oid, 1)) == NULLOID)
                     98:                    return int_SNMP_error__status_genErr;
                     99:                new -> oid_elements[new -> oid_nelem - 1] = 0;
                    100: 
                    101:                if (v -> name)
                    102:                    free_SNMP_ObjectName (v -> name);
                    103:                v -> name = new;
                    104:            }
                    105:            else
                    106:                return NOTOK;
                    107:            break;
                    108: 
                    109:        default:
                    110:            return int_SNMP_error__status_genErr;
                    111:     }
                    112: 
                    113:     if (quantum != lastq) {
                    114:        lastq = quantum;
                    115: 
                    116:        if (getkmem (nl + N_UDPSTAT, (caddr_t) udps, sizeof *udps) == NOTOK)
                    117:            return int_SNMP_error__status_genErr;
                    118:     }
                    119: 
                    120:     switch (ifvar) {
                    121: #ifdef udpInDatagrams
                    122:        case udpInDatagrams:
                    123:            return o_integer (oi, v, udps -> udps_ipackets);
                    124: #endif
                    125: 
                    126: #ifdef udpNoPorts
                    127:        case udpNoPorts:
                    128:            return o_integer (oi, v, udps -> udps_noport);
                    129: #endif
                    130: 
                    131:        case udpInErrors:
                    132:            return o_integer (oi, v, udps -> udps_hdrops
                    133:                                   + udps -> udps_badsum
                    134:                                   + udps -> udps_badlen);
                    135: 
                    136: #ifdef udpOutDatagrams
                    137:        case udpOutDatagrams:
                    138:            return o_integer (oi, v, udps -> udps_opackets);
                    139: #endif
                    140: 
                    141:        default:
                    142:            return int_SNMP_error__status_noSuchName;
                    143:     }
                    144: }
                    145: 
                    146: /*  */
                    147: 
                    148: struct udptab {
                    149: #define        UT_SIZE 5                       /* object instance */
                    150:     unsigned int   ut_instance[UT_SIZE];
                    151: 
                    152:     struct inpcb   ut_pcb;             /* protocol control block */
                    153: 
                    154:     struct socket  ut_socb;            /* socket info */
                    155: 
                    156:     struct udptab *ut_next;
                    157: };
                    158: 
                    159: static struct udptab *uts = NULL;
                    160: 
                    161: 
                    162: struct udptab *get_udpent ();
                    163: 
                    164: /*  */
                    165: 
                    166: #define        udpLocalAddress 0
                    167: #define        udpLocalPort 1
                    168: #define        unixUdpRemAddress 2
                    169: #define        unixUdpRemPort 3
                    170: #define        unixUdpSendQ 4
                    171: #define        unixUdpRecvQ 5
                    172: 
                    173: 
                    174: static int  o_udp_listen (oi, v, offset)
                    175: OI     oi;
                    176: register struct type_SNMP_VarBind *v;
                    177: int    offset;
                    178: {
                    179:     int            ifvar;
                    180:     register int    i;
                    181:     register unsigned int *ip,
                    182:                          *jp;
                    183:     register struct udptab *ut;
                    184:     struct sockaddr_in netaddr;
                    185:     register OID    oid = oi -> oi_name;
                    186:     OID            new;
                    187:     register OT            ot = oi -> oi_type;
                    188: 
                    189:     if (get_listeners () == NOTOK)
                    190:        return int_SNMP_error__status_genErr;
                    191: 
                    192:     ifvar = (int) ot -> ot_info;
                    193:     switch (offset) {
                    194:        case type_SNMP_PDUs_get__request:
                    195:            if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + UT_SIZE)
                    196:                return int_SNMP_error__status_noSuchName;
                    197:            if ((ut = get_udpent (oid -> oid_elements + oid -> oid_nelem
                    198:                                      - UT_SIZE, 0)) == NULL)
                    199:                return int_SNMP_error__status_noSuchName;
                    200:            break;
                    201: 
                    202:        case type_SNMP_PDUs_get__next__request:
                    203:            if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0
                    204:                    && i < UT_SIZE) {
                    205:                for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i;
                    206:                         jp > ip;
                    207:                         jp--)
                    208:                    if (*jp != 0)
                    209:                        break;
                    210:                if (jp == ip)
                    211:                    oid -> oid_nelem = ot -> ot_name -> oid_nelem;
                    212:                else {
                    213:                    if ((new = oid_normalize (oid, UT_SIZE - i, 65536)) == NULLOID)
                    214:                        return int_SNMP_error__status_genErr;
                    215:                    if (v -> name)
                    216:                        free_SNMP_ObjectName (v -> name);
                    217:                    v -> name = oid = new;
                    218:                }
                    219:            }
                    220: 
                    221:            if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
                    222:                if ((ut = uts) == NULL)
                    223:                    return NOTOK;
                    224: 
                    225:                if ((new = oid_extend (oid, UT_SIZE)) == NULLOID)
                    226:                    return int_SNMP_error__status_genErr;
                    227:                ip = new -> oid_elements + new -> oid_nelem - UT_SIZE;
                    228:                jp = ut -> ut_instance;
                    229:                for (i = UT_SIZE; i > 0; i--)
                    230:                    *ip++ = *jp++;
                    231: 
                    232:                if (v -> name)
                    233:                    free_SNMP_ObjectName (v -> name);
                    234:                v -> name = new;
                    235:            }
                    236:            else {
                    237:                if ((ut = get_udpent (ip = oid -> oid_elements
                    238:                                         + oid -> oid_nelem - UT_SIZE, 1))
                    239:                        == NULL)
                    240:                    return NOTOK;
                    241: 
                    242:                jp = ut -> ut_instance;
                    243:                for (i = UT_SIZE; i > 0; i--)
                    244:                    *ip++ = *jp++;
                    245:            }
                    246:            break;
                    247: 
                    248:        default:
                    249:            return int_SNMP_error__status_genErr;
                    250:     }
                    251: 
                    252:     switch (ifvar) {
                    253:        case udpLocalAddress:
                    254:            netaddr.sin_addr = ut -> ut_pcb.inp_laddr;  /* struct copy */
                    255:            return o_ipaddr (oi, v, &netaddr);
                    256:            
                    257:        case udpLocalPort:
                    258:            return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_lport) & 0xffff);
                    259: 
                    260:        case unixUdpRemAddress:
                    261:            netaddr.sin_addr = ut -> ut_pcb.inp_faddr;  /* struct copy */
                    262:            return o_ipaddr (oi, v, &netaddr);
                    263: 
                    264:        case unixUdpRemPort:
                    265:            return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_fport) & 0xffff);
                    266: 
                    267:        case unixUdpSendQ:
                    268:            return o_integer (oi, v, ut -> ut_socb.so_snd.sb_cc);
                    269:        
                    270:        case unixUdpRecvQ:
                    271:            return o_integer (oi, v, ut -> ut_socb.so_rcv.sb_cc);
                    272:        
                    273:        default:
                    274:            return int_SNMP_error__status_noSuchName;
                    275:     }
                    276: }
                    277: 
                    278: /*  */
                    279: 
                    280: static int  ut_compar (a, b)
                    281: struct udptab **a,
                    282:              **b;
                    283: {
                    284:     return elem_cmp ((*a) -> ut_instance, UT_SIZE,
                    285:                     (*b) -> ut_instance, UT_SIZE);
                    286: }
                    287: 
                    288: 
                    289: static int  get_listeners () {
                    290:     register int    i;
                    291:     register unsigned int  *cp;
                    292:     register struct udptab *us,
                    293:                           *up,
                    294:                          **usp;
                    295:     register struct inpcb  *ip;
                    296:     struct inpcb *head,
                    297:                  udb,
                    298:                  zdb;
                    299:     struct nlist nzs;
                    300:     register struct nlist *nz = &nzs;
                    301:     static   int first_time = 1;
                    302:     static   int lastq = -1;
                    303: 
                    304:     if (quantum == lastq)
                    305:        return OK;
                    306:     lastq = quantum;
                    307: 
                    308:     for (us = uts; us; us = up) {
                    309:        up = us -> ut_next;
                    310: 
                    311:        free ((char *) us);
                    312:     }
                    313:     uts = NULL;
                    314: 
                    315:     if (getkmem (nl + N_UDB, (char *) &udb, sizeof udb) == NOTOK)
                    316:        return NOTOK;
                    317:     head = (struct inpcb *) nl[N_UDB].n_value;
                    318: 
                    319:     usp = &uts, i = 0;
                    320:     ip = &udb;
                    321:     while (ip -> inp_next != head) {
                    322:        register struct udptab *uz;
                    323:        OIDentifier     oids;
                    324: 
                    325:        if ((us = (struct udptab *) calloc (1, sizeof *us)) == NULL)
                    326:            adios (NULLCP, "out of memory");
                    327: 
                    328:        nz -> n_name = "struct inpcb",
                    329:        nz -> n_value = (unsigned long) ip -> inp_next;
                    330:        if (getkmem (nz, (caddr_t) &us -> ut_pcb, sizeof us -> ut_pcb)
                    331:                == NOTOK)
                    332:            return NOTOK;
                    333:        ip = &us -> ut_pcb;
                    334: 
                    335:        nz ->n_name = "struct socket",
                    336:        nz -> n_value = (unsigned long) ip -> inp_socket;
                    337:        if (getkmem (nz, (caddr_t) &us -> ut_socb, sizeof us -> ut_socb)
                    338:                == NOTOK)
                    339:            return NOTOK;
                    340: 
                    341:        cp = us -> ut_instance;
                    342:        cp += ipaddr2oid (cp, &ip -> inp_laddr);
                    343:        *cp++ = ntohs (ip -> inp_lport) & 0xffff;
                    344: 
                    345:        for (uz = uts; uz; uz = uz -> ut_next)
                    346:            if (elem_cmp (uz -> ut_instance, UT_SIZE,
                    347:                          us -> ut_instance, UT_SIZE) == 0)
                    348:                break;
                    349:        if (uz) {
                    350:            if (first_time) {
                    351:                oids.oid_elements = us -> ut_instance;
                    352:                oids.oid_nelem = UT_SIZE;
                    353:                advise (LLOG_EXCEPTIONS, NULLCP,
                    354:                        "duplicate listeners: %s", sprintoid (&oids));
                    355:            }
                    356: 
                    357:            *(ip = &zdb) = us -> ut_pcb;        /* struct copy */
                    358:            free ((char *) us);
                    359:            continue;
                    360:        }
                    361:        *usp = us, usp = &us -> ut_next, i++;
                    362: 
                    363:        if (debug && first_time) {
                    364:            oids.oid_elements = us -> ut_instance;
                    365:            oids.oid_nelem = UT_SIZE;
                    366:            advise (LLOG_DEBUG, NULLCP,
                    367:                    "add listener: %s", sprintoid (&oids));
                    368:        }
                    369:     }
                    370:     first_time = 0;
                    371: 
                    372:     if (i > 1) {
                    373:        register struct udptab **base,
                    374:                               **use;
                    375: 
                    376:        if ((base = (struct udptab **) malloc ((unsigned) (i * sizeof *base)))
                    377:                == NULL)
                    378:            adios (NULLCP, "out of memory");
                    379: 
                    380:        use = base;
                    381:        for (us = uts; us; us = us -> ut_next)
                    382:            *use++ = us;
                    383: 
                    384:        qsort ((char *) base, i, sizeof *base, ut_compar);
                    385: 
                    386:        usp = base;
                    387:        us = uts = *usp++;
                    388: 
                    389:        while (usp < use) {
                    390:            us -> ut_next = *usp;
                    391:            us = *usp++;
                    392:        }
                    393:        us -> ut_next = NULL;
                    394: 
                    395:        free ((char *) base);
                    396:     }
                    397: 
                    398:     return OK;    
                    399: }
                    400: 
                    401: /*  */
                    402: 
                    403: static struct udptab *get_udpent (ip, isnext)
                    404: register unsigned int *ip;
                    405: int    isnext;
                    406: {
                    407:     register struct udptab *ut;
                    408: 
                    409:     for (ut = uts; ut; ut = ut -> ut_next)
                    410:        switch (elem_cmp (ut -> ut_instance, UT_SIZE, ip, UT_SIZE)) {
                    411:            case 0:
                    412:                return (isnext ? ut -> ut_next : ut);
                    413: 
                    414:            case 1:
                    415:                return (isnext ? ut : NULL);
                    416:        }
                    417: 
                    418:     return NULL;
                    419: }
                    420: 
                    421: /*  */
                    422: 
                    423: init_udp () {
                    424:     register OT            ot;
                    425: 
                    426: #ifdef udpInDatagrams
                    427:     if (ot = text2obj ("udpInDatagrams"))
                    428:        ot -> ot_getfnx = o_udp,
                    429:        ot -> ot_info = (caddr_t) udpInDatagrams;
                    430: #endif
                    431: #ifdef udpNoPorts
                    432:     if (ot = text2obj ("udpNoPorts"))
                    433:        ot -> ot_getfnx = o_udp,
                    434:        ot -> ot_info = (caddr_t) udpNoPorts;
                    435: #endif
                    436:     if (ot = text2obj ("udpInErrors"))
                    437:        ot -> ot_getfnx = o_udp,
                    438:        ot -> ot_info = (caddr_t) udpInErrors;
                    439: #ifdef udpOutDatagrams
                    440:     if (ot = text2obj ("udpOutDatagrams"))
                    441:        ot -> ot_getfnx = o_udp,
                    442:        ot -> ot_info = (caddr_t) udpOutDatagrams;
                    443: #endif
                    444: 
                    445:     if (ot = text2obj ("udpLocalAddress"))
                    446:        ot -> ot_getfnx = o_udp_listen,
                    447:        ot -> ot_info = (caddr_t) udpLocalAddress;
                    448:     if (ot = text2obj ("udpLocalPort"))
                    449:        ot -> ot_getfnx = o_udp_listen,
                    450:        ot -> ot_info = (caddr_t) udpLocalPort;
                    451: 
                    452:     if (ot = text2obj ("unixUdpRemAddress"))
                    453:        ot -> ot_getfnx = o_udp_listen,
                    454:        ot -> ot_info = (caddr_t) unixUdpRemAddress;
                    455:     if (ot = text2obj ("unixUdpRemPort"))
                    456:        ot -> ot_getfnx = o_udp_listen,
                    457:        ot -> ot_info = (caddr_t) unixUdpRemPort;
                    458:     if (ot = text2obj ("unixUdpSendQ"))
                    459:        ot -> ot_getfnx = o_udp_listen,
                    460:        ot -> ot_info = (caddr_t) unixUdpSendQ;
                    461:     if (ot = text2obj ("unixUdpRecvQ"))
                    462:        ot -> ot_getfnx = o_udp_listen,
                    463:        ot -> ot_info = (caddr_t) unixUdpRecvQ;
                    464: }

unix.superglobalmegacorp.com

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