Annotation of embedaddon/quagga/zebra/if_proc.c, revision 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>