Annotation of embedaddon/quagga/zebra/if_proc.c, revision 1.1.1.1

1.1       misho       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>