⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rip_snmp.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
字号:
/* RIP SNMP support * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org> * * 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.   */#include <zebra.h>#ifdef HAVE_SNMP#include <asn1.h>#include <snmp.h>#include <snmp_impl.h>#include "if.h"#include "log.h"#include "prefix.h"#include "command.h"#include "table.h"#include "smux.h"#include "ripd/ripd.h"/* RIPv2-MIB. */#define RIPV2MIB 1,3,6,1,2,1,23/* Zebra enterprise RIP MIB.  This variable is used for register   RIPv2-MIB to SNMP agent under SMUX protocol.  */#define RIPDOID 1,3,6,1,4,1,3317,1,2,3/* RIPv2-MIB rip2Globals values. */#define RIP2GLOBALROUTECHANGES  1#define RIP2GLOBALQUERIES       2/* RIPv2-MIB rip2IfStatEntry. */#define RIP2IFSTATENTRY         1/* RIPv2-MIB rip2IfStatTable. */#define RIP2IFSTATADDRESS       1#define RIP2IFSTATRCVBADPACKETS 2#define RIP2IFSTATRCVBADROUTES  3#define RIP2IFSTATSENTUPDATES   4#define RIP2IFSTATSTATUS        5/* RIPv2-MIB rip2IfConfTable. */#define RIP2IFCONFADDRESS       1#define RIP2IFCONFDOMAIN        2#define RIP2IFCONFAUTHTYPE      3#define RIP2IFCONFAUTHKEY       4#define RIP2IFCONFSEND          5#define RIP2IFCONFRECEIVE       6#define RIP2IFCONFDEFAULTMETRIC 7#define RIP2IFCONFSTATUS        8#define RIP2IFCONFSRCADDRESS    9/* RIPv2-MIB rip2PeerTable. */#define RIP2PEERADDRESS         1#define RIP2PEERDOMAIN          2#define RIP2PEERLASTUPDATE      3#define RIP2PEERVERSION         4#define RIP2PEERRCVBADPACKETS   5#define RIP2PEERRCVBADROUTES    6/* SNMP value hack. */#define COUNTER     ASN_COUNTER#define INTEGER     ASN_INTEGER#define TIMETICKS   ASN_TIMETICKS#define IPADDRESS   ASN_IPADDRESS#define STRING      ASN_OCTET_STR/* Define SNMP local variables. */SNMP_LOCAL_VARIABLES/* RIP-MIB instances. */oid rip_oid [] = { RIPV2MIB };oid ripd_oid [] = { RIPDOID };/* Interface cache table sorted by interface's address. */struct route_table *rip_ifaddr_table;/* Hook functions. */static u_char *rip2Globals ();static u_char *rip2IfStatEntry ();static u_char *rip2IfConfAddress ();static u_char *rip2PeerTable ();struct variable rip_variables[] = {  /* RIP Global Counters. */  {RIP2GLOBALROUTECHANGES,    COUNTER, RONLY, rip2Globals,   2, {1, 1}},  {RIP2GLOBALQUERIES,         COUNTER, RONLY, rip2Globals,   2, {1, 2}},  /* RIP Interface Tables. */  {RIP2IFSTATADDRESS,         IPADDRESS, RONLY, rip2IfStatEntry,   3, {2, 1, 1}},  {RIP2IFSTATRCVBADPACKETS,   COUNTER, RONLY, rip2IfStatEntry,   3, {2, 1, 2}},  {RIP2IFSTATRCVBADROUTES,    COUNTER, RONLY, rip2IfStatEntry,   3, {2, 1, 3}},  {RIP2IFSTATSENTUPDATES,     COUNTER, RONLY, rip2IfStatEntry,   3, {2, 1, 4}},  {RIP2IFSTATSTATUS,          COUNTER, RWRITE, rip2IfStatEntry,   3, {2, 1, 5}},  {RIP2IFCONFADDRESS,         IPADDRESS, RONLY, rip2IfConfAddress,   /* RIP Interface Configuration Table. */   3, {3, 1, 1}},  {RIP2IFCONFDOMAIN,          STRING, RONLY, rip2IfConfAddress,   3, {3, 1, 2}},  {RIP2IFCONFAUTHTYPE,        COUNTER, RONLY, rip2IfConfAddress,   3, {3, 1, 3}},  {RIP2IFCONFAUTHKEY,         STRING, RONLY, rip2IfConfAddress,   3, {3, 1, 4}},  {RIP2IFCONFSEND,            COUNTER, RONLY, rip2IfConfAddress,   3, {3, 1, 5}},  {RIP2IFCONFRECEIVE,         COUNTER, RONLY, rip2IfConfAddress,   3, {3, 1, 6}},  {RIP2IFCONFDEFAULTMETRIC,   COUNTER, RONLY, rip2IfConfAddress,   3, {3, 1, 7}},  {RIP2IFCONFSTATUS,          COUNTER, RONLY, rip2IfConfAddress,   3, {3, 1, 8}},  {RIP2IFCONFSRCADDRESS,      IPADDRESS, RONLY, rip2IfConfAddress,   3, {3, 1, 9}},  {RIP2PEERADDRESS,           IPADDRESS, RONLY, rip2PeerTable,   /* RIP Peer Table. */   3, {4, 1, 1}},  {RIP2PEERDOMAIN,            INTEGER, RONLY, rip2PeerTable,   3, {4, 1, 2}},  {RIP2PEERLASTUPDATE,        TIMETICKS, RONLY, rip2PeerTable,   3, {4, 1, 3}},  {RIP2PEERVERSION,           INTEGER, RONLY, rip2PeerTable,   3, {4, 1, 4}},  {RIP2PEERRCVBADPACKETS,     COUNTER, RONLY, rip2PeerTable,   3, {4, 1, 5}},  {RIP2PEERRCVBADROUTES,      COUNTER, RONLY, rip2PeerTable,   3, {4, 1, 6}}};static u_char *rip2Globals (struct variable *v, oid name[], size_t *length,	     int exact, size_t *var_len, WriteMethod **write_method){  if (smux_header_generic(v, name, length, exact, var_len, write_method)      == MATCH_FAILED)    return NULL;  /* Retrun global counter. */  switch (v->magic)    {    case RIP2GLOBALROUTECHANGES:      return SNMP_INTEGER (rip_global_route_changes);      break;    case RIP2GLOBALQUERIES:      return SNMP_INTEGER (rip_global_queries);      break;    default:      return NULL;      break;    }  return NULL;}voidrip_ifaddr_add (struct interface *ifp, struct connected *ifc){  struct prefix *p;  struct route_node *rn;  p = ifc->address;  if (p->family != AF_INET)    return;  rn = route_node_get (rip_ifaddr_table, p);  rn->info = ifp;}voidrip_ifaddr_delete (struct interface *ifp, struct connected *ifc){  struct prefix *p;  struct route_node *rn;  struct interface *i;  p = ifc->address;  if (p->family != AF_INET)    return;  rn = route_node_lookup (rip_ifaddr_table, p);  if (! rn)    return;  i = rn->info;  if (rn && !strncmp(i->name,ifp->name,INTERFACE_NAMSIZ))    {      rn->info = NULL;      route_unlock_node (rn);      route_unlock_node (rn);    }}struct interface *rip_ifaddr_lookup_next (struct in_addr *addr){  struct prefix_ipv4 p;  struct route_node *rn;  struct interface *ifp;  p.family = AF_INET;  p.prefixlen = IPV4_MAX_BITLEN;  p.prefix = *addr;  rn = route_node_get (rip_ifaddr_table, (struct prefix *) &p);  for (rn = route_next (rn); rn; rn = route_next (rn))    if (rn->info)      break;  if (rn && rn->info)    {      ifp = rn->info;      *addr = rn->p.u.prefix4;      route_unlock_node (rn);      return ifp;    }  return NULL;}static struct interface *rip2IfLookup (struct variable *v, oid name[], size_t *length, 	      struct in_addr *addr, int exact){  int len;  struct interface *ifp;    if (exact)    {      /* Check the length. */      if (*length - v->namelen != sizeof (struct in_addr))	return NULL;      oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);      return if_lookup_exact_address (*addr);    }  else    {      len = *length - v->namelen;      if (len > 4) len = 4;      oid2in_addr (name + v->namelen, len, addr);      ifp = rip_ifaddr_lookup_next (addr);      if (ifp == NULL)	return NULL;      oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));      *length = v->namelen + sizeof (struct in_addr);      return ifp;    }  return NULL;}static struct rip_peer *rip2PeerLookup (struct variable *v, oid name[], size_t *length, 		struct in_addr *addr, int exact){  int len;  struct rip_peer *peer;    if (exact)    {      /* Check the length. */      if (*length - v->namelen != sizeof (struct in_addr) + 1)	return NULL;      oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);      peer = rip_peer_lookup (addr);      if (peer->domain == name[v->namelen + sizeof (struct in_addr)])	return peer;      return NULL;    }  else    {      len = *length - v->namelen;      if (len > 4) len = 4;      oid2in_addr (name + v->namelen, len, addr);      len = *length - v->namelen;      peer = rip_peer_lookup (addr);      if (peer)	{	  if ((len < sizeof (struct in_addr) + 1) ||	      (peer->domain > name[v->namelen + sizeof (struct in_addr)]))	    {	      oid_copy_addr (name + v->namelen, &peer->addr,			     sizeof (struct in_addr));	      name[v->namelen + sizeof (struct in_addr)] = peer->domain;	      *length = sizeof (struct in_addr) + v->namelen + 1;	      return peer;	    }        }       peer = rip_peer_lookup_next (addr);      if (! peer)	return NULL;      oid_copy_addr (name + v->namelen, &peer->addr,		     sizeof (struct in_addr));      name[v->namelen + sizeof (struct in_addr)] = peer->domain;      *length = sizeof (struct in_addr) + v->namelen + 1;      return peer;    }  return NULL;}static u_char *rip2IfStatEntry (struct variable *v, oid name[], size_t *length,	         int exact, size_t *var_len, WriteMethod **write_method){  struct interface *ifp;  struct rip_interface *ri;  static struct in_addr addr;  static long valid = SNMP_VALID;  memset (&addr, 0, sizeof (struct in_addr));    /* Lookup interface. */  ifp = rip2IfLookup (v, name, length, &addr, exact);  if (! ifp)    return NULL;  /* Fetch rip_interface information. */  ri = ifp->info;  switch (v->magic)    {    case RIP2IFSTATADDRESS:      return SNMP_IPADDRESS (addr);      break;    case RIP2IFSTATRCVBADPACKETS:      *var_len = sizeof (long);      return (u_char *) &ri->recv_badpackets;    case RIP2IFSTATRCVBADROUTES:      *var_len = sizeof (long);      return (u_char *) &ri->recv_badroutes;    case RIP2IFSTATSENTUPDATES:      *var_len = sizeof (long);      return (u_char *) &ri->sent_updates;    case RIP2IFSTATSTATUS:      *var_len = sizeof (long);      v->type = ASN_INTEGER;      return (u_char *) &valid;    default:      return NULL;    }  return NULL;}static longrip2IfConfSend (struct rip_interface *ri){#define doNotSend       1#define ripVersion1     2#define rip1Compatible  3#define ripVersion2     4#define ripV1Demand     5#define ripV2Demand     6  if (! ri->running)    return doNotSend;      if (ri->ri_send & RIPv2)    return ripVersion2;  else if (ri->ri_send & RIPv1)    return ripVersion1;  else if (rip)    {      if (rip->version == RIPv2)	return ripVersion2;      else if (rip->version == RIPv1)	return ripVersion1;    }  return doNotSend;}static longrip2IfConfReceive (struct rip_interface *ri){#define rip1            1#define rip2            2#define rip1OrRip2      3#define doNotReceive    4  if (! ri->running)    return doNotReceive;  if (ri->ri_receive == RI_RIP_VERSION_1_AND_2)    return rip1OrRip2;  else if (ri->ri_receive & RIPv2)    return ripVersion2;  else if (ri->ri_receive & RIPv1)    return ripVersion1;  else    return doNotReceive;}static u_char *rip2IfConfAddress (struct variable *v, oid name[], size_t *length,	           int exact, size_t *val_len, WriteMethod **write_method){  static struct in_addr addr;  static long valid = SNMP_INVALID;  static long domain = 0;  static long config = 0;  static u_int auth = 0;  struct interface *ifp;  struct rip_interface *ri;  memset (&addr, 0, sizeof (struct in_addr));    /* Lookup interface. */  ifp = rip2IfLookup (v, name, length, &addr, exact);  if (! ifp)    return NULL;  /* Fetch rip_interface information. */  ri = ifp->info;  switch (v->magic)    {    case RIP2IFCONFADDRESS:      *val_len = sizeof (struct in_addr);      return (u_char *) &addr;    case RIP2IFCONFDOMAIN:      *val_len = 2;      return (u_char *) &domain;    case RIP2IFCONFAUTHTYPE:      auth = ri->auth_type;      *val_len = sizeof (long);      v->type = ASN_INTEGER;      return (u_char *)&auth;    case RIP2IFCONFAUTHKEY:      *val_len = 0;      return (u_char *) &domain;    case RIP2IFCONFSEND:      config = rip2IfConfSend (ri);      *val_len = sizeof (long);      v->type = ASN_INTEGER;      return (u_char *) &config;    case RIP2IFCONFRECEIVE:      config = rip2IfConfReceive (ri);      *val_len = sizeof (long);      v->type = ASN_INTEGER;      return (u_char *) &config;    case RIP2IFCONFDEFAULTMETRIC:      *val_len = sizeof (long);      v->type = ASN_INTEGER;      return (u_char *) &ifp->metric;    case RIP2IFCONFSTATUS:      *val_len = sizeof (long);      v->type = ASN_INTEGER;      return (u_char *) &valid;    case RIP2IFCONFSRCADDRESS:      *val_len = sizeof (struct in_addr);      return (u_char *) &addr;    default:      return NULL;    }  return NULL;}static u_char *rip2PeerTable (struct variable *v, oid name[], size_t *length,	       int exact, size_t *val_len, WriteMethod **write_method){  static struct in_addr addr;  static int version;  /* static time_t uptime; */  struct rip_peer *peer;  memset (&addr, 0, sizeof (struct in_addr));    /* Lookup interface. */  peer = rip2PeerLookup (v, name, length, &addr, exact);  if (! peer)    return NULL;  switch (v->magic)    {    case RIP2PEERADDRESS:      *val_len = sizeof (struct in_addr);      return (u_char *) &peer->addr;    case RIP2PEERDOMAIN:      *val_len = sizeof (int);      return (u_char *) &peer->domain;    case RIP2PEERLASTUPDATE:#if 0       /* We don't know the SNMP agent startup time. We have two choices here:       * - assume ripd startup time equals SNMP agent startup time       * - don't support this variable, at all       * Currently, we do the latter...       */      *val_len = sizeof (time_t);      uptime = peer->uptime; /* now - snmp_agent_startup - peer->uptime */      return (u_char *) &uptime;#else      return (u_char *) NULL;#endif    case RIP2PEERVERSION:      *val_len = sizeof (int);      version = peer->version;      return (u_char *) &version;    case RIP2PEERRCVBADPACKETS:      *val_len = sizeof (int);      return (u_char *) &peer->recv_badpackets;    case RIP2PEERRCVBADROUTES:      *val_len = sizeof (int);      return (u_char *) &peer->recv_badroutes;    default:      return NULL;    }  return NULL;}/* Register RIPv2-MIB. */voidrip_snmp_init (){  rip_ifaddr_table = route_table_init ();  smux_init (ripd_oid, sizeof (ripd_oid) / sizeof (oid));  REGISTER_MIB("mibII/rip", rip_variables, variable, rip_oid);  smux_start ();}#endif /* HAVE_SNMP */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -