Annotation of embedaddon/quagga/bgpd/bgp_snmp.c, revision 1.1.1.1
1.1 misho 1: /* BGP4 SNMP support
2: Copyright (C) 1999, 2000 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: #include <zebra.h>
22:
23: #ifdef HAVE_SNMP
24: #ifdef HAVE_NETSNMP
25: #include <net-snmp/net-snmp-config.h>
26: #include <net-snmp/net-snmp-includes.h>
27: #else
28: #include <asn1.h>
29: #include <snmp.h>
30: #include <snmp_impl.h>
31: #endif
32:
33: #include "if.h"
34: #include "log.h"
35: #include "prefix.h"
36: #include "command.h"
37: #include "thread.h"
38: #include "smux.h"
39:
40: #include "bgpd/bgpd.h"
41: #include "bgpd/bgp_table.h"
42: #include "bgpd/bgp_aspath.h"
43: #include "bgpd/bgp_attr.h"
44: #include "bgpd/bgp_route.h"
45: #include "bgpd/bgp_fsm.h"
46: #include "bgpd/bgp_snmp.h"
47:
48: /* BGP4-MIB described in RFC1657. */
49: #define BGP4MIB 1,3,6,1,2,1,15
50:
51: /* BGP TRAP. */
52: #define BGPESTABLISHED 1
53: #define BGPBACKWARDTRANSITION 2
54:
55: /* BGP MIB bgpVersion. */
56: #define BGPVERSION 0
57:
58: /* BGP MIB bgpLocalAs. */
59: #define BGPLOCALAS 0
60:
61: /* BGP MIB bgpPeerTable. */
62: #define BGPPEERIDENTIFIER 1
63: #define BGPPEERSTATE 2
64: #define BGPPEERADMINSTATUS 3
65: #define BGPPEERNEGOTIATEDVERSION 4
66: #define BGPPEERLOCALADDR 5
67: #define BGPPEERLOCALPORT 6
68: #define BGPPEERREMOTEADDR 7
69: #define BGPPEERREMOTEPORT 8
70: #define BGPPEERREMOTEAS 9
71: #define BGPPEERINUPDATES 10
72: #define BGPPEEROUTUPDATES 11
73: #define BGPPEERINTOTALMESSAGES 12
74: #define BGPPEEROUTTOTALMESSAGES 13
75: #define BGPPEERLASTERROR 14
76: #define BGPPEERFSMESTABLISHEDTRANSITIONS 15
77: #define BGPPEERFSMESTABLISHEDTIME 16
78: #define BGPPEERCONNECTRETRYINTERVAL 17
79: #define BGPPEERHOLDTIME 18
80: #define BGPPEERKEEPALIVE 19
81: #define BGPPEERHOLDTIMECONFIGURED 20
82: #define BGPPEERKEEPALIVECONFIGURED 21
83: #define BGPPEERMINASORIGINATIONINTERVAL 22
84: #define BGPPEERMINROUTEADVERTISEMENTINTERVAL 23
85: #define BGPPEERINUPDATEELAPSEDTIME 24
86:
87: /* BGP MIB bgpIdentifier. */
88: #define BGPIDENTIFIER 0
89:
90: /* BGP MIB bgpRcvdPathAttrTable */
91: #define BGPPATHATTRPEER 1
92: #define BGPPATHATTRDESTNETWORK 2
93: #define BGPPATHATTRORIGIN 3
94: #define BGPPATHATTRASPATH 4
95: #define BGPPATHATTRNEXTHOP 5
96: #define BGPPATHATTRINTERASMETRIC 6
97:
98: /* BGP MIB bgp4PathAttrTable. */
99: #define BGP4PATHATTRPEER 1
100: #define BGP4PATHATTRIPADDRPREFIXLEN 2
101: #define BGP4PATHATTRIPADDRPREFIX 3
102: #define BGP4PATHATTRORIGIN 4
103: #define BGP4PATHATTRASPATHSEGMENT 5
104: #define BGP4PATHATTRNEXTHOP 6
105: #define BGP4PATHATTRMULTIEXITDISC 7
106: #define BGP4PATHATTRLOCALPREF 8
107: #define BGP4PATHATTRATOMICAGGREGATE 9
108: #define BGP4PATHATTRAGGREGATORAS 10
109: #define BGP4PATHATTRAGGREGATORADDR 11
110: #define BGP4PATHATTRCALCLOCALPREF 12
111: #define BGP4PATHATTRBEST 13
112: #define BGP4PATHATTRUNKNOWN 14
113:
114: /* SNMP value hack. */
115: #define INTEGER ASN_INTEGER
116: #define INTEGER32 ASN_INTEGER
117: #define COUNTER32 ASN_COUNTER
118: #define OCTET_STRING ASN_OCTET_STR
119: #define IPADDRESS ASN_IPADDRESS
120: #define GAUGE32 ASN_UNSIGNED
121:
122: /* Declare static local variables for convenience. */
123: SNMP_LOCAL_VARIABLES
124:
125: /* BGP-MIB instances. */
126: oid bgp_oid [] = { BGP4MIB };
127:
128: /* IP address 0.0.0.0. */
129: static struct in_addr bgp_empty_addr = {0};
130:
131: /* Hook functions. */
132: static u_char *bgpVersion (struct variable *, oid [], size_t *, int,
133: size_t *, WriteMethod **);
134: static u_char *bgpLocalAs (struct variable *, oid [], size_t *,
135: int, size_t *, WriteMethod **);
136: static u_char *bgpPeerTable (struct variable *, oid [], size_t *,
137: int, size_t *, WriteMethod **);
138: static u_char *bgpRcvdPathAttrTable (struct variable *, oid [], size_t *,
139: int, size_t *, WriteMethod **);
140: static u_char *bgpIdentifier (struct variable *, oid [], size_t *,
141: int, size_t *, WriteMethod **);
142: static u_char *bgp4PathAttrTable (struct variable *, oid [], size_t *,
143: int, size_t *, WriteMethod **);
144: /* static u_char *bgpTraps (); */
145:
146: struct variable bgp_variables[] =
147: {
148: /* BGP version. */
149: {BGPVERSION, OCTET_STRING, RONLY, bgpVersion,
150: 1, {1}},
151: /* BGP local AS. */
152: {BGPLOCALAS, INTEGER, RONLY, bgpLocalAs,
153: 1, {2}},
154: /* BGP peer table. */
155: {BGPPEERIDENTIFIER, IPADDRESS, RONLY, bgpPeerTable,
156: 3, {3, 1, 1}},
157: {BGPPEERSTATE, INTEGER, RONLY, bgpPeerTable,
158: 3, {3, 1, 2}},
159: {BGPPEERADMINSTATUS, INTEGER, RWRITE, bgpPeerTable,
160: 3, {3, 1, 3}},
161: {BGPPEERNEGOTIATEDVERSION, INTEGER32, RONLY, bgpPeerTable,
162: 3, {3, 1, 4}},
163: {BGPPEERLOCALADDR, IPADDRESS, RONLY, bgpPeerTable,
164: 3, {3, 1, 5}},
165: {BGPPEERLOCALPORT, INTEGER, RONLY, bgpPeerTable,
166: 3, {3, 1, 6}},
167: {BGPPEERREMOTEADDR, IPADDRESS, RONLY, bgpPeerTable,
168: 3, {3, 1, 7}},
169: {BGPPEERREMOTEPORT, INTEGER, RONLY, bgpPeerTable,
170: 3, {3, 1, 8}},
171: {BGPPEERREMOTEAS, INTEGER, RONLY, bgpPeerTable,
172: 3, {3, 1, 9}},
173: {BGPPEERINUPDATES, COUNTER32, RONLY, bgpPeerTable,
174: 3, {3, 1, 10}},
175: {BGPPEEROUTUPDATES, COUNTER32, RONLY, bgpPeerTable,
176: 3, {3, 1, 11}},
177: {BGPPEERINTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
178: 3, {3, 1, 12}},
179: {BGPPEEROUTTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
180: 3, {3, 1, 13}},
181: {BGPPEERLASTERROR, OCTET_STRING, RONLY, bgpPeerTable,
182: 3, {3, 1, 14}},
183: {BGPPEERFSMESTABLISHEDTRANSITIONS, COUNTER32, RONLY, bgpPeerTable,
184: 3, {3, 1, 15}},
185: {BGPPEERFSMESTABLISHEDTIME, GAUGE32, RONLY, bgpPeerTable,
186: 3, {3, 1, 16}},
187: {BGPPEERCONNECTRETRYINTERVAL, INTEGER, RWRITE, bgpPeerTable,
188: 3, {3, 1, 17}},
189: {BGPPEERHOLDTIME, INTEGER, RONLY, bgpPeerTable,
190: 3, {3, 1, 18}},
191: {BGPPEERKEEPALIVE, INTEGER, RONLY, bgpPeerTable,
192: 3, {3, 1, 19}},
193: {BGPPEERHOLDTIMECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
194: 3, {3, 1, 20}},
195: {BGPPEERKEEPALIVECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
196: 3, {3, 1, 21}},
197: {BGPPEERMINASORIGINATIONINTERVAL, INTEGER, RWRITE, bgpPeerTable,
198: 3, {3, 1, 22}},
199: {BGPPEERMINROUTEADVERTISEMENTINTERVAL, INTEGER, RWRITE, bgpPeerTable,
200: 3, {3, 1, 23}},
201: {BGPPEERINUPDATEELAPSEDTIME, GAUGE32, RONLY, bgpPeerTable,
202: 3, {3, 1, 24}},
203: /* BGP identifier. */
204: {BGPIDENTIFIER, IPADDRESS, RONLY, bgpIdentifier,
205: 1, {4}},
206: /* BGP received path attribute table. */
207: {BGPPATHATTRPEER, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
208: 3, {5, 1, 1}},
209: {BGPPATHATTRDESTNETWORK, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
210: 3, {5, 1, 2}},
211: {BGPPATHATTRORIGIN, INTEGER, RONLY, bgpRcvdPathAttrTable,
212: 3, {5, 1, 3}},
213: {BGPPATHATTRASPATH, OCTET_STRING, RONLY, bgpRcvdPathAttrTable,
214: 3, {5, 1, 4}},
215: {BGPPATHATTRNEXTHOP, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
216: 3, {5, 1, 5}},
217: {BGPPATHATTRINTERASMETRIC, INTEGER32, RONLY, bgpRcvdPathAttrTable,
218: 3, {5, 1, 6}},
219: /* BGP-4 received path attribute table. */
220: {BGP4PATHATTRPEER, IPADDRESS, RONLY, bgp4PathAttrTable,
221: 3, {6, 1, 1}},
222: {BGP4PATHATTRIPADDRPREFIXLEN, INTEGER, RONLY, bgp4PathAttrTable,
223: 3, {6, 1, 2}},
224: {BGP4PATHATTRIPADDRPREFIX, IPADDRESS, RONLY, bgp4PathAttrTable,
225: 3, {6, 1, 3}},
226: {BGP4PATHATTRORIGIN, INTEGER, RONLY, bgp4PathAttrTable,
227: 3, {6, 1, 4}},
228: {BGP4PATHATTRASPATHSEGMENT, OCTET_STRING, RONLY, bgp4PathAttrTable,
229: 3, {6, 1, 5}},
230: {BGP4PATHATTRNEXTHOP, IPADDRESS, RONLY, bgp4PathAttrTable,
231: 3, {6, 1, 6}},
232: {BGP4PATHATTRMULTIEXITDISC, INTEGER, RONLY, bgp4PathAttrTable,
233: 3, {6, 1, 7}},
234: {BGP4PATHATTRLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
235: 3, {6, 1, 8}},
236: {BGP4PATHATTRATOMICAGGREGATE, INTEGER, RONLY, bgp4PathAttrTable,
237: 3, {6, 1, 9}},
238: {BGP4PATHATTRAGGREGATORAS, INTEGER, RONLY, bgp4PathAttrTable,
239: 3, {6, 1, 10}},
240: {BGP4PATHATTRAGGREGATORADDR, IPADDRESS, RONLY, bgp4PathAttrTable,
241: 3, {6, 1, 11}},
242: {BGP4PATHATTRCALCLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
243: 3, {6, 1, 12}},
244: {BGP4PATHATTRBEST, INTEGER, RONLY, bgp4PathAttrTable,
245: 3, {6, 1, 13}},
246: {BGP4PATHATTRUNKNOWN, OCTET_STRING, RONLY, bgp4PathAttrTable,
247: 3, {6, 1, 14}},
248: };
249:
250:
251: static u_char *
252: bgpVersion (struct variable *v, oid name[], size_t *length, int exact,
253: size_t *var_len, WriteMethod **write_method)
254: {
255: static u_char version;
256:
257: if (smux_header_generic(v, name, length, exact, var_len, write_method)
258: == MATCH_FAILED)
259: return NULL;
260:
261: /* Retrun BGP version. Zebra bgpd only support version 4. */
262: version = (0x80 >> (BGP_VERSION_4 - 1));
263:
264: /* Return octet string length 1. */
265: *var_len = 1;
266: return (u_char *)&version;
267: }
268:
269: static u_char *
270: bgpLocalAs (struct variable *v, oid name[], size_t *length,
271: int exact, size_t *var_len, WriteMethod **write_method)
272: {
273: struct bgp *bgp;
274:
275: if (smux_header_generic(v, name, length, exact, var_len, write_method)
276: == MATCH_FAILED)
277: return NULL;
278:
279: /* Get BGP structure. */
280: bgp = bgp_get_default ();
281: if (! bgp)
282: return NULL;
283:
284: return SNMP_INTEGER (bgp->as);
285: }
286:
287: static struct peer *
288: peer_lookup_addr_ipv4 (struct in_addr *src)
289: {
290: struct bgp *bgp;
291: struct peer *peer;
292: struct listnode *node;
293: struct in_addr addr;
294: int ret;
295:
296: bgp = bgp_get_default ();
297: if (! bgp)
298: return NULL;
299:
300: for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
301: {
302: ret = inet_pton (AF_INET, peer->host, &addr);
303: if (ret > 0)
304: {
305: if (IPV4_ADDR_SAME (&addr, src))
306: return peer;
307: }
308: }
309: return NULL;
310: }
311:
312: static struct peer *
313: bgp_peer_lookup_next (struct in_addr *src)
314: {
315: struct bgp *bgp;
316: struct peer *peer;
317: struct listnode *node;
318: struct in_addr *p;
319: union sockunion su;
320: int ret;
321:
322: memset (&su, 0, sizeof (union sockunion));
323:
324: bgp = bgp_get_default ();
325: if (! bgp)
326: return NULL;
327:
328: for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
329: {
330: ret = inet_pton (AF_INET, peer->host, &su.sin.sin_addr);
331: if (ret > 0)
332: {
333: p = &su.sin.sin_addr;
334:
335: if (ntohl (p->s_addr) > ntohl (src->s_addr))
336: {
337: src->s_addr = p->s_addr;
338: return peer;
339: }
340: }
341: }
342: return NULL;
343: }
344:
345: static struct peer *
346: bgpPeerTable_lookup (struct variable *v, oid name[], size_t *length,
347: struct in_addr *addr, int exact)
348: {
349: struct peer *peer = NULL;
350: int len;
351:
352: if (exact)
353: {
354: /* Check the length. */
355: if (*length - v->namelen != sizeof (struct in_addr))
356: return NULL;
357:
358: oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
359:
360: peer = peer_lookup_addr_ipv4 (addr);
361: return peer;
362: }
363: else
364: {
365: len = *length - v->namelen;
366: if (len > 4) len = 4;
367:
368: oid2in_addr (name + v->namelen, len, addr);
369:
370: peer = bgp_peer_lookup_next (addr);
371:
372: if (peer == NULL)
373: return NULL;
374:
375: oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
376: *length = sizeof (struct in_addr) + v->namelen;
377:
378: return peer;
379: }
380: return NULL;
381: }
382:
383: /* BGP write methods. */
384: static int
385: write_bgpPeerTable (int action, u_char *var_val,
386: u_char var_val_type, size_t var_val_len,
387: u_char *statP, oid *name, size_t length,
388: struct variable *v)
389: {
390: struct in_addr addr;
391: struct peer *peer;
392: long intval;
393: size_t bigsize = SNMP_MAX_LEN;
394:
395: if (var_val_type != ASN_INTEGER)
396: {
397: return SNMP_ERR_WRONGTYPE;
398: }
399: if (var_val_len != sizeof (long))
400: {
401: return SNMP_ERR_WRONGLENGTH;
402: }
403:
404: if (! asn_parse_int(var_val, &bigsize, &var_val_type,
405: &intval, sizeof(long)))
406: {
407: return SNMP_ERR_WRONGENCODING;
408: }
409:
410: memset (&addr, 0, sizeof (struct in_addr));
411:
412: peer = bgpPeerTable_lookup (v, name, &length, &addr, 1);
413: if (! peer)
414: return SNMP_ERR_NOSUCHNAME;
415:
416: printf ("val: %ld\n", intval);
417:
418: switch (v->magic)
419: {
420: case BGPPEERADMINSTATUS:
421: #define BGP_PeerAdmin_stop 1
422: #define BGP_PeerAdmin_start 2
423: /* When the peer is established, */
424: if (intval == BGP_PeerAdmin_stop)
425: BGP_EVENT_ADD (peer, BGP_Stop);
426: else if (intval == BGP_PeerAdmin_start)
427: ; /* Do nothing. */
428: else
429: return SNMP_ERR_NOSUCHNAME;
430: break;
431: case BGPPEERCONNECTRETRYINTERVAL:
432: SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
433: peer->connect = intval;
434: peer->v_connect = intval;
435: break;
436: case BGPPEERHOLDTIMECONFIGURED:
437: SET_FLAG (peer->config, PEER_CONFIG_TIMER);
438: peer->holdtime = intval;
439: peer->v_holdtime = intval;
440: break;
441: case BGPPEERKEEPALIVECONFIGURED:
442: SET_FLAG (peer->config, PEER_CONFIG_TIMER);
443: peer->keepalive = intval;
444: peer->v_keepalive = intval;
445: break;
446: case BGPPEERMINASORIGINATIONINTERVAL:
447: peer->v_asorig = intval;
448: break;
449: case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
450: peer->v_routeadv = intval;
451: break;
452: }
453: return SNMP_ERR_NOERROR;
454: }
455:
456: static u_char *
457: bgpPeerTable (struct variable *v, oid name[], size_t *length,
458: int exact, size_t *var_len, WriteMethod **write_method)
459: {
460: static struct in_addr addr;
461: struct peer *peer;
462:
463: *write_method = NULL;
464: memset (&addr, 0, sizeof (struct in_addr));
465:
466: peer = bgpPeerTable_lookup (v, name, length, &addr, exact);
467: if (! peer)
468: return NULL;
469:
470: switch (v->magic)
471: {
472: case BGPPEERIDENTIFIER:
473: return SNMP_IPADDRESS (peer->remote_id);
474: break;
475: case BGPPEERSTATE:
476: return SNMP_INTEGER (peer->status);
477: break;
478: case BGPPEERADMINSTATUS:
479: *write_method = write_bgpPeerTable;
480: #define BGP_PeerAdmin_stop 1
481: #define BGP_PeerAdmin_start 2
482: if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
483: return SNMP_INTEGER (BGP_PeerAdmin_stop);
484: else
485: return SNMP_INTEGER (BGP_PeerAdmin_start);
486: break;
487: case BGPPEERNEGOTIATEDVERSION:
488: return SNMP_INTEGER (BGP_VERSION_4);
489: break;
490: case BGPPEERLOCALADDR:
491: if (peer->su_local)
492: return SNMP_IPADDRESS (peer->su_local->sin.sin_addr);
493: else
494: return SNMP_IPADDRESS (bgp_empty_addr);
495: break;
496: case BGPPEERLOCALPORT:
497: if (peer->su_local)
498: return SNMP_INTEGER (ntohs (peer->su_local->sin.sin_port));
499: else
500: return SNMP_INTEGER (0);
501: break;
502: case BGPPEERREMOTEADDR:
503: if (peer->su_remote)
504: return SNMP_IPADDRESS (peer->su_remote->sin.sin_addr);
505: else
506: return SNMP_IPADDRESS (bgp_empty_addr);
507: break;
508: case BGPPEERREMOTEPORT:
509: if (peer->su_remote)
510: return SNMP_INTEGER (ntohs (peer->su_remote->sin.sin_port));
511: else
512: return SNMP_INTEGER (0);
513: break;
514: case BGPPEERREMOTEAS:
515: return SNMP_INTEGER (peer->as);
516: break;
517: case BGPPEERINUPDATES:
518: return SNMP_INTEGER (peer->update_in);
519: break;
520: case BGPPEEROUTUPDATES:
521: return SNMP_INTEGER (peer->update_out);
522: break;
523: case BGPPEERINTOTALMESSAGES:
524: return SNMP_INTEGER (peer->open_in + peer->update_in
525: + peer->keepalive_in + peer->notify_in
526: + peer->refresh_in + peer->dynamic_cap_in);
527: break;
528: case BGPPEEROUTTOTALMESSAGES:
529: return SNMP_INTEGER (peer->open_out + peer->update_out
530: + peer->keepalive_out + peer->notify_out
531: + peer->refresh_out + peer->dynamic_cap_out);
532: break;
533: case BGPPEERLASTERROR:
534: {
535: static u_char lasterror[2];
536: lasterror[0] = peer->notify.code;
537: lasterror[1] = peer->notify.subcode;
538: *var_len = 2;
539: return (u_char *)&lasterror;
540: }
541: break;
542: case BGPPEERFSMESTABLISHEDTRANSITIONS:
543: return SNMP_INTEGER (peer->established);
544: break;
545: case BGPPEERFSMESTABLISHEDTIME:
546: if (peer->uptime == 0)
547: return SNMP_INTEGER (0);
548: else
549: return SNMP_INTEGER (bgp_clock () - peer->uptime);
550: break;
551: case BGPPEERCONNECTRETRYINTERVAL:
552: *write_method = write_bgpPeerTable;
553: return SNMP_INTEGER (peer->v_connect);
554: break;
555: case BGPPEERHOLDTIME:
556: return SNMP_INTEGER (peer->v_holdtime);
557: break;
558: case BGPPEERKEEPALIVE:
559: return SNMP_INTEGER (peer->v_keepalive);
560: break;
561: case BGPPEERHOLDTIMECONFIGURED:
562: *write_method = write_bgpPeerTable;
563: if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
564: return SNMP_INTEGER (peer->holdtime);
565: else
566: return SNMP_INTEGER (peer->v_holdtime);
567: break;
568: case BGPPEERKEEPALIVECONFIGURED:
569: *write_method = write_bgpPeerTable;
570: if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
571: return SNMP_INTEGER (peer->keepalive);
572: else
573: return SNMP_INTEGER (peer->v_keepalive);
574: break;
575: case BGPPEERMINASORIGINATIONINTERVAL:
576: *write_method = write_bgpPeerTable;
577: return SNMP_INTEGER (peer->v_asorig);
578: break;
579: case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
580: *write_method = write_bgpPeerTable;
581: return SNMP_INTEGER (peer->v_routeadv);
582: break;
583: case BGPPEERINUPDATEELAPSEDTIME:
584: if (peer->update_time == 0)
585: return SNMP_INTEGER (0);
586: else
587: return SNMP_INTEGER (bgp_clock () - peer->update_time);
588: break;
589: default:
590: return NULL;
591: break;
592: }
593: return NULL;
594: }
595:
596: static u_char *
597: bgpIdentifier (struct variable *v, oid name[], size_t *length,
598: int exact, size_t *var_len, WriteMethod **write_method)
599: {
600: struct bgp *bgp;
601:
602: if (smux_header_generic(v, name, length, exact, var_len, write_method)
603: == MATCH_FAILED)
604: return NULL;
605:
606: bgp = bgp_get_default ();
607: if (!bgp)
608: return NULL;
609:
610: return SNMP_IPADDRESS (bgp->router_id);
611: }
612:
613: static u_char *
614: bgpRcvdPathAttrTable (struct variable *v, oid name[], size_t *length,
615: int exact, size_t *var_len, WriteMethod **write_method)
616: {
617: /* Received Path Attribute Table. This table contains, one entry
618: per path to a network, path attributes received from all peers
619: running BGP version 3 or less. This table is obsolete, having
620: been replaced in functionality with the bgp4PathAttrTable. */
621: return NULL;
622: }
623:
624: static struct bgp_info *
625: bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
626: struct bgp *bgp, struct prefix_ipv4 *addr, int exact)
627: {
628: oid *offset;
629: int offsetlen;
630: struct bgp_info *binfo;
631: struct bgp_info *min;
632: struct bgp_node *rn;
633: union sockunion su;
634: unsigned int len;
635: struct in_addr paddr;
636:
637: #define BGP_PATHATTR_ENTRY_OFFSET \
638: (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
639:
640: if (exact)
641: {
642: if (*length - v->namelen != BGP_PATHATTR_ENTRY_OFFSET)
643: return NULL;
644:
645: /* Set OID offset for prefix. */
646: offset = name + v->namelen;
647: oid2in_addr (offset, IN_ADDR_SIZE, &addr->prefix);
648: offset += IN_ADDR_SIZE;
649:
650: /* Prefix length. */
651: addr->prefixlen = *offset;
652: offset++;
653:
654: /* Peer address. */
655: su.sin.sin_family = AF_INET;
656: oid2in_addr (offset, IN_ADDR_SIZE, &su.sin.sin_addr);
657:
658: /* Lookup node. */
659: rn = bgp_node_lookup (bgp->rib[AFI_IP][SAFI_UNICAST],
660: (struct prefix *) addr);
661: if (rn)
662: {
663: bgp_unlock_node (rn);
664:
665: for (binfo = rn->info; binfo; binfo = binfo->next)
666: if (sockunion_same (&binfo->peer->su, &su))
667: return binfo;
668: }
669: }
670: else
671: {
672: offset = name + v->namelen;
673: offsetlen = *length - v->namelen;
674: len = offsetlen;
675:
676: if (offsetlen == 0)
677: rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_UNICAST]);
678: else
679: {
680: if (len > IN_ADDR_SIZE)
681: len = IN_ADDR_SIZE;
682:
683: oid2in_addr (offset, len, &addr->prefix);
684:
685: offset += IN_ADDR_SIZE;
686: offsetlen -= IN_ADDR_SIZE;
687:
688: if (offsetlen > 0)
689: addr->prefixlen = *offset;
690: else
691: addr->prefixlen = len * 8;
692:
693: rn = bgp_node_get (bgp->rib[AFI_IP][SAFI_UNICAST],
694: (struct prefix *) addr);
695:
696: offset++;
697: offsetlen--;
698: }
699:
700: if (offsetlen > 0)
701: {
702: len = offsetlen;
703: if (len > IN_ADDR_SIZE)
704: len = IN_ADDR_SIZE;
705:
706: oid2in_addr (offset, len, &paddr);
707: }
708: else
709: paddr.s_addr = 0;
710:
711: if (! rn)
712: return NULL;
713:
714: do
715: {
716: min = NULL;
717:
718: for (binfo = rn->info; binfo; binfo = binfo->next)
719: {
720: if (binfo->peer->su.sin.sin_family == AF_INET
721: && ntohl (paddr.s_addr)
722: < ntohl (binfo->peer->su.sin.sin_addr.s_addr))
723: {
724: if (min)
725: {
726: if (ntohl (binfo->peer->su.sin.sin_addr.s_addr)
727: < ntohl (min->peer->su.sin.sin_addr.s_addr))
728: min = binfo;
729: }
730: else
731: min = binfo;
732: }
733: }
734:
735: if (min)
736: {
737: *length = v->namelen + BGP_PATHATTR_ENTRY_OFFSET;
738:
739: offset = name + v->namelen;
740: oid_copy_addr (offset, &rn->p.u.prefix4, IN_ADDR_SIZE);
741: offset += IN_ADDR_SIZE;
742: *offset = rn->p.prefixlen;
743: offset++;
744: oid_copy_addr (offset, &min->peer->su.sin.sin_addr,
745: IN_ADDR_SIZE);
746: addr->prefix = rn->p.u.prefix4;
747: addr->prefixlen = rn->p.prefixlen;
748:
749: bgp_unlock_node (rn);
750:
751: return min;
752: }
753:
754: paddr.s_addr = 0;
755: }
756: while ((rn = bgp_route_next (rn)) != NULL);
757: }
758: return NULL;
759: }
760:
761: static u_char *
762: bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
763: int exact, size_t *var_len, WriteMethod **write_method)
764: {
765: struct bgp *bgp;
766: struct bgp_info *binfo;
767: struct prefix_ipv4 addr;
768:
769: bgp = bgp_get_default ();
770: if (! bgp)
771: return NULL;
772:
773: memset (&addr, 0, sizeof (struct prefix_ipv4));
774:
775: binfo = bgp4PathAttrLookup (v, name, length, bgp, &addr, exact);
776: if (! binfo)
777: return NULL;
778:
779: switch (v->magic)
780: {
781: case BGP4PATHATTRPEER: /* 1 */
782: return SNMP_IPADDRESS (binfo->peer->su.sin.sin_addr);
783: break;
784: case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
785: return SNMP_INTEGER (addr.prefixlen);
786: break;
787: case BGP4PATHATTRIPADDRPREFIX: /* 3 */
788: return SNMP_IPADDRESS (addr.prefix);
789: break;
790: case BGP4PATHATTRORIGIN: /* 4 */
791: return SNMP_INTEGER (binfo->attr->origin);
792: break;
793: case BGP4PATHATTRASPATHSEGMENT: /* 5 */
794: return aspath_snmp_pathseg (binfo->attr->aspath, var_len);
795: break;
796: case BGP4PATHATTRNEXTHOP: /* 6 */
797: return SNMP_IPADDRESS (binfo->attr->nexthop);
798: break;
799: case BGP4PATHATTRMULTIEXITDISC: /* 7 */
800: return SNMP_INTEGER (binfo->attr->med);
801: break;
802: case BGP4PATHATTRLOCALPREF: /* 8 */
803: return SNMP_INTEGER (binfo->attr->local_pref);
804: break;
805: case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
806: return SNMP_INTEGER (1);
807: break;
808: case BGP4PATHATTRAGGREGATORAS: /* 10 */
809: if (binfo->attr->extra)
810: return SNMP_INTEGER (binfo->attr->extra->aggregator_as);
811: else
812: return SNMP_INTEGER (0);
813: break;
814: case BGP4PATHATTRAGGREGATORADDR: /* 11 */
815: if (binfo->attr->extra)
816: return SNMP_IPADDRESS (binfo->attr->extra->aggregator_addr);
817: else
818: return SNMP_INTEGER (0);
819: break;
820: case BGP4PATHATTRCALCLOCALPREF: /* 12 */
821: return SNMP_INTEGER (-1);
822: break;
823: case BGP4PATHATTRBEST: /* 13 */
824: #define BGP4_PathAttrBest_false 1
825: #define BGP4_PathAttrBest_true 2
826: if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
827: return SNMP_INTEGER (BGP4_PathAttrBest_true);
828: else
829: return SNMP_INTEGER (BGP4_PathAttrBest_false);
830: break;
831: case BGP4PATHATTRUNKNOWN: /* 14 */
832: *var_len = 0;
833: return NULL;
834: break;
835: }
836: return NULL;
837: }
838:
839: /* BGP Traps. */
840: struct trap_object bgpTrapList[] =
841: {
842: {bgpPeerTable, 3, {3, 1, BGPPEERLASTERROR}},
843: {bgpPeerTable, 3, {3, 1, BGPPEERSTATE}}
844: };
845:
846: void
847: bgpTrapEstablished (struct peer *peer)
848: {
849: int ret;
850: struct in_addr addr;
851: oid index[sizeof (oid) * IN_ADDR_SIZE];
852:
853: ret = inet_aton (peer->host, &addr);
854: if (ret == 0)
855: return;
856:
857: oid_copy_addr (index, &addr, IN_ADDR_SIZE);
858:
859: smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid),
860: index, IN_ADDR_SIZE,
861: bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
862: bm->start_time - bgp_clock (), BGPESTABLISHED);
863: }
864:
865: void
866: bgpTrapBackwardTransition (struct peer *peer)
867: {
868: int ret;
869: struct in_addr addr;
870: oid index[sizeof (oid) * IN_ADDR_SIZE];
871:
872: ret = inet_aton (peer->host, &addr);
873: if (ret == 0)
874: return;
875:
876: oid_copy_addr (index, &addr, IN_ADDR_SIZE);
877:
878: smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid),
879: index, IN_ADDR_SIZE,
880: bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
881: bm->start_time - bgp_clock (), BGPBACKWARDTRANSITION);
882: }
883:
884: void
885: bgp_snmp_init (void)
886: {
887: smux_init (bm->master);
888: REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
889: }
890: #endif /* HAVE_SNMP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>