bgp_snmp.c 24 KB

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