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