2 * Copyright (c) 1983, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 /* "@(#)if.c 8.2 (Berkeley) 2/21/94" */
38 #include <devices/timer.h>
40 #include <proto/exec.h>
42 #include <sys/types.h>
43 #include <sys/protosw.h>
44 #include <sys/socket.h>
47 #include <net/if_dl.h>
48 #include <netinet/in.h>
49 #include <netinet/in_var.h>
52 #include <netns/ns_if.h>
55 #include <netiso/iso.h>
56 #include <netiso/iso_var.h>
58 #include <arpa/inet.h>
70 static void sidewaysintpr
__P((u_int
, u_long
));
71 static void catchalarm
__P((int));
74 * Print a description of the network interfaces.
77 intpr(interval
, ifnetaddr
)
89 struct iso_ifaddr iso
;
97 printf("ifnet: symbol not defined\n");
101 sidewaysintpr((unsigned)interval
, ifnetaddr
);
104 if (kread(ifnetaddr
, (char *)&ifnetaddr
, sizeof ifnetaddr
))
106 printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s",
107 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
109 printf(" %10.10s","Ibytes");
110 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
112 printf(" %10.10s","Obytes");
113 printf(" %5s", "Coll");
115 printf(" %s", "Time");
117 printf(" %s", "Drop");
120 while (ifnetaddr
|| ifaddraddr
) {
121 struct sockaddr_in
*sin
;
125 if (ifaddraddr
== 0) {
126 if (kread(ifnetaddr
, (char *)&ifnet
, sizeof ifnet
) ||
127 kread((u_long
)ifnet
.if_name
, name
, 16))
130 ifnetaddr
= (u_long
)ifnet
.if_next
;
131 if (interface
!= 0 && (strcmp(name
, interface
) != 0 ||
132 unit
!= ifnet
.if_unit
))
134 cp
= index(name
, '\0');
135 cp
+= sprintf(cp
, "%d", ifnet
.if_unit
);
136 if ((ifnet
.if_flags
&IFF_UP
) == 0)
139 ifaddraddr
= (u_long
)ifnet
.if_addrlist
;
141 printf("%-5.5s %-5d ", name
, ifnet
.if_mtu
);
142 if (ifaddraddr
== 0) {
143 printf("%-11.11s ", "none");
144 printf("%-15.15s ", "none");
146 if (kread(ifaddraddr
, (char *)&ifaddr
, sizeof ifaddr
)) {
150 #define CP(x) ((char *)(x))
151 cp
= (CP(ifaddr
.ifa
.ifa_addr
) - CP(ifaddraddr
)) +
152 CP(&ifaddr
); sa
= (struct sockaddr
*)cp
;
153 switch (sa
->sa_family
) {
155 printf("%-11.11s ", "none");
156 printf("%-15.15s ", "none");
159 sin
= (struct sockaddr_in
*)sa
;
161 /* can't use inet_makeaddr because kernel
162 * keeps nets unshifted.
164 in
= inet_makeaddr(ifaddr
.in
.ia_subnet
,
166 printf("%-11.11s ", netname(in
.s_addr
,
167 ifaddr
.in
.ia_subnetmask
));
170 netname(htonl(ifaddr
.in
.ia_subnet
),
171 ifaddr
.in
.ia_subnetmask
));
174 routename(sin
->sin_addr
.s_addr
));
179 struct sockaddr_ns
*sns
=
180 (struct sockaddr_ns
*)sa
;
184 *(union ns_net
*) &net
= sns
->sns_addr
.x_net
;
185 sprintf(netnum
, "%lxH", ntohl(net
));
187 printf("ns:%-8s ", netnum
);
189 ns_phost((struct sockaddr
*)sns
));
195 struct sockaddr_dl
*sdl
=
196 (struct sockaddr_dl
*)sa
;
197 cp
= (char *)LLADDR(sdl
);
200 m
= printf("<Link>");
203 m
= printf("(%d)", sa
->sa_family
);
204 for (cp
= sa
->sa_len
+ (char *)sa
;
205 --cp
> sa
->sa_data
&& (*cp
== 0);) {}
206 n
= cp
- sa
->sa_data
+ 1;
210 m
+= printf("%02x%c", *cp
++ & 0xff,
217 ifaddraddr
= (u_long
)ifaddr
.ifa
.ifa_next
;
220 ifnet
.if_ipackets
, ifnet
.if_ierrors
);
222 printf("%10d ", ifnet
.if_ibytes
);
224 ifnet
.if_opackets
, ifnet
.if_oerrors
);
226 printf("%10d ", ifnet
.if_obytes
);
227 printf("%5d", ifnet
.if_collisions
);
229 printf(" %3d", ifnet
.if_timer
);
231 printf(" %3d", ifnet
.if_snd
.ifq_drops
);
238 char ift_name
[16]; /* interface name */
239 u_int ift_ip
; /* input packets */
240 u_int ift_ie
; /* input errors */
241 u_int ift_op
; /* output packets */
242 u_int ift_oe
; /* output errors */
243 u_int ift_co
; /* collisions */
244 u_int ift_dr
; /* drops */
245 u_int ift_ib
; /* input bytes */
246 u_int ift_ob
; /* output bytes */
249 u_char signalled
; /* set if alarm goes off "early" */
251 struct MsgPort
*timerport
;
252 struct timerequest
*timerio
;
261 DeleteIORequest(timerio
);
263 DeleteMsgPort(timerport
);
268 * Print a running summary of interface statistics.
269 * Repeat display every interval seconds, showing statistics
270 * collected over that interval. Assumes that interval is non-zero.
271 * First line printed at top of screen is always cumulative.
274 sidewaysintpr(interval
, off
)
280 register struct iftot
*ip
, *total
;
282 struct iftot
*lastif
, *sum
, *interesting
;
285 if (kread(off
, (char *)&firstifnet
, sizeof (u_long
)))
288 sum
= iftot
+ MAXIF
- 1;
291 for (off
= firstifnet
, ip
= iftot
; off
;) {
294 if (kread(off
, (char *)&ifnet
, sizeof ifnet
))
296 ip
->ift_name
[0] = '(';
297 if (kread((u_long
)ifnet
.if_name
, ip
->ift_name
+ 1, 15))
299 if (interface
&& strcmp(ip
->ift_name
+ 1, interface
) == 0 &&
300 unit
== ifnet
.if_unit
)
302 ip
->ift_name
[15] = '\0';
303 cp
= index(ip
->ift_name
, '\0');
304 sprintf(cp
, "%d)", ifnet
.if_unit
);
306 if (ip
>= iftot
+ MAXIF
- 2)
308 off
= (u_long
) ifnet
.if_next
;
312 timerport
= CreateMsgPort();
314 fprintf(stderr
, "Unable to create timer message port\n");
317 sigmask
= (1 << timerport
->mp_SigBit
) | SIGBREAKF_CTRL_C
;
318 timerio
= CreateIORequest(timerport
, sizeof(struct timerequest
));
320 fprintf(stderr
, "Unable to create timer I/O request\n");
323 if (OpenDevice("timer.device", UNIT_VBLANK
, (struct IORequest
*)timerio
, 0)) {
324 fprintf(stderr
, "Unable to open timer.device\n");
327 timerio
->tr_node
.io_Command
= TR_ADDREQUEST
;
328 timerio
->tr_time
.tv_secs
= interval
;
329 timerio
->tr_time
.tv_micro
= 0;
330 SendIO ((struct IORequest
*)timerio
);
332 printf(" input %s%-6.6s %soutput ", bflag
? " " : "",
333 interesting
->ift_name
, bflag
? " " : "");
334 if (lastif
- iftot
> 0) {
337 printf(" input %s(Total) %soutput", bflag
? " " : "",
340 for (ip
= iftot
; ip
< iftot
+ MAXIF
; ip
++) {
351 printf("%8.8s %5.5s ", "packets", "errs");
353 printf("%10.10s ","bytes");
354 printf("%8.8s %5.5s ", "packets", "errs");
356 printf("%10.10s ","bytes");
357 printf("%5.5s ", "colls");
359 printf("%5.5s ", "drops");
360 if (lastif
- iftot
> 0) {
361 printf(" %8.8s %5.5s", "packets", "errs");
363 printf(" %10.10s", "bytes");
364 printf(" %8.8s %5.5s", "packets", "errs");
366 printf(" %10.10s", "bytes");
367 printf(" %5.5s", "colls");
369 printf(" %5.5s", "drops");
383 for (off
= firstifnet
, ip
= iftot
; off
&& ip
< lastif
; ip
++) {
384 if (kread(off
, (char *)&ifnet
, sizeof ifnet
)) {
388 if (ip
== interesting
) {
390 ifnet
.if_ipackets
- ip
->ift_ip
,
391 ifnet
.if_ierrors
- ip
->ift_ie
);
393 printf("%10d ", ifnet
.if_ibytes
- ip
->ift_ib
);
395 ifnet
.if_opackets
- ip
->ift_op
,
396 ifnet
.if_oerrors
- ip
->ift_oe
);
398 printf("%10d ", ifnet
.if_obytes
- ip
->ift_ob
);
399 printf("%5d", ifnet
.if_collisions
- ip
->ift_co
);
402 ifnet
.if_snd
.ifq_drops
- ip
->ift_dr
);
404 ip
->ift_ip
= ifnet
.if_ipackets
;
405 ip
->ift_ie
= ifnet
.if_ierrors
;
406 ip
->ift_op
= ifnet
.if_opackets
;
407 ip
->ift_oe
= ifnet
.if_oerrors
;
408 ip
->ift_co
= ifnet
.if_collisions
;
409 ip
->ift_dr
= ifnet
.if_snd
.ifq_drops
;
410 ip
->ift_ib
= ifnet
.if_ibytes
;
411 ip
->ift_ob
= ifnet
.if_obytes
;
412 sum
->ift_ip
+= ip
->ift_ip
;
413 sum
->ift_ie
+= ip
->ift_ie
;
414 sum
->ift_op
+= ip
->ift_op
;
415 sum
->ift_oe
+= ip
->ift_oe
;
416 sum
->ift_co
+= ip
->ift_co
;
417 sum
->ift_dr
+= ip
->ift_dr
;
418 sum
->ift_ib
+= ip
->ift_ib
;
419 sum
->ift_ob
+= ip
->ift_ob
;
420 off
= (u_long
) ifnet
.if_next
;
422 if (lastif
- iftot
> 0) {
424 sum
->ift_ip
- total
->ift_ip
,
425 sum
->ift_ie
- total
->ift_ie
);
427 printf(" %10d", sum
->ift_ib
- total
->ift_ib
);
429 sum
->ift_op
- total
->ift_op
,
430 sum
->ift_oe
- total
->ift_oe
);
432 printf(" %10d", sum
->ift_ob
- total
->ift_ob
);
433 printf(" %5d", sum
->ift_co
- total
->ift_co
);
435 printf(" %5d", sum
->ift_dr
- total
->ift_dr
);
441 if (Wait (sigmask
) & SIGBREAKF_CTRL_C
) {
442 AbortIO ((struct IORequest
*)timerio
);
443 WaitIO ((struct IORequest
*)timerio
);
444 CloseDevice ((struct IORequest
*)timerio
);
447 WaitIO ((struct IORequest
*)timerio
);
448 timerio
->tr_node
.io_Command
= TR_ADDREQUEST
;
449 timerio
->tr_time
.tv_secs
= interval
;
450 timerio
->tr_time
.tv_micro
= 0;
451 SendIO ((struct IORequest
*)timerio
);
459 * Called if an interval expires before sidewaysintpr has completed a loop.
460 * Sets a flag to not wait for the alarm.