]>
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 u_char
*rip2Globals (struct variable
*, oid
[], size_t *,
92 int, size_t *, WriteMethod
**);
93 static u_char
*rip2IfStatEntry (struct variable
*, oid
[], size_t *,
94 int, size_t *, WriteMethod
**);
95 static u_char
*rip2IfConfAddress (struct variable
*, oid
[], size_t *,
96 int, size_t *, WriteMethod
**);
97 static u_char
*rip2PeerTable (struct variable
*, oid
[], size_t *,
98 int, size_t *, WriteMethod
**);
100 static struct variable rip_variables
[] =
102 /* RIP Global Counters. */
103 {RIP2GLOBALROUTECHANGES
, COUNTER
, RONLY
, rip2Globals
,
105 {RIP2GLOBALQUERIES
, COUNTER
, RONLY
, rip2Globals
,
107 /* RIP Interface Tables. */
108 {RIP2IFSTATADDRESS
, IPADDRESS
, RONLY
, rip2IfStatEntry
,
110 {RIP2IFSTATRCVBADPACKETS
, COUNTER
, RONLY
, rip2IfStatEntry
,
112 {RIP2IFSTATRCVBADROUTES
, COUNTER
, RONLY
, rip2IfStatEntry
,
114 {RIP2IFSTATSENTUPDATES
, COUNTER
, RONLY
, rip2IfStatEntry
,
116 {RIP2IFSTATSTATUS
, COUNTER
, RWRITE
, rip2IfStatEntry
,
118 {RIP2IFCONFADDRESS
, IPADDRESS
, RONLY
, rip2IfConfAddress
,
119 /* RIP Interface Configuration Table. */
121 {RIP2IFCONFDOMAIN
, STRING
, RONLY
, rip2IfConfAddress
,
123 {RIP2IFCONFAUTHTYPE
, COUNTER
, RONLY
, rip2IfConfAddress
,
125 {RIP2IFCONFAUTHKEY
, STRING
, RONLY
, rip2IfConfAddress
,
127 {RIP2IFCONFSEND
, COUNTER
, RONLY
, rip2IfConfAddress
,
129 {RIP2IFCONFRECEIVE
, COUNTER
, RONLY
, rip2IfConfAddress
,
131 {RIP2IFCONFDEFAULTMETRIC
, COUNTER
, RONLY
, rip2IfConfAddress
,
133 {RIP2IFCONFSTATUS
, COUNTER
, RONLY
, rip2IfConfAddress
,
135 {RIP2IFCONFSRCADDRESS
, IPADDRESS
, RONLY
, rip2IfConfAddress
,
137 {RIP2PEERADDRESS
, IPADDRESS
, RONLY
, rip2PeerTable
,
138 /* RIP Peer Table. */
140 {RIP2PEERDOMAIN
, STRING
, RONLY
, rip2PeerTable
,
142 {RIP2PEERLASTUPDATE
, TIMETICKS
, RONLY
, rip2PeerTable
,
144 {RIP2PEERVERSION
, INTEGER
, RONLY
, rip2PeerTable
,
146 {RIP2PEERRCVBADPACKETS
, COUNTER
, RONLY
, rip2PeerTable
,
148 {RIP2PEERRCVBADROUTES
, COUNTER
, RONLY
, rip2PeerTable
,
152 extern struct thread_master
*master
;
155 rip2Globals (struct variable
*v
, oid name
[], size_t *length
,
156 int exact
, size_t *var_len
, WriteMethod
**write_method
)
158 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
162 /* Retrun global counter. */
165 case RIP2GLOBALROUTECHANGES
:
166 return SNMP_INTEGER (rip_global_route_changes
);
168 case RIP2GLOBALQUERIES
:
169 return SNMP_INTEGER (rip_global_queries
);
179 rip_snmp_ifaddr_add (struct connected
*ifc
)
181 struct interface
*ifp
= ifc
->ifp
;
183 struct route_node
*rn
;
187 if (p
->family
!= AF_INET
)
190 rn
= route_node_get (rip_ifaddr_table
, p
);
196 rip_snmp_ifaddr_del (struct connected
*ifc
)
198 struct interface
*ifp
= ifc
->ifp
;
200 struct route_node
*rn
;
205 if (p
->family
!= AF_INET
)
208 rn
= route_node_lookup (rip_ifaddr_table
, p
);
212 if (rn
&& !strncmp(i
->name
,ifp
->name
,INTERFACE_NAMSIZ
))
215 route_unlock_node (rn
);
216 route_unlock_node (rn
);
221 static struct interface
*
222 rip_ifaddr_lookup_next (struct in_addr
*addr
)
224 struct prefix_ipv4 p
;
225 struct route_node
*rn
;
226 struct interface
*ifp
;
229 p
.prefixlen
= IPV4_MAX_BITLEN
;
232 rn
= route_node_get (rip_ifaddr_table
, (struct prefix
*) &p
);
234 for (rn
= route_next (rn
); rn
; rn
= route_next (rn
))
241 *addr
= rn
->p
.u
.prefix4
;
242 route_unlock_node (rn
);
248 static struct interface
*
249 rip2IfLookup (struct variable
*v
, oid name
[], size_t *length
,
250 struct in_addr
*addr
, int exact
)
253 struct interface
*ifp
;
257 /* Check the length. */
258 if (*length
- v
->namelen
!= sizeof (struct in_addr
))
261 oid2in_addr (name
+ v
->namelen
, sizeof (struct in_addr
), addr
);
263 return if_lookup_exact_address ((void *)addr
, AF_INET
, VRF_DEFAULT
);
267 len
= *length
- v
->namelen
;
268 if (len
> 4) len
= 4;
270 oid2in_addr (name
+ v
->namelen
, len
, addr
);
272 ifp
= rip_ifaddr_lookup_next (addr
);
277 oid_copy_addr (name
+ v
->namelen
, addr
, sizeof (struct in_addr
));
279 *length
= v
->namelen
+ sizeof (struct in_addr
);
286 static struct rip_peer
*
287 rip2PeerLookup (struct variable
*v
, oid name
[], size_t *length
,
288 struct in_addr
*addr
, int exact
)
291 struct rip_peer
*peer
;
295 /* Check the length. */
296 if (*length
- v
->namelen
!= sizeof (struct in_addr
) + 1)
299 oid2in_addr (name
+ v
->namelen
, sizeof (struct in_addr
), addr
);
301 peer
= rip_peer_lookup (addr
);
303 if (peer
->domain
== (int)name
[v
->namelen
+ sizeof (struct in_addr
)])
310 len
= *length
- v
->namelen
;
311 if (len
> 4) len
= 4;
313 oid2in_addr (name
+ v
->namelen
, len
, addr
);
315 len
= *length
- v
->namelen
;
316 peer
= rip_peer_lookup (addr
);
319 if ((len
< (int)sizeof (struct in_addr
) + 1) ||
320 (peer
->domain
> (int)name
[v
->namelen
+ sizeof (struct in_addr
)]))
322 oid_copy_addr (name
+ v
->namelen
, &peer
->addr
,
323 sizeof (struct in_addr
));
324 name
[v
->namelen
+ sizeof (struct in_addr
)] = peer
->domain
;
325 *length
= sizeof (struct in_addr
) + v
->namelen
+ 1;
329 peer
= rip_peer_lookup_next (addr
);
334 oid_copy_addr (name
+ v
->namelen
, &peer
->addr
,
335 sizeof (struct in_addr
));
336 name
[v
->namelen
+ sizeof (struct in_addr
)] = peer
->domain
;
337 *length
= sizeof (struct in_addr
) + v
->namelen
+ 1;
345 rip2IfStatEntry (struct variable
*v
, oid name
[], size_t *length
,
346 int exact
, size_t *var_len
, WriteMethod
**write_method
)
348 struct interface
*ifp
;
349 struct rip_interface
*ri
;
350 static struct in_addr addr
;
351 static long valid
= SNMP_VALID
;
353 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
357 memset (&addr
, 0, sizeof (struct in_addr
));
359 /* Lookup interface. */
360 ifp
= rip2IfLookup (v
, name
, length
, &addr
, exact
);
364 /* Fetch rip_interface information. */
369 case RIP2IFSTATADDRESS
:
370 return SNMP_IPADDRESS (addr
);
372 case RIP2IFSTATRCVBADPACKETS
:
373 *var_len
= sizeof (long);
374 return (u_char
*) &ri
->recv_badpackets
;
376 case RIP2IFSTATRCVBADROUTES
:
377 *var_len
= sizeof (long);
378 return (u_char
*) &ri
->recv_badroutes
;
380 case RIP2IFSTATSENTUPDATES
:
381 *var_len
= sizeof (long);
382 return (u_char
*) &ri
->sent_updates
;
384 case RIP2IFSTATSTATUS
:
385 *var_len
= sizeof (long);
386 v
->type
= ASN_INTEGER
;
387 return (u_char
*) &valid
;
397 rip2IfConfSend (struct rip_interface
*ri
)
400 #define ripVersion1 2
401 #define rip1Compatible 3
402 #define ripVersion2 4
403 #define ripV1Demand 5
404 #define ripV2Demand 6
409 if (ri
->ri_send
& RIPv2
)
411 else if (ri
->ri_send
& RIPv1
)
415 if (rip
->version_send
== RIPv2
)
417 else if (rip
->version_send
== RIPv1
)
424 rip2IfConfReceive (struct rip_interface
*ri
)
429 #define doNotReceive 4
436 recvv
= (ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
:
438 if (recvv
== RI_RIP_VERSION_1_AND_2
)
440 else if (recvv
& RIPv2
)
442 else if (recvv
& RIPv1
)
449 rip2IfConfAddress (struct variable
*v
, oid name
[], size_t *length
,
450 int exact
, size_t *val_len
, WriteMethod
**write_method
)
452 static struct in_addr addr
;
453 static long valid
= SNMP_INVALID
;
454 static long domain
= 0;
455 static long config
= 0;
456 static u_int auth
= 0;
457 struct interface
*ifp
;
458 struct rip_interface
*ri
;
460 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
464 memset (&addr
, 0, sizeof (struct in_addr
));
466 /* Lookup interface. */
467 ifp
= rip2IfLookup (v
, name
, length
, &addr
, exact
);
471 /* Fetch rip_interface information. */
476 case RIP2IFCONFADDRESS
:
477 *val_len
= sizeof (struct in_addr
);
478 return (u_char
*) &addr
;
480 case RIP2IFCONFDOMAIN
:
482 return (u_char
*) &domain
;
484 case RIP2IFCONFAUTHTYPE
:
485 auth
= ri
->auth_type
;
486 *val_len
= sizeof (long);
487 v
->type
= ASN_INTEGER
;
488 return (u_char
*)&auth
;
490 case RIP2IFCONFAUTHKEY
:
492 return (u_char
*) &domain
;
494 config
= rip2IfConfSend (ri
);
495 *val_len
= sizeof (long);
496 v
->type
= ASN_INTEGER
;
497 return (u_char
*) &config
;
498 case RIP2IFCONFRECEIVE
:
499 config
= rip2IfConfReceive (ri
);
500 *val_len
= sizeof (long);
501 v
->type
= ASN_INTEGER
;
502 return (u_char
*) &config
;
504 case RIP2IFCONFDEFAULTMETRIC
:
505 *val_len
= sizeof (long);
506 v
->type
= ASN_INTEGER
;
507 return (u_char
*) &ifp
->metric
;
508 case RIP2IFCONFSTATUS
:
509 *val_len
= sizeof (long);
510 v
->type
= ASN_INTEGER
;
511 return (u_char
*) &valid
;
512 case RIP2IFCONFSRCADDRESS
:
513 *val_len
= sizeof (struct in_addr
);
514 return (u_char
*) &addr
;
524 rip2PeerTable (struct variable
*v
, oid name
[], size_t *length
,
525 int exact
, size_t *val_len
, WriteMethod
**write_method
)
527 static struct in_addr addr
;
528 static int domain
= 0;
530 /* static time_t uptime; */
532 struct rip_peer
*peer
;
534 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
538 memset (&addr
, 0, sizeof (struct in_addr
));
540 /* Lookup interface. */
541 peer
= rip2PeerLookup (v
, name
, length
, &addr
, exact
);
547 case RIP2PEERADDRESS
:
548 *val_len
= sizeof (struct in_addr
);
549 return (u_char
*) &peer
->addr
;
553 return (u_char
*) &domain
;
555 case RIP2PEERLASTUPDATE
:
557 /* We don't know the SNMP agent startup time. We have two choices here:
558 * - assume ripd startup time equals SNMP agent startup time
559 * - don't support this variable, at all
560 * Currently, we do the latter...
562 *val_len
= sizeof (time_t);
563 uptime
= peer
->uptime
; /* now - snmp_agent_startup - peer->uptime */
564 return (u_char
*) &uptime
;
566 return (u_char
*) NULL
;
569 case RIP2PEERVERSION
:
570 *val_len
= sizeof (int);
571 version
= peer
->version
;
572 return (u_char
*) &version
;
574 case RIP2PEERRCVBADPACKETS
:
575 *val_len
= sizeof (int);
576 return (u_char
*) &peer
->recv_badpackets
;
578 case RIP2PEERRCVBADROUTES
:
579 *val_len
= sizeof (int);
580 return (u_char
*) &peer
->recv_badroutes
;
589 /* Register RIPv2-MIB. */
591 rip_snmp_init (struct thread_master
*master
)
593 rip_ifaddr_table
= route_table_init ();
596 REGISTER_MIB("mibII/rip", rip_variables
, variable
, rip_oid
);
601 rip_snmp_module_init (void)
603 hook_register(rip_ifaddr_add
, rip_snmp_ifaddr_add
);
604 hook_register(rip_ifaddr_del
, rip_snmp_ifaddr_del
);
606 hook_register(frr_late_init
, rip_snmp_init
);
612 .version
= FRR_VERSION
,
613 .description
= "ripd AgentX SNMP module",
614 .init
= rip_snmp_module_init
,