mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 13:43:22 +00:00 
			
		
		
		
	Make it easier to see which bits in *_snmp.c are actually referenced from non-SNMP parts of the code. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
		
			
				
	
	
		
			581 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			581 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* FIB SNMP.
 | 
						|
 * Copyright (C) 1999 Kunihiro Ishiguro
 | 
						|
 *
 | 
						|
 * This file is part of GNU Zebra.
 | 
						|
 *
 | 
						|
 * GNU Zebra is free software; you can redistribute it and/or modify it
 | 
						|
 * under the terms of the GNU General Public License as published by the
 | 
						|
 * Free Software Foundation; either version 2, or (at your option) any
 | 
						|
 * later version.
 | 
						|
 *
 | 
						|
 * GNU Zebra is distributed in the hope that it will be useful, but
 | 
						|
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
 * General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with GNU Zebra; see the file COPYING.  If not, write to the Free
 | 
						|
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
						|
 * 02111-1307, USA.  
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 * Currently SNMP is only running properly for MIBs in the default VRF.
 | 
						|
 */
 | 
						|
 | 
						|
#include <zebra.h>
 | 
						|
 | 
						|
#ifdef HAVE_SNMP
 | 
						|
#include <net-snmp/net-snmp-config.h>
 | 
						|
#include <net-snmp/net-snmp-includes.h>
 | 
						|
 | 
						|
#include "if.h"
 | 
						|
#include "log.h"
 | 
						|
#include "prefix.h"
 | 
						|
#include "command.h"
 | 
						|
#include "smux.h"
 | 
						|
#include "table.h"
 | 
						|
#include "vrf.h"
 | 
						|
 | 
						|
#include "zebra/rib.h"
 | 
						|
#include "zebra/zserv.h"
 | 
						|
#include "zebra/zebra_vrf.h"
 | 
						|
 | 
						|
#define IPFWMIB 1,3,6,1,2,1,4,24
 | 
						|
 | 
						|
/* ipForwardTable */
 | 
						|
#define IPFORWARDDEST                         1
 | 
						|
#define IPFORWARDMASK                         2
 | 
						|
#define IPFORWARDPOLICY                       3
 | 
						|
#define IPFORWARDNEXTHOP                      4
 | 
						|
#define IPFORWARDIFINDEX                      5
 | 
						|
#define IPFORWARDTYPE                         6
 | 
						|
#define IPFORWARDPROTO                        7
 | 
						|
#define IPFORWARDAGE                          8
 | 
						|
#define IPFORWARDINFO                         9
 | 
						|
#define IPFORWARDNEXTHOPAS                   10
 | 
						|
#define IPFORWARDMETRIC1                     11
 | 
						|
#define IPFORWARDMETRIC2                     12
 | 
						|
#define IPFORWARDMETRIC3                     13
 | 
						|
#define IPFORWARDMETRIC4                     14
 | 
						|
#define IPFORWARDMETRIC5                     15
 | 
						|
 | 
						|
/* ipCidrRouteTable */
 | 
						|
#define IPCIDRROUTEDEST                       1
 | 
						|
#define IPCIDRROUTEMASK                       2
 | 
						|
#define IPCIDRROUTETOS                        3
 | 
						|
#define IPCIDRROUTENEXTHOP                    4
 | 
						|
#define IPCIDRROUTEIFINDEX                    5
 | 
						|
#define IPCIDRROUTETYPE                       6
 | 
						|
#define IPCIDRROUTEPROTO                      7
 | 
						|
#define IPCIDRROUTEAGE                        8
 | 
						|
#define IPCIDRROUTEINFO                       9
 | 
						|
#define IPCIDRROUTENEXTHOPAS                 10
 | 
						|
#define IPCIDRROUTEMETRIC1                   11
 | 
						|
#define IPCIDRROUTEMETRIC2                   12
 | 
						|
#define IPCIDRROUTEMETRIC3                   13
 | 
						|
#define IPCIDRROUTEMETRIC4                   14
 | 
						|
#define IPCIDRROUTEMETRIC5                   15
 | 
						|
#define IPCIDRROUTESTATUS                    16
 | 
						|
 | 
						|
#define INTEGER32 ASN_INTEGER
 | 
						|
#define GAUGE32 ASN_GAUGE
 | 
						|
#define ENUMERATION ASN_INTEGER
 | 
						|
