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>