1 /* Interface name and statistics get function using proc file system
2 * Copyright (C) 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
28 #include "zebra/ioctl.h"
29 #include "zebra/connected.h"
30 #include "zebra/interface.h"
32 /* Proc filesystem one line buffer. */
33 #define PROCBUFSIZ 1024
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 */
40 /* Return statistics data pointer. */
42 interface_name_cut (char *buf
, char **name
)
46 /* Skip white space. Line will include header spaces. */
51 /* Cut interface name. */
52 stat
= strrchr (buf
, ':');
58 /* Fetch each statistics field. */
60 ifstat_dev_fields (int version
, char *buf
, struct interface
*ifp
)
66 "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
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
,
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
);
86 sscanf(buf
, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
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
,
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;
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
,
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;
125 /* Update interface's statistics. */
127 ifstat_update_proc (void)
130 char buf
[PROCBUFSIZ
];
132 struct interface
*ifp
;
136 /* Open /proc/net/dev. */
137 fp
= fopen (_PATH_PROC_NET_DEV
, "r");
140 zlog_warn ("Can't open proc file %s: %s",
141 _PATH_PROC_NET_DEV
, safe_strerror (errno
));
145 /* Drop header lines. */
146 fgets (buf
, PROCBUFSIZ
, fp
);
147 fgets (buf
, PROCBUFSIZ
, fp
);
149 /* To detect proc format veresion, parse second line. */
150 if (strstr (buf
, "compressed"))
152 else if (strstr (buf
, "bytes"))
157 /* Update each interface's statistics. */
158 while (fgets (buf
, PROCBUFSIZ
, fp
) != NULL
)
160 stat
= interface_name_cut (buf
, &name
);
161 ifp
= if_get_by_name (name
);
162 ifstat_dev_fields (version
, stat
, ifp
);
168 /* Interface structure allocation by proc filesystem. */
170 interface_list_proc ()
173 char buf
[PROCBUFSIZ
];
174 struct interface
*ifp
;
177 /* Open /proc/net/dev. */
178 fp
= fopen (_PATH_PROC_NET_DEV
, "r");
181 zlog_warn ("Can't open proc file %s: %s",
182 _PATH_PROC_NET_DEV
, safe_strerror (errno
));
186 /* Drop header lines. */
187 fgets (buf
, PROCBUFSIZ
, fp
);
188 fgets (buf
, PROCBUFSIZ
, fp
);
190 /* Only allocate interface structure. Other jobs will be done in
192 while (fgets (buf
, PROCBUFSIZ
, fp
) != NULL
)
194 interface_name_cut (buf
, &name
);
195 ifp
= if_get_by_name (name
);
202 #if defined(HAVE_IPV6) && defined(HAVE_PROC_NET_IF_INET6)
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 */
212 char buf
[PROCBUFSIZ
];
216 int ifindex
, plen
, scope
, status
;
217 struct interface
*ifp
;
218 struct prefix_ipv6 p
;
220 /* Open proc file system. */
221 fp
= fopen (_PATH_PROC_NET_IF_INET6
, "r");
224 zlog_warn ("Can't open proc file %s: %s",
225 _PATH_PROC_NET_IF_INET6
, safe_strerror (errno
));
229 /* Get interface's IPv6 address. */
230 while (fgets (buf
, PROCBUFSIZ
, fp
) != NULL
)
232 n
= sscanf (buf
, "%32s %02x %02x %02x %02x %20s",
233 addr
, &ifindex
, &plen
, &scope
, &status
, ifname
);
237 ifp
= if_get_by_name (ifname
);
239 /* Fetch interface's IPv6 address. */
240 str2in6_addr (addr
, &p
.prefix
);
243 connected_add_ipv6 (ifp
, 0, &p
.prefix
, p
.prefixlen
, NULL
, ifname
);
248 #endif /* HAVE_IPV6 && HAVE_PROC_NET_IF_INET6 */