#define ROWSTATUS ASN_INTEGER
 | 
						|
#define IPADDRESS ASN_IPADDRESS
 | 
						|
#define OBJECTIDENTIFIER ASN_OBJECT_ID
 | 
						|
 | 
						|
static oid ipfw_oid [] = { IPFWMIB };
 | 
						|
 | 
						|
/* Hook functions. */
 | 
						|
static u_char * ipFwNumber (struct variable *, oid [], size_t *,
 | 
						|
		     int, size_t *, WriteMethod **);
 | 
						|
static u_char * ipFwTable (struct variable *, oid [], size_t *,
 | 
						|
			   int, size_t *, WriteMethod **);
 | 
						|
static u_char * ipCidrNumber (struct variable *, oid [], size_t *,
 | 
						|
			      int, size_t *, WriteMethod **);
 | 
						|
static u_char * ipCidrTable (struct variable *, oid [], size_t *,
 | 
						|
			     int, size_t *, WriteMethod **);
 | 
						|
 | 
						|
static struct variable zebra_variables[] =
 | 
						|
  {
 | 
						|
    {0, GAUGE32, RONLY, ipFwNumber, 1, {1}},
 | 
						|
    {IPFORWARDDEST, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 1}},
 | 
						|
    {IPFORWARDMASK, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 2}},
 | 
						|
    {IPFORWARDPOLICY, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 3}},
 | 
						|
    {IPFORWARDNEXTHOP, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 4}},
 | 
						|
    {IPFORWARDIFINDEX, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 5}},
 | 
						|
    {IPFORWARDTYPE, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 6}},
 | 
						|
    {IPFORWARDPROTO, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 7}},
 | 
						|
    {IPFORWARDAGE, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 8}},
 | 
						|
    {IPFORWARDINFO, OBJECTIDENTIFIER, RONLY, ipFwTable, 3, {2, 1, 9}},
 | 
						|
    {IPFORWARDNEXTHOPAS, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 10}},
 | 
						|
    {IPFORWARDMETRIC1, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 11}},
 | 
						|
    {IPFORWARDMETRIC2, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 12}},
 | 
						|
    {IPFORWARDMETRIC3, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 13}},
 | 
						|
    {IPFORWARDMETRIC4, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 14}},
 | 
						|
    {IPFORWARDMETRIC5, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 15}},
 | 
						|
    {0, GAUGE32, RONLY, ipCidrNumber, 1, {3}},
 | 
						|
    {IPCIDRROUTEDEST, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 1}},
 | 
						|
    {IPCIDRROUTEMASK, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 2}},
 | 
						|
    {IPCIDRROUTETOS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 3}},
 | 
						|
    {IPCIDRROUTENEXTHOP, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 4}},
 | 
						|
    {IPCIDRROUTEIFINDEX, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 5}},
 | 
						|
    {IPCIDRROUTETYPE, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 6}},
 | 
						|
    {IPCIDRROUTEPROTO, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 7}},
 | 
						|
    {IPCIDRROUTEAGE, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 8}},
 | 
						|
    {IPCIDRROUTEINFO, OBJECTIDENTIFIER, RONLY, ipCidrTable, 3, {4, 1, 9}},
 | 
						|
    {IPCIDRROUTENEXTHOPAS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 10}},
 | 
						|
    {IPCIDRROUTEMETRIC1, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 11}},
 | 
						|
    {IPCIDRROUTEMETRIC2, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 12}},
 | 
						|
    {IPCIDRROUTEMETRIC3, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 13}},
 | 
						|
    {IPCIDRROUTEMETRIC4, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 14}},
 | 
						|
    {IPCIDRROUTEMETRIC5, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 15}},
 | 
						|
    {IPCIDRROUTESTATUS, ROWSTATUS, RONLY, ipCidrTable, 3, {4, 1, 16}}
 | 
						|
  };
 | 
						|
 | 
						|
 | 
						|
