121986Sdist /*
262144Sbostic * Copyright (c) 1983, 1988, 1993
362144Sbostic * The Regents of the University of California. All rights reserved.
433451Skarels *
542748Sbostic * %sccs.include.redist.c%
621986Sdist */
721986Sdist
87905Ssam #ifndef lint
9*69046Sbostic static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 04/28/95";
1034902Sbostic #endif /* not lint */
117905Ssam
127905Ssam #include <sys/types.h>
1353698Ssklower #include <sys/protosw.h>
147905Ssam #include <sys/socket.h>
1566219Sbostic
167905Ssam #include <net/if.h>
1740839Ssklower #include <net/if_dl.h>
189203Ssam #include <netinet/in.h>
1921906Skarels #include <netinet/in_var.h>
2023499Ssklower #include <netns/ns.h>
2139214Smarc #include <netns/ns_if.h>
2243251Ssklower #include <netiso/iso.h>
2343251Ssklower #include <netiso/iso_var.h>
2466219Sbostic #include <arpa/inet.h>
259203Ssam
2666219Sbostic #include <signal.h>
278331Ssam #include <stdio.h>
2853698Ssklower #include <string.h>
2954721Ssklower #include <unistd.h>
3066219Sbostic
3153698Ssklower #include "netstat.h"
327905Ssam
3329746Skupfer #define YES 1
3429746Skupfer #define NO 0
3529746Skupfer
3666219Sbostic static void sidewaysintpr __P((u_int, u_long));
3766219Sbostic static void catchalarm __P((int));
387905Ssam
397905Ssam /*
407905Ssam * Print a description of the network interfaces.
417905Ssam */
4253698Ssklower void
intpr(interval,ifnetaddr)437905Ssam intpr(interval, ifnetaddr)
447905Ssam int interval;
4554761Ssklower u_long ifnetaddr;
467905Ssam {
477905Ssam struct ifnet ifnet;
4821906Skarels union {
4921906Skarels struct ifaddr ifa;
5021906Skarels struct in_ifaddr in;
5139214Smarc struct ns_ifaddr ns;
5243251Ssklower struct iso_ifaddr iso;
5321906Skarels } ifaddr;
5454761Ssklower u_long ifaddraddr;
5539214Smarc struct sockaddr *sa;
567905Ssam char name[16];
577905Ssam
587905Ssam if (ifnetaddr == 0) {
597905Ssam printf("ifnet: symbol not defined\n");
607905Ssam return;
617905Ssam }
627905Ssam if (interval) {
6329746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr);
647905Ssam return;
657905Ssam }
6653698Ssklower if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr))
6753698Ssklower return;
6832085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s",
697905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
707905Ssam "Opkts", "Oerrs");
7132085Skarels printf(" %5s", "Coll");
727905Ssam if (tflag)
7332085Skarels printf(" %s", "Time");
7434270Skarels if (dflag)
7534270Skarels printf(" %s", "Drop");
767905Ssam putchar('\n');
7721906Skarels ifaddraddr = 0;
7821906Skarels while (ifnetaddr || ifaddraddr) {
797905Ssam struct sockaddr_in *sin;
807905Ssam register char *cp;
8140839Ssklower int n, m;
827905Ssam
8321906Skarels if (ifaddraddr == 0) {
8453698Ssklower if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) ||
8554761Ssklower kread((u_long)ifnet.if_name, name, 16))
8653698Ssklower return;
8721906Skarels name[15] = '\0';
8866219Sbostic ifnetaddr = (u_long)ifnet.if_next;
8966219Sbostic if (interface != 0 && (strcmp(name, interface) != 0 ||
9066219Sbostic unit != ifnet.if_unit))
9121906Skarels continue;
9221906Skarels cp = index(name, '\0');
9366219Sbostic cp += sprintf(cp, "%d", ifnet.if_unit);
9421906Skarels if ((ifnet.if_flags&IFF_UP) == 0)
9521906Skarels *cp++ = '*';
9621906Skarels *cp = '\0';
9754761Ssklower ifaddraddr = (u_long)ifnet.if_addrlist;
9821906Skarels }
997905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu);
10021906Skarels if (ifaddraddr == 0) {
10132085Skarels printf("%-11.11s ", "none");
10232085Skarels printf("%-15.15s ", "none");
10321906Skarels } else {
10453698Ssklower if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
10553698Ssklower ifaddraddr = 0;
10653698Ssklower continue;
10753698Ssklower }
10839214Smarc #define CP(x) ((char *)(x))
10939214Smarc cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
11039214Smarc CP(&ifaddr); sa = (struct sockaddr *)cp;
11139214Smarc switch (sa->sa_family) {
11221906Skarels case AF_UNSPEC:
11332085Skarels printf("%-11.11s ", "none");
11432085Skarels printf("%-15.15s ", "none");
11521906Skarels break;
11621906Skarels case AF_INET:
11739214Smarc sin = (struct sockaddr_in *)sa;
11821906Skarels #ifdef notdef
11921906Skarels /* can't use inet_makeaddr because kernel
12021906Skarels * keeps nets unshifted.
12121906Skarels */
12221906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet,
12321906Skarels INADDR_ANY);
12453698Ssklower printf("%-11.11s ", netname(in.s_addr,
12553698Ssklower ifaddr.in.ia_subnetmask));
12621906Skarels #else
12732085Skarels printf("%-11.11s ",
12853698Ssklower netname(htonl(ifaddr.in.ia_subnet),
12953698Ssklower ifaddr.in.ia_subnetmask));
13021906Skarels #endif
13153698Ssklower printf("%-15.15s ",
13253698Ssklower routename(sin->sin_addr.s_addr));
13321906Skarels break;
13423499Ssklower case AF_NS:
13523499Ssklower {
13623499Ssklower struct sockaddr_ns *sns =
13739214Smarc (struct sockaddr_ns *)sa;
13829746Skupfer u_long net;
13932085Skarels char netnum[8];
14029746Skupfer
14127265Skarels *(union ns_net *) &net = sns->sns_addr.x_net;
14239214Smarc sprintf(netnum, "%lxH", ntohl(net));
14332085Skarels upHex(netnum);
14432085Skarels printf("ns:%-8s ", netnum);
14553698Ssklower printf("%-15s ",
14653698Ssklower ns_phost((struct sockaddr *)sns));
14723499Ssklower }
14823499Ssklower break;
14940839Ssklower case AF_LINK:
15040839Ssklower {
15140839Ssklower struct sockaddr_dl *sdl =
15240839Ssklower (struct sockaddr_dl *)sa;
15341185Ssklower cp = (char *)LLADDR(sdl);
15441185Ssklower n = sdl->sdl_alen;
15540839Ssklower }
156*69046Sbostic m = printf("%-11.11s ", "<Link>");
15741185Ssklower goto hexprint;
15821906Skarels default:
15941185Ssklower m = printf("(%d)", sa->sa_family);
16041185Ssklower for (cp = sa->sa_len + (char *)sa;
16141185Ssklower --cp > sa->sa_data && (*cp == 0);) {}
16239214Smarc n = cp - sa->sa_data + 1;
16339214Smarc cp = sa->sa_data;
16440839Ssklower hexprint:
16541185Ssklower while (--n >= 0)
16641185Ssklower m += printf("%x%c", *cp++ & 0xff,
16741185Ssklower n > 0 ? '.' : ' ');
16841185Ssklower m = 28 - m;
16940839Ssklower while (m-- > 0)
17040839Ssklower putchar(' ');
17121906Skarels break;
17221906Skarels }
17354761Ssklower ifaddraddr = (u_long)ifaddr.ifa.ifa_next;
17421906Skarels }
17532085Skarels printf("%8d %5d %8d %5d %5d",
1767905Ssam ifnet.if_ipackets, ifnet.if_ierrors,
1777905Ssam ifnet.if_opackets, ifnet.if_oerrors,
1787905Ssam ifnet.if_collisions);
1797905Ssam if (tflag)
18032085Skarels printf(" %3d", ifnet.if_timer);
18134270Skarels if (dflag)
18234270Skarels printf(" %3d", ifnet.if_snd.ifq_drops);
1837905Ssam putchar('\n');
1847905Ssam }
1857905Ssam }
1867905Ssam
1878331Ssam #define MAXIF 10
1888331Ssam struct iftot {
1898331Ssam char ift_name[16]; /* interface name */
1908331Ssam int ift_ip; /* input packets */
1918331Ssam int ift_ie; /* input errors */
1928331Ssam int ift_op; /* output packets */
1938331Ssam int ift_oe; /* output errors */
1948331Ssam int ift_co; /* collisions */
19534270Skarels int ift_dr; /* drops */
1968331Ssam } iftot[MAXIF];
1978331Ssam
19829746Skupfer u_char signalled; /* set if alarm goes off "early" */
19929746Skupfer
2008331Ssam /*
2018331Ssam * Print a running summary of interface statistics.
20229746Skupfer * Repeat display every interval seconds, showing statistics
20329746Skupfer * collected over that interval. Assumes that interval is non-zero.
20429746Skupfer * First line printed at top of screen is always cumulative.
2058331Ssam */
20653698Ssklower static void
sidewaysintpr(interval,off)2077905Ssam sidewaysintpr(interval, off)
20829746Skupfer unsigned interval;
20954761Ssklower u_long off;
2107905Ssam {
2117905Ssam struct ifnet ifnet;
21254761Ssklower u_long firstifnet;
2138331Ssam register struct iftot *ip, *total;
2148331Ssam register int line;
2158331Ssam struct iftot *lastif, *sum, *interesting;
21629746Skupfer int oldmask;
2177905Ssam
21854761Ssklower if (kread(off, (char *)&firstifnet, sizeof (u_long)))
21953698Ssklower return;
2208331Ssam lastif = iftot;
2218331Ssam sum = iftot + MAXIF - 1;
2228331Ssam total = sum - 1;
22317402Sedward interesting = iftot;
2248331Ssam for (off = firstifnet, ip = iftot; off;) {
2258331Ssam char *cp;
2267905Ssam
22753698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet))
22853698Ssklower break;
2298331Ssam ip->ift_name[0] = '(';
23054761Ssklower if (kread((u_long)ifnet.if_name, ip->ift_name + 1, 15))
23153698Ssklower break;
23217402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
23317402Sedward unit == ifnet.if_unit)
23417402Sedward interesting = ip;
2358331Ssam ip->ift_name[15] = '\0';
2368331Ssam cp = index(ip->ift_name, '\0');
2378331Ssam sprintf(cp, "%d)", ifnet.if_unit);
2388331Ssam ip++;
2398331Ssam if (ip >= iftot + MAXIF - 2)
2408331Ssam break;
24154761Ssklower off = (u_long) ifnet.if_next;
2427905Ssam }
2438331Ssam lastif = ip;
24429746Skupfer
24529746Skupfer (void)signal(SIGALRM, catchalarm);
24629746Skupfer signalled = NO;
24729746Skupfer (void)alarm(interval);
2488331Ssam banner:
24934270Skarels printf(" input %-6.6s output ", interesting->ift_name);
25034270Skarels if (lastif - iftot > 0) {
25134270Skarels if (dflag)
25234270Skarels printf(" ");
25334270Skarels printf(" input (Total) output");
25434270Skarels }
2558331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) {
2568331Ssam ip->ift_ip = 0;
2578331Ssam ip->ift_ie = 0;
2588331Ssam ip->ift_op = 0;
2598331Ssam ip->ift_oe = 0;
2608331Ssam ip->ift_co = 0;
26134270Skarels ip->ift_dr = 0;
2628331Ssam }
2638331Ssam putchar('\n');
26432085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
2658331Ssam "packets", "errs", "packets", "errs", "colls");
26634270Skarels if (dflag)
26734270Skarels printf("%5.5s ", "drops");
2688331Ssam if (lastif - iftot > 0)
26934270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
2708331Ssam "packets", "errs", "packets", "errs", "colls");
27134270Skarels if (dflag)
27234270Skarels printf(" %5.5s", "drops");
2738331Ssam putchar('\n');
2748331Ssam fflush(stdout);
2758331Ssam line = 0;
2768331Ssam loop:
2778331Ssam sum->ift_ip = 0;
2788331Ssam sum->ift_ie = 0;
2798331Ssam sum->ift_op = 0;
2808331Ssam sum->ift_oe = 0;
2818331Ssam sum->ift_co = 0;
28234270Skarels sum->ift_dr = 0;
2838331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
28453698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet)) {
28553698Ssklower off = 0;
28653698Ssklower continue;
28753698Ssklower }
28834270Skarels if (ip == interesting) {
28934270Skarels printf("%8d %5d %8d %5d %5d",
2908331Ssam ifnet.if_ipackets - ip->ift_ip,
2918331Ssam ifnet.if_ierrors - ip->ift_ie,
2928331Ssam ifnet.if_opackets - ip->ift_op,
2938331Ssam ifnet.if_oerrors - ip->ift_oe,
2948331Ssam ifnet.if_collisions - ip->ift_co);
29534270Skarels if (dflag)
29634270Skarels printf(" %5d",
29734270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr);
29834270Skarels }
2998331Ssam ip->ift_ip = ifnet.if_ipackets;
3008331Ssam ip->ift_ie = ifnet.if_ierrors;
3018331Ssam ip->ift_op = ifnet.if_opackets;
3028331Ssam ip->ift_oe = ifnet.if_oerrors;
3038331Ssam ip->ift_co = ifnet.if_collisions;
30434270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops;
3058331Ssam sum->ift_ip += ip->ift_ip;
3068331Ssam sum->ift_ie += ip->ift_ie;
3078331Ssam sum->ift_op += ip->ift_op;
3088331Ssam sum->ift_oe += ip->ift_oe;
3098331Ssam sum->ift_co += ip->ift_co;
31034270Skarels sum->ift_dr += ip->ift_dr;
31154761Ssklower off = (u_long) ifnet.if_next;
3128331Ssam }
31334270Skarels if (lastif - iftot > 0) {
31434270Skarels printf(" %8d %5d %8d %5d %5d",
3158331Ssam sum->ift_ip - total->ift_ip,
3168331Ssam sum->ift_ie - total->ift_ie,
3178331Ssam sum->ift_op - total->ift_op,
3188331Ssam sum->ift_oe - total->ift_oe,
3198331Ssam sum->ift_co - total->ift_co);
32034270Skarels if (dflag)
32134270Skarels printf(" %5d", sum->ift_dr - total->ift_dr);
32234270Skarels }
3238331Ssam *total = *sum;
32432085Skarels putchar('\n');
3258331Ssam fflush(stdout);
3268331Ssam line++;
32729746Skupfer oldmask = sigblock(sigmask(SIGALRM));
32829746Skupfer if (! signalled) {
32929746Skupfer sigpause(0);
33029746Skupfer }
33129746Skupfer sigsetmask(oldmask);
33229746Skupfer signalled = NO;
33329746Skupfer (void)alarm(interval);
3348331Ssam if (line == 21)
3358331Ssam goto banner;
3368331Ssam goto loop;
3378331Ssam /*NOTREACHED*/
3387905Ssam }
33929746Skupfer
34029746Skupfer /*
34129746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop.
34229746Skupfer * Sets a flag to not wait for the alarm.
34329746Skupfer */
34453698Ssklower static void
catchalarm(signo)34566219Sbostic catchalarm(signo)
34666219Sbostic int signo;
34729746Skupfer {
34829746Skupfer signalled = YES;
34929746Skupfer }
350