arp_linux.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:5k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Interface MIB architecture support
  3.  *
  4.  * $Id: arp_linux.c,v 1.3 2004/09/02 05:12:11 rstory Exp $
  5.  */
  6. #include <net-snmp/net-snmp-config.h>
  7. #include <net-snmp/net-snmp-includes.h>
  8. #include <net-snmp/agent/net-snmp-agent-includes.h>
  9. #include <net-snmp/data_access/arp.h>
  10. #include <net-snmp/data_access/interface.h>
  11. #include <sys/socket.h>
  12. #include <netinet/in.h>
  13. #include <net/if_arp.h>
  14. #include <arpa/inet.h>
  15. int _load_v4(netsnmp_container *container, int idx_offset);
  16. /**
  17.  */
  18. int
  19. netsnmp_access_arp_container_arch_load(netsnmp_container *container)
  20. {
  21.     int rc = 0, idx_offset = 0;
  22.     rc = _load_v4(container, idx_offset);
  23.     if(rc < 0) {
  24.         u_int flags = NETSNMP_ACCESS_ARP_FREE_KEEP_CONTAINER;
  25.         netsnmp_access_arp_container_free(container, flags);
  26.         return rc;
  27.     }
  28. #if defined (INET6) && 0 /* xx-rks: arp for v6? */
  29.     idx_offset = rc;
  30.     rc = _load_v6(container, idx_offset);
  31.     if(rc < 0) {
  32.         u_int flags = NETSNMP_ACCESS_ARP_FREE_KEEP_CONTAINER;
  33.         netsnmp_access_arp_container_free(container, flags);
  34.     }
  35. #endif
  36.     /*
  37.      * return no errors (0) if we found any interfaces
  38.      */
  39.     if(rc > 0)
  40.         rc = 0;
  41.     return rc;
  42. }
  43. /**
  44.  */
  45. int
  46. _load_v4(netsnmp_container *container, int idx_offset)
  47. {
  48.     FILE           *in;
  49.     char            line[128];
  50.     int             rc = 0;
  51.     netsnmp_arp_entry *entry;
  52.     
  53.     netsnmp_assert(NULL != container);
  54. #define PROCFILE "/proc/net/arp"
  55.     if (!(in = fopen(PROCFILE, "r"))) {
  56.         snmp_log(LOG_ERR,"could not open " PROCFILE "n");
  57.         return -2;
  58.     }
  59.     /*
  60.      * Get rid of the header line 
  61.      */
  62.     fgets(line, sizeof(line), in);
  63.     /*
  64.      * IP address | HW | Flag | HW address      | Mask | Device
  65.      * 192.168.1.4  0x1  0x2   00:40:63:CC:1C:8C  *      eth0
  66.      */
  67.     while (fgets(line, sizeof(line), in)) {
  68.         
  69.         int             za, zb, zc, zd, ze, zf, zg, zh, zi, zj;
  70.         int             tmp_flags;
  71.         char            ifname[21];
  72.         rc = sscanf(line,
  73.                     "%d.%d.%d.%d 0x%*x 0x%x %x:%x:%x:%x:%x:%x %*[^ ] %20sn",
  74.                     &za, &zb, &zc, &zd, &tmp_flags, &ze, &zf, &zg, &zh, &zi,
  75.                     &zj, ifname);
  76.         if (12 != rc) {            
  77.             snmp_log(LOG_ERR, PROCFILE " data format error (%d!=12)n", rc);
  78.             snmp_log(LOG_ERR, " line ==|%s|n", line);
  79.             continue;
  80.         }
  81.         DEBUGMSGTL(("access:arp:container",
  82.                     "ip addr %d.%d.%d.%d, flags 0x%X, hw addr "
  83.                     "%x:%x:%x:%x:%x:%x, name %sn",
  84.                     za,zb,zc,zd, tmp_flags, ze,zf,zg,zh,zi,zj, ifname ));
  85.         /*
  86.          * Invalidated entries have their flag set to 0.
  87.          * * We want to ignore them 
  88.          */
  89.         if (tmp_flags == 0) {
  90.             continue;
  91.         }
  92.         /*
  93.          */
  94.         entry = netsnmp_access_arp_entry_create();
  95.         if(NULL == entry) {
  96.             rc = -3;
  97.             break;
  98.         }
  99.         /*
  100.          * look up ifIndex
  101.          */
  102.         entry->if_index = netsnmp_access_interface_index_find(ifname);
  103.         if(0 == entry->if_index) {
  104.             snmp_log(LOG_ERR,"couldn't find ifIndex for '%s', skippingn",
  105.                      ifname);
  106.             netsnmp_access_arp_entry_free(entry);
  107.             continue;
  108.         }
  109.         /*
  110.          * now that we've passed all the possible 'continue', assign
  111.          * index offset.
  112.          */
  113.         entry->ns_arp_index = ++idx_offset;
  114.         /*
  115.          * parse ip addr
  116.          */
  117.         entry->arp_ipaddress[0] = za;
  118.         entry->arp_ipaddress[1] = zb;
  119.         entry->arp_ipaddress[2] = zc;
  120.         entry->arp_ipaddress[3] = zd;
  121.         entry->arp_ipaddress_len = 4;
  122.         /*
  123.          * parse hw addr
  124.          */
  125.         entry->arp_physaddress[0] = ze;
  126.         entry->arp_physaddress[1] = zf;
  127.         entry->arp_physaddress[2] = zg;
  128.         entry->arp_physaddress[3] = zh;
  129.         entry->arp_physaddress[4] = zi;
  130.         entry->arp_physaddress[5] = zj;
  131.         entry->arp_physaddress_len = 6;
  132.         /*
  133.          * what can we do with hw? from arp manpage:
  134.          default  value  of  this  parameter is ether (i.e. hardware code
  135.          0x01 for  IEEE  802.3  10Mbps  Ethernet).   Other  values  might
  136.          include  network  technologies  such as ARCnet (arcnet) , PROnet
  137.          (pronet) , AX.25 (ax25) and NET/ROM (netrom).
  138.         */
  139.         /*
  140.          * parse mask
  141.          */
  142.         /* xxx-rks: what is mask? how to interpret '*'? */
  143.         /*
  144.          * process type
  145.          */
  146.         if(tmp_flags & ATF_PERM)
  147.             entry->arp_type = INETNETTOMEDIATYPE_STATIC;
  148.         else
  149.             entry->arp_type = INETNETTOMEDIATYPE_DYNAMIC;
  150.         /*
  151.          * process status
  152.          */
  153.         /** entry->arp_status = ?; */
  154.         /*
  155.          * add entry to container
  156.          */
  157.         CONTAINER_INSERT(container, entry);
  158.     }
  159.     if( rc < 0 )
  160.         return rc;
  161.     return idx_offset;
  162. }