if_proc.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:6k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* Interface name and statistics get function using proc file system
  2.  * Copyright (C) 1999 Kunihiro Ishiguro
  3.  *
  4.  * This file is part of GNU Zebra.
  5.  *
  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
  9.  * later version.
  10.  *
  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.
  15.  *
  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
  19.  * 02111-1307, USA.  
  20.  */
  21. #include <zebra.h>
  22. #include "if.h"
  23. #include "prefix.h"
  24. #include "log.h"
  25. #include "zebra/ioctl.h"
  26. #include "zebra/connected.h"
  27. #include "zebra/interface.h"
  28. /* Proc filesystem one line buffer. */
  29. #define PROCBUFSIZ                  1024
  30. /* Path to device proc file system. */
  31. #ifndef _PATH_PROC_NET_DEV
  32. #define _PATH_PROC_NET_DEV        "/proc/net/dev"
  33. #endif /* _PATH_PROC_NET_DEV */
  34. /* Return statistics data pointer. */
  35. static char *
  36. interface_name_cut (char *buf, char **name)
  37. {
  38.   char *stat;
  39.   /* Skip white space.  Line will include header spaces. */
  40.   while (*buf == ' ')
  41.     buf++;
  42.   *name = buf;
  43.   /* Cut interface name. */
  44.   stat = strrchr (buf, ':');
  45.   *stat++ = '';
  46.   return stat;
  47. }
  48. /* Fetch each statistics field. */
  49. static int
  50. ifstat_dev_fields (int version, char *buf, struct interface *ifp)
  51. {
  52.   switch (version) 
  53.     {
  54.     case 3:
  55.       sscanf(buf,
  56.      "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
  57.      &ifp->stats.rx_bytes,
  58.      &ifp->stats.rx_packets,
  59.      &ifp->stats.rx_errors,
  60.      &ifp->stats.rx_dropped,
  61.      &ifp->stats.rx_fifo_errors,
  62.      &ifp->stats.rx_frame_errors,
  63.      &ifp->stats.rx_compressed,
  64.      &ifp->stats.rx_multicast,
  65.      &ifp->stats.tx_bytes,
  66.      &ifp->stats.tx_packets,
  67.      &ifp->stats.tx_errors,
  68.      &ifp->stats.tx_dropped,
  69.      &ifp->stats.tx_fifo_errors,
  70.      &ifp->stats.collisions,
  71.      &ifp->stats.tx_carrier_errors,
  72.      &ifp->stats.tx_compressed);
  73.       break;
  74.     case 2:
  75.       sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
  76.      &ifp->stats.rx_bytes,
  77.      &ifp->stats.rx_packets,
  78.      &ifp->stats.rx_errors,
  79.      &ifp->stats.rx_dropped,
  80.      &ifp->stats.rx_fifo_errors,
  81.      &ifp->stats.rx_frame_errors,
  82.      &ifp->stats.tx_bytes,
  83.      &ifp->stats.tx_packets,
  84.      &ifp->stats.tx_errors,
  85.      &ifp->stats.tx_dropped,
  86.      &ifp->stats.tx_fifo_errors,
  87.      &ifp->stats.collisions,
  88.      &ifp->stats.tx_carrier_errors);
  89.       ifp->stats.rx_multicast = 0;
  90.       break;
  91.     case 1:
  92.       sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
  93.      &ifp->stats.rx_packets,
  94.      &ifp->stats.rx_errors,
  95.      &ifp->stats.rx_dropped,
  96.      &ifp->stats.rx_fifo_errors,
  97.      &ifp->stats.rx_frame_errors,
  98.      &ifp->stats.tx_packets,
  99.      &ifp->stats.tx_errors,
  100.      &ifp->stats.tx_dropped,
  101.      &ifp->stats.tx_fifo_errors,
  102.      &ifp->stats.collisions,
  103.      &ifp->stats.tx_carrier_errors);
  104.       ifp->stats.rx_bytes = 0;
  105.       ifp->stats.tx_bytes = 0;
  106.       ifp->stats.rx_multicast = 0;
  107.       break;
  108.     }
  109.   return 0;
  110. }
  111. /* Update interface's statistics. */
  112. int
  113. ifstat_update_proc ()
  114. {
  115.   FILE *fp;
  116.   char buf[PROCBUFSIZ];
  117.   int version;
  118.   struct interface *ifp;
  119.   char *stat;
  120.   char *name;
  121.   /* Open /proc/net/dev. */
  122.   fp = fopen (_PATH_PROC_NET_DEV, "r");
  123.   if (fp == NULL)
  124.     {
  125.       zlog_warn ("Can't open proc file %s: %s",
  126.  _PATH_PROC_NET_DEV, strerror (errno));
  127.       return -1;
  128.     }
  129.   /* Drop header lines. */
  130.   fgets (buf, PROCBUFSIZ, fp);
  131.   fgets (buf, PROCBUFSIZ, fp);
  132.   /* To detect proc format veresion, parse second line. */
  133.   if (strstr (buf, "compressed"))
  134.     version = 3;
  135.   else if (strstr (buf, "bytes"))
  136.     version = 2;
  137.   else
  138.     version = 1;
  139.   /* Update each interface's statistics. */
  140.   while (fgets (buf, PROCBUFSIZ, fp) != NULL)
  141.     {
  142.       stat = interface_name_cut (buf, &name);
  143.       ifp = if_get_by_name (name);
  144.       ifstat_dev_fields (version, stat, ifp);
  145.     }
  146.   fclose(fp);
  147.   return 0;
  148. }
  149. /* Interface structure allocation by proc filesystem. */
  150. int
  151. interface_list_proc ()
  152. {
  153.   FILE *fp;
  154.   char buf[PROCBUFSIZ];
  155.   struct interface *ifp;
  156.   char *name;
  157.   /* Open /proc/net/dev. */
  158.   fp = fopen (_PATH_PROC_NET_DEV, "r");
  159.   if (fp == NULL)
  160.     {
  161.       zlog_warn ("Can't open proc file %s: %s",
  162.  _PATH_PROC_NET_DEV, strerror (errno));
  163.       return -1;
  164.     }
  165.   /* Drop header lines. */
  166.   fgets (buf, PROCBUFSIZ, fp);
  167.   fgets (buf, PROCBUFSIZ, fp);
  168.   /* Only allocate interface structure.  Other jobs will be done in
  169.      if_ioctl.c. */
  170.   while (fgets (buf, PROCBUFSIZ, fp) != NULL)
  171.     {
  172.       interface_name_cut (buf, &name);
  173.       ifp = if_get_by_name (name);
  174.       if_add_update (ifp);
  175.     }
  176.   fclose(fp);
  177.   return 0;
  178. }
  179. #if defined(HAVE_IPV6) && defined(HAVE_PROC_NET_IF_INET6)
  180. #ifndef _PATH_PROC_NET_IF_INET6
  181. #define _PATH_PROC_NET_IF_INET6          "/proc/net/if_inet6"
  182. #endif /* _PATH_PROC_NET_IF_INET6 */
  183. int
  184. ifaddr_proc_ipv6 ()
  185. {
  186.   FILE *fp;
  187.   char buf[PROCBUFSIZ];
  188.   int n;
  189.   char addr[33];
  190.   char ifname[20];
  191.   int ifindex, plen, scope, status;
  192.   struct interface *ifp;
  193.   struct prefix_ipv6 p;
  194.   /* Open proc file system. */
  195.   fp = fopen (_PATH_PROC_NET_IF_INET6, "r");
  196.   if (fp == NULL)
  197.     {
  198.       zlog_warn ("Can't open proc file %s: %s",
  199.  _PATH_PROC_NET_IF_INET6, strerror (errno));
  200.       return -1;
  201.     }
  202.   
  203.   /* Get interface's IPv6 address. */
  204.   while (fgets (buf, PROCBUFSIZ, fp) != NULL)
  205.     {
  206.       n = sscanf (buf, "%32s %02x %02x %02x %02x %20s", 
  207.   addr, &ifindex, &plen, &scope, &status, ifname);
  208.       if (n != 6)
  209. continue;
  210.       ifp = if_get_by_name (ifname);
  211.       /* Fetch interface's IPv6 address. */
  212.       str2in6_addr (addr, &p.prefix);
  213.       p.prefixlen = plen;
  214.       connected_add_ipv6 (ifp, &p.prefix, p.prefixlen, NULL);
  215.     }
  216.   return 0;
  217. }
  218. #endif /* HAVE_IPV6 && HAVE_PROC_NET_IF_INET6 */