]>
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
26 #include <net-snmp/net-snmp-config.h>
30 #include <snmp_impl.h>
39 #include "ripd/ripd.h"
42 #define RIPV2MIB 1,3,6,1,2,1,23
44 /* Zebra enterprise RIP MIB. This variable is used for register
45 RIPv2-MIB to SNMP agent under SMUX protocol. */
46 #define RIPDOID 1,3,6,1,4,1,3317,1,2,3
48 /* RIPv2-MIB rip2Globals values. */
49 #define RIP2GLOBALROUTECHANGES 1
50 #define RIP2GLOBALQUERIES 2
52 /* RIPv2-MIB rip2IfStatEntry. */
53 #define RIP2IFSTATENTRY 1
55 /* RIPv2-MIB rip2IfStatTable. */
56 #define RIP2IFSTATADDRESS 1
57 #define RIP2IFSTATRCVBADPACKETS 2
58 #define RIP2IFSTATRCVBADROUTES 3
59 #define RIP2IFSTATSENTUPDATES 4
60 #define RIP2IFSTATSTATUS 5
62 /* RIPv2-MIB rip2IfConfTable. */
63 #define RIP2IFCONFADDRESS 1
64 #define RIP2IFCONFDOMAIN 2
65 #define RIP2IFCONFAUTHTYPE 3
66 #define RIP2IFCONFAUTHKEY 4
67 #define RIP2IFCONFSEND 5
68 #define RIP2IFCONFRECEIVE 6
69 #define RIP2IFCONFDEFAULTMETRIC 7
70 #define RIP2IFCONFSTATUS 8
71 #define RIP2IFCONFSRCADDRESS 9
73 /* RIPv2-MIB rip2PeerTable. */
74 #define RIP2PEERADDRESS 1
75 #define RIP2PEERDOMAIN 2
76 #define RIP2PEERLASTUPDATE 3
77 #define RIP2PEERVERSION 4
78 #define RIP2PEERRCVBADPACKETS 5
79 #define RIP2PEERRCVBADROUTES 6
81 /* SNMP value hack. */
82 #define COUNTER ASN_COUNTER
83 #define INTEGER ASN_INTEGER
84 #define TIMETICKS ASN_TIMETICKS
85 #define IPADDRESS ASN_IPADDRESS
86 #define STRING ASN_OCTET_STR
88 /* Define SNMP local variables. */
91 /* RIP-MIB instances. */
92 oid rip_oid
[] = { RIPV2MIB
};
93 oid ripd_oid
[] = { RIPDOID
};
95 /* Interface cache table sorted by interface's address. */
96 struct route_table
*rip_ifaddr_table
;
99 static u_char
*rip2Globals ();
100 static u_char
*rip2IfStatEntry ();
101 static u_char
*rip2IfConfAddress ();
102 static u_char
*rip2PeerTable ();
104 struct variable rip_variables
[] =
106 /* RIP Global Counters. */
107 {RIP2GLOBALROUTECHANGES
, COUNTER
, RONLY
, rip2Globals
,
109 {RIP2GLOBALQUERIES
, COUNTER
, RONLY
, rip2Globals
,
111 /* RIP Interface Tables. */
112 {RIP2IFSTATADDRESS
, IPADDRESS
, RONLY
, rip2IfStatEntry
,
114 {RIP2IFSTATRCVBADPACKETS
, COUNTER
, RONLY
, rip2IfStatEntry
,
116 {RIP2IFSTATRCVBADROUTES
, COUNTER
, RONLY
, rip2IfStatEntry
,
118 {RIP2IFSTATSENTUPDATES
, COUNTER
, RONLY
, rip2IfStatEntry
,
120 {RIP2IFSTATSTATUS
, COUNTER
, RWRITE
, rip2IfStatEntry
,
122 {RIP2IFCONFADDRESS
, IPADDRESS
, RONLY
, rip2IfConfAddress
,
123 /* RIP Interface Configuration Table. */
125 {RIP2IFCONFDOMAIN
, STRING
, RONLY
, rip2IfConfAddress
,
127 {RIP2IFCONFAUTHTYPE
, COUNTER
, RONLY
, rip2IfConfAddress
,
129 {RIP2IFCONFAUTHKEY
, STRING
, RONLY
, rip2IfConfAddress
,
131 {RIP2IFCONFSEND
, COUNTER
, RONLY
, rip2IfConfAddress
,
133 {RIP2IFCONFRECEIVE
, COUNTER
, RONLY
, rip2IfConfAddress
,
135 {RIP2IFCONFDEFAULTMETRIC
, COUNTER
, RONLY
, rip2IfConfAddress
,
137 {RIP2IFCONFSTATUS
, COUNTER
, RONLY
, rip2IfConfAddress
,
139 {RIP2IFCONFSRCADDRESS
, IPADDRESS
, RONLY
, rip2IfConfAddress
,
141 {RIP2PEERADDRESS
, IPADDRESS
, RONLY
, rip2PeerTable
,
142 /* RIP Peer Table. */
144 {RIP2PEERDOMAIN
, INTEGER
, RONLY
, rip2PeerTable
,
146 {RIP2PEERLASTUPDATE
, TIMETICKS
, RONLY
, rip2PeerTable
,
148 {RIP2PEERVERSION
, INTEGER
, RONLY
, rip2PeerTable
,
150 {RIP2PEERRCVBADPACKETS
, COUNTER
, RONLY
, rip2PeerTable
,
152 {RIP2PEERRCVBADROUTES
, COUNTER
, RONLY
, rip2PeerTable
,
157 rip2Globals (struct variable
*v
, oid name
[], size_t *length
,
158 int exact
, size_t *var_len
, WriteMethod
**write_method
)
160 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
164 /* Retrun global counter. */
167 case RIP2GLOBALROUTECHANGES
:
168 return SNMP_INTEGER (rip_global_route_changes
);
170 case RIP2GLOBALQUERIES
:
171 return SNMP_INTEGER (rip_global_queries
);
181 rip_ifaddr_add (struct interface
*ifp
, struct connected
*ifc
)
184 struct route_node
*rn
;
188 if (p
->family
!= AF_INET
)
191 rn
= route_node_get (rip_ifaddr_table
, p
);
196 rip_ifaddr_delete (struct interface
*ifp
, struct connected
*ifc
)
199 struct route_node
*rn
;
204 if (p
->family
!= AF_INET
)
207 rn
= route_node_lookup (rip_ifaddr_table
, p
);
211 if (rn
&& !strncmp(i
->name
,ifp
->name
,INTERFACE_NAMSIZ
))
214 route_unlock_node (rn
);
215 route_unlock_node (rn
);
220 rip_ifaddr_lookup_next (struct in_addr
*addr
)
222 struct prefix_ipv4 p
;
223 struct route_node
*rn
;
224 struct interface
*ifp
;
227 p
.prefixlen
= IPV4_MAX_BITLEN
;
230 rn
= route_node_get (rip_ifaddr_table
, (struct prefix
*) &p
);
232 for (rn
= route_next (rn
); rn
; rn
= route_next (rn
))
239 *addr
= rn
->p
.u
.prefix4
;
240 route_unlock_node (rn
);
246 static struct interface
*
247 rip2IfLookup (struct variable
*v
, oid name
[], size_t *length
,
248 struct in_addr
*addr
, int exact
)
251 struct interface
*ifp
;
255 /* Check the length. */
256 if (*length
- v
->namelen
!= sizeof (struct in_addr
))
259 oid2in_addr (name
+ v
->namelen
, sizeof (struct in_addr
), addr
);
261 return if_lookup_exact_address (*addr
);
265 len
= *length
- v
->namelen
;
266 if (len
> 4) len
= 4;
268 oid2in_addr (name
+ v
->namelen
, len
, addr
);
270 ifp
= rip_ifaddr_lookup_next (addr
);
275 oid_copy_addr (name
+ v
->namelen
, addr
, sizeof (struct in_addr
));
277 *length
= v
->namelen
+ sizeof (struct in_addr
);
284 static struct rip_peer
*
285 rip2PeerLookup (struct variable
*v
, oid name
[], size_t *length
,
286 struct in_addr
*addr
, int exact
)
289 struct rip_peer
*peer
;
293 /* Check the length. */
294 if (*length
- v
->namelen
!= sizeof (struct in_addr
) + 1)
297 oid2in_addr (name
+ v
->namelen
, sizeof (struct in_addr
), addr
);
299 peer
= rip_peer_lookup (addr
);
301 if (peer
->domain
== name
[v
->namelen
+ sizeof (struct in_addr
)])
308 len
= *length
- v
->namelen
;
309 if (len
> 4) len
= 4;
311 oid2in_addr (name
+ v
->namelen
, len
, addr
);
313 len
= *length
- v
->namelen
;
314 peer
= rip_peer_lookup (addr
);
317 if ((len
< sizeof (struct in_addr
) + 1) ||
318 (peer
->domain
> name
[v
->namelen
+ sizeof (struct in_addr
)]))
320 oid_copy_addr (name
+ v
->namelen
, &peer
->addr
,
321 sizeof (struct in_addr
));
322 name
[v
->namelen
+ sizeof (struct in_addr
)] = peer
->domain
;
323 *length
= sizeof (struct in_addr
) + v
->namelen
+ 1;
327 peer
= rip_peer_lookup_next (addr
);
332 oid_copy_addr (name
+ v
->namelen
, &peer
->addr
,
333 sizeof (struct in_addr
));
334 name
[v
->namelen
+ sizeof (struct in_addr
)] = peer
->domain
;
335 *length
= sizeof (struct in_addr
) + v
->namelen
+ 1;
343 rip2IfStatEntry (struct variable
*v
, oid name
[], size_t *length
,
344 int exact
, size_t *var_len
, WriteMethod
**write_method
)
346 struct interface
*ifp
;
347 struct rip_interface
*ri
;
348 static struct in_addr addr
;
349 static long valid
= SNMP_VALID
;
351 memset (&addr
, 0, sizeof (struct in_addr
));
353 /* Lookup interface. */
354 ifp
= rip2IfLookup (v
, name
, length
, &addr
, exact
);
358 /* Fetch rip_interface information. */
363 case RIP2IFSTATADDRESS
:
364 return SNMP_IPADDRESS (addr
);
366 case RIP2IFSTATRCVBADPACKETS
:
367 *var_len
= sizeof (long);
368 return (u_char
*) &ri
->recv_badpackets
;
370 case RIP2IFSTATRCVBADROUTES
:
371 *var_len
= sizeof (long);
372 return (u_char
*) &ri
->recv_badroutes
;
374 case RIP2IFSTATSENTUPDATES
:
375 *var_len
= sizeof (long);
376 return (u_char
*) &ri
->sent_updates
;
378 case RIP2IFSTATSTATUS
:
379 *var_len
= sizeof (long);
380 v
->type
= ASN_INTEGER
;
381 return (u_char
*) &valid
;
391 rip2IfConfSend (struct rip_interface
*ri
)
394 #define ripVersion1 2
395 #define rip1Compatible 3
396 #define ripVersion2 4
397 #define ripV1Demand 5
398 #define ripV2Demand 6
403 if (ri
->ri_send
& RIPv2
)
405 else if (ri
->ri_send
& RIPv1
)
409 if (rip
->version
== RIPv2
)
411 else if (rip
->version
== RIPv1
)
418 rip2IfConfReceive (struct rip_interface
*ri
)
423 #define doNotReceive 4
428 if (ri
->ri_receive
== RI_RIP_VERSION_1_AND_2
)
430 else if (ri
->ri_receive
& RIPv2
)
432 else if (ri
->ri_receive
& RIPv1
)
439 rip2IfConfAddress (struct variable
*v
, oid name
[], size_t *length
,
440 int exact
, size_t *val_len
, WriteMethod
**write_method
)
442 static struct in_addr addr
;
443 static long valid
= SNMP_INVALID
;
444 static long domain
= 0;
445 static long config
= 0;
446 static u_int auth
= 0;
447 struct interface
*ifp
;
448 struct rip_interface
*ri
;
450 memset (&addr
, 0, sizeof (struct in_addr
));
452 /* Lookup interface. */
453 ifp
= rip2IfLookup (v
, name
, length
, &addr
, exact
);
457 /* Fetch rip_interface information. */
462 case RIP2IFCONFADDRESS
:
463 *val_len
= sizeof (struct in_addr
);
464 return (u_char
*) &addr
;
466 case RIP2IFCONFDOMAIN
:
468 return (u_char
*) &domain
;
470 case RIP2IFCONFAUTHTYPE
:
471 auth
= ri
->auth_type
;
472 *val_len
= sizeof (long);
473 v
->type
= ASN_INTEGER
;
474 return (u_char
*)&auth
;
476 case RIP2IFCONFAUTHKEY
:
478 return (u_char
*) &domain
;
480 config
= rip2IfConfSend (ri
);
481 *val_len
= sizeof (long);
482 v
->type
= ASN_INTEGER
;
483 return (u_char
*) &config
;
484 case RIP2IFCONFRECEIVE
:
485 config
= rip2IfConfReceive (ri
);
486 *val_len
= sizeof (long);
487 v
->type
= ASN_INTEGER
;
488 return (u_char
*) &config
;
490 case RIP2IFCONFDEFAULTMETRIC
:
491 *val_len
= sizeof (long);
492 v
->type
= ASN_INTEGER
;
493 return (u_char
*) &ifp
->metric
;
494 case RIP2IFCONFSTATUS
:
495 *val_len
= sizeof (long);
496 v
->type
= ASN_INTEGER
;
497 return (u_char
*) &valid
;
498 case RIP2IFCONFSRCADDRESS
:
499 *val_len
= sizeof (struct in_addr
);
500 return (u_char
*) &addr
;
510 rip2PeerTable (struct variable
*v
, oid name
[], size_t *length
,
511 int exact
, size_t *val_len
, WriteMethod
**write_method
)
513 static struct in_addr addr
;
515 /* static time_t uptime; */
517 struct rip_peer
*peer
;
519 memset (&addr
, 0, sizeof (struct in_addr
));
521 /* Lookup interface. */
522 peer
= rip2PeerLookup (v
, name
, length
, &addr
, exact
);
528 case RIP2PEERADDRESS
:
529 *val_len
= sizeof (struct in_addr
);
530 return (u_char
*) &peer
->addr
;
533 *val_len
= sizeof (int);
534 return (u_char
*) &peer
->domain
;
536 case RIP2PEERLASTUPDATE
:
538 /* We don't know the SNMP agent startup time. We have two choices here:
539 * - assume ripd startup time equals SNMP agent startup time
540 * - don't support this variable, at all
541 * Currently, we do the latter...
543 *val_len
= sizeof (time_t);
544 uptime
= peer
->uptime
; /* now - snmp_agent_startup - peer->uptime */
545 return (u_char
*) &uptime
;
547 return (u_char
*) NULL
;
550 case RIP2PEERVERSION
:
551 *val_len
= sizeof (int);
552 version
= peer
->version
;
553 return (u_char
*) &version
;
555 case RIP2PEERRCVBADPACKETS
:
556 *val_len
= sizeof (int);
557 return (u_char
*) &peer
->recv_badpackets
;
559 case RIP2PEERRCVBADROUTES
:
560 *val_len
= sizeof (int);
561 return (u_char
*) &peer
->recv_badroutes
;
570 /* Register RIPv2-MIB. */
574 rip_ifaddr_table
= route_table_init ();
576 smux_init (ripd_oid
, sizeof (ripd_oid
) / sizeof (oid
));
577 REGISTER_MIB("mibII/rip", rip_variables
, variable
, rip_oid
);
580 #endif /* HAVE_SNMP */