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>