]>
git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_snmp.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
8 #include <net-snmp/net-snmp-config.h>
9 #include <net-snmp/net-snmp-includes.h>
19 #include "lib/version.h"
21 #include "ripd/ripd.h"
24 #define RIPV2MIB 1,3,6,1,2,1,23
26 /* RIPv2-MIB rip2Globals values. */
27 #define RIP2GLOBALROUTECHANGES 1
28 #define RIP2GLOBALQUERIES 2
30 /* RIPv2-MIB rip2IfStatEntry. */
31 #define RIP2IFSTATENTRY 1
33 /* RIPv2-MIB rip2IfStatTable. */
34 #define RIP2IFSTATADDRESS 1
35 #define RIP2IFSTATRCVBADPACKETS 2
36 #define RIP2IFSTATRCVBADROUTES 3
37 #define RIP2IFSTATSENTUPDATES 4
38 #define RIP2IFSTATSTATUS 5
40 /* RIPv2-MIB rip2IfConfTable. */
41 #define RIP2IFCONFADDRESS 1
42 #define RIP2IFCONFDOMAIN 2
43 #define RIP2IFCONFAUTHTYPE 3
44 #define RIP2IFCONFAUTHKEY 4
45 #define RIP2IFCONFSEND 5
46 #define RIP2IFCONFRECEIVE 6
47 #define RIP2IFCONFDEFAULTMETRIC 7
48 #define RIP2IFCONFSTATUS 8
49 #define RIP2IFCONFSRCADDRESS 9
51 /* RIPv2-MIB rip2PeerTable. */
52 #define RIP2PEERADDRESS 1
53 #define RIP2PEERDOMAIN 2
54 #define RIP2PEERLASTUPDATE 3
55 #define RIP2PEERVERSION 4
56 #define RIP2PEERRCVBADPACKETS 5
57 #define RIP2PEERRCVBADROUTES 6
59 /* SNMP value hack. */
60 #define COUNTER ASN_COUNTER
61 #define INTEGER ASN_INTEGER
62 #define TIMETICKS ASN_TIMETICKS
63 #define IPADDRESS ASN_IPADDRESS
64 #define STRING ASN_OCTET_STR
66 /* Define SNMP local variables. */
69 /* RIP-MIB instances. */
70 static oid rip_oid
[] = {RIPV2MIB
};
72 /* Interface cache table sorted by interface's address. */
73 static struct route_table
*rip_ifaddr_table
;
76 static uint8_t *rip2Globals(struct variable
*, oid
[], size_t *, int, size_t *,
78 static uint8_t *rip2IfStatEntry(struct variable
*, oid
[], size_t *, int,
79 size_t *, WriteMethod
**);
80 static uint8_t *rip2IfConfAddress(struct variable
*, oid
[], size_t *, int,
81 size_t *, WriteMethod
**);
82 static uint8_t *rip2PeerTable(struct variable
*, oid
[], size_t *, int, size_t *,
85 static struct variable rip_variables
[] = {
86 /* RIP Global Counters. */
87 {RIP2GLOBALROUTECHANGES
, COUNTER
, RONLY
, rip2Globals
, 2, {1, 1}},
88 {RIP2GLOBALQUERIES
, COUNTER
, RONLY
, rip2Globals
, 2, {1, 2}},
89 /* RIP Interface Tables. */
90 {RIP2IFSTATADDRESS
, IPADDRESS
, RONLY
, rip2IfStatEntry
, 3, {2, 1, 1}},
91 {RIP2IFSTATRCVBADPACKETS
,
97 {RIP2IFSTATRCVBADROUTES
, COUNTER
, RONLY
, rip2IfStatEntry
, 3, {2, 1, 3}},
98 {RIP2IFSTATSENTUPDATES
, COUNTER
, RONLY
, rip2IfStatEntry
, 3, {2, 1, 4}},
99 {RIP2IFSTATSTATUS
, COUNTER
, RWRITE
, rip2IfStatEntry
, 3, {2, 1, 5}},
104 /* RIP Interface Configuration Table. */
107 {RIP2IFCONFDOMAIN
, STRING
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 2}},
108 {RIP2IFCONFAUTHTYPE
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 3}},
109 {RIP2IFCONFAUTHKEY
, STRING
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 4}},
110 {RIP2IFCONFSEND
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 5}},
111 {RIP2IFCONFRECEIVE
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 6}},
112 {RIP2IFCONFDEFAULTMETRIC
,
118 {RIP2IFCONFSTATUS
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 8}},
119 {RIP2IFCONFSRCADDRESS
,
129 /* RIP Peer Table. */
132 {RIP2PEERDOMAIN
, STRING
, RONLY
, rip2PeerTable
, 3, {4, 1, 2}},
133 {RIP2PEERLASTUPDATE
, TIMETICKS
, RONLY
, rip2PeerTable
, 3, {4, 1, 3}},
134 {RIP2PEERVERSION
, INTEGER
, RONLY
, rip2PeerTable
, 3, {4, 1, 4}},
135 {RIP2PEERRCVBADPACKETS
, COUNTER
, RONLY
, rip2PeerTable
, 3, {4, 1, 5}},
136 {RIP2PEERRCVBADROUTES
, COUNTER
, RONLY
, rip2PeerTable
, 3, {4, 1, 6}}};
138 extern struct thread_master
*master
;
140 static uint8_t *rip2Globals(struct variable
*v
, oid name
[], size_t *length
,
141 int exact
, size_t *var_len
,
142 WriteMethod
**write_method
)
146 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
150 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
154 /* Return global counter. */
156 case RIP2GLOBALROUTECHANGES
:
157 return SNMP_INTEGER(rip
->counters
.route_changes
);
158 case RIP2GLOBALQUERIES
:
159 return SNMP_INTEGER(rip
->counters
.queries
);
166 static int rip_snmp_ifaddr_add(struct connected
*ifc
)
168 struct interface
*ifp
= ifc
->ifp
;
170 struct route_node
*rn
;
174 if (p
->family
!= AF_INET
)
177 rn
= route_node_get(rip_ifaddr_table
, p
);
182 static int rip_snmp_ifaddr_del(struct connected
*ifc
)
184 struct interface
*ifp
= ifc
->ifp
;
186 struct route_node
*rn
;
191 if (p
->family
!= AF_INET
)
194 rn
= route_node_lookup(rip_ifaddr_table
, p
);
198 if (!strncmp(i
->name
, ifp
->name
, INTERFACE_NAMSIZ
)) {
200 route_unlock_node(rn
);
201 route_unlock_node(rn
);
206 static struct interface
*rip_ifaddr_lookup_next(struct in_addr
*addr
)
208 struct prefix_ipv4 p
;
209 struct route_node
*rn
;
210 struct interface
*ifp
;
213 p
.prefixlen
= IPV4_MAX_BITLEN
;
216 rn
= route_node_get(rip_ifaddr_table
, (struct prefix
*)&p
);
218 for (rn
= route_next(rn
); rn
; rn
= route_next(rn
))
222 if (rn
&& rn
->info
) {
224 *addr
= rn
->p
.u
.prefix4
;
225 route_unlock_node(rn
);
231 static struct interface
*rip2IfLookup(struct variable
*v
, oid name
[],
232 size_t *length
, struct in_addr
*addr
,
236 struct interface
*ifp
;
239 /* Check the length. */
240 if (*length
- v
->namelen
!= sizeof(struct in_addr
))
243 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
245 return if_lookup_address_local((void *)addr
, AF_INET
,
248 len
= *length
- v
->namelen
;
252 oid2in_addr(name
+ v
->namelen
, len
, addr
);
254 ifp
= rip_ifaddr_lookup_next(addr
);
259 oid_copy_in_addr(name
+ v
->namelen
, addr
);
261 *length
= v
->namelen
+ sizeof(struct in_addr
);
268 static struct rip_peer
*rip2PeerLookup(struct variable
*v
, oid name
[],
269 size_t *length
, struct in_addr
*addr
,
274 struct rip_peer
*peer
;
276 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
281 /* Check the length. */
282 if (*length
- v
->namelen
!= sizeof(struct in_addr
) + 1)
285 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
287 peer
= rip_peer_lookup(rip
, addr
);
290 == (int)name
[v
->namelen
+ sizeof(struct in_addr
)])
295 len
= *length
- v
->namelen
;
299 oid2in_addr(name
+ v
->namelen
, len
, addr
);
301 len
= *length
- v
->namelen
;
302 peer
= rip_peer_lookup(rip
, addr
);
304 if ((len
< (int)sizeof(struct in_addr
) + 1)
306 > (int)name
[v
->namelen
307 + sizeof(struct in_addr
)])) {
308 oid_copy_in_addr(name
+ v
->namelen
,
310 name
[v
->namelen
+ sizeof(struct in_addr
)] =
313 sizeof(struct in_addr
) + v
->namelen
+ 1;
317 peer
= rip_peer_lookup_next(rip
, addr
);
322 oid_copy_in_addr(name
+ v
->namelen
, &peer
->addr
);
323 name
[v
->namelen
+ sizeof(struct in_addr
)] = peer
->domain
;
324 *length
= sizeof(struct in_addr
) + v
->namelen
+ 1;
331 static uint8_t *rip2IfStatEntry(struct variable
*v
, oid name
[], size_t *length
,
332 int exact
, size_t *var_len
,
333 WriteMethod
**write_method
)
335 struct interface
*ifp
;
336 struct rip_interface
*ri
;
337 static struct in_addr addr
;
338 static long valid
= SNMP_VALID
;
340 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
344 memset(&addr
, 0, sizeof(addr
));
346 /* Lookup interface. */
347 ifp
= rip2IfLookup(v
, name
, length
, &addr
, exact
);
351 /* Fetch rip_interface information. */
355 case RIP2IFSTATADDRESS
:
356 return SNMP_IPADDRESS(addr
);
357 case RIP2IFSTATRCVBADPACKETS
:
358 *var_len
= sizeof(long);
359 return (uint8_t *)&ri
->recv_badpackets
;
361 case RIP2IFSTATRCVBADROUTES
:
362 *var_len
= sizeof(long);
363 return (uint8_t *)&ri
->recv_badroutes
;
365 case RIP2IFSTATSENTUPDATES
:
366 *var_len
= sizeof(long);
367 return (uint8_t *)&ri
->sent_updates
;
369 case RIP2IFSTATSTATUS
:
370 *var_len
= sizeof(long);
371 v
->type
= ASN_INTEGER
;
372 return (uint8_t *)&valid
;
380 static long rip2IfConfSend(struct rip_interface
*ri
)
383 #define ripVersion1 2
384 #define rip1Compatible 3
385 #define ripVersion2 4
386 #define ripV1Demand 5
387 #define ripV2Demand 6
392 if (ri
->ri_send
& RIPv2
)
394 else if (ri
->ri_send
& RIPv1
)
397 if (ri
->rip
->version_send
== RIPv2
)
399 else if (ri
->rip
->version_send
== RIPv1
)
405 static long rip2IfConfReceive(struct rip_interface
*ri
)
410 #define doNotReceive 4
417 recvv
= (ri
->ri_receive
== RI_RIP_UNSPEC
) ? ri
->rip
->version_recv
419 if (recvv
== RI_RIP_VERSION_1_AND_2
)
421 else if (recvv
& RIPv2
)
423 else if (recvv
& RIPv1
)
429 static uint8_t *rip2IfConfAddress(struct variable
*v
, oid name
[],
430 size_t *length
, int exact
, size_t *val_len
,
431 WriteMethod
**write_method
)
433 static struct in_addr addr
;
434 static long valid
= SNMP_INVALID
;
435 static long domain
= 0;
436 static long config
= 0;
437 static unsigned int auth
= 0;
438 struct interface
*ifp
;
439 struct rip_interface
*ri
;
441 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
445 memset(&addr
, 0, sizeof(addr
));
447 /* Lookup interface. */
448 ifp
= rip2IfLookup(v
, name
, length
, &addr
, exact
);
452 /* Fetch rip_interface information. */
456 case RIP2IFCONFADDRESS
:
457 *val_len
= sizeof(struct in_addr
);
458 return (uint8_t *)&addr
;
460 case RIP2IFCONFDOMAIN
:
462 return (uint8_t *)&domain
;
464 case RIP2IFCONFAUTHTYPE
:
465 auth
= ri
->auth_type
;
466 *val_len
= sizeof(long);
467 v
->type
= ASN_INTEGER
;
468 return (uint8_t *)&auth
;
470 case RIP2IFCONFAUTHKEY
:
472 return (uint8_t *)&domain
;
474 config
= rip2IfConfSend(ri
);
475 *val_len
= sizeof(long);
476 v
->type
= ASN_INTEGER
;
477 return (uint8_t *)&config
;
478 case RIP2IFCONFRECEIVE
:
479 config
= rip2IfConfReceive(ri
);
480 *val_len
= sizeof(long);
481 v
->type
= ASN_INTEGER
;
482 return (uint8_t *)&config
;
484 case RIP2IFCONFDEFAULTMETRIC
:
485 *val_len
= sizeof(long);
486 v
->type
= ASN_INTEGER
;
487 return (uint8_t *)&ifp
->metric
;
488 case RIP2IFCONFSTATUS
:
489 *val_len
= sizeof(long);
490 v
->type
= ASN_INTEGER
;
491 return (uint8_t *)&valid
;
492 case RIP2IFCONFSRCADDRESS
:
493 *val_len
= sizeof(struct in_addr
);
494 return (uint8_t *)&addr
;
502 static uint8_t *rip2PeerTable(struct variable
*v
, oid name
[], size_t *length
,
503 int exact
, size_t *val_len
,
504 WriteMethod
**write_method
)
506 static struct in_addr addr
;
507 static int domain
= 0;
509 /* static time_t uptime; */
511 struct rip_peer
*peer
;
513 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
517 memset(&addr
, 0, sizeof(addr
));
519 /* Lookup interface. */
520 peer
= rip2PeerLookup(v
, name
, length
, &addr
, exact
);
525 case RIP2PEERADDRESS
:
526 *val_len
= sizeof(struct in_addr
);
527 return (uint8_t *)&peer
->addr
;
531 return (uint8_t *)&domain
;
533 case RIP2PEERLASTUPDATE
:
534 return (uint8_t *)NULL
;
536 case RIP2PEERVERSION
:
537 *val_len
= sizeof(int);
538 version
= peer
->version
;
539 return (uint8_t *)&version
;
541 case RIP2PEERRCVBADPACKETS
:
542 *val_len
= sizeof(int);
543 return (uint8_t *)&peer
->recv_badpackets
;
545 case RIP2PEERRCVBADROUTES
:
546 *val_len
= sizeof(int);
547 return (uint8_t *)&peer
->recv_badroutes
;
555 /* Register RIPv2-MIB. */
556 static int rip_snmp_init(struct thread_master
*master
)
558 rip_ifaddr_table
= route_table_init();
561 REGISTER_MIB("mibII/rip", rip_variables
, variable
, rip_oid
);
565 static int rip_snmp_module_init(void)
567 hook_register(rip_ifaddr_add
, rip_snmp_ifaddr_add
);
568 hook_register(rip_ifaddr_del
, rip_snmp_ifaddr_del
);
570 hook_register(frr_late_init
, rip_snmp_init
);
574 FRR_MODULE_SETUP(.name
= "ripd_snmp", .version
= FRR_VERSION
,
575 .description
= "ripd AgentX SNMP module",
576 .init
= rip_snmp_module_init
,