bgp_snmp.c 24 KB

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