|
|
1.1 ! root 1: /* interfaces.c - MIB realization of the Interfaces group */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/snmp/RCS/interfaces.c,v 7.6 90/03/24 10:54:02 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/snmp/RCS/interfaces.c,v 7.6 90/03/24 10:54:02 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: interfaces.c,v $ ! 17: * Revision 7.6 90/03/24 10:54:02 mrose ! 18: * update ! 19: * ! 20: * Revision 7.5 90/02/27 18:49:35 mrose ! 21: * unix stuff ! 22: * ! 23: * Revision 7.4 90/02/23 17:47:38 mrose ! 24: * update ! 25: * ! 26: * Revision 7.3 90/02/17 10:38:10 mrose ! 27: * smux ! 28: * ! 29: * Revision 7.2 90/01/27 08:21:47 mrose ! 30: * touch-up ! 31: * ! 32: * Revision 7.1 90/01/11 18:34:04 mrose ! 33: * real-sync ! 34: * ! 35: * Revision 7.0 89/11/23 22:23:03 mrose ! 36: * Release 6.0 ! 37: * ! 38: */ ! 39: ! 40: /* ! 41: * NOTICE ! 42: * ! 43: * Acquisition, use, and distribution of this module and related ! 44: * materials are subject to the restrictions of a license agreement. ! 45: * Consult the Preface in the User's Manual for the full terms of ! 46: * this agreement. ! 47: * ! 48: */ ! 49: ! 50: ! 51: #include <stdio.h> ! 52: #include "mib.h" ! 53: #include "interfaces.h" ! 54: #ifdef BSD44 ! 55: #include <net/if_types.h> ! 56: #endif ! 57: #include <sys/ioctl.h> ! 58: ! 59: /* */ ! 60: ! 61: #define TYPE_MIN 1 /* ifType */ ! 62: #define TYPE_OTHER 1 ! 63: #define TYPE_ETHER 6 ! 64: #define TYPE_P10 12 ! 65: #define TYPE_P80 13 ! 66: #define TYPE_MAX 28 ! 67: ! 68: ! 69: #define ADMIN_MIN 1 /* ifAdminStatus */ ! 70: #define ADMIN_MAX 3 ! 71: ! 72: #define OPER_UP 1 /* ifOperStatus */ ! 73: #define OPER_DOWN 2 ! 74: ! 75: ! 76: /* we assume that all interfaces are present at startup time and that they ! 77: don't move around in memory... */ ! 78: ! 79: int ifNumber = 0; ! 80: ! 81: struct interface *ifs = NULL; ! 82: ! 83: static struct address *afs = NULL; ! 84: struct address *afs_inet = NULL; ! 85: #ifdef BSD44 ! 86: struct address *afs_iso = NULL; ! 87: #endif ! 88: ! 89: static OID nullSpecific = NULLOID; ! 90: ! 91: /* */ ! 92: ! 93: #define ifIndex 0 ! 94: #define ifDescr 1 ! 95: #define ifType 2 /* SEMI IMPLEMENTED */ ! 96: #define ifMtu 3 ! 97: #define ifSpeed 4 /* SEMI IMPLEMENTED */ ! 98: #define ifPhysAddress 5 ! 99: #define ifAdminStatus 6 ! 100: #define ifOperStatus 7 ! 101: #ifdef BSD44 ! 102: #define ifLastChange 8 ! 103: #endif ! 104: #ifdef BSD44 ! 105: #define ifInOctets 9 ! 106: #endif ! 107: #define ifInUcastPkts 10 ! 108: #ifdef BSD44 ! 109: #define ifInNUcastPkts 11 ! 110: #define ifInDiscards 12 ! 111: #endif ! 112: #define ifInErrors 13 ! 113: #ifdef BSD44 ! 114: #define ifInUnknownProtos 14 ! 115: #define ifOutOctets 15 ! 116: #endif ! 117: #define ifOutUcastPkts 16 ! 118: #ifdef BSD44 ! 119: #define ifOutNUcastPkts 17 ! 120: #endif ! 121: #define ifOutDiscards 18 ! 122: #define ifOutErrors 19 ! 123: #define ifOutQLen 20 ! 124: #define ifSpecific 21 ! 125: ! 126: ! 127: static int o_interfaces (oi, v, offset) ! 128: OI oi; ! 129: register struct type_SNMP_VarBind *v; ! 130: int offset; ! 131: { ! 132: int ifnum, ! 133: ifvar; ! 134: register struct interface *is; ! 135: register struct ifnet *ifn; ! 136: register OID oid = oi -> oi_name; ! 137: register OT ot = oi -> oi_type; ! 138: #ifdef ifLastChange ! 139: static int lastq = -1; ! 140: static integer diff; ! 141: #endif ! 142: ! 143: if (sort_interfaces () == NOTOK) ! 144: return int_SNMP_error__status_genErr; ! 145: ! 146: ifvar = (int) ot -> ot_info; ! 147: switch (offset) { ! 148: case type_SNMP_PDUs_get__request: ! 149: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1) ! 150: return int_SNMP_error__status_noSuchName; ! 151: ifnum = oid -> oid_elements[oid -> oid_nelem - 1]; ! 152: for (is = ifs; is; is = is -> ifn_next) ! 153: if (is -> ifn_index == ifnum) ! 154: break; ! 155: if (is == NULL || !is -> ifn_ready) ! 156: return int_SNMP_error__status_noSuchName; ! 157: break; ! 158: ! 159: case type_SNMP_PDUs_get__next__request: ! 160: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { ! 161: OID new; ! 162: ! 163: for (is = ifs; is; is = is -> ifn_next) ! 164: if (is -> ifn_ready) ! 165: break; ! 166: if (!is) ! 167: return NOTOK; ! 168: ifnum = is -> ifn_index; ! 169: ! 170: if ((new = oid_extend (oid, 1)) == NULLOID) ! 171: return int_SNMP_error__status_genErr; ! 172: new -> oid_elements[new -> oid_nelem - 1] = ifnum; ! 173: ! 174: if (v -> name) ! 175: free_SNMP_ObjectName (v -> name); ! 176: v -> name = new; ! 177: } ! 178: else { ! 179: int i = ot -> ot_name -> oid_nelem; ! 180: register struct interface *iz; ! 181: ! 182: if ((ifnum = oid -> oid_elements[i]) == 0) { ! 183: if ((is = ifs) == NULL) ! 184: return NOTOK; ! 185: if (is -> ifn_ready) ! 186: goto stuff_ifnum; ! 187: ifnum = 1; ! 188: } ! 189: for (is = iz = ifs; is; is = is -> ifn_next) ! 190: if ((iz = is) -> ifn_index == ifnum) ! 191: break; ! 192: for (is = iz -> ifn_next; is; is = is -> ifn_next) ! 193: if (is -> ifn_ready) ! 194: break; ! 195: if (!is) ! 196: return NOTOK; ! 197: stuff_ifnum: ; ! 198: ifnum = is -> ifn_index; ! 199: ! 200: oid -> oid_elements[i] = ifnum; ! 201: oid -> oid_nelem = i + 1; ! 202: } ! 203: break; ! 204: ! 205: default: ! 206: return int_SNMP_error__status_genErr; ! 207: } ! 208: ifn = &is -> ifn_interface.ac_if; ! 209: ! 210: switch (ifvar) { ! 211: case ifIndex: ! 212: return o_integer (oi, v, is -> ifn_index); ! 213: ! 214: case ifDescr: ! 215: return o_string (oi, v, is -> ifn_descr, strlen (is -> ifn_descr)); ! 216: ! 217: case ifType: ! 218: if (is -> ifn_type < TYPE_MIN || is -> ifn_type > TYPE_MAX) ! 219: is -> ifn_type = TYPE_OTHER; ! 220: return o_integer (oi, v, is -> ifn_type); ! 221: ! 222: case ifMtu: ! 223: return o_integer (oi, v, ifn -> if_mtu); ! 224: ! 225: case ifSpeed: ! 226: return o_integer (oi, v, is -> ifn_speed); ! 227: ! 228: case ifPhysAddress: ! 229: #ifdef NEW_AT ! 230: return o_string (oi, v, ! 231: (char *) is -> ifn_interface.ac_enaddr, ! 232: sizeof is -> ifn_interface.ac_enaddr); ! 233: #else ! 234: return o_string (oi, v, ! 235: (char *) is -> ifn_interface.ac_enaddr.ether_addr_octet, ! 236: sizeof is -> ifn_interface.ac_enaddr.ether_addr_octet); ! 237: #endif ! 238: ! 239: case ifAdminStatus: ! 240: return o_integer (oi, v, is -> ifn_admin); ! 241: ! 242: case ifOperStatus: ! 243: return o_integer (oi, v, ifn -> if_flags & IFF_UP ? OPER_UP ! 244: : OPER_DOWN); ! 245: ! 246: #ifdef ifLastChange ! 247: case ifLastChange: ! 248: if (quantum != lastq) { ! 249: struct timeval now; ! 250: ! 251: lastq = quantum; ! 252: ! 253: if (gettimeofday (&now, (struct timezone *) 0) == NOTOK) { ! 254: advise (LLOG_EXCEPTIONS, "failed", "gettimeofday"); ! 255: return int_SNMP_error__status_genErr; ! 256: } ! 257: diff = (now.tv_sec - ifn -> if_lastchange.tv_sec) * 100 ! 258: + ((now.tv_usec - ifn -> if_lastchange.tv_usec) / 10000); ! 259: } ! 260: ! 261: return o_number (oi, v, diff); ! 262: #endif ! 263: ! 264: #ifdef ifInOctets ! 265: case ifInOctets: ! 266: return o_integer (oi, v, ifn -> if_ibytes); ! 267: #endif ! 268: ! 269: case ifInUcastPkts: ! 270: #ifndef BSD44 ! 271: return o_integer (oi, v, ifn -> if_ipackets); ! 272: #else ! 273: return o_integer (oi, v, ifn -> if_ipackets - ifn -> if_imcasts); ! 274: #endif ! 275: ! 276: #ifdef ifInNUcastPkts ! 277: case ifInNUcastPkts: ! 278: return o_integer (oi, v, ifn -> if_imcasts); ! 279: #endif ! 280: ! 281: #ifdef ifInDiscards ! 282: case ifInDiscards: ! 283: return o_integer (oi, v, ifn -> if_iqdrops); ! 284: #endif ! 285: ! 286: case ifInErrors: ! 287: return o_integer (oi, v, ifn -> if_ierrors); ! 288: ! 289: #ifdef ifInUnknownProtos ! 290: case ifInUnknownProtos: ! 291: return o_integer (oi, v, ifn -> if_noproto); ! 292: #endif ! 293: ! 294: #ifdef ifOutOctets ! 295: case ifOutOctets: ! 296: return o_integer (oi, v, ifn -> if_obytes); ! 297: #endif ! 298: ! 299: case ifOutUcastPkts: ! 300: #ifndef BSD44 ! 301: return o_integer (oi, v, ifn -> if_opackets); ! 302: #else ! 303: return o_integer (oi, v, ifn -> if_opackets - ifn -> if_omcasts); ! 304: #endif ! 305: ! 306: #ifdef ifOutNUcastPkts ! 307: case ifOutNUcastPkts: ! 308: return o_integer (oi, v, ifn -> if_omcasts); ! 309: #endif ! 310: ! 311: case ifOutDiscards: ! 312: return o_integer (oi, v, ifn -> if_snd.ifq_drops); ! 313: ! 314: case ifOutErrors: ! 315: return o_integer (oi, v, ifn -> if_oerrors); ! 316: ! 317: case ifOutQLen: ! 318: return o_integer (oi, v, ifn -> if_snd.ifq_len); ! 319: ! 320: case ifSpecific: ! 321: return o_specific (oi, v, (caddr_t) nullSpecific); ! 322: ! 323: default: ! 324: return int_SNMP_error__status_noSuchName; ! 325: } ! 326: } ! 327: ! 328: /* */ ! 329: ! 330: set_interface (name, ava) ! 331: char *name, ! 332: *ava; ! 333: { ! 334: int i; ! 335: register char *cp; ! 336: register struct interface *is; ! 337: ! 338: for (is = ifs; is; is = is -> ifn_next) ! 339: if (strcmp (is -> ifn_descr, name) == 0) ! 340: break; ! 341: if (!is) { ! 342: advise (LLOG_DEBUG, NULLCP, "no such interface as \"%s\"", name); ! 343: return; ! 344: } ! 345: ! 346: if ((cp = index (ava, '=')) == NULL) ! 347: return; ! 348: *cp++ = NULL; ! 349: ! 350: if (lexequ (ava, "ifType") == 0) { ! 351: if (sscanf (cp, "%d", &i) != 1 || i < TYPE_MIN || i > TYPE_MAX) { ! 352: malformed: ; ! 353: advise (LLOG_EXCEPTIONS, NULLCP, "malformed attribute \"%s=%s\"", ! 354: ava, cp); ! 355: return; ! 356: } ! 357: ! 358: switch (is -> ifn_type = i) { ! 359: case TYPE_ETHER: ! 360: case TYPE_P10: ! 361: is -> ifn_speed = 10000000; ! 362: break; ! 363: ! 364: case TYPE_P80: ! 365: is -> ifn_speed = 80000000; ! 366: break; ! 367: ! 368: default: ! 369: break; ! 370: } ! 371: return; ! 372: } ! 373: ! 374: if (lexequ (ava, "ifSpeed") == 0) { ! 375: if (sscanf (cp, "%d", &i) != 1 || i < 0) ! 376: goto malformed; ! 377: ! 378: is -> ifn_speed = i; ! 379: return; ! 380: } ! 381: ! 382: if (lexequ (ava, "ifAdminStatus") == 0) { ! 383: if (sscanf (cp, "%d", &i) != 1 || i < ADMIN_MIN || i > ADMIN_MAX) ! 384: goto malformed; ! 385: ! 386: is -> ifn_admin = i; ! 387: return; ! 388: } ! 389: ! 390: advise (LLOG_EXCEPTIONS, NULLCP, "unknown attribute \"%s=%s\"", ava, cp); ! 391: } ! 392: ! 393: /* */ ! 394: ! 395: init_interfaces () { ! 396: int i; ! 397: struct ifnet *ifnet; ! 398: register OT ot; ! 399: register struct interface *is, ! 400: **ifp; ! 401: struct nlist nzs; ! 402: register struct nlist *nz = &nzs; ! 403: ! 404: if (getkmem (nl + N_IFNET, (caddr_t) &ifnet, sizeof ifnet) == NOTOK) { ! 405: register struct interface *ip; ! 406: ! 407: disabled: ; ! 408: advise (LLOG_EXCEPTIONS, NULLCP, "interfaces group disabled!"); ! 409: for (is = ifs; is; is = ip) { ! 410: ip = is -> ifn_next; ! 411: ! 412: free ((char *) is); ! 413: } ! 414: ifs = NULL; ! 415: ! 416: return; ! 417: } ! 418: ! 419: ifp = &ifs; ! 420: for (i = 0; ifnet; i++) { ! 421: register struct ifnet *ifn; ! 422: ! 423: if ((is = (struct interface *) calloc (1, sizeof *is)) == NULL) ! 424: adios (NULLCP, "out of memory"); ! 425: is -> ifn_index = i + 1; ! 426: is -> ifn_indexmask = 1 << i; ! 427: ! 428: ifn = &is -> ifn_interface.ac_if; ! 429: ! 430: is -> ifn_offset = (unsigned long) ifnet; ! 431: ! 432: nz -> n_name = "struct ifnet", nz -> n_value = is -> ifn_offset; ! 433: if (getkmem (nz, (caddr_t) ifn, sizeof is -> ifn_interface) == NOTOK) ! 434: goto disabled; ! 435: ifnet = ifn -> if_next; ! 436: ! 437: nz -> n_name = "if_name", ! 438: nz -> n_value = (unsigned long) ifn -> if_name; ! 439: if (getkmem (nz, (caddr_t) is -> ifn_descr, sizeof is -> ifn_descr - 1) ! 440: == NOTOK) ! 441: goto disabled; ! 442: is -> ifn_descr[sizeof is -> ifn_descr - 1] = NULL; ! 443: (void) sprintf (is -> ifn_descr + strlen (is -> ifn_descr), "%d", ! 444: ifn -> if_unit); ! 445: ! 446: #ifdef BSD44 ! 447: switch (is -> ifn_type = ifn -> if_type) { ! 448: case IFT_ETHER: ! 449: case IFT_P10: ! 450: is -> ifn_speed = 10000000; ! 451: break; ! 452: ! 453: case IFT_P80: ! 454: is -> ifn_speed = 80000000; ! 455: break; ! 456: ! 457: default: ! 458: break; ! 459: } ! 460: #endif ! 461: if (is -> ifn_type != TYPE_ETHER) ! 462: #ifdef NEW_AT ! 463: bzero ((char *) is -> ifn_interface.ac_enaddr, ! 464: sizeof is -> ifn_interface.ac_enaddr); ! 465: #else ! 466: bzero ((char *) is -> ifn_interface.ac_enaddr.ether_addr_octet, ! 467: sizeof is -> ifn_interface.ac_enaddr.ether_addr_octet); ! 468: #endif ! 469: ! 470: is -> ifn_admin = OPER_UP; ! 471: ! 472: *ifp = is, ifp = &is -> ifn_next; ! 473: ! 474: if (debug) ! 475: advise (LLOG_DEBUG, NULLCP, ! 476: "add interface %d: %s 0x%x", ! 477: is -> ifn_index, is -> ifn_descr, is -> ifn_offset); ! 478: } ! 479: ! 480: if (ot = text2obj ("ifNumber")) { ! 481: ot -> ot_getfnx = o_generic; ! 482: if ((ot -> ot_info = (caddr_t) malloc (sizeof (integer))) == NULL) ! 483: adios (NULLCP, "out of memory"); ! 484: *((integer *) ot -> ot_info) = ifNumber = i; ! 485: } ! 486: ! 487: (void) sort_interfaces (); ! 488: ! 489: if (ot = text2obj ("ifIndex")) ! 490: ot -> ot_getfnx = o_interfaces, ! 491: ot -> ot_info = (caddr_t) ifIndex; ! 492: if (ot = text2obj ("ifDescr")) ! 493: ot -> ot_getfnx = o_interfaces, ! 494: ot -> ot_info = (caddr_t) ifDescr; ! 495: if (ot = text2obj ("ifType")) ! 496: ot -> ot_getfnx = o_interfaces, ! 497: ot -> ot_info = (caddr_t) ifType; ! 498: if (ot = text2obj ("ifMtu")) ! 499: ot -> ot_getfnx = o_interfaces, ! 500: ot -> ot_info = (caddr_t) ifMtu; ! 501: if (ot = text2obj ("ifSpeed")) ! 502: ot -> ot_getfnx = o_interfaces, ! 503: ot -> ot_info = (caddr_t) ifSpeed; ! 504: if (ot = text2obj ("ifPhysAddress")) ! 505: ot -> ot_getfnx = o_interfaces, ! 506: ot -> ot_info = (caddr_t) ifPhysAddress; ! 507: if (ot = text2obj ("ifAdminStatus")) ! 508: ot -> ot_getfnx = o_interfaces, ! 509: ot -> ot_info = (caddr_t) ifAdminStatus; ! 510: if (ot = text2obj ("ifOperStatus")) ! 511: ot -> ot_getfnx = o_interfaces, ! 512: ot -> ot_info = (caddr_t) ifOperStatus; ! 513: #ifdef ifLastChange ! 514: if (ot = text2obj ("ifLastChange")) ! 515: ot -> ot_getfnx = o_interfaces, ! 516: ot -> ot_info = (caddr_t) ifLastChange; ! 517: #endif ! 518: #ifdef ifInOctets ! 519: if (ot = text2obj ("ifInOctets")) ! 520: ot -> ot_getfnx = o_interfaces, ! 521: ot -> ot_info = (caddr_t) ifInOctets; ! 522: #endif ! 523: if (ot = text2obj ("ifInUcastPkts")) ! 524: ot -> ot_getfnx = o_interfaces, ! 525: ot -> ot_info = (caddr_t) ifInUcastPkts; ! 526: #ifdef ifInNUcastPkts ! 527: if (ot = text2obj ("ifInNUcastPkts")) ! 528: ot -> ot_getfnx = o_interfaces, ! 529: ot -> ot_info = (caddr_t) ifInNUcastPkts; ! 530: #endif ! 531: #ifdef ifInDiscards ! 532: if (ot = text2obj ("ifInDiscards")) ! 533: ot -> ot_getfnx = o_interfaces, ! 534: ot -> ot_info = (caddr_t) ifInDiscards; ! 535: #endif ! 536: if (ot = text2obj ("ifInErrors")) ! 537: ot -> ot_getfnx = o_interfaces, ! 538: ot -> ot_info = (caddr_t) ifInErrors; ! 539: #ifdef ifInUnknownProtos ! 540: if (ot = text2obj ("ifInUnknownProtos")) ! 541: ot -> ot_getfnx = o_interfaces, ! 542: ot -> ot_info = (caddr_t) ifInUnknownProtos; ! 543: #endif ! 544: #ifdef ifOutOctets ! 545: if (ot = text2obj ("ifOutOctets")) ! 546: ot -> ot_getfnx = o_interfaces, ! 547: ot -> ot_info = (caddr_t) ifOutOctets; ! 548: #endif ! 549: if (ot = text2obj ("ifOutUcastPkts")) ! 550: ot -> ot_getfnx = o_interfaces, ! 551: ot -> ot_info = (caddr_t) ifOutUcastPkts; ! 552: #ifdef ifOutNUcastPkts ! 553: if (ot = text2obj ("ifOutNUcastPkts")) ! 554: ot -> ot_getfnx = o_interfaces, ! 555: ot -> ot_info = (caddr_t) ifOutNUcastPkts; ! 556: #endif ! 557: if (ot = text2obj ("ifOutDiscards")) ! 558: ot -> ot_getfnx = o_interfaces, ! 559: ot -> ot_info = (caddr_t) ifOutDiscards; ! 560: if (ot = text2obj ("ifOutErrors")) ! 561: ot -> ot_getfnx = o_interfaces, ! 562: ot -> ot_info = (caddr_t) ifOutErrors; ! 563: if (ot = text2obj ("ifOutQLen")) ! 564: ot -> ot_getfnx = o_interfaces, ! 565: ot -> ot_info = (caddr_t) ifOutQLen; ! 566: if (ot = text2obj ("ifSpecific")) ! 567: ot -> ot_getfnx = o_interfaces, ! 568: ot -> ot_info = (caddr_t) ifSpecific; ! 569: if ((nullSpecific = text2oid ("nullSpecific")) == NULLOID) ! 570: adios (NULLCP, "unable to find nullSpecific"); ! 571: } ! 572: ! 573: /* */ ! 574: ! 575: static int adr_compar (a, b) ! 576: register struct address **a, ! 577: **b; ! 578: { ! 579: int i; ! 580: ! 581: if ((i = (*a) -> adr_address.sa.sa_family ! 582: - (*b) -> adr_address.sa.sa_family)) ! 583: return (i > 0 ? 1 : -1); ! 584: ! 585: return elem_cmp ((*a) -> adr_instance, (*a) -> adr_insize, ! 586: (*b) -> adr_instance, (*b) -> adr_insize); ! 587: } ! 588: ! 589: ! 590: int sort_interfaces () { ! 591: int adrNumber = 0; ! 592: register OT ot; ! 593: register struct interface *is; ! 594: register struct address *as, ! 595: *ap, ! 596: **base, ! 597: **afe, ! 598: **afp; ! 599: static int first_time = 1; ! 600: static int lastq = -1; ! 601: ! 602: if (quantum == lastq) ! 603: return OK; ! 604: lastq = quantum; ! 605: ! 606: for (as = afs; as; as = ap) { ! 607: ap = as -> adr_next; ! 608: ! 609: free ((char *) as); ! 610: } ! 611: afs = afs_inet = NULL; ! 612: #ifdef BSD44 ! 613: afs_iso = NULL; ! 614: #endif ! 615: ! 616: afp = &afs; ! 617: for (is = ifs; is; is = is -> ifn_next) { ! 618: struct arpcom ifns; ! 619: register struct ifnet *ifn = &ifns.ac_if; ! 620: #ifdef BSD43 ! 621: struct ifaddr ifaddr; ! 622: register struct ifaddr *ifa; ! 623: #ifdef BSD44 ! 624: union sockaddr_un ifsocka, ! 625: ifsockb; ! 626: #endif ! 627: union sockaddr_un ifsockc; ! 628: register union sockaddr_un *ia, ! 629: *ib; ! 630: register union sockaddr_un *ic = &ifsockc; ! 631: #endif ! 632: #ifndef BSD44 ! 633: struct ifreq ifreq; ! 634: #endif ! 635: struct nlist nzs; ! 636: register struct nlist *nz = &nzs; ! 637: ! 638: nz -> n_name = "struct ifnet", nz -> n_value = is -> ifn_offset; ! 639: if (getkmem (nz, (caddr_t) ifn, sizeof ifns) == NOTOK) ! 640: return NOTOK; ! 641: ! 642: #ifndef BSD43 ! 643: if (ifn -> if_addr.sa_family == AF_UNSPEC) ! 644: continue; ! 645: ! 646: if (nd != NOTOK) { ! 647: (void) strcpy (ifreq.ifr_name, is -> ifn_descr); ! 648: if (ioctl (nd, SIOCGIFNETMASK, (char *) &ifreq) == NOTOK) { ! 649: advise (LLOG_EXCEPTIONS, "failed", "SIOCGIFNETMASK on %s", ! 650: is -> ifn_descr); ! 651: continue; ! 652: } ! 653: } ! 654: else ! 655: bzero ((char *) &ifreq, sizeof ifreq); ! 656: if (ifn -> if_addr.sa_family == AF_INET) { ! 657: struct sockaddr_in *sx = (struct sockaddr_in *) &ifreq.ifr_addr; ! 658: struct sockaddr_in *sy = (struct sockaddr_in *) &ifn -> if_addr; ! 659: ! 660: if (sx -> sin_addr.s_addr == 0) { ! 661: if (IN_CLASSA (sy -> sin_addr.s_addr)) ! 662: sx -> sin_addr.s_addr = IN_CLASSA_NET; ! 663: else ! 664: if (IN_CLASSB (sy -> sin_addr.s_addr)) ! 665: sx -> sin_addr.s_addr = IN_CLASSB_NET; ! 666: else ! 667: sx -> sin_addr.s_addr = IN_CLASSC_NET; ! 668: } ! 669: } ! 670: ! 671: if (as = find_address ((union sockaddr_un *) &ifn -> if_addr)) ! 672: as -> adr_indexmask |= is -> ifn_indexmask; ! 673: else { ! 674: if ((as = (struct address *) calloc (1, sizeof *as)) == NULL) ! 675: adios (NULLCP, "out of memory"); ! 676: *afp = as, afp = &as -> adr_next, adrNumber++; ! 677: ! 678: as -> adr_address.sa = ifn -> if_addr; /* struct copy */ ! 679: if (ifn -> if_addr.sa_family == AF_INET) ! 680: as -> adr_broadaddr.sa = ifn -> if_broadaddr; /* .. */ ! 681: as -> adr_netmask.sa = ifreq.ifr_addr; /* .. */ ! 682: as -> adr_indexmask = is -> ifn_indexmask; ! 683: ! 684: switch (ifn -> if_addr.sa_family) { ! 685: case AF_INET: ! 686: as -> adr_insize = ! 687: ipaddr2oid (as -> adr_instance, ! 688: &((struct sockaddr_in *) &ifn -> if_addr) ! 689: -> sin_addr); ! 690: if (afs_inet == NULL) /* needed for find_address */ ! 691: afs_inet = as; ! 692: break; ! 693: ! 694: default: ! 695: bzero ((char *) as -> adr_instance, ! 696: sizeof as -> adr_instance); ! 697: as -> adr_insize = 0; ! 698: break; ! 699: } ! 700: } ! 701: #else ! 702: #ifndef BSD44 ! 703: ia = (union sockaddr_un *) &ifaddr.ifa_addr, ! 704: ib = (union sockaddr_un *) &ifaddr.ifa_broadaddr; ! 705: #else ! 706: ia = &ifsocka, ib = &ifsockb; ! 707: #endif ! 708: ! 709: for (ifa = ifn -> if_addrlist; ifa; ifa = ifaddr.ifa_next) { ! 710: nz -> n_name = "struct ifaddr", ! 711: nz -> n_value = (unsigned long) ifa; ! 712: if (getkmem (nz, (caddr_t) &ifaddr, sizeof ifaddr) == NOTOK) ! 713: continue; ! 714: #ifndef BSD44 ! 715: if (ia -> sa.sa_family == AF_UNSPEC) ! 716: continue; ! 717: ! 718: if (nd != NOTOK) { ! 719: (void) strcpy (ifreq.ifr_name, is -> ifn_descr); ! 720: if (ioctl (nd, SIOCGIFNETMASK, (char *) &ifreq) == NOTOK) { ! 721: advise (LLOG_EXCEPTIONS, "failed", "SIOCGIFNETMASK on %s", ! 722: is -> ifn_descr); ! 723: continue; ! 724: } ! 725: ic -> sa = ifreq.ifr_addr; /* struct copy */ ! 726: } ! 727: else ! 728: bzero ((char *) ic, sizeof *ic); ! 729: #else ! 730: nz -> n_name = "union sockaddr_un", ! 731: nz -> n_value = (unsigned long) ifaddr.ifa_addr; ! 732: if (getkmem (nz, (caddr_t) ia, sizeof *ia) == NOTOK) ! 733: continue; ! 734: ! 735: if (ia -> sa.sa_family == AF_UNSPEC) ! 736: continue; ! 737: ! 738: if (ia -> sa.sa_family == AF_INET) { ! 739: nz -> n_value = (unsigned long) ifaddr.ifa_broadaddr; ! 740: if (getkmem (nz, (caddr_t) ib, sizeof *ib) == NOTOK) ! 741: continue; ! 742: } ! 743: ! 744: nz -> n_value = (unsigned long) ifaddr.ifa_netmask; ! 745: if (getkmem (nz, (caddr_t) ic, sizeof *ic) == NOTOK) ! 746: continue; ! 747: #endif ! 748: if (ia -> sa.sa_family == AF_INET ! 749: && ic -> un_in.sin_addr.s_addr == 0) { ! 750: if (IN_CLASSA (ia -> un_in.sin_addr.s_addr)) ! 751: ic -> un_in.sin_addr.s_addr = IN_CLASSA_NET; ! 752: else ! 753: if (IN_CLASSB (ia -> un_in.sin_addr.s_addr)) ! 754: ic -> un_in.sin_addr.s_addr = IN_CLASSB_NET; ! 755: else ! 756: ic -> un_in.sin_addr.s_addr = IN_CLASSC_NET; ! 757: } ! 758: ! 759: if (as = find_address (ia)) ! 760: as -> adr_indexmask |= is -> ifn_indexmask; ! 761: else { ! 762: if ((as = (struct address *) calloc (1, sizeof *as)) == NULL) ! 763: adios (NULLCP, "out of memory"); ! 764: *afp = as, afp = &as -> adr_next, adrNumber++; ! 765: ! 766: as -> adr_address = *ia; /* struct copy */ ! 767: if (ia -> sa.sa_family == AF_INET) ! 768: as -> adr_broadaddr = *ib; /* struct copy */ ! 769: as -> adr_netmask = *ic; /* .. */ ! 770: ! 771: as -> adr_indexmask = is -> ifn_indexmask; ! 772: ! 773: switch (ia -> sa.sa_family) { ! 774: case AF_INET: ! 775: as -> adr_insize = ! 776: ipaddr2oid (as -> adr_instance, ! 777: &ia -> un_in.sin_addr); ! 778: if (afs_inet == NULL) /* needed for find_address */ ! 779: afs_inet = as; ! 780: break; ! 781: ! 782: #ifdef BSD44 ! 783: case AF_ISO: ! 784: as -> adr_insize = ! 785: clnpaddr2oid (as -> adr_instance, ! 786: &ia -> un_iso.siso_addr); ! 787: if (afs_iso == NULL) /* needed for find_address */ ! 788: afs_iso = as; ! 789: break; ! 790: #endif ! 791: ! 792: default: ! 793: bzero ((char *) as -> adr_instance, ! 794: sizeof as -> adr_instance); ! 795: as -> adr_insize = 0; ! 796: break; ! 797: } ! 798: } ! 799: } ! 800: #endif ! 801: ! 802: is -> ifn_interface = ifns; /* struct copy */ ! 803: ! 804: if (is -> ifn_type != TYPE_ETHER) ! 805: #ifdef NEW_AT ! 806: bzero ((char *) is -> ifn_interface.ac_enaddr, ! 807: sizeof is -> ifn_interface.ac_enaddr); ! 808: #else ! 809: bzero ((char *) is -> ifn_interface.ac_enaddr.ether_addr_octet, ! 810: sizeof is -> ifn_interface.ac_enaddr.ether_addr_octet); ! 811: #endif ! 812: } ! 813: ! 814: ifNumber = 0; ! 815: for (is = ifs; is; is = is -> ifn_next) { ! 816: is -> ifn_ready = 0; ! 817: ! 818: for (as = afs; as; as = as -> adr_next) ! 819: if (as -> adr_indexmask & is -> ifn_indexmask) ! 820: break; ! 821: if (as) ! 822: ifNumber += (is -> ifn_ready = 1); ! 823: } ! 824: if (ot = text2obj ("ifNumber")) ! 825: *((integer *) ot -> ot_info) = ifNumber; ! 826: ! 827: if (debug && first_time) { ! 828: first_time = 0; ! 829: ! 830: for (as = afs; as; as = as -> adr_next) { ! 831: OIDentifier oids; ! 832: ! 833: oids.oid_elements = as -> adr_instance; ! 834: oids.oid_nelem = as -> adr_insize; ! 835: advise (LLOG_DEBUG, NULLCP, ! 836: "add address: %d/%s with mask 0x%x", ! 837: as -> adr_address.sa.sa_family, sprintoid (&oids), ! 838: as -> adr_indexmask); ! 839: } ! 840: } ! 841: ! 842: if (adrNumber <= 1) ! 843: return OK; ! 844: ! 845: if ((base = (struct address **) ! 846: malloc ((unsigned) (adrNumber * sizeof *base))) == NULL) ! 847: adios (NULLCP, "out of memory"); ! 848: ! 849: afe = base; ! 850: for (as = afs; as; as = as -> adr_next) ! 851: *afe++ = as; ! 852: ! 853: qsort ((char *) base, adrNumber, sizeof *base, adr_compar); ! 854: ! 855: afp = base; ! 856: as = afs = *afp++; ! 857: afs_inet = NULL; ! 858: #ifdef BSD44 ! 859: afs_iso = NULL; ! 860: #endif ! 861: while (afp < afe) { ! 862: switch (as -> adr_address.sa.sa_family) { ! 863: case AF_INET: ! 864: if (afs_inet == NULL) ! 865: afs_inet = as; ! 866: break; ! 867: ! 868: #ifdef BSD44 ! 869: case AF_ISO: ! 870: if (afs_iso == NULL) ! 871: afs_iso = as; ! 872: break; ! 873: #endif ! 874: } ! 875: ! 876: as -> adr_next = *afp; ! 877: as = *afp++; ! 878: } ! 879: switch (as -> adr_address.sa.sa_family) { ! 880: case AF_INET: ! 881: if (afs_inet == NULL) ! 882: afs_inet = as; ! 883: break; ! 884: ! 885: #ifdef BSD44 ! 886: case AF_ISO: ! 887: if (afs_iso == NULL) ! 888: afs_iso = as; ! 889: break; ! 890: #endif ! 891: } ! 892: as -> adr_next = NULL; ! 893: ! 894: free ((char *) base); ! 895: ! 896: return OK; ! 897: } ! 898: ! 899: /* */ ! 900: ! 901: struct address *find_address (addr) ! 902: register union sockaddr_un *addr; ! 903: { ! 904: register struct address *as; ! 905: register struct in_addr *in; ! 906: #ifdef BSD44 ! 907: register struct iso_addr *iso; ! 908: #endif ! 909: ! 910: switch (addr -> sa.sa_family) { ! 911: case AF_INET: ! 912: in = &addr -> un_in.sin_addr; ! 913: for (as = afs_inet; as; as = as -> adr_next) ! 914: if (as -> adr_address.sa.sa_family != AF_INET) ! 915: break; ! 916: else ! 917: if (bcmp ((char *) in, ! 918: (char *) &as -> adr_address.un_in.sin_addr, ! 919: sizeof *in) == 0) ! 920: return as; ! 921: break; ! 922: ! 923: #ifdef BSD44 ! 924: case AF_ISO: ! 925: iso = &addr -> un_iso.siso_addr; ! 926: for (as = afs_iso; as; as = as -> adr_next) ! 927: if (as -> adr_address.sa.sa_family != AF_ISO) ! 928: break; ! 929: else ! 930: if (bcmp ((char *) iso, ! 931: (char *) &as -> adr_address.un_iso.siso_addr, ! 932: sizeof *iso) == 0) ! 933: return as; ! 934: ! 935: break; ! 936: #endif ! 937: ! 938: default: ! 939: break; ! 940: } ! 941: ! 942: return NULL; ! 943: } ! 944: ! 945: /* */ ! 946: ! 947: struct address *get_addrent (ip, len, head, isnext) ! 948: register unsigned int *ip; ! 949: int len; ! 950: struct address *head; ! 951: int isnext; ! 952: { ! 953: int family; ! 954: register struct address *as; ! 955: ! 956: if (head) ! 957: family = head -> adr_address.sa.sa_family; ! 958: for (as = head; as; as = as -> adr_next) ! 959: if (as -> adr_address.sa.sa_family != family) ! 960: break; ! 961: else ! 962: switch (elem_cmp (as -> adr_instance, as -> adr_insize, ip, len)) { ! 963: case 0: ! 964: if (!isnext) ! 965: return as; ! 966: if ((as = as -> adr_next) == NULL ! 967: || as -> adr_address.sa.sa_family != family) ! 968: return NULL; ! 969: /* else fall... */ ! 970: ! 971: case 1: ! 972: return (isnext ? as : NULL); ! 973: } ! 974: ! 975: return NULL; ! 976: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.