Annotation of embedaddon/quagga/zebra/zebra_snmp.c, revision 1.1.1.3
1.1 misho 1: /* FIB SNMP.
2: * Copyright (C) 1999 Kunihiro Ishiguro
3: *
4: * This file is part of GNU Zebra.
5: *
6: * GNU Zebra is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2, or (at your option) any
9: * later version.
10: *
11: * GNU Zebra is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with GNU Zebra; see the file COPYING. If not, write to the Free
18: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19: * 02111-1307, USA.
20: */
21:
1.1.1.3 ! misho 22: /*
! 23: * Currently SNMP is only running properly for MIBs in the default VRF.
! 24: */
! 25:
1.1 misho 26: #include <zebra.h>
27:
28: #ifdef HAVE_SNMP
29: #include <net-snmp/net-snmp-config.h>
30: #include <net-snmp/net-snmp-includes.h>
31:
32: #include "if.h"
33: #include "log.h"
34: #include "prefix.h"
35: #include "command.h"
36: #include "smux.h"
37: #include "table.h"
1.1.1.3 ! misho 38: #include "vrf.h"
1.1 misho 39:
40: #include "zebra/rib.h"
41: #include "zebra/zserv.h"
1.1.1.3 ! misho 42:
1.1 misho 43: #define IPFWMIB 1,3,6,1,2,1,4,24
44:
45: /* ipForwardTable */
46: #define IPFORWARDDEST 1
47: #define IPFORWARDMASK 2
48: #define IPFORWARDPOLICY 3
49: #define IPFORWARDNEXTHOP 4
50: #define IPFORWARDIFINDEX 5
51: #define IPFORWARDTYPE 6
52: #define IPFORWARDPROTO 7
53: #define IPFORWARDAGE 8
54: #define IPFORWARDINFO 9
55: #define IPFORWARDNEXTHOPAS 10
56: #define IPFORWARDMETRIC1 11
57: #define IPFORWARDMETRIC2 12
58: #define IPFORWARDMETRIC3 13
59: #define IPFORWARDMETRIC4 14
60: #define IPFORWARDMETRIC5 15
61:
62: /* ipCidrRouteTable */
63: #define IPCIDRROUTEDEST 1
64: #define IPCIDRROUTEMASK 2
65: #define IPCIDRROUTETOS 3
66: #define IPCIDRROUTENEXTHOP 4
67: #define IPCIDRROUTEIFINDEX 5
68: #define IPCIDRROUTETYPE 6
69: #define IPCIDRROUTEPROTO 7
70: #define IPCIDRROUTEAGE 8
71: #define IPCIDRROUTEINFO 9
72: #define IPCIDRROUTENEXTHOPAS 10
73: #define IPCIDRROUTEMETRIC1 11
74: #define IPCIDRROUTEMETRIC2 12
75: #define IPCIDRROUTEMETRIC3 13
76: #define IPCIDRROUTEMETRIC4 14
77: #define IPCIDRROUTEMETRIC5 15
78: #define IPCIDRROUTESTATUS 16
79:
80: #define INTEGER32 ASN_INTEGER
81: #define GAUGE32 ASN_GAUGE
82: #define ENUMERATION ASN_INTEGER
83: #define ROWSTATUS ASN_INTEGER
84: #define IPADDRESS ASN_IPADDRESS
85: #define OBJECTIDENTIFIER ASN_OBJECT_ID
1.1.1.3 ! misho 86:
1.1 misho 87: extern struct zebra_t zebrad;
88:
89: oid ipfw_oid [] = { IPFWMIB };
90:
91: /* Hook functions. */
92: static u_char * ipFwNumber (struct variable *, oid [], size_t *,
93: int, size_t *, WriteMethod **);
94: static u_char * ipFwTable (struct variable *, oid [], size_t *,
95: int, size_t *, WriteMethod **);
96: static u_char * ipCidrNumber (struct variable *, oid [], size_t *,
97: int, size_t *, WriteMethod **);
98: static u_char * ipCidrTable (struct variable *, oid [], size_t *,
99: int, size_t *, WriteMethod **);
100:
101: struct variable zebra_variables[] =
102: {
103: {0, GAUGE32, RONLY, ipFwNumber, 1, {1}},
104: {IPFORWARDDEST, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 1}},
105: {IPFORWARDMASK, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 2}},
106: {IPFORWARDPOLICY, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 3}},
107: {IPFORWARDNEXTHOP, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 4}},
108: {IPFORWARDIFINDEX, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 5}},
109: {IPFORWARDTYPE, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 6}},
110: {IPFORWARDPROTO, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 7}},
111: {IPFORWARDAGE, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 8}},
112: {IPFORWARDINFO, OBJECTIDENTIFIER, RONLY, ipFwTable, 3, {2, 1, 9}},
113: {IPFORWARDNEXTHOPAS, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 10}},
114: {IPFORWARDMETRIC1, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 11}},
115: {IPFORWARDMETRIC2, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 12}},
116: {IPFORWARDMETRIC3, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 13}},
117: {IPFORWARDMETRIC4, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 14}},
118: {IPFORWARDMETRIC5, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 15}},
119: {0, GAUGE32, RONLY, ipCidrNumber, 1, {3}},
120: {IPCIDRROUTEDEST, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 1}},
121: {IPCIDRROUTEMASK, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 2}},
122: {IPCIDRROUTETOS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 3}},
123: {IPCIDRROUTENEXTHOP, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 4}},
124: {IPCIDRROUTEIFINDEX, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 5}},
125: {IPCIDRROUTETYPE, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 6}},
126: {IPCIDRROUTEPROTO, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 7}},
127: {IPCIDRROUTEAGE, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 8}},
128: {IPCIDRROUTEINFO, OBJECTIDENTIFIER, RONLY, ipCidrTable, 3, {4, 1, 9}},
129: {IPCIDRROUTENEXTHOPAS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 10}},
130: {IPCIDRROUTEMETRIC1, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 11}},
131: {IPCIDRROUTEMETRIC2, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 12}},
132: {IPCIDRROUTEMETRIC3, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 13}},
133: {IPCIDRROUTEMETRIC4, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 14}},
134: {IPCIDRROUTEMETRIC5, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 15}},
135: {IPCIDRROUTESTATUS, ROWSTATUS, RONLY, ipCidrTable, 3, {4, 1, 16}}
136: };
137:
1.1.1.3 ! misho 138:
1.1 misho 139: static u_char *
140: ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
141: int exact, size_t *val_len, WriteMethod **write_method)
142: {
143: static int result;
144: struct route_table *table;
145: struct route_node *rn;
146: struct rib *rib;
147:
148: if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
149: return NULL;
150:
1.1.1.3 ! misho 151: table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
1.1 misho 152: if (! table)
153: return NULL;
154:
155: /* Return number of routing entries. */
156: result = 0;
157: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.2 misho 158: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 159: result++;
160:
161: return (u_char *)&result;
162: }
163:
164: static u_char *
165: ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
166: int exact, size_t *val_len, WriteMethod **write_method)
167: {
168: static int result;
169: struct route_table *table;
170: struct route_node *rn;
171: struct rib *rib;
172:
173: if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
174: return NULL;
175:
1.1.1.3 ! misho 176: table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
1.1 misho 177: if (! table)
178: return 0;
179:
180: /* Return number of routing entries. */
181: result = 0;
182: for (rn = route_top (table); rn; rn = route_next (rn))
1.1.1.2 misho 183: RNODE_FOREACH_RIB (rn, rib)
1.1 misho 184: result++;
185:
186: return (u_char *)&result;
187: }
188:
189: static int
190: in_addr_cmp(u_char *p1, u_char *p2)
191: {
192: int i;
193:
194: for (i=0; i<4; i++)
195: {
196: if (*p1 < *p2)
197: return -1;
198: if (*p1 > *p2)
199: return 1;
200: p1++; p2++;
201: }
202: return 0;
203: }
204:
205: static int
206: in_addr_add(u_char *p, int num)
207: {
208: int i, ip0;
209:
210: ip0 = *p;
211: p += 4;
212: for (i = 3; 0 <= i; i--) {
213: p--;
214: if (*p + num > 255) {
215: *p += num;
216: num = 1;
217: } else {
218: *p += num;
219: return 1;
220: }
221: }
222: if (ip0 > *p) {
223: /* ip + num > 0xffffffff */
224: return 0;
225: }
226:
227: return 1;
228: }
229:
230: static int
231: proto_trans(int type)
232: {
233: switch (type)
234: {
235: case ZEBRA_ROUTE_SYSTEM:
236: return 1; /* other */
237: case ZEBRA_ROUTE_KERNEL:
238: return 1; /* other */
239: case ZEBRA_ROUTE_CONNECT:
240: return 2; /* local interface */
241: case ZEBRA_ROUTE_STATIC:
242: return 3; /* static route */
243: case ZEBRA_ROUTE_RIP:
244: return 8; /* rip */
245: case ZEBRA_ROUTE_RIPNG:
246: return 1; /* shouldn't happen */
247: case ZEBRA_ROUTE_OSPF:
248: return 13; /* ospf */
249: case ZEBRA_ROUTE_OSPF6:
250: return 1; /* shouldn't happen */
251: case ZEBRA_ROUTE_BGP:
252: return 14; /* bgp */
253: default:
254: return 1; /* other */
255: }
256: }
257:
258: static void
259: check_replace(struct route_node *np2, struct rib *rib2,
260: struct route_node **np, struct rib **rib)
261: {
262: int proto, proto2;
263:
264: if (!*np)
265: {
266: *np = np2;
267: *rib = rib2;
268: return;
269: }
270:
271: if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) < 0)
272: return;
273: if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0)
274: {
275: *np = np2;
276: *rib = rib2;
277: return;
278: }
279:
280: proto = proto_trans((*rib)->type);
281: proto2 = proto_trans(rib2->type);
282:
283: if (proto2 > proto)
284: return;
285: if (proto2 < proto)
286: {
287: *np = np2;
288: *rib = rib2;
289: return;
290: }
291:
292: if (in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,
293: (u_char *)&rib2->nexthop->gate.ipv4) <= 0)
294: return;
295:
296: *np = np2;
297: *rib = rib2;
298: return;
299: }
300:
301: static void
302: get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
303: int exact, struct route_node **np, struct rib **rib)
304: {
305: struct in_addr dest;
306: struct route_table *table;
307: struct route_node *np2;
308: struct rib *rib2;
309: int proto;
310: int policy;
311: struct in_addr nexthop;
312: u_char *pnt;
313: int i;
314:
315: /* Init index variables */
316:
317: pnt = (u_char *) &dest;
318: for (i = 0; i < 4; i++)
319: *pnt++ = 0;
320:
321: pnt = (u_char *) &nexthop;
322: for (i = 0; i < 4; i++)
323: *pnt++ = 0;
324:
325: proto = 0;
326: policy = 0;
327:
328: /* Init return variables */
329:
330: *np = NULL;
331: *rib = NULL;
332:
333: /* Short circuit exact matches of wrong length */
334:
335: if (exact && (*objid_len != (unsigned) v->namelen + 10))
336: return;
337:
1.1.1.3 ! misho 338: table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
1.1 misho 339: if (! table)
340: return;
341:
342: /* Get INDEX information out of OID.
343: * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
344: */
345:
346: if (*objid_len > (unsigned) v->namelen)
347: oid2in_addr (objid + v->namelen, MIN(4, *objid_len - v->namelen), &dest);
348:
349: if (*objid_len > (unsigned) v->namelen + 4)
350: proto = objid[v->namelen + 4];
351:
352: if (*objid_len > (unsigned) v->namelen + 5)
353: policy = objid[v->namelen + 5];
354:
355: if (*objid_len > (unsigned) v->namelen + 6)
356: oid2in_addr (objid + v->namelen + 6, MIN(4, *objid_len - v->namelen - 6),
357: &nexthop);
358:
359: /* Apply GETNEXT on not exact search */
360:
361: if (!exact && (*objid_len >= (unsigned) v->namelen + 10))
362: {
363: if (! in_addr_add((u_char *) &nexthop, 1))
364: return;
365: }
366:
367: /* For exact: search matching entry in rib table. */
368:
369: if (exact)
370: {
371: if (policy) /* Not supported (yet?) */
372: return;
373: for (*np = route_top (table); *np; *np = route_next (*np))
374: {
375: if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest))
376: {
1.1.1.2 misho 377: RNODE_FOREACH_RIB (*np, *rib)
1.1 misho 378: {
379: if (!in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,
380: (u_char *)&nexthop))
381: if (proto == proto_trans((*rib)->type))
382: return;
383: }
384: }
385: }
386: return;
387: }
388:
389: /* Search next best entry */
390:
391: for (np2 = route_top (table); np2; np2 = route_next (np2))
392: {
393:
394: /* Check destination first */
395: if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0)
1.1.1.2 misho 396: RNODE_FOREACH_RIB (np2, rib2)
1.1 misho 397: check_replace(np2, rib2, np, rib);
398:
399: if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0)
400: { /* have to look at each rib individually */
1.1.1.2 misho 401: RNODE_FOREACH_RIB (np2, rib2)
1.1 misho 402: {
403: int proto2, policy2;
404:
405: proto2 = proto_trans(rib2->type);
406: policy2 = 0;
407:
408: if ((policy < policy2)
409: || ((policy == policy2) && (proto < proto2))
410: || ((policy == policy2) && (proto == proto2)
411: && (in_addr_cmp((u_char *)&rib2->nexthop->gate.ipv4,
412: (u_char *) &nexthop) >= 0)
413: ))
414: check_replace(np2, rib2, np, rib);
415: }
416: }
417: }
418:
419: if (!*rib)
420: return;
421:
422: policy = 0;
423: proto = proto_trans((*rib)->type);
424:
425: *objid_len = v->namelen + 10;
426: pnt = (u_char *) &(*np)->p.u.prefix;
427: for (i = 0; i < 4; i++)
428: objid[v->namelen + i] = *pnt++;
429:
430: objid[v->namelen + 4] = proto;
431: objid[v->namelen + 5] = policy;
432:
433: {
434: struct nexthop *nexthop;
435:
436: nexthop = (*rib)->nexthop;
437: if (nexthop)
438: {
439: pnt = (u_char *) &nexthop->gate.ipv4;
440: for (i = 0; i < 4; i++)
441: objid[i + v->namelen + 6] = *pnt++;
442: }
443: }
444:
445: return;
446: }
447:
448: static u_char *
449: ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
450: int exact, size_t *val_len, WriteMethod **write_method)
451: {
452: struct route_node *np;
453: struct rib *rib;
454: static int result;
455: static int resarr[2];
456: static struct in_addr netmask;
457: struct nexthop *nexthop;
458:
1.1.1.2 misho 459: if (smux_header_table(v, objid, objid_len, exact, val_len, write_method)
460: == MATCH_FAILED)
461: return NULL;
462:
1.1 misho 463: get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib);
464: if (!np)
465: return NULL;
466:
467: nexthop = rib->nexthop;
468: if (! nexthop)
469: return NULL;
470:
471: switch (v->magic)
472: {
473: case IPFORWARDDEST:
474: *val_len = 4;
475: return &np->p.u.prefix;
476: break;
477: case IPFORWARDMASK:
478: masklen2ip(np->p.prefixlen, &netmask);
479: *val_len = 4;
480: return (u_char *)&netmask;
481: break;
482: case IPFORWARDPOLICY:
483: result = 0;
484: *val_len = sizeof(int);
485: return (u_char *)&result;
486: break;
487: case IPFORWARDNEXTHOP:
488: *val_len = 4;
489: return (u_char *)&nexthop->gate.ipv4;
490: break;
491: case IPFORWARDIFINDEX:
492: *val_len = sizeof(int);
493: return (u_char *)&nexthop->ifindex;
494: break;
495: case IPFORWARDTYPE:
496: if (nexthop->type == NEXTHOP_TYPE_IFINDEX
497: || nexthop->type == NEXTHOP_TYPE_IFNAME)
498: result = 3;
499: else
500: result = 4;
501: *val_len = sizeof(int);
502: return (u_char *)&result;
503: break;
504: case IPFORWARDPROTO:
505: result = proto_trans(rib->type);
506: *val_len = sizeof(int);
507: return (u_char *)&result;
508: break;
509: case IPFORWARDAGE:
510: result = 0;
511: *val_len = sizeof(int);
512: return (u_char *)&result;
513: break;
514: case IPFORWARDINFO:
515: resarr[0] = 0;
516: resarr[1] = 0;
517: *val_len = 2 * sizeof(int);
518: return (u_char *)resarr;
519: break;
520: case IPFORWARDNEXTHOPAS:
521: result = -1;
522: *val_len = sizeof(int);
523: return (u_char *)&result;
524: break;
525: case IPFORWARDMETRIC1:
526: result = 0;
527: *val_len = sizeof(int);
528: return (u_char *)&result;
529: break;
530: case IPFORWARDMETRIC2:
531: result = 0;
532: *val_len = sizeof(int);
533: return (u_char *)&result;
534: break;
535: case IPFORWARDMETRIC3:
536: result = 0;
537: *val_len = sizeof(int);
538: return (u_char *)&result;
539: break;
540: case IPFORWARDMETRIC4:
541: result = 0;
542: *val_len = sizeof(int);
543: return (u_char *)&result;
544: break;
545: case IPFORWARDMETRIC5:
546: result = 0;
547: *val_len = sizeof(int);
548: return (u_char *)&result;
549: break;
550: default:
551: return NULL;
552: break;
553: }
554: return NULL;
555: }
556:
557: static u_char *
558: ipCidrTable (struct variable *v, oid objid[], size_t *objid_len,
559: int exact, size_t *val_len, WriteMethod **write_method)
560: {
1.1.1.2 misho 561: if (smux_header_table(v, objid, objid_len, exact, val_len, write_method)
562: == MATCH_FAILED)
563: return NULL;
564:
1.1 misho 565: switch (v->magic)
566: {
567: case IPCIDRROUTEDEST:
568: break;
569: default:
570: return NULL;
571: break;
572: }
573: return NULL;
574: }
575:
576: void
577: zebra_snmp_init ()
578: {
579: smux_init (zebrad.master);
580: REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid);
581: }
582: #endif /* HAVE_SNMP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>