static u_char *
 | 
						|
ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
 | 
						|
	    int exact, size_t *val_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  static int result;
 | 
						|
  struct route_table *table;
 | 
						|
  struct route_node *rn;
 | 
						|
  struct rib *rib;
 | 
						|
 | 
						|
  if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
 | 
						|
  if (! table)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return number of routing entries. */
 | 
						|
  result = 0;
 | 
						|
  for (rn = route_top (table); rn; rn = route_next (rn))
 | 
						|
    RNODE_FOREACH_RIB (rn, rib)
 | 
						|
      result++;
 | 
						|
 | 
						|
  return (u_char *)&result;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
 | 
						|
	      int exact, size_t *val_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  static int result;
 | 
						|
  struct route_table *table;
 | 
						|
  struct route_node *rn;
 | 
						|
  struct rib *rib;
 | 
						|
 | 
						|
  if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
 | 
						|
  if (! table)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  /* Return number of routing entries. */
 | 
						|
  result = 0;
 | 
						|
  for (rn = route_top (table); rn; rn = route_next (rn))
 | 
						|
    RNODE_FOREACH_RIB (rn, rib)
 | 
						|
      result++;
 | 
						|
 | 
						|
  return (u_char *)&result;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
in_addr_cmp(u_char *p1, u_char *p2)
 | 
						|
{
 | 
						|
  int i;
 | 
						|
 | 
						|
  for (i=0; i<4; i++)
 | 
						|
    {
 | 
						|
      if (*p1 < *p2)
 | 
						|
        return -1;
 | 
						|
      if (*p1 > *p2)
 | 
						|
        return 1;
 | 
						|
      p1++; p2++;
 | 
						|
    }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int 
 | 
						|
in_addr_add(u_char *p, int num)
 | 
						|
{
 | 
						|
  int i, ip0;
 | 
						|
 | 
						|
  ip0 = *p;
 | 
						|
  p += 4;
 | 
						|
  for (i = 3; 0 <= i; i--) {
 | 
						|
    p--;
 | 
						|
    if (*p + num > 255) {
 | 
						|
      *p += num;
 | 
						|
      num = 1;
 | 
						|
    } else {
 | 
						|
      *p += num;
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (ip0 > *p) {
 | 
						|
    /* ip + num > 0xffffffff */
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
proto_trans(int type)
 | 
						|
{
 | 
						|
  switch (type)
 | 
						|
    {
 | 
						|
    case ZEBRA_ROUTE_SYSTEM:
 | 
						|
      return 1; /* other */
 | 
						|
    case ZEBRA_ROUTE_KERNEL:
 | 
						|
      return 1; /* other */
 | 
						|
    case ZEBRA_ROUTE_CONNECT:
 | 
						|
      return 2; /* local interface */
 | 
						|
    case ZEBRA_ROUTE_STATIC:
 | 
						|
      return 3; /* static route */
 | 
						|
    case ZEBRA_ROUTE_RIP:
 | 
						|
      return 8; /* rip */
 | 
						|
    case ZEBRA_ROUTE_RIPNG:
 | 
						|
      return 1; /* shouldn't happen */
 | 
						|
    case ZEBRA_ROUTE_OSPF:
 | 
						|
      return 13; /* ospf */
 | 
						|
    case ZEBRA_ROUTE_OSPF6:
 | 
						|
      return 1; /* shouldn't happen */
 | 
						|
    case ZEBRA_ROUTE_BGP:
 | 
						|
      return 14; /* bgp */
 | 
						|
    default:
 | 
						|
      return 1; /* other */
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
check_replace(struct route_node *np2, struct rib *rib2, 
 | 
						|
              struct route_node **np, struct rib **rib)
 | 
						|
{
 | 
						|
  int proto, proto2;
 | 
						|
 | 
						|
  if (!*np)
 | 
						|
    {
 | 
						|
      *np = np2;
 | 
						|
      *rib = rib2;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) < 0)
 | 
						|
    return;
 | 
						|
  if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0)
 | 
						|
    {
 | 
						|
      *np = np2;
 | 
						|
      *rib = rib2;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  proto = proto_trans((*rib)->type);
 | 
						|
  proto2 = proto_trans(rib2->type);
 | 
						|
 | 
						|
  if (proto2 > proto)
 | 
						|
    return;
 | 
						|
  if (proto2 < proto)
 | 
						|
    {
 | 
						|
      *np = np2;
 | 
						|
      *rib = rib2;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  if (in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4, 
 | 
						|
                  (u_char *)&rib2->nexthop->gate.ipv4) <= 0)
 | 
						|
    return;
 | 
						|
 | 
						|
  *np = np2;
 | 
						|
  *rib = rib2;
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len, 
 | 
						|
		       int exact, struct route_node **np, struct rib **rib)
 | 
						|
{
 | 
						|
  struct in_addr dest;
 | 
						|
  struct route_table *table;
 | 
						|
  struct route_node *np2;
 | 
						|
  struct rib *rib2;
 | 
						|
  int proto;
 | 
						|
  int policy;
 | 
						|
  struct in_addr nexthop;
 | 
						|
  u_char *pnt;
 | 
						|
  int i;
 | 
						|
 | 
						|
  /* Init index variables */
 | 
						|
 | 
						|
  pnt = (u_char *) &dest;
 | 
						|
  for (i = 0; i < 4; i++)
 | 
						|
    *pnt++ = 0;
 | 
						|
 | 
						|
  pnt = (u_char *) &nexthop;
 | 
						|
  for (i = 0; i < 4; i++)
 | 
						|
    *pnt++ = 0;
 | 
						|
 | 
						|
  proto = 0;
 | 
						|
  policy = 0;
 | 
						|
 
 | 
						|
  /* Init return variables */
 | 
						|
 | 
						|
  *np = NULL;
 | 
						|
  *rib = NULL;
 | 
						|
 | 
						|
  /* Short circuit exact matches of wrong length */
 | 
						|
 | 
						|
  if (exact && (*objid_len != (unsigned) v->namelen + 10))
 | 
						|
    return;
 | 
						|
 | 
						|
  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
 | 
						|
  if (! table)
 | 
						|
    return;
 | 
						|
 | 
						|
  /* Get INDEX information out of OID.
 | 
						|
   * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
 | 
						|
   */
 | 
						|
 | 
						|
  if (*objid_len > (unsigned) v->namelen)
 | 
						|
    oid2in_addr (objid + v->namelen, MIN(4, *objid_len - v->namelen), &dest);
 | 
						|
 | 
						|
  if (*objid_len > (unsigned) v->namelen + 4)
 | 
						|
    proto = objid[v->namelen + 4];
 | 
						|
 | 
						|
  if (*objid_len > (unsigned) v->namelen + 5)
 | 
						|
    policy = objid[v->namelen + 5];
 | 
						|
 | 
						|
  if (*objid_len > (unsigned) v->namelen + 6)
 | 
						|
    oid2in_addr (objid + v->namelen + 6, MIN(4, *objid_len - v->namelen - 6),
 | 
						|
		 &nexthop);
 | 
						|
 | 
						|
  /* Apply GETNEXT on not exact search */
 | 
						|
 | 
						|
  if (!exact && (*objid_len >= (unsigned) v->namelen + 10))
 | 
						|
    {
 | 
						|
      if (! in_addr_add((u_char *) &nexthop, 1)) 
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
  /* For exact: search matching entry in rib table. */
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      if (policy) /* Not supported (yet?) */
 | 
						|
        return;
 | 
						|
      for (*np = route_top (table); *np; *np = route_next (*np))
 | 
						|
	{
 | 
						|
	  if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest))
 | 
						|
	    {
 | 
						|
	      RNODE_FOREACH_RIB (*np, *rib)
 | 
						|
	        {
 | 
						|
		  if (!in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,
 | 
						|
				   (u_char *)&nexthop))
 | 
						|
		    if (proto == proto_trans((*rib)->type))
 | 
						|
		      return;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Search next best entry */
 | 
						|
 | 
						|
  for (np2 = route_top (table); np2; np2 = route_next (np2))
 | 
						|
    {
 | 
						|
 | 
						|
      /* Check destination first */
 | 
						|
      if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0)
 | 
						|
	RNODE_FOREACH_RIB (np2, rib2)
 | 
						|
	  check_replace(np2, rib2, np, rib);
 | 
						|
 | 
						|
      if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0)
 | 
						|
        { /* have to look at each rib individually */
 | 
						|
	  RNODE_FOREACH_RIB (np2, rib2)
 | 
						|
	    {
 | 
						|
	      int proto2, policy2;
 | 
						|
 | 
						|
	      proto2 = proto_trans(rib2->type);
 | 
						|
	      policy2 = 0;
 | 
						|
 | 
						|
	      if ((policy < policy2)
 | 
						|
		  || ((policy == policy2) && (proto < proto2))
 | 
						|
		  || ((policy == policy2) && (proto == proto2)
 | 
						|
		      && (in_addr_cmp((u_char *)&rib2->nexthop->gate.ipv4,
 | 
						|
				      (u_char *) &nexthop) >= 0)
 | 
						|
		      ))
 | 
						|
		check_replace(np2, rib2, np, rib);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  if (!*rib)
 | 
						|
    return;
 | 
						|
 | 
						|
  policy = 0;
 | 
						|
  proto = proto_trans((*rib)->type);
 | 
						|
 | 
						|
  *objid_len = v->namelen + 10;
 | 
						|
  pnt = (u_char *) &(*np)->p.u.prefix;
 | 
						|
  for (i = 0; i < 4; i++)
 | 
						|
    objid[v->namelen + i] = *pnt++;
 | 
						|
 | 
						|
  objid[v->namelen + 4] = proto;
 | 
						|
  objid[v->namelen + 5] = policy;
 | 
						|
 | 
						|
  {
 | 
						|
    struct nexthop *nexthop;
 | 
						|
 | 
						|
    nexthop = (*rib)->nexthop;
 | 
						|
    if (nexthop)
 | 
						|
      {
 | 
						|
	pnt = (u_char *) &nexthop->gate.ipv4;
 | 
						|
	for (i = 0; i < 4; i++)
 | 
						|
	  objid[i + v->namelen + 6] = *pnt++;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
 | 
						|
	   int exact, size_t *val_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct route_node *np;
 | 
						|
  struct rib *rib;
 | 
						|
  static int result;
 | 
						|
  static int resarr[2];
 | 
						|
  static struct in_addr netmask;
 | 
						|
  struct nexthop *nexthop;
 | 
						|
 | 
						|
  if (smux_header_table(v, objid, objid_len, exact, val_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib);
 | 
						|
  if (!np)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  nexthop = rib->nexthop;
 | 
						|
  if (! nexthop)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  switch (v->magic)
 | 
						|
    {
 | 
						|
    case IPFORWARDDEST:
 | 
						|
      *val_len = 4;
 | 
						|
      return &np->p.u.prefix;
 | 
						|
      break;
 | 
						|
    case IPFORWARDMASK:
 | 
						|
      masklen2ip(np->p.prefixlen, &netmask);
 | 
						|
      *val_len = 4;
 | 
						|
      return (u_char *)&netmask;
 | 
						|
      break;
 | 
						|
    case IPFORWARDPOLICY:
 | 
						|
      result = 0;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDNEXTHOP:
 | 
						|
      *val_len = 4;
 | 
						|
      return (u_char *)&nexthop->gate.ipv4;
 | 
						|
      break;
 | 
						|
    case IPFORWARDIFINDEX:
 | 
						|
      *val_len = sizeof(int);
 | 
						|
      return (u_char *)&nexthop->ifindex;
 | 
						|
      break;
 | 
						|
    case IPFORWARDTYPE:
 | 
						|
      if (nexthop->type == NEXTHOP_TYPE_IFINDEX)
 | 
						|
        result = 3;
 | 
						|
      else
 | 
						|
        result = 4;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDPROTO:
 | 
						|
      result = proto_trans(rib->type);
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDAGE:
 | 
						|
      result = 0;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDINFO:
 | 
						|
      resarr[0] = 0;
 | 
						|
      resarr[1] = 0;
 | 
						|
      *val_len  = 2 * sizeof(int);
 | 
						|
      return (u_char *)resarr;
 | 
						|
      break;
 | 
						|
    case IPFORWARDNEXTHOPAS:
 | 
						|
      result = -1;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDMETRIC1:
 | 
						|
      result = 0;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDMETRIC2:
 | 
						|
      result = 0;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDMETRIC3:
 | 
						|
      result = 0;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDMETRIC4:
 | 
						|
      result = 0;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    case IPFORWARDMETRIC5:
 | 
						|
      result = 0;
 | 
						|
      *val_len  = sizeof(int);
 | 
						|
      return (u_char *)&result;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }  
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ipCidrTable (struct variable *v, oid objid[], size_t *objid_len,
 | 
						|
	     int exact, size_t *val_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  if (smux_header_table(v, objid, objid_len, exact, val_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  switch (v->magic)
 | 
						|
    {
 | 
						|
    case IPCIDRROUTEDEST:
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }  
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
zebra_snmp_init ()
 | 
						|
{
 | 
						|
  smux_init (zebrad.master);
 | 
						|
  REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid);
 | 
						|
}
 | 
						|
#endif /* HAVE_SNMP */
 |