]>
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
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 #include <net-snmp/net-snmp-config.h>
25 #include <net-snmp/net-snmp-includes.h>
37 #include "ripd/ripd.h"
40 #define RIPV2MIB 1,3,6,1,2,1,23
42 /* RIPv2-MIB rip2Globals values. */
43 #define RIP2GLOBALROUTECHANGES 1
44 #define RIP2GLOBALQUERIES 2
46 /* RIPv2-MIB rip2IfStatEntry. */
47 #define RIP2IFSTATENTRY 1
49 /* RIPv2-MIB rip2IfStatTable. */
50 #define RIP2IFSTATADDRESS 1
51 #define RIP2IFSTATRCVBADPACKETS 2
52 #define RIP2IFSTATRCVBADROUTES 3
53 #define RIP2IFSTATSENTUPDATES 4
54 #define RIP2IFSTATSTATUS 5
56 /* RIPv2-MIB rip2IfConfTable. */
57 #define RIP2IFCONFADDRESS 1
58 #define RIP2IFCONFDOMAIN 2
59 #define RIP2IFCONFAUTHTYPE 3
60 #define RIP2IFCONFAUTHKEY 4
61 #define RIP2IFCONFSEND 5
62 #define RIP2IFCONFRECEIVE 6
63 #define RIP2IFCONFDEFAULTMETRIC 7
64 #define RIP2IFCONFSTATUS 8
65 #define RIP2IFCONFSRCADDRESS 9
67 /* RIPv2-MIB rip2PeerTable. */
68 #define RIP2PEERADDRESS 1
69 #define RIP2PEERDOMAIN 2
70 #define RIP2PEERLASTUPDATE 3
71 #define RIP2PEERVERSION 4
72 #define RIP2PEERRCVBADPACKETS 5
73 #define RIP2PEERRCVBADROUTES 6
75 /* SNMP value hack. */
76 #define COUNTER ASN_COUNTER
77 #define INTEGER ASN_INTEGER
78 #define TIMETICKS ASN_TIMETICKS
79 #define IPADDRESS ASN_IPADDRESS
80 #define STRING ASN_OCTET_STR
82 /* Define SNMP local variables. */
85 /* RIP-MIB instances. */
86 static oid rip_oid
[] = { RIPV2MIB
};
88 /* Interface cache table sorted by interface's address. */
89 static struct route_table
*rip_ifaddr_table
;
92 static u_char
*rip2Globals (struct variable
*, oid
[], size_t *,
93 int, size_t *, WriteMethod
**);
94 static u_char
*rip2IfStatEntry (struct variable
*, oid
[], size_t *,
95 int, size_t *, WriteMethod
**);
96 static u_char
*rip2IfConfAddress (struct variable
*, oid
[], size_t *,
97 int, size_t *, WriteMethod
**);
98 static u_char
*rip2PeerTable (struct variable
*, oid
[], size_t *,
99 int, size_t *, WriteMethod
**);
101 static struct variable rip_variables
[] =
103 /* RIP Global Counters. */
104 {RIP2GLOBALROUTECHANGES
, COUNTER
, RONLY
, rip2Globals
,
106 {RIP2GLOBALQUERIES
, COUNTER
, RONLY
, rip2Globals
,
108 /* RIP Interface Tables. */
109 {RIP2IFSTATADDRESS
, IPADDRESS
, RONLY
, rip2IfStatEntry
,
111 {RIP2IFSTATRCVBADPACKETS
, COUNTER
, RONLY
, rip2IfStatEntry
,
113 {RIP2IFSTATRCVBADROUTES
, COUNTER
, RONLY
, rip2IfStatEntry
,
115 {RIP2IFSTATSENTUPDATES
, COUNTER
, RONLY
, rip2IfStatEntry
,
117 {RIP2IFSTATSTATUS
, COUNTER
, RWRITE
, rip2IfStatEntry
,
119 {RIP2IFCONFADDRESS
, IPADDRESS
, RONLY
, rip2IfConfAddress
,
120 /* RIP Interface Configuration Table. */
122 {RIP2IFCONFDOMAIN
, STRING
, RONLY
, rip2IfConfAddress
,
124 {RIP2IFCONFAUTHTYPE
, COUNTER
, RONLY
, rip2IfConfAddress
,
126 {RIP2IFCONFAUTHKEY
, STRING
, RONLY
, rip2IfConfAddress
,
128 {RIP2IFCONFSEND
, COUNTER
, RONLY
, rip2IfConfAddress
,
130 {RIP2IFCONFRECEIVE
, COUNTER
, RONLY
, rip2IfConfAddress
,
132 {RIP2IFCONFDEFAULTMETRIC
, COUNTER
, RONLY
, rip2IfConfAddress
,
134 {RIP2IFCONFSTATUS
, COUNTER
, RONLY
, rip2IfConfAddress
,
136 {RIP2IFCONFSRCADDRESS
, IPADDRESS
, RONLY
, rip2IfConfAddress
,
138 {RIP2PEERADDRESS
, IPADDRESS
, RONLY
, rip2PeerTable
,
139 /* RIP Peer Table. */
141 {RIP2PEERDOMAIN
, STRING
, RONLY
, rip2PeerTable
,
143 {RIP2PEERLASTUPDATE
, TIMETICKS
, RONLY
, rip2PeerTable
,
145 {RIP2PEERVERSION
, INTEGER
, RONLY
, rip2PeerTable
,
147 {RIP2PEERRCVBADPACKETS
, COUNTER
, RONLY
, rip2PeerTable
,
149 {RIP2PEERRCVBADROUTES
, COUNTER
, RONLY
, rip2PeerTable
,
153 extern struct thread_master
*master
;
156 rip2Globals (struct variable
*v
, oid name
[], size_t *length
,
157 int exact
, size_t *var_len
, WriteMethod
**write_method
)
159 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
163 /* Retrun global counter. */
166 case RIP2GLOBALROUTECHANGES
:
167 return SNMP_INTEGER (rip_global_route_changes
);
169 case RIP2GLOBALQUERIES
:
170 return SNMP_INTEGER (rip_global_queries
);
180 rip_snmp_ifaddr_add (struct connected
*ifc
)
182 struct interface
*ifp
= ifc
->ifp
;
184 struct route_node
*rn
;
188 if (p
->family
!= AF_INET
)
191 rn
= route_node_get (rip_ifaddr_table
, p
);
197 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 (rn
&& !strncmp(i
->name
,ifp
->name
,INTERFACE_NAMSIZ
))
216 route_unlock_node (rn
);
217 route_unlock_node (rn
);
222 static struct interface
*
223 rip_ifaddr_lookup_next (struct in_addr
*addr
)
225 struct prefix_ipv4 p
;
226 struct route_node
*rn
;
227 struct interface
*ifp
;
230 p
.prefixlen
= IPV4_MAX_BITLEN
;
233 rn
= route_node_get (rip_ifaddr_table
, (struct prefix
*) &p
);
235 for (rn
= route_next (rn
); rn
; rn
= route_next (rn
))
242 *addr
= rn
->p
.u
.prefix4
;
243 route_unlock_node (rn
);
249 static struct interface
*
250 rip2IfLookup (struct variable
*v
, oid name
[], size_t *length
,
251 struct in_addr
*addr
, int exact
)
254 struct interface
*ifp
;
258 /* Check the length. */
259 if (*length
- v
->namelen
!= sizeof (struct in_addr
))
262 oid2in_addr (name
+ v
->namelen
, sizeof (struct in_addr
), addr
);
264 return if_lookup_exact_address ((void *)addr
, AF_INET
, VRF_DEFAULT
);
268 len
= *length
- v
->namelen
;
269 if (len
> 4) len
= 4;
271 oid2in_addr (name
+ v
->namelen
, len
, addr
);
273 ifp
= rip_ifaddr_lookup_next (addr
);
278 oid_copy_addr (name
+ v
->namelen
, addr
, sizeof (struct in_addr
));
280 *length
= v
->namelen
+ sizeof (struct in_addr
);
287 static struct rip_peer
*
288 rip2PeerLookup (struct variable
*v
, oid name
[], size_t *length
,
289 struct in_addr
*addr
, int exact
)
292 struct rip_peer
*peer
;
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 (addr
);
304 if (peer
->domain
== (int)name
[v
->namelen
+ sizeof (struct in_addr
)])
311 len
= *length
- v
->namelen
;
312 if (len
> 4) len
= 4;
314 oid2in_addr (name
+ v
->namelen
, len
, addr
);
316 len
= *length
- v
->namelen
;
317 peer
= rip_peer_lookup (addr
);
320 if ((len
< (int)sizeof (struct in_addr
) + 1) ||
321 (peer
->domain
> (int)name
[v
->namelen
+ 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
)] = peer
->domain
;
326 *length
= sizeof (struct in_addr
) + v
->namelen
+ 1;
330 peer
= rip_peer_lookup_next (addr
);
335 oid_copy_addr (name
+ v
->namelen
, &peer
->addr
,
336 sizeof (struct in_addr
));
337 name
[v
->namelen
+ sizeof (struct in_addr
)] = peer
->domain
;
338 *length
= sizeof (struct in_addr
) + v
->namelen
+ 1;
346 rip2IfStatEntry (struct variable
*v
, oid name
[], size_t *length
,
347 int exact
, size_t *var_len
, WriteMethod
**write_method
)
349 struct interface
*ifp
;
350 struct rip_interface
*ri
;
351 static struct in_addr addr
;
352 static long valid
= SNMP_VALID
;
354 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
358 memset (&addr
, 0, sizeof (struct in_addr
));
360 /* Lookup interface. */
361 ifp
= rip2IfLookup (v
, name
, length
, &addr
, exact
);
365 /* Fetch rip_interface information. */
370 case RIP2IFSTATADDRESS
:
371 return SNMP_IPADDRESS (addr
);
373 case RIP2IFSTATRCVBADPACKETS
:
374 *var_len
= sizeof (long);
375 return (u_char
*) &ri
->recv_badpackets
;
377 case RIP2IFSTATRCVBADROUTES
:
378 *var_len
= sizeof (long);
379 return (u_char
*) &ri
->recv_badroutes
;
381 case RIP2IFSTATSENTUPDATES
:
382 *var_len
= sizeof (long);
383 return (u_char
*) &ri
->sent_updates
;
385 case RIP2IFSTATSTATUS
:
386 *var_len
= sizeof (long);
387 v
->type
= ASN_INTEGER
;
388 return (u_char
*) &valid
;
398 rip2IfConfSend (struct rip_interface
*ri
)
401 #define ripVersion1 2
402 #define rip1Compatible 3
403 #define ripVersion2 4
404 #define ripV1Demand 5
405 #define ripV2Demand 6
410 if (ri
->ri_send
& RIPv2
)
412 else if (ri
->ri_send
& RIPv1
)
416 if (rip
->version_send
== RIPv2
)
418 else if (rip
->version_send
== RIPv1
)
425 rip2IfConfReceive (struct rip_interface
*ri
)
430 #define doNotReceive 4
437 recvv
= (ri
->ri_receive
== RI_RIP_UNSPEC
) ? rip
->version_recv
:
439 if (recvv
== RI_RIP_VERSION_1_AND_2
)
441 else if (recvv
& RIPv2
)
443 else if (recvv
& RIPv1
)
450 rip2IfConfAddress (struct variable
*v
, oid name
[], size_t *length
,
451 int exact
, size_t *val_len
, WriteMethod
**write_method
)
453 static struct in_addr addr
;
454 static long valid
= SNMP_INVALID
;
455 static long domain
= 0;
456 static long config
= 0;
457 static u_int auth
= 0;
458 struct interface
*ifp
;
459 struct rip_interface
*ri
;
461 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
465 memset (&addr
, 0, sizeof (struct in_addr
));
467 /* Lookup interface. */
468 ifp
= rip2IfLookup (v
, name
, length
, &addr
, exact
);
472 /* Fetch rip_interface information. */
477 case RIP2IFCONFADDRESS
:
478 *val_len
= sizeof (struct in_addr
);
479 return (u_char
*) &addr
;
481 case RIP2IFCONFDOMAIN
:
483 return (u_char
*) &domain
;
485 case RIP2IFCONFAUTHTYPE
:
486 auth
= ri
->auth_type
;
487 *val_len
= sizeof (long);
488 v
->type
= ASN_INTEGER
;
489 return (u_char
*)&auth
;
491 case RIP2IFCONFAUTHKEY
:
493 return (u_char
*) &domain
;
495 config
= rip2IfConfSend (ri
);
496 *val_len
= sizeof (long);
497 v
->type
= ASN_INTEGER
;
498 return (u_char
*) &config
;
499 case RIP2IFCONFRECEIVE
:
500 config
= rip2IfConfReceive (ri
);
501 *val_len
= sizeof (long);
502 v
->type
= ASN_INTEGER
;
503 return (u_char
*) &config
;
505 case RIP2IFCONFDEFAULTMETRIC
:
506 *val_len
= sizeof (long);
507 v
->type
= ASN_INTEGER
;
508 return (u_char
*) &ifp
->metric
;
509 case RIP2IFCONFSTATUS
:
510 *val_len
= sizeof (long);
511 v
->type
= ASN_INTEGER
;
512 return (u_char
*) &valid
;
513 case RIP2IFCONFSRCADDRESS
:
514 *val_len
= sizeof (struct in_addr
);
515 return (u_char
*) &addr
;
525 rip2PeerTable (struct variable
*v
, oid name
[], size_t *length
,
526 int exact
, size_t *val_len
, WriteMethod
**write_method
)
528 static struct in_addr addr
;
529 static int domain
= 0;
531 /* static time_t uptime; */
533 struct rip_peer
*peer
;
535 if (smux_header_table(v
, name
, length
, exact
, val_len
, write_method
)
539 memset (&addr
, 0, sizeof (struct in_addr
));
541 /* Lookup interface. */
542 peer
= rip2PeerLookup (v
, name
, length
, &addr
, exact
);
548 case RIP2PEERADDRESS
:
549 *val_len
= sizeof (struct in_addr
);
550 return (u_char
*) &peer
->addr
;
554 return (u_char
*) &domain
;
556 case RIP2PEERLASTUPDATE
:
558 /* We don't know the SNMP agent startup time. We have two choices here:
559 * - assume ripd startup time equals SNMP agent startup time
560 * - don't support this variable, at all
561 * Currently, we do the latter...
563 *val_len
= sizeof (time_t);
564 uptime
= peer
->uptime
; /* now - snmp_agent_startup - peer->uptime */
565 return (u_char
*) &uptime
;
567 return (u_char
*) NULL
;
570 case RIP2PEERVERSION
:
571 *val_len
= sizeof (int);
572 version
= peer
->version
;
573 return (u_char
*) &version
;
575 case RIP2PEERRCVBADPACKETS
:
576 *val_len
= sizeof (int);
577 return (u_char
*) &peer
->recv_badpackets
;
579 case RIP2PEERRCVBADROUTES
:
580 *val_len
= sizeof (int);
581 return (u_char
*) &peer
->recv_badroutes
;
590 /* Register RIPv2-MIB. */
592 rip_snmp_init (struct thread_master
*master
)
594 rip_ifaddr_table
= route_table_init ();
597 REGISTER_MIB("mibII/rip", rip_variables
, variable
, rip_oid
);
602 rip_snmp_module_init (void)
604 hook_register(rip_ifaddr_add
, rip_snmp_ifaddr_add
);
605 hook_register(rip_ifaddr_del
, rip_snmp_ifaddr_del
);
607 hook_register(frr_late_init
, rip_snmp_init
);
613 .version
= FRR_VERSION
,
614 .description
= "ripd AgentX SNMP module",
615 .init
= rip_snmp_module_init
,