]>
git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_snmp.c
2 * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
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
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.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <net-snmp/net-snmp-config.h>
24 #include <net-snmp/net-snmp-includes.h>
36 #include "ripd/ripd.h"
39 #define RIPV2MIB 1,3,6,1,2,1,23
41 /* RIPv2-MIB rip2Globals values. */
42 #define RIP2GLOBALROUTECHANGES 1
43 #define RIP2GLOBALQUERIES 2
45 /* RIPv2-MIB rip2IfStatEntry. */
46 #define RIP2IFSTATENTRY 1
48 /* RIPv2-MIB rip2IfStatTable. */
49 #define RIP2IFSTATADDRESS 1
50 #define RIP2IFSTATRCVBADPACKETS 2
51 #define RIP2IFSTATRCVBADROUTES 3
52 #define RIP2IFSTATSENTUPDATES 4
53 #define RIP2IFSTATSTATUS 5
55 /* RIPv2-MIB rip2IfConfTable. */
56 #define RIP2IFCONFADDRESS 1
57 #define RIP2IFCONFDOMAIN 2
58 #define RIP2IFCONFAUTHTYPE 3
59 #define RIP2IFCONFAUTHKEY 4
60 #define RIP2IFCONFSEND 5
61 #define RIP2IFCONFRECEIVE 6
62 #define RIP2IFCONFDEFAULTMETRIC 7
63 #define RIP2IFCONFSTATUS 8
64 #define RIP2IFCONFSRCADDRESS 9
66 /* RIPv2-MIB rip2PeerTable. */
67 #define RIP2PEERADDRESS 1
68 #define RIP2PEERDOMAIN 2
69 #define RIP2PEERLASTUPDATE 3
70 #define RIP2PEERVERSION 4
71 #define RIP2PEERRCVBADPACKETS 5
72 #define RIP2PEERRCVBADROUTES 6
74 /* SNMP value hack. */
75 #define COUNTER ASN_COUNTER
76 #define INTEGER ASN_INTEGER
77 #define TIMETICKS ASN_TIMETICKS
78 #define IPADDRESS ASN_IPADDRESS
79 #define STRING ASN_OCTET_STR
81 /* Define SNMP local variables. */
84 /* RIP-MIB instances. */
85 static oid rip_oid
[] = {RIPV2MIB
};
87 /* Interface cache table sorted by interface's address. */
88 static struct route_table
*rip_ifaddr_table
;
91 static uint8_t *rip2Globals(struct variable
*, oid
[], size_t *, int, size_t *,
93 static uint8_t *rip2IfStatEntry(struct variable
*, oid
[], size_t *, int,
94 size_t *, WriteMethod
**);
95 static uint8_t *rip2IfConfAddress(struct variable
*, oid
[], size_t *, int,
96 size_t *, WriteMethod
**);
97 static uint8_t *rip2PeerTable(struct variable
*, oid
[], size_t *, int, size_t *,
100 static struct variable rip_variables
[] = {
101 /* RIP Global Counters. */
102 {RIP2GLOBALROUTECHANGES
, COUNTER
, RONLY
, rip2Globals
, 2, {1, 1}},
103 {RIP2GLOBALQUERIES
, COUNTER
, RONLY
, rip2Globals
, 2, {1, 2}},
104 /* RIP Interface Tables. */
105 {RIP2IFSTATADDRESS
, IPADDRESS
, RONLY
, rip2IfStatEntry
, 3, {2, 1, 1}},
106 {RIP2IFSTATRCVBADPACKETS
,
112 {RIP2IFSTATRCVBADROUTES
, COUNTER
, RONLY
, rip2IfStatEntry
, 3, {2, 1, 3}},
113 {RIP2IFSTATSENTUPDATES
, COUNTER
, RONLY
, rip2IfStatEntry
, 3, {2, 1, 4}},
114 {RIP2IFSTATSTATUS
, COUNTER
, RWRITE
, rip2IfStatEntry
, 3, {2, 1, 5}},
119 /* RIP Interface Configuration Table. */
122 {RIP2IFCONFDOMAIN
, STRING
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 2}},
123 {RIP2IFCONFAUTHTYPE
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 3}},
124 {RIP2IFCONFAUTHKEY
, STRING
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 4}},
125 {RIP2IFCONFSEND
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 5}},
126 {RIP2IFCONFRECEIVE
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 6}},
127 {RIP2IFCONFDEFAULTMETRIC
,
133 {RIP2IFCONFSTATUS
, COUNTER
, RONLY
, rip2IfConfAddress
, 3, {3, 1, 8}},
134 {RIP2IFCONFSRCADDRESS
,
144 /* RIP Peer Table. */
147 {RIP2PEERDOMAIN
, STRING
, RONLY
, rip2PeerTable
, 3, {4, 1, 2}},
148 {RIP2PEERLASTUPDATE
, TIMETICKS
, RONLY
, rip2PeerTable
, 3, {4, 1, 3}},
149 {RIP2PEERVERSION
, INTEGER
, RONLY
, rip2PeerTable
, 3, {4, 1, 4}},
150 {RIP2PEERRCVBADPACKETS
, COUNTER
, RONLY
, rip2PeerTable
, 3, {4, 1, 5}},
151 {RIP2PEERRCVBADROUTES
, COUNTER
, RONLY
, rip2PeerTable
, 3, {4, 1, 6}}};
153 extern struct thread_master
*master
;
155 static uint8_t *rip2Globals(struct variable
*v
, oid name
[], size_t *length
,
156 int exact
, size_t *var_len
,
157 WriteMethod
**write_method
)
161 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
165 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
169 /* Retrun global counter. */
171 case RIP2GLOBALROUTECHANGES
:
172 return SNMP_INTEGER(rip
->counters
.route_changes
);
173 case RIP2GLOBALQUERIES
:
174 return SNMP_INTEGER(rip
->counters
.queries
);
181 static int rip_snmp_ifaddr_add(struct connected
*ifc
)
183 struct interface
*ifp
= ifc
->ifp
;
185 struct route_node
*rn
;
189 if (p
->family
!= AF_INET
)
192 rn
= route_node_get(rip_ifaddr_table
, p
);
197 static int rip_snmp_ifaddr_del(struct connected
*ifc
)
199 struct interface
*ifp
= ifc
->ifp
;
201 struct route_node
*rn
;
206 if (p
->family
!= AF_INET
)
209 rn
= route_node_lookup(rip_ifaddr_table
, p
);
213 if (!strncmp(i
->name
, ifp
->name
, INTERFACE_NAMSIZ
)) {
215 route_unlock_node(rn
);
216 route_unlock_node(rn
);
221 static struct interface
*rip_ifaddr_lookup_next(struct in_addr
*addr
)
223 struct prefix_ipv4 p
;
224 struct route_node
*rn
;
225 struct interface
*ifp
;
228 p
.prefixlen
= IPV4_MAX_BITLEN
;
231 rn
= route_node_get(rip_ifaddr_table
, (struct prefix
*)&p
);
233 for (rn
= route_next(rn
); rn
; rn
= route_next(rn
))
237 if (rn
&& rn
->info
) {
239 *addr
= rn
->p
.u
.prefix4
;
240 route_unlock_node(rn
);
246 static struct interface
*rip2IfLookup(struct variable
*v
, oid name
[],
247 size_t *length
, struct in_addr
*addr
,
251 struct interface
*ifp
;
254 /* Check the length. */
255 if (*length
- v
->namelen
!= sizeof(struct in_addr
))
258 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
260 return if_lookup_exact_address((void *)addr
, AF_INET
,
263 len
= *length
- v
->namelen
;
267 oid2in_addr(name
+ v
->namelen
, len
, addr
);
269 ifp
= rip_ifaddr_lookup_next(addr
);
274 oid_copy_addr(name
+ v
->namelen
, addr
, sizeof(struct in_addr
));
276 *length
= v
->namelen
+ sizeof(struct in_addr
);
283 static struct rip_peer
*rip2PeerLookup(struct variable
*v
, oid name
[],
284 size_t *length
, struct in_addr
*addr
,
289 struct rip_peer
*peer
;
291 rip
= rip_lookup_by_vrf_id(VRF_DEFAULT
);
296 /* Check the length. */
297 if (*length
- v
->namelen
!= sizeof(struct in_addr
) + 1)
300 oid2in_addr(name
+ v
->namelen
, sizeof(struct in_addr
), addr
);
302 peer
= rip_peer_lookup(rip
, addr
);
305 == (int)name
[v
->namelen
+ sizeof(struct in_addr
)])
310 len
= *length
- v
->namelen
;
314 oid2in_addr(name
+ v
->namelen
, len
, addr
);
316 len
= *length
- v
->namelen
;
317 peer
= rip_peer_lookup(rip
, addr
);
319 if ((len
< (int)sizeof(struct in_addr
) + 1)
321 > (int)name
[v
->namelen
322 + sizeof(struct in_addr
)])) {
323 oid_copy_addr(name
+ v
->namelen
, &peer
->addr
,
324 sizeof(struct in_addr
));
325 name
[v
->namelen
+ sizeof(struct in_addr
)] =
328 sizeof(struct in_addr
) + v
->namelen
+ 1;
332 peer
= rip_peer_lookup_next(rip
, addr
);
337 oid_copy_addr(name
+ v
->namelen
, &peer
->addr
,
338 sizeof(struct in_addr
));
339 name
[v
->namelen
+ sizeof(struct in_addr
)] = peer
->domain
;
340 *length
= sizeof(struct in_addr
) + v
->namelen
+ 1;
347 static uint8_t *rip2IfStatEntry(struct variable
*v
, oid name
[], size_t *length
,
348 int exact
, size_t *var_len
,
349 WriteMethod
**write_method
)
351 struct interface
*ifp
;
352 struct rip_interface
*ri
;
353 static struct in_addr addr
;
354 static long valid
= SNMP_VALID
;
356 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
360 memset(&addr
, 0, sizeof(struct in_addr
));
362 /* Lookup interface. */
363 ifp
= rip2IfLookup(v
, name
, length
, &addr
, exact
);
367 /* Fetch rip_interface information. */
371 case RIP2IFSTATADDRESS
:
372 return SNMP_IPADDRESS(addr
);
373 case RIP2IFSTATRCVBADPACKETS
:
374 *var_len
= sizeof(long);
375 return (uint8_t *)&ri
->recv_badpackets
;
377 case RIP2IFSTATRCVBADROUTES
:
378 *var_len
= sizeof(long);
379 return (uint8_t *)&ri
->recv_badroutes
;
381 case RIP2IFSTATSENTUPDATES
:
382 *var_len
= sizeof(long);
383 return (uint8_t *)&ri
->sent_updates
;
385 case RIP2IFSTATSTATUS
:
386 *var_len
= sizeof(long);
387 v
->type
= ASN_INTEGER
;
388 return (uint8_t *)&valid
;
396 static long rip2IfConfSend(struct rip_interface
*ri
)
399 #define ripVersion1 2
400 #define rip1Compatible 3
401 #define ripVersion2 4
402 #define ripV1Demand 5
403 #define ripV2Demand 6
408 if (ri
->ri_send
& RIPv2
)
410 else if (ri
->ri_send
& RIPv1
)
413 if (ri
->rip
->version_send
== RIPv2
)
415 else if (ri
->rip
->version_send
== RIPv1
)
421 static long rip2IfConfReceive(struct rip_interface
*ri
)
426 #define doNotReceive 4
433 recvv
= (ri
->ri_receive
== RI_RIP_UNSPEC
) ? ri
->rip
->version_recv
435 if (recvv
== RI_RIP_VERSION_1_AND_2
)
437 else if (recvv
& RIPv2
)
439 else if (recvv
& RIPv1
)
445 static uint8_t *rip2IfConfAddress(struct variable
*v
, oid name
[],
446 size_t *length
, int exact
, size_t *val_len
,
447 WriteMethod
**write_method
)
449 static struct in_addr addr
;
450 static long valid
= SNMP_INVALID
;
451 static long domain
= 0;
452 static long config
= 0;
453 static unsigned int auth
= 0;
454 struct interface
*ifp
;
455 struct rip_interface
*ri
;
457 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
461 memset(&addr
, 0, sizeof(struct in_addr
));
463 /* Lookup interface. */
464 ifp
= rip2IfLookup(v
, name
, length
, &addr
, exact
);
468 /* Fetch rip_interface information. */
472 case RIP2IFCONFADDRESS
:
473 *val_len
= sizeof(struct in_addr
);
474 return (uint8_t *)&addr
;
476 case RIP2IFCONFDOMAIN
:
478 return (uint8_t *)&domain
;
480 case RIP2IFCONFAUTHTYPE
:
481 auth
= ri
->auth_type
;
482 *val_len
= sizeof(long);
483 v
->type
= ASN_INTEGER
;
484 return (uint8_t *)&auth
;
486 case RIP2IFCONFAUTHKEY
:
488 return (uint8_t *)&domain
;
490 config
= rip2IfConfSend(ri
);
491 *val_len
= sizeof(long);
492 v
->type
= ASN_INTEGER
;
493 return (uint8_t *)&config
;
494 case RIP2IFCONFRECEIVE
:
495 config
= rip2IfConfReceive(ri
);
496 *val_len
= sizeof(long);
497 v
->type
= ASN_INTEGER
;
498 return (uint8_t *)&config
;
500 case RIP2IFCONFDEFAULTMETRIC
:
501 *val_len
= sizeof(long);
502 v
->type
= ASN_INTEGER
;
503 return (uint8_t *)&ifp
->metric
;
504 case RIP2IFCONFSTATUS
:
505 *val_len
= sizeof(long);
506 v
->type
= ASN_INTEGER
;
507 return (uint8_t *)&valid
;
508 case RIP2IFCONFSRCADDRESS
:
509 *val_len
= sizeof(struct in_addr
);
510 return (uint8_t *)&addr
;
518 static uint8_t *rip2PeerTable(struct variable
*v
, oid name
[], size_t *length
,
519 int exact
, size_t *val_len
,
520 WriteMethod
**write_method
)
522 static struct in_addr addr
;
523 static int domain
= 0;
525 /* static time_t uptime; */
527 struct rip_peer
*peer
;
529 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
533 memset(&addr
, 0, sizeof(struct in_addr
));
535 /* Lookup interface. */
536 peer
= rip2PeerLookup(v
, name
, length
, &addr
, exact
);
541 case RIP2PEERADDRESS
:
542 *val_len
= sizeof(struct in_addr
);
543 return (uint8_t *)&peer
->addr
;
547 return (uint8_t *)&domain
;
549 case RIP2PEERLASTUPDATE
:
551 /* We don't know the SNMP agent startup time. We have two choices here:
552 * - assume ripd startup time equals SNMP agent startup time
553 * - don't support this variable, at all
554 * Currently, we do the latter...
556 *val_len
= sizeof (time_t);
557 uptime
= peer
->uptime
; /* now - snmp_agent_startup - peer->uptime */
558 return (uint8_t *) &uptime
;
560 return (uint8_t *)NULL
;
563 case RIP2PEERVERSION
:
564 *val_len
= sizeof(int);
565 version
= peer
->version
;
566 return (uint8_t *)&version
;
568 case RIP2PEERRCVBADPACKETS
:
569 *val_len
= sizeof(int);
570 return (uint8_t *)&peer
->recv_badpackets
;
572 case RIP2PEERRCVBADROUTES
:
573 *val_len
= sizeof(int);
574 return (uint8_t *)&peer
->recv_badroutes
;
582 /* Register RIPv2-MIB. */
583 static int rip_snmp_init(struct thread_master
*master
)
585 rip_ifaddr_table
= route_table_init();
588 REGISTER_MIB("mibII/rip", rip_variables
, variable
, rip_oid
);
592 static int rip_snmp_module_init(void)
594 hook_register(rip_ifaddr_add
, rip_snmp_ifaddr_add
);
595 hook_register(rip_ifaddr_del
, rip_snmp_ifaddr_del
);
597 hook_register(frr_late_init
, rip_snmp_init
);
601 FRR_MODULE_SETUP(.name
= "ripd_snmp", .version
= FRR_VERSION
,
602 .description
= "ripd AgentX SNMP module",
603 .init
= rip_snmp_module_init
, )