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
26
#include <net-snmp/net-snmp-config.h>
30
#include <snmp_impl.h>
39
#include "zebra/rib.h"
40
#include "zebra/zserv.h"
42
#define IPFWMIB 1,3,6,1,2,1,4,24
45
#define IPFORWARDDEST 1
46
#define IPFORWARDMASK 2
47
#define IPFORWARDPOLICY 3
48
#define IPFORWARDNEXTHOP 4
49
#define IPFORWARDIFINDEX 5
50
#define IPFORWARDTYPE 6
51
#define IPFORWARDPROTO 7
52
#define IPFORWARDAGE 8
53
#define IPFORWARDINFO 9
54
#define IPFORWARDNEXTHOPAS 10
55
#define IPFORWARDMETRIC1 11
56
#define IPFORWARDMETRIC2 12
57
#define IPFORWARDMETRIC3 13
58
#define IPFORWARDMETRIC4 14
59
#define IPFORWARDMETRIC5 15
61
/* ipCidrRouteTable */
62
#define IPCIDRROUTEDEST 1
63
#define IPCIDRROUTEMASK 2
64
#define IPCIDRROUTETOS 3
65
#define IPCIDRROUTENEXTHOP 4
66
#define IPCIDRROUTEIFINDEX 5
67
#define IPCIDRROUTETYPE 6
68
#define IPCIDRROUTEPROTO 7
69
#define IPCIDRROUTEAGE 8
70
#define IPCIDRROUTEINFO 9
71
#define IPCIDRROUTENEXTHOPAS 10
72
#define IPCIDRROUTEMETRIC1 11
73
#define IPCIDRROUTEMETRIC2 12
74
#define IPCIDRROUTEMETRIC3 13
75
#define IPCIDRROUTEMETRIC4 14
76
#define IPCIDRROUTEMETRIC5 15
77
#define IPCIDRROUTESTATUS 16
79
#define INTEGER32 ASN_INTEGER
80
#define GAUGE32 ASN_GAUGE
81
#define ENUMERATION ASN_INTEGER
82
#define ROWSTATUS ASN_INTEGER
83
#define IPADDRESS ASN_IPADDRESS
84
#define OBJECTIDENTIFIER ASN_OBJECT_ID
86
extern struct zebra_t zebrad;
88
oid ipfw_oid [] = { IPFWMIB };
91
u_char * ipFwNumber ();
92
u_char * ipFwTable ();
93
u_char * ipCidrNumber ();
94
u_char * ipCidrTable ();
96
struct variable zebra_variables[] =
98
{0, GAUGE32, RONLY, ipFwNumber, 1, {1}},
99
{IPFORWARDDEST, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 1}},
100
{IPFORWARDMASK, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 2}},
101
{IPFORWARDPOLICY, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 3}},
102
{IPFORWARDNEXTHOP, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 4}},
103
{IPFORWARDIFINDEX, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 5}},
104
{IPFORWARDTYPE, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 6}},
105
{IPFORWARDPROTO, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 7}},
106
{IPFORWARDAGE, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 8}},
107
{IPFORWARDINFO, OBJECTIDENTIFIER, RONLY, ipFwTable, 3, {2, 1, 9}},
108
{IPFORWARDNEXTHOPAS, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 10}},
109
{IPFORWARDMETRIC1, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 11}},
110
{IPFORWARDMETRIC2, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 12}},
111
{IPFORWARDMETRIC3, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 13}},
112
{IPFORWARDMETRIC4, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 14}},
113
{IPFORWARDMETRIC5, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 15}},
114
{0, GAUGE32, RONLY, ipCidrNumber, 1, {3}},
115
{IPCIDRROUTEDEST, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 1}},
116
{IPCIDRROUTEMASK, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 2}},
117
{IPCIDRROUTETOS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 3}},
118
{IPCIDRROUTENEXTHOP, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 4}},
119
{IPCIDRROUTEIFINDEX, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 5}},
120
{IPCIDRROUTETYPE, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 6}},
121
{IPCIDRROUTEPROTO, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 7}},
122
{IPCIDRROUTEAGE, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 8}},
123
{IPCIDRROUTEINFO, OBJECTIDENTIFIER, RONLY, ipCidrTable, 3, {4, 1, 9}},
124
{IPCIDRROUTENEXTHOPAS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 10}},
125
{IPCIDRROUTEMETRIC1, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 11}},
126
{IPCIDRROUTEMETRIC2, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 12}},
127
{IPCIDRROUTEMETRIC3, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 13}},
128
{IPCIDRROUTEMETRIC4, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 14}},
129
{IPCIDRROUTEMETRIC5, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 15}},
130
{IPCIDRROUTESTATUS, ROWSTATUS, RONLY, ipCidrTable, 3, {4, 1, 16}}
135
ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
136
int exact, size_t *val_len, WriteMethod **write_method)
139
struct route_table *table;
140
struct route_node *rn;
143
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
146
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
150
/* Return number of routing entries. */
152
for (rn = route_top (table); rn; rn = route_next (rn))
153
for (rib = rn->info; rib; rib = rib->next)
156
return (u_char *)&result;
160
ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
161
int exact, size_t *val_len, WriteMethod **write_method)
164
struct route_table *table;
165
struct route_node *rn;
168
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
171
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
175
/* Return number of routing entries. */
177
for (rn = route_top (table); rn; rn = route_next (rn))
178
for (rib = rn->info; rib; rib = rib->next)
181
return (u_char *)&result;
185
in_addr_cmp(u_char *p1, u_char *p2)
201
in_addr_add(u_char *p, int num)
207
for (i = 3; 0 <= i; i--) {
209
if (*p + num > 255) {
218
/* ip + num > 0xffffffff */
225
int proto_trans(int type)
229
case ZEBRA_ROUTE_SYSTEM:
230
return 1; /* other */
231
case ZEBRA_ROUTE_KERNEL:
232
return 1; /* other */
233
case ZEBRA_ROUTE_CONNECT:
234
return 2; /* local interface */
235
case ZEBRA_ROUTE_STATIC:
236
return 3; /* static route */
237
case ZEBRA_ROUTE_RIP:
239
case ZEBRA_ROUTE_RIPNG:
240
return 1; /* shouldn't happen */
241
case ZEBRA_ROUTE_OSPF:
242
return 13; /* ospf */
243
case ZEBRA_ROUTE_OSPF6:
244
return 1; /* shouldn't happen */
245
case ZEBRA_ROUTE_BGP:
248
return 1; /* other */
253
check_replace(struct route_node *np2, struct rib *rib2,
254
struct route_node **np, struct rib **rib)
265
if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) < 0)
267
if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0)
274
proto = proto_trans((*rib)->type);
275
proto2 = proto_trans(rib2->type);
286
if (in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,
287
(u_char *)&rib2->nexthop->gate.ipv4) <= 0)
296
get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
297
int exact, struct route_node **np, struct rib **rib)
300
struct route_table *table;
301
struct route_node *np2;
305
struct in_addr nexthop;
309
/* Init index variables */
311
pnt = (u_char *) &dest;
312
for (i = 0; i < 4; i++)
315
pnt = (u_char *) &nexthop;
316
for (i = 0; i < 4; i++)
322
/* Init return variables */
327
/* Short circuit exact matches of wrong length */
329
if (exact && (*objid_len != (unsigned) v->namelen + 10))
332
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
336
/* Get INDEX information out of OID.
337
* ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
340
if (*objid_len > v->namelen)
341
oid2in_addr (objid + v->namelen, MIN(4, *objid_len - v->namelen), &dest);
343
if (*objid_len > (unsigned) v->namelen + 4)
344
proto = objid[v->namelen + 4];
346
if (*objid_len > (unsigned) v->namelen + 5)
347
policy = objid[v->namelen + 5];
349
if (*objid_len > (unsigned) v->namelen + 6)
350
oid2in_addr (objid + v->namelen + 6, MIN(4, *objid_len - v->namelen - 6),
353
/* Apply GETNEXT on not exact search */
355
if (!exact && (*objid_len >= (unsigned) v->namelen + 10))
357
if (! in_addr_add((u_char *) &nexthop, 1))
361
/* For exact: search matching entry in rib table. */
365
if (policy) /* Not supported (yet?) */
367
for (*np = route_top (table); *np; *np = route_next (*np))
369
if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest))
371
for (*rib = (*np)->info; *rib; *rib = (*rib)->next)
373
if (!in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,
375
if (proto == proto_trans((*rib)->type))
383
/* Search next best entry */
385
for (np2 = route_top (table); np2; np2 = route_next (np2))
388
/* Check destination first */
389
if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0)
390
for (rib2 = np2->info; rib2; rib2 = rib2->next)
391
check_replace(np2, rib2, np, rib);
393
if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0)
394
{ /* have to look at each rib individually */
395
for (rib2 = np2->info; rib2; rib2 = rib2->next)
399
proto2 = proto_trans(rib2->type);
402
if ((policy < policy2)
403
|| ((policy == policy2) && (proto < proto2))
404
|| ((policy == policy2) && (proto == proto2)
405
&& (in_addr_cmp((u_char *)&rib2->nexthop->gate.ipv4,
406
(u_char *) &nexthop) >= 0)
408
check_replace(np2, rib2, np, rib);
417
proto = proto_trans((*rib)->type);
419
*objid_len = v->namelen + 10;
420
pnt = (u_char *) &(*np)->p.u.prefix;
421
for (i = 0; i < 4; i++)
422
objid[v->namelen + i] = *pnt++;
424
objid[v->namelen + 4] = proto;
425
objid[v->namelen + 5] = policy;
428
struct nexthop *nexthop;
430
nexthop = (*rib)->nexthop;
433
pnt = (u_char *) &nexthop->gate.ipv4;
434
for (i = 0; i < 4; i++)
435
objid[i + v->namelen + 6] = *pnt++;
443
ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
444
int exact, size_t *val_len, WriteMethod **write_method)
446
struct route_node *np;
449
static int resarr[2];
450
static struct in_addr netmask;
451
struct nexthop *nexthop;
453
get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib);
457
nexthop = rib->nexthop;
465
return &np->p.u.prefix;
468
masklen2ip(np->p.prefixlen, &netmask);
470
return (u_char *)&netmask;
472
case IPFORWARDPOLICY:
474
*val_len = sizeof(int);
475
return (u_char *)&result;
477
case IPFORWARDNEXTHOP:
479
return (u_char *)&nexthop->gate.ipv4;
481
case IPFORWARDIFINDEX:
482
*val_len = sizeof(int);
483
return (u_char *)&nexthop->ifindex;
486
if (nexthop->type == NEXTHOP_TYPE_IFINDEX
487
|| nexthop->type == NEXTHOP_TYPE_IFNAME)
491
*val_len = sizeof(int);
492
return (u_char *)&result;
495
result = proto_trans(rib->type);
496
*val_len = sizeof(int);
497
return (u_char *)&result;
501
*val_len = sizeof(int);
502
return (u_char *)&result;
507
*val_len = 2 * sizeof(int);
508
return (u_char *)resarr;
510
case IPFORWARDNEXTHOPAS:
512
*val_len = sizeof(int);
513
return (u_char *)&result;
515
case IPFORWARDMETRIC1:
517
*val_len = sizeof(int);
518
return (u_char *)&result;
520
case IPFORWARDMETRIC2:
522
*val_len = sizeof(int);
523
return (u_char *)&result;
525
case IPFORWARDMETRIC3:
527
*val_len = sizeof(int);
528
return (u_char *)&result;
530
case IPFORWARDMETRIC4:
532
*val_len = sizeof(int);
533
return (u_char *)&result;
535
case IPFORWARDMETRIC5:
537
*val_len = sizeof(int);
538
return (u_char *)&result;
548
ipCidrTable (struct variable *v, oid objid[], size_t *objid_len,
549
int exact, size_t *val_len, WriteMethod **write_method)
553
case IPCIDRROUTEDEST:
565
smux_init (zebrad.master);
566
REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid);
568
#endif /* HAVE_SNMP */