]>
git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_snmp.c
2 * Copyright (C) 1999 Kunihiro Ishiguro
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
27 #include <snmp_impl.h>
36 #include "zebra/rib.h"
38 #define IPFWMIB 1,3,6,1,2,1,4,24
39 #define ZEBRAOID 1,3,6,1,4,1,3317,1,2,1
42 #define IPFORWARDDEST 1
43 #define IPFORWARDMASK 2
44 #define IPFORWARDPOLICY 3
45 #define IPFORWARDNEXTHOP 4
46 #define IPFORWARDIFINDEX 5
47 #define IPFORWARDTYPE 6
48 #define IPFORWARDPROTO 7
49 #define IPFORWARDAGE 8
50 #define IPFORWARDINFO 9
51 #define IPFORWARDNEXTHOPAS 10
52 #define IPFORWARDMETRIC1 11
53 #define IPFORWARDMETRIC2 12
54 #define IPFORWARDMETRIC3 13
55 #define IPFORWARDMETRIC4 14
56 #define IPFORWARDMETRIC5 15
58 /* ipCidrRouteTable */
59 #define IPCIDRROUTEDEST 1
60 #define IPCIDRROUTEMASK 2
61 #define IPCIDRROUTETOS 3
62 #define IPCIDRROUTENEXTHOP 4
63 #define IPCIDRROUTEIFINDEX 5
64 #define IPCIDRROUTETYPE 6
65 #define IPCIDRROUTEPROTO 7
66 #define IPCIDRROUTEAGE 8
67 #define IPCIDRROUTEINFO 9
68 #define IPCIDRROUTENEXTHOPAS 10
69 #define IPCIDRROUTEMETRIC1 11
70 #define IPCIDRROUTEMETRIC2 12
71 #define IPCIDRROUTEMETRIC3 13
72 #define IPCIDRROUTEMETRIC4 14
73 #define IPCIDRROUTEMETRIC5 15
74 #define IPCIDRROUTESTATUS 16
76 #define INTEGER32 ASN_INTEGER
77 #define GAUGE32 ASN_GAUGE
78 #define ENUMERATION ASN_INTEGER
79 #define ROWSTATUS ASN_INTEGER
80 #define IPADDRESS ASN_IPADDRESS
81 #define OBJECTIDENTIFIER ASN_OBJECT_ID
83 oid ipfw_oid
[] = { IPFWMIB
};
84 oid zebra_oid
[] = { ZEBRAOID
};
87 u_char
* ipFwNumber ();
88 u_char
* ipFwTable ();
89 u_char
* ipCidrNumber ();
90 u_char
* ipCidrTable ();
92 struct variable zebra_variables
[] =
94 {0, GAUGE32
, RONLY
, ipFwNumber
, 1, {1}},
95 {IPFORWARDDEST
, IPADDRESS
, RONLY
, ipFwTable
, 3, {2, 1, 1}},
96 {IPFORWARDMASK
, IPADDRESS
, RONLY
, ipFwTable
, 3, {2, 1, 2}},
97 {IPFORWARDPOLICY
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 3}},
98 {IPFORWARDNEXTHOP
, IPADDRESS
, RONLY
, ipFwTable
, 3, {2, 1, 4}},
99 {IPFORWARDIFINDEX
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 5}},
100 {IPFORWARDTYPE
, ENUMERATION
, RONLY
, ipFwTable
, 3, {2, 1, 6}},
101 {IPFORWARDPROTO
, ENUMERATION
, RONLY
, ipFwTable
, 3, {2, 1, 7}},
102 {IPFORWARDAGE
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 8}},
103 {IPFORWARDINFO
, OBJECTIDENTIFIER
, RONLY
, ipFwTable
, 3, {2, 1, 9}},
104 {IPFORWARDNEXTHOPAS
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 10}},
105 {IPFORWARDMETRIC1
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 11}},
106 {IPFORWARDMETRIC2
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 12}},
107 {IPFORWARDMETRIC3
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 13}},
108 {IPFORWARDMETRIC4
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 14}},
109 {IPFORWARDMETRIC5
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 15}},
110 {0, GAUGE32
, RONLY
, ipCidrNumber
, 1, {3}},
111 {IPCIDRROUTEDEST
, IPADDRESS
, RONLY
, ipCidrTable
, 3, {4, 1, 1}},
112 {IPCIDRROUTEMASK
, IPADDRESS
, RONLY
, ipCidrTable
, 3, {4, 1, 2}},
113 {IPCIDRROUTETOS
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 3}},
114 {IPCIDRROUTENEXTHOP
, IPADDRESS
, RONLY
, ipCidrTable
, 3, {4, 1, 4}},
115 {IPCIDRROUTEIFINDEX
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 5}},
116 {IPCIDRROUTETYPE
, ENUMERATION
, RONLY
, ipCidrTable
, 3, {4, 1, 6}},
117 {IPCIDRROUTEPROTO
, ENUMERATION
, RONLY
, ipCidrTable
, 3, {4, 1, 7}},
118 {IPCIDRROUTEAGE
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 8}},
119 {IPCIDRROUTEINFO
, OBJECTIDENTIFIER
, RONLY
, ipCidrTable
, 3, {4, 1, 9}},
120 {IPCIDRROUTENEXTHOPAS
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 10}},
121 {IPCIDRROUTEMETRIC1
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 11}},
122 {IPCIDRROUTEMETRIC2
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 12}},
123 {IPCIDRROUTEMETRIC3
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 13}},
124 {IPCIDRROUTEMETRIC4
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 14}},
125 {IPCIDRROUTEMETRIC5
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 15}},
126 {IPCIDRROUTESTATUS
, ROWSTATUS
, RONLY
, ipCidrTable
, 3, {4, 1, 16}}
131 ipFwNumber (struct variable
*v
, oid objid
[], size_t *objid_len
,
132 int exact
, size_t *val_len
, WriteMethod
**write_method
)
135 struct route_node
*np
;
138 if (smux_header_generic(v
, objid
, objid_len
, exact
, val_len
, write_method
) == MATCH_FAILED
)
141 /* Return number of routing entries. */
143 for (np
= route_top (rib_table_ipv4
); np
; np
= route_next (np
))
144 for (rib
= np
->info
; rib
; rib
= rib
->next
)
147 return (u_char
*)&result
;
151 ipCidrNumber (struct variable
*v
, oid objid
[], size_t *objid_len
,
152 int exact
, size_t *val_len
, WriteMethod
**write_method
)
155 struct route_node
*np
;
158 if (smux_header_generic(v
, objid
, objid_len
, exact
, val_len
, write_method
) == MATCH_FAILED
)
161 /* Return number of routing entries. */
163 for (np
= route_top (rib_table_ipv4
); np
; np
= route_next (np
))
164 for (rib
= np
->info
; rib
; rib
= rib
->next
)
167 return (u_char
*)&result
;
171 in_addr_cmp(u_char
*p1
, u_char
*p2
)
187 in_addr_add(u_char
*p
, int num
)
193 for (i
= 3; 0 <= i
; i
--) {
195 if (*p
+ num
> 255) {
204 /* ip + num > 0xffffffff */
211 int proto_trans(int type
)
215 case ZEBRA_ROUTE_SYSTEM
:
216 return 1; /* other */
217 case ZEBRA_ROUTE_KERNEL
:
218 return 1; /* other */
219 case ZEBRA_ROUTE_CONNECT
:
220 return 2; /* local interface */
221 case ZEBRA_ROUTE_STATIC
:
222 return 3; /* static route */
223 case ZEBRA_ROUTE_RIP
:
225 case ZEBRA_ROUTE_RIPNG
:
226 return 1; /* shouldn't happen */
227 case ZEBRA_ROUTE_OSPF
:
228 return 13; /* ospf */
229 case ZEBRA_ROUTE_OSPF6
:
230 return 1; /* shouldn't happen */
231 case ZEBRA_ROUTE_BGP
:
234 return 1; /* other */
239 check_replace(struct route_node
*np2
, struct rib
*rib2
,
240 struct route_node
**np
, struct rib
**rib
)
251 if (in_addr_cmp(&(*np
)->p
.u
.prefix
, &np2
->p
.u
.prefix
) < 0)
253 if (in_addr_cmp(&(*np
)->p
.u
.prefix
, &np2
->p
.u
.prefix
) > 0)
260 proto
= proto_trans((*rib
)->type
);
261 proto2
= proto_trans(rib2
->type
);
272 if (in_addr_cmp((u_char
*)&(*rib
)->nexthop
->gate
.ipv4
,
273 (u_char
*)&rib2
->nexthop
->gate
.ipv4
) <= 0)
282 get_fwtable_route_node(struct variable
*v
, oid objid
[], size_t *objid_len
,
283 int exact
, struct route_node
**np
, struct rib
**rib
)
286 struct route_node
*np2
;
290 struct in_addr nexthop
;
294 /* Init index variables */
296 pnt
= (u_char
*) &dest
;
297 for (i
= 0; i
< 4; i
++)
300 pnt
= (u_char
*) &nexthop
;
301 for (i
= 0; i
< 4; i
++)
307 /* Init return variables */
312 /* Short circuit exact matches of wrong length */
314 if (exact
&& (*objid_len
!= v
->namelen
+ 10))
317 /* Get INDEX information out of OID.
318 * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
321 if (*objid_len
> v
->namelen
)
322 oid2in_addr (objid
+ v
->namelen
, MIN(4, *objid_len
- v
->namelen
), &dest
);
324 if (*objid_len
> v
->namelen
+ 4)
325 proto
= objid
[v
->namelen
+ 4];
327 if (*objid_len
> v
->namelen
+ 5)
328 policy
= objid
[v
->namelen
+ 5];
330 if (*objid_len
> v
->namelen
+ 6)
331 oid2in_addr (objid
+ v
->namelen
+ 6, MIN(4, *objid_len
- v
->namelen
- 6),
334 /* Apply GETNEXT on not exact search */
336 if (!exact
&& (*objid_len
>= v
->namelen
+ 10))
338 if (! in_addr_add((u_char
*) &nexthop
, 1))
342 /* For exact: search matching entry in rib table. */
346 if (policy
) /* Not supported (yet?) */
348 for (*np
= route_top (rib_table_ipv4
); *np
; *np
= route_next (*np
))
350 if (!in_addr_cmp(&(*np
)->p
.u
.prefix
, (u_char
*)&dest
))
352 for (*rib
= (*np
)->info
; *rib
; *rib
= (*rib
)->next
)
354 if (!in_addr_cmp((u_char
*)&(*rib
)->nexthop
->gate
.ipv4
,
356 if (proto
== proto_trans((*rib
)->type
))
364 /* Search next best entry */
366 for (np2
= route_top (rib_table_ipv4
); np2
; np2
= route_next (np2
))
369 /* Check destination first */
370 if (in_addr_cmp(&np2
->p
.u
.prefix
, (u_char
*)&dest
) > 0)
371 for (rib2
= np2
->info
; rib2
; rib2
= rib2
->next
)
372 check_replace(np2
, rib2
, np
, rib
);
374 if (in_addr_cmp(&np2
->p
.u
.prefix
, (u_char
*)&dest
) == 0)
375 { /* have to look at each rib individually */
376 for (rib2
= np2
->info
; rib2
; rib2
= rib2
->next
)
380 proto2
= proto_trans(rib2
->type
);
383 if ((policy
< policy2
)
384 || ((policy
== policy2
) && (proto
< proto2
))
385 || ((policy
== policy2
) && (proto
== proto2
)
386 && (in_addr_cmp((u_char
*)&rib2
->nexthop
->gate
.ipv4
,
387 (u_char
*) &nexthop
) >= 0)
389 check_replace(np2
, rib2
, np
, rib
);
398 proto
= proto_trans((*rib
)->type
);
400 *objid_len
= v
->namelen
+ 10;
401 pnt
= (u_char
*) &(*np
)->p
.u
.prefix
;
402 for (i
= 0; i
< 4; i
++)
403 objid
[v
->namelen
+ i
] = *pnt
++;
405 objid
[v
->namelen
+ 4] = proto
;
406 objid
[v
->namelen
+ 5] = policy
;
409 struct nexthop
*nexthop
;
411 nexthop
= (*rib
)->nexthop
;
414 pnt
= (u_char
*) &nexthop
->gate
.ipv4
;
415 for (i
= 0; i
< 4; i
++)
416 objid
[i
+ v
->namelen
+ 6] = *pnt
++;
424 ipFwTable (struct variable
*v
, oid objid
[], size_t *objid_len
,
425 int exact
, size_t *val_len
, WriteMethod
**write_method
)
427 struct route_node
*np
;
430 static int resarr
[2];
431 static struct in_addr netmask
;
432 struct nexthop
*nexthop
;
434 get_fwtable_route_node(v
, objid
, objid_len
, exact
, &np
, &rib
);
438 nexthop
= rib
->nexthop
;
446 return &np
->p
.u
.prefix
;
449 masklen2ip(np
->p
.prefixlen
, &netmask
);
451 return (u_char
*)&netmask
;
453 case IPFORWARDPOLICY
:
455 *val_len
= sizeof(int);
456 return (u_char
*)&result
;
458 case IPFORWARDNEXTHOP
:
460 return (u_char
*)&nexthop
->gate
.ipv4
;
462 case IPFORWARDIFINDEX
:
463 *val_len
= sizeof(int);
464 return (u_char
*)&nexthop
->ifindex
;
467 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
468 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
)
472 *val_len
= sizeof(int);
473 return (u_char
*)&result
;
476 result
= proto_trans(rib
->type
);
477 *val_len
= sizeof(int);
478 return (u_char
*)&result
;
482 *val_len
= sizeof(int);
483 return (u_char
*)&result
;
488 *val_len
= 2 * sizeof(int);
489 return (u_char
*)resarr
;
491 case IPFORWARDNEXTHOPAS
:
493 *val_len
= sizeof(int);
494 return (u_char
*)&result
;
496 case IPFORWARDMETRIC1
:
498 *val_len
= sizeof(int);
499 return (u_char
*)&result
;
501 case IPFORWARDMETRIC2
:
503 *val_len
= sizeof(int);
504 return (u_char
*)&result
;
506 case IPFORWARDMETRIC3
:
508 *val_len
= sizeof(int);
509 return (u_char
*)&result
;
511 case IPFORWARDMETRIC4
:
513 *val_len
= sizeof(int);
514 return (u_char
*)&result
;
516 case IPFORWARDMETRIC5
:
518 *val_len
= sizeof(int);
519 return (u_char
*)&result
;
529 ipCidrTable (struct variable
*v
, oid objid
[], size_t *objid_len
,
530 int exact
, size_t *val_len
, WriteMethod
**write_method
)
534 case IPCIDRROUTEDEST
:
546 smux_init (zebra_oid
, sizeof (zebra_oid
) / sizeof (oid
));
547 REGISTER_MIB("mibII/ipforward", zebra_variables
, variable
, ipfw_oid
);
550 #endif /* HAVE_SNMP */