|
|
1.1 root 1: /* ip.c - MIB realization of the IP (and Address Translation) group */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/snmp/RCS/ip.c,v 7.12 90/07/09 14:48:44 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/snmp/RCS/ip.c,v 7.12 90/07/09 14:48:44 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: ip.c,v $
17: * Revision 7.12 90/07/09 14:48:44 mrose
18: * sync
19: *
20: * Revision 7.11 90/05/22 20:30:26 mrose
21: * cache
22: *
23: * Revision 7.10 90/05/12 17:02:02 mrose
24: * sync
25: *
26: * Revision 7.9 90/04/18 08:51:47 mrose
27: * oid_normalize
28: *
29: * Revision 7.8 90/03/24 10:54:09 mrose
30: * update
31: *
32: * Revision 7.7 90/03/06 13:50:55 mrose
33: * jch
34: *
35: * Revision 7.6 90/02/27 18:52:11 mrose
36: * unix stuff
37: *
38: * Revision 7.5 90/02/27 18:49:40 mrose
39: * unix stuff
40: *
41: * Revision 7.4 90/02/23 17:47:43 mrose
42: * update
43: *
44: * Revision 7.3 90/02/17 10:38:14 mrose
45: * smux
46: *
47: * Revision 7.2 90/01/27 08:21:52 mrose
48: * touch-up
49: *
50: * Revision 7.1 90/01/11 18:34:10 mrose
51: * real-sync
52: *
53: * Revision 7.0 89/11/23 22:23:06 mrose
54: * Release 6.0
55: *
56: */
57:
58: /*
59: * NOTICE
60: *
61: * Acquisition, use, and distribution of this module and related
62: * materials are subject to the restrictions of a license agreement.
63: * Consult the Preface in the User's Manual for the full terms of
64: * this agreement.
65: *
66: */
67:
68:
69: #include <stdio.h>
70: #include "mib.h"
71: #include "interfaces.h"
72: #include "routes.h"
73:
74: #include <netinet/in_systm.h>
75: #include <netinet/ip.h>
76: #include <netinet/ip_var.h>
77: #include <sys/ioctl.h>
78:
79: /* */
80:
81: #define FORW_GATEWAY 1 /* ipForwarding */
82: #define FORW_HOST 2
83: static int ipforwarding;
84:
85: static struct ipstat ipstat;
86:
87: /* */
88:
89: #define ipForwarding 0
90: #define ipDefaultTTL 1
91: #ifdef BSD43
92: #define ipInReceives 2
93: #endif
94: #define ipInHdrErrors 3
95: #undef ipInAddrErrors 4 /* NOT IMPLEMENTED */
96: #ifdef BSD43
97: #define ipForwDatagrams 5
98: #endif
99: #ifdef BSD44
100: #define ipInUnknownProtos 6
101: #endif
102: #undef ipInDiscards 7 /* NOT IMPLEMENTED */
103: #ifdef BSD44
104: #define ipInDelivers 8
105: #define ipOutRequests 9
106: #define ipOutDiscards 10
107: #endif
108: #ifdef BSD43
109: #define ipOutNoRoutes 11
110: #endif
111: #define ipReasmTimeout 12
112: #ifdef BSD43
113: #define ipReasmReqds 13
114: #endif
115: #ifdef BSD44
116: #define ipReasmOKs 14
117: #endif
118: #ifdef BSD43
119: #define ipReasmFails 15
120: #endif
121: #ifdef BSD44
122: #undef ipFragOKs 16
123: #undef ipFragFails 17
124: #undef ipFragCreates 18
125: #endif
126:
127:
128: static int o_ip (oi, v, offset)
129: OI oi;
130: register struct type_SNMP_VarBind *v;
131: int offset;
132: {
133: int ifvar;
134: register struct ipstat *ips = &ipstat;
135: register OID oid = oi -> oi_name;
136: register OT ot = oi -> oi_type;
137: static int lastq = -1;
138:
139: ifvar = (int) ot -> ot_info;
140: switch (offset) {
141: case type_SNMP_PDUs_get__request:
142: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
143: || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
144: return int_SNMP_error__status_noSuchName;
145: break;
146:
147: case type_SNMP_PDUs_get__next__request:
148: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
149: OID new;
150:
151: if ((new = oid_extend (oid, 1)) == NULLOID)
152: return int_SNMP_error__status_genErr;
153: new -> oid_elements[new -> oid_nelem - 1] = 0;
154:
155: if (v -> name)
156: free_SNMP_ObjectName (v -> name);
157: v -> name = new;
158: }
159: else
160: return NOTOK;
161: break;
162:
163: default:
164: return int_SNMP_error__status_genErr;
165: }
166:
167: switch (ifvar) {
168: case ipDefaultTTL:
169: case ipReasmTimeout:
170: break;
171:
172: default:
173: if (quantum != lastq) {
174: lastq = quantum;
175:
176: if (getkmem (nl + N_IPFORWARDING, (caddr_t) &ipforwarding,
177: sizeof ipforwarding) == NOTOK
178: || getkmem (nl + N_IPSTAT, (caddr_t) ips, sizeof *ips)
179: == NOTOK)
180: return int_SNMP_error__status_genErr;
181: }
182: break;
183: }
184:
185: switch (ifvar) {
186: case ipForwarding:
187: return o_integer (oi, v, ipforwarding ? FORW_GATEWAY : FORW_HOST);
188:
189: case ipDefaultTTL:
190: return o_integer (oi, v, MAXTTL);
191:
192: #ifdef ipInReceives
193: case ipInReceives:
194: return o_integer (oi, v, ips -> ips_total);
195: #endif
196:
197: case ipInHdrErrors:
198: return o_integer (oi, v, ips -> ips_badsum
199: + ips -> ips_tooshort
200: + ips -> ips_toosmall
201: + ips -> ips_badhlen
202: + ips -> ips_badlen);
203:
204: #ifdef ipForwDatagrams
205: case ipForwDatagrams:
206: return o_integer (oi, v, ips -> ips_forward);
207: #endif
208:
209: #ifdef ipInUnknownProtos
210: case ipInUnknownProtos:
211: return o_integer (oi, v, ips -> ips_noproto);
212: #endif
213:
214: #ifdef ipInDelivers
215: case ipInDelivers:
216: return o_integer (oi, v, ips -> ips_delivered);
217: #endif
218:
219: #ifdef ipOutRequests
220: case ipOutRequests:
221: return o_integer (oi, v, ips -> ips_localout);
222: #endif
223:
224: #ifdef ipOutDiscards
225: case ipOutDiscards:
226: return o_integer (oi, v, ips -> ips_odropped);
227: #endif
228:
229: #ifdef ipOutNoRoutes
230: case ipOutNoRoutes:
231: return o_integer (oi, v, ips -> ips_cantforward);
232: #endif
233:
234: case ipReasmTimeout:
235: return o_integer (oi, v, IPFRAGTTL);
236:
237: #ifdef ipReasmReqds
238: case ipReasmReqds:
239: return o_integer (oi, v, ips -> ips_fragments);
240: #endif
241:
242: #ifdef ipReasmOKs
243: case ipReasmOKs:
244: return o_integer (oi, v, ips -> ips_reassembled);
245: #endif
246:
247: #ifdef ipReasmFails
248: case ipReasmFails:
249: return o_integer (oi, v, ips -> ips_fragdropped
250: + ips -> ips_fragtimeout);
251: #endif
252:
253: #ifdef ipFragOKs
254: case ipFragOKs:
255: return o_integer (oi, v, ips -> ips_fragmented);
256: #endif
257:
258: #ifdef ipFragFails
259: case ipFragFails:
260: return o_integer (oi, v, ips -> ips_cantfrag);
261: #endif
262:
263: #ifdef ipFragCreates
264: case ipFragCreates:
265: return o_integer (oi, v, ips -> ips_ofragments);
266: #endif
267:
268: default:
269: return int_SNMP_error__status_noSuchName;
270: }
271: }
272:
273: /* */
274:
275: #ifndef IP_MAXPACKET
276: #define IP_MAXPACKET 65535 /* ipAdEntReasmMaxSize */
277: #endif
278:
279:
280: #define IFN_SIZE 4
281:
282: /* */
283:
284: #define ipAdEntAddr 0
285: #define ipAdEntIfIndex 1
286: #define ipAdEntNetMask 2
287: #define ipAdEntBcastAddr 3
288: #define ipAdEntReasmMaxSize 4
289:
290:
291: static int o_ip_addr (oi, v, offset)
292: OI oi;
293: register struct type_SNMP_VarBind *v;
294: int offset;
295: {
296: register int i;
297: int ifvar;
298: register unsigned int *ip,
299: *jp;
300: register struct address *as;
301: register OID oid = oi -> oi_name;
302: OID new;
303: register OT ot = oi -> oi_type;
304:
305: if (sort_interfaces () == NOTOK)
306: return int_SNMP_error__status_genErr;
307:
308: ifvar = (int) ot -> ot_info;
309: switch (offset) {
310: case type_SNMP_PDUs_get__request:
311: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + IFN_SIZE)
312: return int_SNMP_error__status_noSuchName;
313: if ((as = get_addrent (oid -> oid_elements + oid -> oid_nelem
314: - IFN_SIZE, IFN_SIZE, afs_inet, 0)) == NULL)
315: return int_SNMP_error__status_noSuchName;
316: break;
317:
318: case type_SNMP_PDUs_get__next__request:
319: if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0
320: && i < IFN_SIZE) {
321: for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i;
322: jp > ip;
323: jp--)
324: if (*jp != 0)
325: break;
326: if (jp == ip)
327: oid -> oid_nelem = ot -> ot_name -> oid_nelem;
328: else {
329: if ((new = oid_normalize (oid, IFN_SIZE - i, 256))
330: == NULLOID)
331: return int_SNMP_error__status_genErr;
332: if (v -> name)
333: free_SNMP_ObjectName (v -> name);
334: v -> name = oid = new;
335: }
336: }
337:
338: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
339: if ((as = afs_inet) == NULL)
340: return NOTOK;
341:
342: if ((new = oid_extend (oid, IFN_SIZE)) == NULLOID)
343: return int_SNMP_error__status_genErr;
344: ip = new -> oid_elements + new -> oid_nelem - IFN_SIZE;
345: jp = as -> adr_instance;
346: for (i = IFN_SIZE; i> 0; i--)
347: *ip++ = *jp++;
348:
349: if (v -> name)
350: free_SNMP_ObjectName (v -> name);
351: v -> name = new;
352: }
353: else {
354: if ((as = get_addrent (ip = oid -> oid_elements
355: + oid -> oid_nelem - IFN_SIZE,
356: IFN_SIZE, afs_inet, 1)) == NULL)
357: return NOTOK;
358:
359: jp = as -> adr_instance;
360: for (i = IFN_SIZE; i > 0; i--)
361: *ip++ = *jp++;
362: }
363: break;
364:
365: default:
366: return int_SNMP_error__status_genErr;
367: }
368:
369: switch (ifvar) {
370: case ipAdEntAddr:
371: return o_ipaddr (oi, v, (struct sockaddr_in *) &as -> adr_address);
372:
373: case ipAdEntIfIndex:
374: return o_integer (oi, v, ffs (as -> adr_indexmask));
375:
376: case ipAdEntNetMask:
377: return o_ipaddr (oi, v, (struct sockaddr_in *) &as -> adr_netmask);
378:
379: case ipAdEntBcastAddr: /* beyond belief! */
380: {
381: u_long a = (((struct sockaddr_in *) &as -> adr_netmask)
382: -> sin_addr.s_addr)
383: & ~(((struct sockaddr_in *) &as
384: -> adr_broadaddr) -> sin_addr.s_addr);
385:
386: return o_integer (oi, v, a ? 1 : 0);
387: }
388:
389: case ipAdEntReasmMaxSize:
390: return o_integer (oi, v, IP_MAXPACKET);
391:
392: default:
393: return int_SNMP_error__status_noSuchName;
394: }
395: }
396:
397: /* */
398:
399: #define ipRouteDest 0
400: #define ipRouteIfIndex 1
401: #define ipRouteMetric1 2
402: #define ipRouteMetric2 3
403: #define ipRouteMetric3 4
404: #define ipRouteMetric4 5
405: #define ipRouteNextHop 6
406: #define ipRouteType 7
407: #define ipRouteProto 8
408: #define ipRouteAge 9
409: #define ipRouteMask 10
410: #define unixIpRouteFlags 11
411: #define unixIpRouteRefCnt 12
412: #define unixIpRouteUses 13
413:
414:
415: static int o_ip_route (oi, v, offset)
416: OI oi;
417: register struct type_SNMP_VarBind *v;
418: int offset;
419: {
420: int ifvar;
421: register int i;
422: register unsigned int *ip,
423: *jp;
424: register struct rtetab *rt;
425: register OID oid = oi -> oi_name;
426: OID new;
427: register OT ot = oi -> oi_type;
428:
429: if (get_routes (offset) == NOTOK)
430: return int_SNMP_error__status_genErr;
431:
432: ifvar = (int) ot -> ot_info;
433: switch (offset) {
434: case type_SNMP_PDUs_get__request:
435: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + IFN_SIZE)
436: return int_SNMP_error__status_noSuchName;
437: if ((rt = get_rtent (oid -> oid_elements + oid -> oid_nelem
438: - IFN_SIZE, IFN_SIZE, rts_inet, 0))
439: == NULL)
440: return int_SNMP_error__status_noSuchName;
441: break;
442:
443: case type_SNMP_PDUs_get__next__request:
444: if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0
445: && i < IFN_SIZE) {
446: for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i;
447: jp > ip;
448: jp--)
449: if (*jp != 0)
450: break;
451: if (jp == ip)
452: oid -> oid_nelem = ot -> ot_name -> oid_nelem;
453: else {
454: if ((new = oid_normalize (oid, IFN_SIZE - i, 256))
455: == NULLOID)
456: return int_SNMP_error__status_genErr;
457: if (v -> name)
458: free_SNMP_ObjectName (v -> name);
459: v -> name = oid = new;
460: }
461: }
462:
463: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
464: if ((rt = rts_inet) == NULL)
465: return NOTOK;
466:
467: if ((new = oid_extend (oid, IFN_SIZE)) == NULLOID)
468: return int_SNMP_error__status_genErr;
469: ip = new -> oid_elements + new -> oid_nelem - IFN_SIZE;
470:
471: if (v -> name)
472: free_SNMP_ObjectName (v -> name);
473: v -> name = new;
474: }
475: else
476: if ((rt = get_rtent (ip = oid -> oid_elements
477: + oid -> oid_nelem - IFN_SIZE,
478: IFN_SIZE, rts_inet, 1)) == NULL)
479: return NOTOK;
480: jp = rt -> rt_instance;
481: for (i = IFN_SIZE; i> 0; i--)
482: *ip++ = *jp++;
483:
484: break;
485:
486: default:
487: return int_SNMP_error__status_genErr;
488: }
489:
490: switch (ifvar) {
491: case ipRouteDest:
492: return o_ipaddr (oi, v, (struct sockaddr_in *) &rt -> rt_dst);
493:
494: case ipRouteIfIndex:
495: {
496: register struct interface *is;
497:
498: if (sort_interfaces () == NOTOK)
499: return int_SNMP_error__status_genErr;
500:
501: for (is = ifs; is; is = is -> ifn_next)
502: if ((caddr_t) is -> ifn_offset
503: == (caddr_t) rt -> rt_rt.rt_ifp) {
504: if (is -> ifn_ready)
505: return o_integer (oi, v, is -> ifn_index);
506: break;
507: }
508:
509: if (offset == type_SNMP_PDUs_get__next__request)
510: return NOTOK;
511: return int_SNMP_error__status_noSuchName;
512: }
513:
514: case ipRouteMetric1:
515: case ipRouteMetric2:
516: case ipRouteMetric3:
517: case ipRouteMetric4:
518: return o_integer (oi, v, METRIC_NONE);
519:
520: case ipRouteNextHop:
521: return o_ipaddr (oi, v, (struct sockaddr_in *) &rt -> rt_gateway);
522:
523: case ipRouteType:
524: switch (rt -> rt_rt.rt_flags & (RTF_GATEWAY | RTF_HOST)) {
525: case RTF_GATEWAY:
526: case RTF_HOST:
527: return o_integer (oi, v, TYPE_REMOTE);
528:
529: case 0:
530: return o_integer (oi, v, TYPE_DIRECT);
531:
532: default:
533: return o_integer (oi, v, TYPE_OTHER);
534: }
535:
536: case ipRouteProto:
537: #ifdef RTF_DYNAMIC
538: #ifndef RTF_MODIFIED
539: if (rt -> rt_rt.rt_flags & RTF_DYNAMIC)
540: #else
541: if (rt -> rt_rt.rt_flags & (RTF_DYNAMIC | RTF_MODIFIED))
542: #endif
543: return o_integer (oi, v, PROTO_ICMP);
544: else
545: #endif
546: return o_integer (oi, v, PROTO_OTHER);
547:
548: case ipRouteAge:
549: return o_integer (oi, v, 0);
550:
551: case ipRouteMask:
552: {
553: struct sockaddr_in mask;
554: struct sockaddr_in *sin = (struct sockaddr_in *) &rt -> rt_dst;
555: #ifndef BSD44
556: register struct interface *is;
557: register struct address *as;
558: #endif
559:
560: bzero ((char *) &mask, sizeof mask);
561:
562: if (rt->rt_rt.rt_flags & RTF_HOST)
563: mask.sin_addr.s_addr = (u_long) 0xffffffff;
564: else
565: if (sin -> sin_addr.s_addr != 0L) {
566: #ifndef BSD44
567: /* XXX - BSD44 shouldn't use this code, it has a */
568: /* mask associated with each route, but I don't */
569: /* know how to locate it at the moment (jch) */
570:
571: if (sort_interfaces () == NOTOK)
572: return int_SNMP_error__status_genErr;
573:
574: for (is = ifs; is; is = is -> ifn_next)
575: if ((caddr_t) is -> ifn_offset
576: == (caddr_t) rt -> rt_rt.rt_ifp)
577: break;
578:
579: if (!is || !is -> ifn_ready)
580: return int_SNMP_error__status_noSuchName;
581:
582: for (as = afs_inet; as; as = as -> adr_next)
583: if (is -> ifn_indexmask & as -> adr_indexmask)
584: break;
585:
586: if (!as)
587: return int_SNMP_error__status_noSuchName;
588:
589: mask.sin_addr.s_addr = as -> adr_netmask.un_in.sin_addr.s_addr;
590: #else
591: if (IN_CLASSA (sin -> sin_addr.s_addr))
592: mask.sin_addr.s_addr = IN_CLASSA_NET;
593: else
594: if (IN_CLASSB (sin -> sin_addr.s_addr))
595: mask.sin_addr.s_addr = IN_CLASSB_NET;
596: else
597: mask.sin_addr.s_addr = IN_CLASSC_NET;
598: #endif
599: }
600:
601: return o_ipaddr (oi, v, &mask);
602: }
603:
604: case unixIpRouteFlags:
605: return o_integer (oi, v, rt -> rt_rt.rt_flags & 0xffff);
606:
607: case unixIpRouteRefCnt:
608: return o_integer (oi, v, rt -> rt_rt.rt_refcnt & 0xffff);
609:
610: case unixIpRouteUses:
611: return o_integer (oi, v, rt -> rt_rt.rt_use);
612:
613: default:
614: return int_SNMP_error__status_noSuchName;
615: }
616: }
617:
618: /* */
619:
620: static struct rtstat rtstat;
621:
622: /* */
623:
624: #define unixRouteBadRedirects 0
625: #define unixRouteCreatedByRedirects 1
626: #define unixRouteModifiedByRedirects 2
627: #define unixRouteLookupFails 3
628: #define unixRouteWildcardUses 4
629:
630:
631: static int o_ip_routing_stats (oi, v, offset)
632: OI oi;
633: register struct type_SNMP_VarBind *v;
634: int offset;
635: {
636: int ifvar;
637: register struct rtstat *rts = &rtstat;
638: register OID oid = oi -> oi_name;
639: register OT ot = oi -> oi_type;
640: static int lastq = -1;
641:
642: ifvar = (int) ot -> ot_info;
643: switch (offset) {
644: case type_SNMP_PDUs_get__request:
645: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
646: || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
647: return int_SNMP_error__status_noSuchName;
648: break;
649:
650: case type_SNMP_PDUs_get__next__request:
651: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
652: OID new;
653:
654: if ((new = oid_extend (oid, 1)) == NULLOID)
655: return int_SNMP_error__status_genErr;
656: new -> oid_elements[new -> oid_nelem - 1] = 0;
657:
658: if (v -> name)
659: free_SNMP_ObjectName (v -> name);
660: v -> name = new;
661: }
662: else
663: return NOTOK;
664: break;
665:
666: default:
667: return int_SNMP_error__status_genErr;
668: }
669:
670: if (quantum != lastq) {
671: lastq = quantum;
672:
673: if (getkmem (nl + N_RTSTAT, (caddr_t) rts, sizeof *rts) == NOTOK)
674: return int_SNMP_error__status_genErr;
675: }
676:
677: switch (ifvar) {
678: case unixRouteBadRedirects:
679: return o_integer (oi, v, rts -> rts_badredirect & 0xffff);
680:
681: case unixRouteCreatedByRedirects:
682: return o_integer (oi, v, rts -> rts_dynamic & 0xffff);
683:
684: case unixRouteModifiedByRedirects:
685: return o_integer (oi, v, rts -> rts_newgateway & 0xffff);
686:
687: case unixRouteLookupFails:
688: return o_integer (oi, v, rts -> rts_unreach & 0xffff);
689:
690: case unixRouteWildcardUses:
691: return o_integer (oi, v, rts -> rts_wildcard & 0xffff);
692:
693: default:
694: return int_SNMP_error__status_noSuchName;
695: }
696: }
697:
698: /* */
699:
700: struct adrtab {
701: #define ADN_SIZE (IFN_SIZE + 1) /* IpAddress instance */
702: unsigned int adn_instance[ADN_SIZE];
703: int adn_insize;
704:
705: struct in_addr adn_address; /* IpAddress */
706:
707:
708: #define ADM_SIZE ADR_SIZE /* PhysAddress instance */
709: unsigned int adm_instance[ADM_SIZE];
710: int adm_insize;
711:
712: u_char adm_address[ADM_SIZE]; /* PhysAddress */
713: u_char adm_addrlen; /* .. */
714:
715:
716: #define ADA_SIZE (IFN_SIZE + 2) /* AtEntry instance */
717: unsigned int ada_instance[ADA_SIZE];
718: int ada_insize;
719:
720:
721: int adr_index; /* ifIndex */
722:
723: int adr_type; /* ipNetToMediaType */
724: #define OTHER_MAPPING 1
725: #define DYNAMIC_MAPPING 3
726: #define STATIC_MAPPING 4
727:
728: struct adrtab *adn_next; /* next IpAddress */
729: struct adrtab *adm_next; /* next PhysAddress */
730: struct adrtab *ada_next; /* next AtEntry */
731: };
732:
733: static struct adrtab *ada = NULL;
734: static struct adrtab *adn = NULL;
735: static struct adrtab *adm = NULL;
736:
737:
738: static struct adrtab *get_arpent ();
739:
740: /* */
741:
742: #define atIfIndex 0
743: #define atPhysAddress 1
744: #define atNetAddress 2
745:
746: #define ipNetToMediaIfIndex 3
747: #define ipNetToMediaPhysAddress 4
748: #define ipNetToMediaNetAddress 5
749: #define ipNetToMediaType 6
750:
751:
752: static int o_address (oi, v, offset)
753: OI oi;
754: register struct type_SNMP_VarBind *v;
755: int offset;
756: {
757: register int i;
758: int ifvar,
759: isnpa;
760: register unsigned int *ip,
761: *jp;
762: register struct adrtab *at;
763: struct sockaddr_in netaddr;
764: register OID oid = oi -> oi_name;
765: register OT ot = oi -> oi_type;
766:
767: if (get_arptab () == NOTOK)
768: return int_SNMP_error__status_genErr;
769:
770: switch (ifvar = (int) ot -> ot_info) {
771: case ipNetToMediaIfIndex:
772: case ipNetToMediaPhysAddress:
773: case ipNetToMediaNetAddress:
774: case ipNetToMediaType:
775: isnpa = 0;
776: break;
777:
778: case atIfIndex:
779: case atPhysAddress:
780: case atNetAddress:
781: isnpa = -1;
782: }
783:
784: switch (offset) {
785: case type_SNMP_PDUs_get__request:
786: if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
787: return int_SNMP_error__status_noSuchName;
788: if ((at = get_arpent (oid -> oid_elements
789: + ot -> ot_name -> oid_nelem,
790: oid -> oid_nelem
791: - ot -> ot_name -> oid_nelem,
792: isnpa, 0)) == NULL)
793: return int_SNMP_error__status_noSuchName;
794: break;
795:
796: case type_SNMP_PDUs_get__next__request:
797: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
798: OID new;
799:
800: switch (isnpa) {
801: case 0:
802: if (at = adn)
803: jp = at -> adn_instance, i = at -> adn_insize;
804: break;
805:
806: case 1:
807: if (at = adm)
808: jp = at -> adm_instance, i = at -> adm_insize;
809: break;
810:
811: case -1:
812: if (at = ada)
813: jp = at -> ada_instance, i = at -> ada_insize;
814: break;
815: }
816: if (at == NULL)
817: return NOTOK;
818:
819: if ((new = oid_extend (oid, i)) == NULLOID)
820: return int_SNMP_error__status_genErr;
821: ip = new -> oid_elements + new -> oid_nelem - i;
822: for (; i > 0; i--)
823: *ip++ = *jp++;
824:
825: if (v -> name)
826: free_SNMP_ObjectName (v -> name);
827: v -> name = new;
828: }
829: else {
830: int j;
831:
832: if ((at = get_arpent (oid -> oid_elements
833: + ot -> ot_name -> oid_nelem,
834: j = oid -> oid_nelem
835: - ot -> ot_name -> oid_nelem,
836: isnpa, 1)) == NULL)
837: return NOTOK;
838: i = isnpa > 0 ? at -> adm_insize
839: : isnpa == 0 ? at -> adn_insize
840: : at -> ada_insize;
841:
842: if ((i = j - i) < 0) {
843: OID new;
844:
845: if ((new = oid_extend (oid, -i)) == NULLOID)
846: return int_SNMP_error__status_genErr;
847: if (v -> name)
848: free_SNMP_ObjectName (v -> name);
849: v -> name = new;
850:
851: oid = new;
852: }
853: else
854: if (i > 0)
855: oid -> oid_nelem -= i;
856:
857: ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
858: switch (isnpa) {
859: case 0:
860: jp = at -> adn_instance, i = at -> adn_insize;
861: break;
862:
863: case 1:
864: jp = at -> adm_instance, i = at -> adm_insize;
865: break;
866:
867: case -1:
868: jp = at -> ada_instance, i = at -> ada_insize;
869: break;
870:
871: }
872: for (; i > 0; i--)
873: *ip++ = *jp++;
874: }
875: break;
876:
877: default:
878: return int_SNMP_error__status_genErr;
879: }
880:
881: switch (ifvar) {
882: case atIfIndex:
883: case ipNetToMediaIfIndex:
884: return o_integer (oi, v, at -> adr_index);
885:
886: case atPhysAddress:
887: case ipNetToMediaPhysAddress:
888: return o_string (oi, v, (char *) at -> adm_address,
889: (int) at -> adm_addrlen);
890:
891: case atNetAddress:
892: case ipNetToMediaNetAddress:
893: netaddr.sin_addr = at -> adn_address; /* struct copy */
894: return o_ipaddr (oi, v, &netaddr);
895:
896: case ipNetToMediaType:
897: return o_integer (oi, v, at -> adr_type);
898:
899: default:
900: return int_SNMP_error__status_noSuchName;
901: }
902: }
903:
904: /* */
905:
906: static int adn_compar (a, b)
907: register struct adrtab **a,
908: **b;
909: {
910: return elem_cmp ((*a) -> adn_instance, (*a) -> adn_insize,
911: (*b) -> adn_instance, (*b) -> adn_insize);
912: }
913:
914:
915: static int adm_compar (a, b)
916: register struct adrtab **a,
917: **b;
918: {
919: return elem_cmp ((*a) -> adm_instance, (*a) -> adm_insize,
920: (*b) -> adm_instance, (*b) -> adm_insize);
921: }
922:
923: static int ada_compar (a, b)
924: register struct adrtab **a,
925: **b;
926: {
927: return elem_cmp ((*a) -> ada_instance, (*a) -> ada_insize,
928: (*b) -> ada_instance, (*b) -> ada_insize);
929: }
930:
931:
932:
933: static int get_arptab () {
934: int adrNumber = 0,
935: arptab_size,
936: tblsize;
937: register struct arptab *ac,
938: *ae;
939: struct arptab *arptab;
940: register struct adrtab *at,
941: *ap,
942: **base,
943: **afe,
944: **afp;
945: register struct interface *is;
946: static int first_time = 1;
947: static int lastq = -1;
948:
949: if (quantum == lastq)
950: return OK;
951: lastq = quantum;
952:
953: for (at = adn; at; at = ap) {
954: ap = at -> adn_next;
955:
956: free ((char *) at);
957: }
958: adn = adm = ada = NULL;
959:
960: if (getkmem (nl + N_ARPTAB_SIZE, (caddr_t) &arptab_size,
961: sizeof arptab_size) == NOTOK)
962: return NOTOK;
963: tblsize = arptab_size * sizeof *arptab;
964: if ((arptab = (struct arptab *) malloc ((unsigned) (tblsize))) == NULL)
965: adios (NULLCP, "out of memory");
966: if (getkmem (nl + N_ARPTAB, (caddr_t) arptab, tblsize) == NOTOK) {
967: free ((char *) arptab);
968: return NOTOK;
969: }
970:
971: afp = &adn;
972: for (ae = (ac = arptab) + arptab_size; ac < ae; ac++) {
973: int type;
974:
975: if (!(ac -> at_iaddr.s_addr) || !(ac -> at_flags & ATF_COM))
976: continue;
977: type = ac -> at_flags & ATF_PERM ? OTHER_MAPPING
978: : ac -> at_flags & ATF_PUBL ? STATIC_MAPPING
979: : DYNAMIC_MAPPING;
980:
981: /* there appears to be no way to gather per-interface address translation
982: tables, so we simply duplicate the arptable for each interface... */
983: for (is = ifs; is; is = is -> ifn_next) {
984: if (!is -> ifn_ready)
985: continue;
986:
987: if ((at = (struct adrtab *) calloc (1, sizeof *at)) == NULL)
988: adios (NULLCP, "out of memory");
989: *afp = at, afp = &at -> adn_next, adrNumber++;
990:
991: at -> adr_index = is -> ifn_index;
992: at -> adr_type = type;
993:
994: at -> adn_address = ac -> at_iaddr; /* struct copy */
995: at -> adn_instance[0] = at -> adr_index, at -> adn_insize = 1;
996: at -> adn_insize += ipaddr2oid (at -> adn_instance + 1,
997: &at -> adn_address);
998:
999: #ifdef NEW_AT
1000: bcopy ((char *) ac -> at_enaddr,
1001: (char *) at -> adm_address,
1002: (int) (at -> adm_addrlen = sizeof ac -> at_enaddr));
1003: #else
1004: bcopy ((char *) ac -> at_enaddr.ether_addr_octet,
1005: (char *) at -> adm_address,
1006: (int) (at -> adm_addrlen =
1007: sizeof ac -> at_enaddr.ether_addr_octet));
1008: #endif
1009: at -> adm_instance[0] = at -> adr_index, at -> adm_insize = 1;
1010: at -> adm_insize += mediaddr2oid (at -> adm_instance + 1,
1011: at -> adm_address,
1012: (int) at -> adm_addrlen, 0);
1013:
1014: at -> ada_instance[0] = at -> adr_index;
1015: at -> ada_instance[1] = 1;
1016: at -> ada_insize = 2;
1017: at -> ada_insize += ipaddr2oid (at -> ada_instance + 2,
1018: &at -> adn_address);
1019:
1020: if (debug && first_time) {
1021: char buffer[BUFSIZ];
1022: OIDentifier oids;
1023:
1024: oids.oid_elements = at -> adn_instance;
1025: oids.oid_nelem = at -> adn_insize;
1026: (void) strcpy (buffer, sprintoid (&oids));
1027: oids.oid_elements = at -> adm_instance;
1028: oids.oid_nelem = at -> adm_insize;
1029: advise (LLOG_DEBUG, NULLCP,
1030: "add mapping on %d: %s -> %s",
1031: at -> adr_index, buffer, sprintoid (&oids));
1032: }
1033: }
1034: }
1035: first_time = 0;
1036: free ((char *) arptab);
1037:
1038: if (adrNumber <= 1) {
1039: adm = ada = adn;
1040: return OK;
1041: }
1042:
1043: if ((base = (struct adrtab **)
1044: malloc ((unsigned) (adrNumber * sizeof *base))) == NULL)
1045: adios (NULLCP, "out of memory");
1046:
1047: afe = base;
1048: for (at = adn; at; at = at -> adn_next)
1049: *afe++ = at;
1050:
1051: qsort ((char *) base, adrNumber, sizeof *base, adn_compar);
1052:
1053: afp = base;
1054: at = adn = *afp++;
1055: while (afp < afe) {
1056: at -> adn_next = *afp;
1057: at = *afp++;
1058: }
1059: at -> adn_next = NULL;
1060:
1061: qsort ((char *) base, adrNumber, sizeof *base, adm_compar);
1062:
1063: afp = base;
1064: at = adm = *afp++;
1065: while (afp < afe) {
1066: at -> adm_next = *afp;
1067: at = *afp++;
1068: }
1069: at -> adm_next = NULL;
1070:
1071: qsort ((char *) base, adrNumber, sizeof *base, ada_compar);
1072:
1073: afp = base;
1074: at = ada = *afp++;
1075: while (afp < afe) {
1076: at -> ada_next = *afp;
1077: at = *afp++;
1078: }
1079: at -> ada_next = NULL;
1080:
1081: free ((char *) base);
1082:
1083: return OK;
1084: }
1085:
1086: /* */
1087:
1088: static struct adrtab *get_arpent (ip, len, isnpa, isnext)
1089: register unsigned int *ip;
1090: int len;
1091: int isnpa,
1092: isnext;
1093: {
1094: register struct adrtab *at;
1095:
1096: switch (isnpa) {
1097: case 0:
1098: for (at = adn; at; at = at -> adn_next)
1099: switch (elem_cmp (at -> adn_instance, at -> adn_insize,
1100: ip, len)) {
1101: case 0:
1102: return (isnext ? at -> adn_next : at);
1103:
1104: case 1:
1105: return (isnext ? at : NULL);
1106: }
1107: break;
1108:
1109: case 1:
1110: for (at = adm; at; at = at -> adm_next)
1111: switch (elem_cmp (at -> adm_instance, at -> adm_insize,
1112: ip, len)) {
1113: case 0:
1114: return (isnext ? at -> adm_next : at);
1115:
1116: case 1:
1117: return (isnext ? at : NULL);
1118: }
1119: break;
1120:
1121: case -1:
1122: for (at = ada; at; at = at -> ada_next)
1123: switch (elem_cmp (at -> ada_instance, at -> ada_insize,
1124: ip, len)) {
1125: case 0:
1126: return (isnext ? at -> ada_next : at);
1127:
1128: case 1:
1129: return (isnext ? at : NULL);
1130: }
1131: break;
1132: }
1133:
1134: return NULL;
1135: }
1136:
1137: /* */
1138:
1139: init_ip () {
1140: register OT ot;
1141:
1142: if (ot = text2obj ("ipForwarding"))
1143: ot -> ot_getfnx = o_ip,
1144: ot -> ot_info = (caddr_t) ipForwarding;
1145: if (ot = text2obj ("ipDefaultTTL"))
1146: ot -> ot_getfnx = o_ip,
1147: ot -> ot_info = (caddr_t) ipDefaultTTL;
1148: #ifdef ipInReceives
1149: if (ot = text2obj ("ipInReceives"))
1150: ot -> ot_getfnx = o_ip,
1151: ot -> ot_info = (caddr_t) ipInReceives;
1152: #endif
1153: if (ot = text2obj ("ipInHdrErrors"))
1154: ot -> ot_getfnx = o_ip,
1155: ot -> ot_info = (caddr_t) ipInHdrErrors;
1156: #ifdef ipInAddrErrors
1157: if (ot = text2obj ("ipInAddrErrors"))
1158: ot -> ot_getfnx = o_ip,
1159: ot -> ot_info = (caddr_t) ipInAddrErrors;
1160: #endif
1161: #ifdef ipForwDatagrams
1162: if (ot = text2obj ("ipForwDatagrams"))
1163: ot -> ot_getfnx = o_ip,
1164: ot -> ot_info = (caddr_t) ipForwDatagrams;
1165: #endif
1166: #ifdef ipInUnknownProtos
1167: if (ot = text2obj ("ipInUnknownProtos"))
1168: ot -> ot_getfnx = o_ip,
1169: ot -> ot_info = (caddr_t) ipInUnknownProtos;
1170: #endif
1171: #ifdef ipInDiscards
1172: if (ot = text2obj ("ipInDiscards"))
1173: ot -> ot_getfnx = o_ip,
1174: ot -> ot_info = (caddr_t) ipInDiscards;
1175: #endif
1176: #ifdef ipInDelivers
1177: if (ot = text2obj ("ipInDelivers"))
1178: ot -> ot_getfnx = o_ip,
1179: ot -> ot_info = (caddr_t) ipInDelivers;
1180: #endif
1181: #ifdef ipOutRequests
1182: if (ot = text2obj ("ipOutRequests"))
1183: ot -> ot_getfnx = o_ip,
1184: ot -> ot_info = (caddr_t) ipOutRequests;
1185: #endif
1186: #ifdef ipOutDiscards
1187: if (ot = text2obj ("ipOutDiscards"))
1188: ot -> ot_getfnx = o_ip,
1189: ot -> ot_info = (caddr_t) ipOutDiscards;
1190: #endif
1191: #ifdef ipOutNoRoutes
1192: if (ot = text2obj ("ipOutNoRoutes"))
1193: ot -> ot_getfnx = o_ip,
1194: ot -> ot_info = (caddr_t) ipOutNoRoutes;
1195: #endif
1196: if (ot = text2obj ("ipReasmTimeout"))
1197: ot -> ot_getfnx = o_ip,
1198: ot -> ot_info = (caddr_t) ipReasmTimeout;
1199: #ifdef ipReasmReqds
1200: if (ot = text2obj ("ipReasmReqds"))
1201: ot -> ot_getfnx = o_ip,
1202: ot -> ot_info = (caddr_t) ipReasmReqds;
1203: #endif
1204: #ifdef ipReasmOKs
1205: if (ot = text2obj ("ipReasmOKs"))
1206: ot -> ot_getfnx = o_ip,
1207: ot -> ot_info = (caddr_t) ipReasmOKs;
1208: #endif
1209: #ifdef ipReasmFails
1210: if (ot = text2obj ("ipReasmFails"))
1211: ot -> ot_getfnx = o_ip,
1212: ot -> ot_info = (caddr_t) ipReasmFails;
1213: #endif
1214: #ifdef ipFragOKs
1215: if (ot = text2obj ("ipFragOKs"))
1216: ot -> ot_getfnx = o_ip,
1217: ot -> ot_info = (caddr_t) ipFragOKs;
1218: #endif
1219: #ifdef ipFragFails
1220: if (ot = text2obj ("ipFragFails"))
1221: ot -> ot_getfnx = o_ip,
1222: ot -> ot_info = (caddr_t) ipFragFails;
1223: #endif
1224: #ifdef ipFragCreates
1225: if (ot = text2obj ("ipFragCreates"))
1226: ot -> ot_getfnx = o_ip,
1227: ot -> ot_info = (caddr_t) ipFragCreates;
1228: #endif
1229:
1230: if (ot = text2obj ("ipAdEntAddr"))
1231: ot -> ot_getfnx = o_ip_addr,
1232: ot -> ot_info = (caddr_t) ipAdEntAddr;
1233: if (ot = text2obj ("ipAdEntIfIndex"))
1234: ot -> ot_getfnx = o_ip_addr,
1235: ot -> ot_info = (caddr_t) ipAdEntIfIndex;
1236: if (ot = text2obj ("ipAdEntNetMask"))
1237: ot -> ot_getfnx = o_ip_addr,
1238: ot -> ot_info = (caddr_t) ipAdEntNetMask;
1239: if (ot = text2obj ("ipAdEntBcastAddr"))
1240: ot -> ot_getfnx = o_ip_addr,
1241: ot -> ot_info = (caddr_t) ipAdEntBcastAddr;
1242: if (ot = text2obj ("ipAdEntReasmMaxSize"))
1243: ot -> ot_getfnx = o_ip_addr,
1244: ot -> ot_info = (caddr_t) ipAdEntReasmMaxSize;
1245:
1246: if (ot = text2obj ("ipRouteDest"))
1247: ot -> ot_getfnx = o_ip_route,
1248: ot -> ot_info = (caddr_t) ipRouteDest;
1249: if (ot = text2obj ("ipRouteIfIndex"))
1250: ot -> ot_getfnx = o_ip_route,
1251: ot -> ot_info = (caddr_t) ipRouteIfIndex;
1252: if (ot = text2obj ("ipRouteMetric1"))
1253: ot -> ot_getfnx = o_ip_route,
1254: ot -> ot_info = (caddr_t) ipRouteMetric1;
1255: if (ot = text2obj ("ipRouteMetric2"))
1256: ot -> ot_getfnx = o_ip_route,
1257: ot -> ot_info = (caddr_t) ipRouteMetric2;
1258: if (ot = text2obj ("ipRouteMetric3"))
1259: ot -> ot_getfnx = o_ip_route,
1260: ot -> ot_info = (caddr_t) ipRouteMetric3;
1261: if (ot = text2obj ("ipRouteMetric4"))
1262: ot -> ot_getfnx = o_ip_route,
1263: ot -> ot_info = (caddr_t) ipRouteMetric4;
1264: if (ot = text2obj ("ipRouteNextHop"))
1265: ot -> ot_getfnx = o_ip_route,
1266: ot -> ot_info = (caddr_t) ipRouteNextHop;
1267: if (ot = text2obj ("ipRouteType"))
1268: ot -> ot_getfnx = o_ip_route,
1269: ot -> ot_info = (caddr_t) ipRouteType;
1270: if (ot = text2obj ("ipRouteProto"))
1271: ot -> ot_getfnx = o_ip_route,
1272: ot -> ot_info = (caddr_t) ipRouteProto;
1273: if (ot = text2obj ("ipRouteAge"))
1274: ot -> ot_getfnx = o_ip_route,
1275: ot -> ot_info = (caddr_t) ipRouteAge;
1276: if (ot = text2obj ("ipRouteMask"))
1277: ot -> ot_getfnx = o_ip_route,
1278: ot -> ot_info = (caddr_t) ipRouteMask;
1279:
1280: if (ot = text2obj ("unixIpRouteFlags"))
1281: ot -> ot_getfnx = o_ip_route,
1282: ot -> ot_info = (caddr_t) unixIpRouteFlags;
1283: if (ot = text2obj ("unixIpRouteRefCnt"))
1284: ot -> ot_getfnx = o_ip_route,
1285: ot -> ot_info = (caddr_t) unixIpRouteRefCnt;
1286: if (ot = text2obj ("unixIpRouteUses"))
1287: ot -> ot_getfnx = o_ip_route,
1288: ot -> ot_info = (caddr_t) unixIpRouteUses;
1289:
1290: if (ot = text2obj ("unixRouteBadRedirects"))
1291: ot -> ot_getfnx = o_ip_routing_stats,
1292: ot -> ot_info = (caddr_t) unixRouteBadRedirects;
1293: if (ot = text2obj ("unixRouteCreatedByRedirects"))
1294: ot -> ot_getfnx = o_ip_routing_stats,
1295: ot -> ot_info = (caddr_t) unixRouteCreatedByRedirects;
1296: if (ot = text2obj ("unixRouteModifiedByRedirects"))
1297: ot -> ot_getfnx = o_ip_routing_stats,
1298: ot -> ot_info = (caddr_t) unixRouteModifiedByRedirects;
1299: if (ot = text2obj ("unixRouteLookupFails"))
1300: ot -> ot_getfnx = o_ip_routing_stats,
1301: ot -> ot_info = (caddr_t) unixRouteLookupFails;
1302: if (ot = text2obj ("unixRouteWildcardUses"))
1303: ot -> ot_getfnx = o_ip_routing_stats,
1304: ot -> ot_info = (caddr_t) unixRouteWildcardUses;
1305:
1306: if (ot = text2obj ("atIfIndex"))
1307: ot -> ot_getfnx = o_address,
1308: ot -> ot_info = (caddr_t) atIfIndex;
1309: if (ot = text2obj ("atPhysAddress"))
1310: ot -> ot_getfnx = o_address,
1311: ot -> ot_info = (caddr_t) atPhysAddress;
1312: if (ot = text2obj ("atNetAddress"))
1313: ot -> ot_getfnx = o_address,
1314: ot -> ot_info = (caddr_t) atNetAddress;
1315:
1316: if (ot = text2obj ("ipNetToMediaIfIndex"))
1317: ot -> ot_getfnx = o_address,
1318: ot -> ot_info = (caddr_t) ipNetToMediaIfIndex;
1319: if (ot = text2obj ("ipNetToMediaPhysAddress"))
1320: ot -> ot_getfnx = o_address,
1321: ot -> ot_info = (caddr_t) ipNetToMediaPhysAddress;
1322: if (ot = text2obj ("ipNetToMediaNetAddress"))
1323: ot -> ot_getfnx = o_address,
1324: ot -> ot_info = (caddr_t) ipNetToMediaNetAddress;
1325: if (ot = text2obj ("ipNetToMediaType"))
1326: ot -> ot_getfnx = o_address,
1327: ot -> ot_info = (caddr_t) ipNetToMediaType;
1328: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.