|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.