File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / if_proc.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:11 2012 UTC (12 years, 4 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>