2 * Copyright (c) 1998 Andrzej Bialecki
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/release/picobsd/tinyware/ns/ns.c,v 1.8.2.7 2002/03/27 20:42:03 abial Exp $
27 * $DragonFly: src/release/picobsd/tinyware/ns/Attic/ns.c,v 1.2 2003/06/17 04:27:20 dillon Exp $
32 * Small replacement for netstat. Uses only sysctl(3) to get the info.
38 #include <sys/param.h>
40 #include <sys/sysctl.h>
41 #include <sys/socket.h>
45 #include <net/route.h>
46 #include <net/if_dl.h>
47 #include <netinet/in_systm.h>
48 #include <netinet/in.h>
49 #include <netinet/ip.h>
50 #include <netinet/ip_icmp.h>
51 #include <netinet/icmp_var.h>
52 #include <netinet/ip_var.h>
53 #include <netinet/tcp.h>
54 #include <netinet/tcp_timer.h>
55 #include <netinet/tcp_var.h>
56 #include <netinet/udp.h>
57 #include <netinet/udp_var.h>
60 #include <net/if_types.h> /* IFT_ETHER */
61 #include <net/ethernet.h>
62 #include <net/bridge.h>
67 #include <osreldate.h>
73 int lflag = 0; /* print cpu load info */
77 int mflag = 0; /* print mbuf stats */
78 int wflag = 0; /* repeat every wait seconds */
87 fprintf(stderr, "\n%s [-nmrsil] [-p proto] [-w wait]\n", progname);
89 fprintf(stderr, " proto: {ip|tcp|udp|icmp|bdg}\n\n");
91 fprintf(stderr, " proto: {ip|tcp|udp|icmp}\n\n");
97 * The following parts related to retrieving the routing table and
98 * interface information, were borrowed from R. Stevens' code examples
99 * accompanying his excellent book. Thanks!
102 sock_ntop(const struct sockaddr *sa, size_t salen)
105 static char str[128]; /* Unix domain is largest */
107 switch (sa->sa_family) {
111 u_int index = 1 << 31;
112 u_short new_mask = 0;
114 mask = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
116 while (mask & index) {
120 sprintf(str, "/%hu", new_mask);
125 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
127 if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str))
130 if (ntohs(sin->sin_port) != 0) {
131 snprintf(portstr, sizeof(portstr), ".%d",
132 ntohs(sin->sin_port));
133 strcat(str, portstr);
135 if (strcmp(str, "0.0.0.0") == 0)
136 sprintf(str, "default");
141 struct sockaddr_un *unp = (struct sockaddr_un *)sa;
144 * OK to have no pathname bound to the socket:
145 * happens on every connect() unless client calls
148 if (unp->sun_path[0] == 0)
149 strcpy(str, "(no pathname bound)");
151 snprintf(str, sizeof(str), "%s", unp->sun_path);
156 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
158 if (sdl->sdl_nlen > 0) {
159 bcopy(&sdl->sdl_data[0], str, sdl->sdl_nlen);
160 str[sdl->sdl_nlen] = '\0';
162 snprintf(str, sizeof(str), "link#%d", sdl->sdl_index);
167 snprintf(str, sizeof(str),
168 "sock_ntop: unknown AF_xxx: %d, len %d", sa->sa_family,
176 Sock_ntop(const struct sockaddr *sa, size_t salen)
180 if ((ptr = sock_ntop(sa, salen)) == NULL)
181 err(1, "sock_ntop error"); /* inet_ntop() sets errno */
186 #define ROUNDUP(a,size) (((a) & ((size)-1))?(1+((a)|((size)-1))):(a))
188 #define NEXT_SA(ap) \
189 ap=(struct sockaddr *) \
190 ((caddr_t)ap+(ap->sa_len?ROUNDUP(ap->sa_len,sizeof(u_long)):\
194 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
198 for (i = 0; i < RTAX_MAX; i++) {
199 if (addrs & (1 << i)) {
208 get_flags(char *buf, int flags)
235 if (flags & 0x200000)
238 if (flags & 0x400000)
241 if (flags & 0x800000)
247 print_routing(char *proto)
258 struct rt_msghdr *rtm;
259 struct if_msghdr *ifm;
260 struct if_msghdr **ifm_table;
261 struct ifa_msghdr *ifam;
263 struct sockaddr *sa1;
264 struct sockaddr *rti_info[RTAX_MAX];
265 struct sockaddr **if_table;
266 struct rt_metrics rm;
269 /* keep a copy of statistics here for future use */
270 static unsigned *base_stats = NULL ;
271 static unsigned base_len = 0 ;
273 /* Get the routing table */
278 mib[4] = NET_RT_DUMP;
281 /*Estimate the size of table */
282 if (sysctl(mib, 6, NULL, &rt_len, NULL, 0) == -1) {
283 perror("sysctl size");
286 if ((rt_buf = (char *)malloc(rt_len)) == NULL) {
292 if (sysctl(mib, 6, rt_buf, &rt_len, NULL, 0) == -1) {
293 perror("sysctl get");
297 /* Get the interfaces table */
302 mib[4] = NET_RT_IFLIST;
305 /* Estimate the size of table */
306 if (sysctl(mib, 6, NULL, &if_len, NULL, 0) == -1) {
307 perror("sysctl size");
310 if ((if_buf = (char *)malloc(if_len)) == NULL) {
316 if (sysctl(mib, 6, if_buf, &if_len, NULL, 0) == -1) {
317 perror("sysctl get");
320 lim = if_buf + if_len;
322 for (next = if_buf, i = 0; next < lim; next += ifm->ifm_msglen) {
323 ifm = (struct if_msghdr *)next;
327 if_table = (struct sockaddr **)calloc(i, sizeof(struct sockaddr));
328 ifm_table = (struct if_msghdr **)calloc(i, sizeof(struct if_msghdr));
330 printf("\nInterface table:\n");
331 printf("----------------\n");
332 printf("Name Mtu Network Address "
333 "Ipkts Ierrs Opkts Oerrs Coll\n");
335 /* scan the list and store base values */
337 for (next = if_buf; next < lim; next += ifm->ifm_msglen) {
338 ifm = (struct if_msghdr *)next;
341 if (base_stats == NULL || i != base_len) {
342 base_stats = calloc(i*5, sizeof(unsigned));
346 for (next = if_buf; next < lim; next += ifm->ifm_msglen) {
347 ifm = (struct if_msghdr *)next;
348 if_table[i] = (struct sockaddr *)(ifm + 1);
352 if (iflag && sa->sa_family == AF_LINK) {
353 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
354 unsigned *bp = &base_stats[i*5];
356 printf("%-4s %-5d <Link> ",
357 sock_ntop(if_table[i], if_table[i]->sa_len),
358 ifm->ifm_data.ifi_mtu);
359 if (sdl->sdl_alen == 6) {
361 sdl->sdl_data + sdl->sdl_nlen;
362 printf("%02x:%02x:%02x:%02x:%02x:%02x ",
363 p[0], p[1], p[2], p[3], p[4], p[5]);
366 printf("%9d%6d%9d%6d%6d\n",
367 ifm->ifm_data.ifi_ipackets - bp[0],
368 ifm->ifm_data.ifi_ierrors - bp[1],
369 ifm->ifm_data.ifi_opackets - bp[2],
370 ifm->ifm_data.ifi_oerrors - bp[3],
371 ifm->ifm_data.ifi_collisions -bp[4]);
373 bp[0] = ifm->ifm_data.ifi_ipackets ;
374 bp[1] = ifm->ifm_data.ifi_ierrors ;
375 bp[2] = ifm->ifm_data.ifi_opackets ;
376 bp[3] = ifm->ifm_data.ifi_oerrors ;
377 bp[4] = ifm->ifm_data.ifi_collisions ;
390 /* Now dump the routing table */
391 printf("\nRouting table:\n");
392 printf("--------------\n");
394 ("Destination Gateway Flags Netif Use\n");
395 lim = rt_buf + rt_len;
396 for (next = rt_buf; next < lim; next += rtm->rtm_msglen) {
397 rtm = (struct rt_msghdr *)next;
398 sa = (struct sockaddr *)(rtm + 1);
399 get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
400 if (rtm->rtm_flags & RTF_WASCLONED) {
401 if ((rtm->rtm_flags & RTF_LLINFO) == 0)
404 if ((sa = rti_info[RTAX_DST]) != NULL) {
405 sprintf(fbuf, "%s", sock_ntop(sa, sa->sa_len));
406 if (((sa1 = rti_info[RTAX_NETMASK]) != NULL)
407 && sa1->sa_family == 255) {
408 strcat(fbuf, sock_ntop(sa1, sa1->sa_len));
410 printf("%-19s", fbuf);
412 if ((sa = rti_info[RTAX_GATEWAY]) != NULL) {
413 printf("%-19s", sock_ntop(sa, sa->sa_len));
415 memset(fbuf, 0, sizeof(fbuf));
416 get_flags(fbuf, rtm->rtm_flags);
417 printf("%-10s", fbuf);
418 for (i = 0; i < if_num; i++) {
420 if ((ifm->ifm_index == rtm->rtm_index) &&
421 (ifm->ifm_data.ifi_type > 0)) {
426 if (ifm->ifm_type == RTM_IFINFO) {
427 get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
428 printf(" %s", Sock_ntop(sa, sa->sa_len));
429 } else if (ifm->ifm_type == RTM_NEWADDR) {
431 (struct ifa_msghdr *)ifm_table[rtm->rtm_index - 1];
432 sa = (struct sockaddr *)(ifam + 1);
433 get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
434 printf(" %s", Sock_ntop(sa, sa->sa_len));
436 printf(" %u", rtm->rtm_use);
457 printf("sorry, ip stats not available\n");
460 mib[3] = IPCTL_STATS;
461 len = sizeof(struct ipstat);
462 if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
466 printf("\nIP statistics:\n");
467 printf("--------------\n");
468 printf(" %10lu total packets received\n", s.ips_total);
469 printf("* Packets ok:\n");
470 printf(" %10lu fragments received\n", s.ips_fragments);
471 printf(" %10lu forwarded\n", s.ips_forward);
472 #if __FreeBSD_version > 300001
473 printf(" %10lu fast forwarded\n", s.ips_fastforward);
475 printf(" %10lu forwarded on same net (redirect)\n",
477 printf(" %10lu delivered to upper level\n", s.ips_delivered);
478 printf(" %10lu total ip packets generated here\n", s.ips_localout);
479 printf(" %10lu total packets reassembled ok\n", s.ips_reassembled);
480 printf(" %10lu total datagrams successfully fragmented\n",
482 printf(" %10lu output fragments created\n", s.ips_ofragments);
483 printf(" %10lu total raw IP packets generated\n", s.ips_rawout);
484 printf("\n* Bad packets:\n");
485 printf(" %10lu bad checksum\n", s.ips_badsum);
486 printf(" %10lu too short\n", s.ips_tooshort);
487 printf(" %10lu not enough data (too small)\n", s.ips_toosmall);
488 printf(" %10lu more data than declared in header\n", s.ips_badhlen);
489 printf(" %10lu less data than declared in header\n", s.ips_badlen);
490 printf(" %10lu fragments dropped (dups, no mbuf)\n",
492 printf(" %10lu fragments timed out in reassembly\n",
494 printf(" %10lu received for unreachable dest.\n", s.ips_cantforward);
495 printf(" %10lu unknown or unsupported protocol\n", s.ips_noproto);
496 printf(" %10lu lost due to no bufs etc.\n", s.ips_odropped);
497 printf(" %10lu couldn't fragment (DF set, etc.)\n", s.ips_cantfrag);
498 printf(" %10lu error in IP options processing\n", s.ips_badoptions);
499 printf(" %10lu dropped due to no route\n", s.ips_noroute);
500 printf(" %10lu bad IP version\n", s.ips_badvers);
501 printf(" %10lu too long (more than max IP size)\n", s.ips_toolong);
502 #if __FreeBSD_version > 300001
503 printf(" %10lu multicast for unregistered groups\n", s.ips_notmember);
516 mib[2] = IPPROTO_TCP;
518 printf("sorry, tcp stats not available\n");
521 mib[3] = TCPCTL_STATS;
522 len = sizeof(struct tcpstat);
523 if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
527 printf("\nTCP statistics:\n");
528 printf("---------------\n");
529 printf("* Connections:\n");
530 printf(" %10lu initiated\n", s.tcps_connattempt);
531 printf(" %10lu accepted\n", s.tcps_accepts);
532 printf(" %10lu established\n", s.tcps_connects);
533 printf(" %10lu dropped\n", s.tcps_drops);
534 printf(" %10lu embryonic connections dropped\n", s.tcps_conndrops);
535 printf(" %10lu closed (includes dropped)\n", s.tcps_closed);
536 printf(" %10lu segments where we tried to get RTT\n",
538 printf(" %10lu times RTT successfully updated\n", s.tcps_rttupdated);
539 printf(" %10lu delayed ACKs sent\n", s.tcps_delack);
540 printf(" %10lu dropped in rxmt timeout\n", s.tcps_timeoutdrop);
541 printf(" %10lu retrasmit timeouts\n", s.tcps_rexmttimeo);
542 printf(" %10lu persist timeouts\n", s.tcps_persisttimeo);
543 printf(" %10lu keepalive timeouts\n", s.tcps_keeptimeo);
544 printf(" %10lu keepalive probes sent\n", s.tcps_keepprobe);
545 printf(" %10lu dropped in keepalive\n", s.tcps_keepdrops);
547 printf("* Packets sent:\n");
548 printf(" %10lu total packets sent\n", s.tcps_sndtotal);
549 printf(" %10lu data packets sent\n", s.tcps_sndpack);
550 printf(" %10lu data bytes sent\n", s.tcps_sndbyte);
551 printf(" %10lu data packets retransmitted\n", s.tcps_sndrexmitpack);
552 printf(" %10lu data bytes retransmitted\n", s.tcps_sndrexmitbyte);
553 printf(" %10lu ACK-only packets sent\n", s.tcps_sndacks);
554 printf(" %10lu window probes sent\n", s.tcps_sndprobe);
555 printf(" %10lu URG-only packets sent\n", s.tcps_sndurg);
556 printf(" %10lu window update-only packets sent\n", s.tcps_sndwinup);
557 printf(" %10lu control (SYN,FIN,RST) packets sent\n", s.tcps_sndctrl);
558 printf("* Packets received:\n");
559 printf(" %10lu total packets received\n", s.tcps_rcvtotal);
560 printf(" %10lu packets in sequence\n", s.tcps_rcvpack);
561 printf(" %10lu bytes in sequence\n", s.tcps_rcvbyte);
562 printf(" %10lu packets with bad checksum\n", s.tcps_rcvbadsum);
563 printf(" %10lu packets with bad offset\n", s.tcps_rcvbadoff);
564 printf(" %10lu packets too short\n", s.tcps_rcvshort);
565 printf(" %10lu duplicate-only packets\n", s.tcps_rcvduppack);
566 printf(" %10lu duplicate-only bytes\n", s.tcps_rcvdupbyte);
567 printf(" %10lu packets with some duplicate data\n",
568 s.tcps_rcvpartduppack);
569 printf(" %10lu duplicate bytes in partially dup. packets\n",
570 s.tcps_rcvpartdupbyte);
571 printf(" %10lu out-of-order packets\n", s.tcps_rcvoopack);
572 printf(" %10lu out-of-order bytes\n", s.tcps_rcvoobyte);
573 printf(" %10lu packets with data after window\n",
574 s.tcps_rcvpackafterwin);
575 printf(" %10lu bytes received after window\n",
576 s.tcps_rcvbyteafterwin);
577 printf(" %10lu packets received after 'close'\n",
578 s.tcps_rcvafterclose);
579 printf(" %10lu window probe packets\n", s.tcps_rcvwinprobe);
580 printf(" %10lu duplicate ACKs\n", s.tcps_rcvdupack);
581 printf(" %10lu ACKs for unsent data\n", s.tcps_rcvacktoomuch);
582 printf(" %10lu ACK packets\n", s.tcps_rcvackpack);
583 printf(" %10lu bytes ACKed by received ACKs\n", s.tcps_rcvackbyte);
584 printf(" %10lu window update packets\n", s.tcps_rcvwinupd);
585 printf(" %10lu segments dropped due to PAWS\n", s.tcps_pawsdrop);
586 printf(" %10lu times header predict ok for ACKs\n", s.tcps_predack);
587 printf(" %10lu times header predict ok for data packets\n",
589 printf(" %10lu PCB cache misses\n", s.tcps_pcbcachemiss);
590 printf(" %10lu times cached RTT in route updated\n",
592 printf(" %10lu times cached RTTVAR updated\n", s.tcps_cachedrttvar);
593 printf(" %10lu times ssthresh updated\n", s.tcps_cachedssthresh);
594 printf(" %10lu times RTT initialized from route\n", s.tcps_usedrtt);
595 printf(" %10lu times RTTVAR initialized from route\n",
597 printf(" %10lu times ssthresh initialized from route\n",
598 s.tcps_usedssthresh);
599 printf(" %10lu timeout in persist state\n", s.tcps_persistdrop);
600 printf(" %10lu bogus SYN, e.g. premature ACK\n", s.tcps_badsyn);
601 printf(" %10lu resends due to MTU discovery\n", s.tcps_mturesent);
602 printf(" %10lu listen queue overflows\n", s.tcps_listendrop);
614 mib[2] = IPPROTO_UDP;
615 mib[3] = UDPCTL_STATS;
616 len = sizeof(struct udpstat);
617 if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
621 printf("\nUDP statistics:\n");
622 printf("---------------\n");
623 printf("* Packets received:\n");
624 printf(" %10lu total input packets\n", s.udps_ipackets);
625 printf(" %10lu packets shorter than header (dropped)\n",
627 printf(" %10lu bad checksum\n", s.udps_badsum);
628 printf(" %10lu data length larger than packet\n", s.udps_badlen);
629 printf(" %10lu no socket on specified port\n", s.udps_noport);
630 printf(" %10lu of above, arrived as broadcast\n", s.udps_noportbcast);
631 printf(" %10lu not delivered, input socket full\n", s.udps_fullsock);
632 printf(" %10lu packets missing PCB cache\n", s.udpps_pcbcachemiss);
633 printf(" %10lu packets not for hashed PCBs\n", s.udpps_pcbhashmiss);
634 printf("* Packets sent:\n");
635 printf(" %10lu total output packets\n", s.udps_opackets);
636 #if __FreeBSD_version > 300001
637 printf(" %10lu output packets on fast path\n", s.udps_fastout);
641 char *icmp_names[] = {
645 "destination unreachable",
651 "router advertisement",
652 "router solicitation",
657 "information request",
658 "information request reply",
659 "address mask request",
660 "address mask reply",
672 mib[2] = IPPROTO_ICMP;
673 mib[3] = ICMPCTL_STATS;
674 len = sizeof(struct icmpstat);
675 if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
679 printf("\nICMP statistics:\n");
680 printf("----------------\n");
681 printf("* Output histogram:\n");
682 for (i = 0; i < (ICMP_MAXTYPE + 1); i++) {
683 if (s.icps_outhist[i] > 0)
684 printf("\t%10lu %s\n",
685 s.icps_outhist[i], icmp_names[i]);
687 printf("* Input histogram:\n");
688 for (i = 0; i < (ICMP_MAXTYPE + 1); i++) {
689 if (s.icps_inhist[i] > 0)
690 printf("\t%10lu %s\n",
691 s.icps_inhist[i], icmp_names[i]);
693 printf("* Other stats:\n");
694 printf(" %10lu calls to icmp_error\n", s.icps_error);
695 printf(" %10lu no error 'cuz old ip too short\n", s.icps_oldshort);
696 printf(" %10lu no error 'cuz old was icmp\n", s.icps_oldicmp);
698 printf(" %10lu icmp code out of range\n", s.icps_badcode);
699 printf(" %10lu packets shorter than min length\n", s.icps_tooshort);
700 printf(" %10lu bad checksum\n", s.icps_checksum);
701 printf(" %10lu calculated bound mismatch\n", s.icps_badlen);
702 printf(" %10lu number of responses\n", s.icps_reflect);
703 printf(" %10lu broad/multi-cast echo requests dropped\n",
705 printf(" %10lu broad/multi-cast timestamp requests dropped\n",
706 s.icps_bmcasttstamp);
709 static struct mbtypenames {
714 { MT_OOBDATA, "oob data" },
715 { MT_CONTROL, "ancillary data" },
716 { MT_HEADER, "packet headers" },
718 { MT_SOCKET, "socket structures" }, /* XXX */
721 { MT_PCB, "protocol control blocks" }, /* XXX */
724 { MT_RTABLE, "routing table entries" }, /* XXX */
727 { MT_HTABLE, "IMP host table entries" }, /* XXX */
730 { MT_ATABLE, "address resolution tables" },
732 { MT_FTABLE, "fragment reassembly queue headers" }, /* XXX */
733 { MT_SONAME, "socket names and addresses" },
735 { MT_SOOPTS, "socket options" },
738 { MT_RIGHTS, "access rights" },
741 { MT_IFADDR, "interface addresses" }, /* XXX */
749 u_long totmem, totpossible, totmbufs;
751 struct mbstat mbstat;
752 struct mbtypenames *mp;
753 int name[3], nmbclusters, nmbufs, nmbtypes;
754 size_t nmbclen, nmbuflen, mbstatlen, mbtypeslen;
756 int *seen; /* "have we seen this type yet?" */
764 if (sysctlbyname("kern.ipc.mbtypes", NULL, &mbtypeslen, NULL, 0) < 0) {
765 warn("sysctl: retrieving mbtypes length");
768 if ((mbtypes = malloc(mbtypeslen)) == NULL) {
769 warn("malloc: %lu bytes for mbtypes", (u_long)mbtypeslen);
773 nmbtypes = mbtypeslen / sizeof(*mbtypes);
774 if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) {
781 name[2] = KIPC_MBSTAT;
782 mbstatlen = sizeof mbstat;
783 if (sysctl(name, 3, &mbstat, &mbstatlen, 0, 0) < 0) {
784 warn("sysctl: retrieving mbstat");
788 if (sysctlbyname("kern.ipc.mbtypes",mbtypes,&mbtypeslen,NULL,0) < 0) {
789 warn("sysctl: retrieving mbtypes");
793 name[2] = KIPC_NMBCLUSTERS;
794 nmbclen = sizeof(int);
795 if (sysctl(name, 3, &nmbclusters, &nmbclen, 0, 0) < 0) {
796 warn("sysctl: retrieving nmbclusters");
800 nmbuflen = sizeof(int);
801 if (sysctlbyname("kern.ipc.nmbufs", &nmbufs, &nmbuflen, 0, 0) < 0) {
802 warn("sysctl: retrieving nmbufs");
807 #define MSIZE (mbstat.m_msize)
809 #define MCLBYTES (mbstat.m_mclbytes)
812 for (mp = mbtypenames; mp->mt_name; mp++)
813 totmbufs += mbtypes[mp->mt_type];
814 printf("%lu/%lu/%u mbufs in use (current/peak/max):\n", totmbufs,
815 mbstat.m_mbufs, nmbufs);
816 for (mp = mbtypenames; mp->mt_name; mp++)
817 if (mbtypes[mp->mt_type]) {
818 seen[mp->mt_type] = 1;
819 printf("\t%lu mbufs allocated to %s\n",
820 mbtypes[mp->mt_type], mp->mt_name);
823 for (i = 0; i < nmbtypes; i++)
824 if (!seen[i] && mbtypes[i]) {
825 printf("\t%lu mbufs allocated to <mbuf type %d>\n",
828 printf("%lu/%lu/%u mbuf clusters in use (current/peak/max)\n",
829 mbstat.m_clusters - mbstat.m_clfree, mbstat.m_clusters,
831 totmem = mbstat.m_mbufs * MSIZE + mbstat.m_clusters * MCLBYTES;
832 totpossible = nmbclusters * MCLBYTES + MSIZE * nmbufs;
833 printf("%lu Kbytes allocated to network (%lu%% of mb_map in use)\n",
834 totmem / 1024, (totmem * 100) / totpossible);
835 printf("%lu requests for memory denied\n", mbstat.m_drops);
836 printf("%lu requests for memory delayed\n", mbstat.m_wait);
837 printf("%lu calls to protocol drain routines\n", mbstat.m_drain);
854 fprintf(stderr, "Option '-p' requires paramter.\n");
858 if (strcmp(proto, "ip") == 0)
860 if (strcmp(proto, "icmp") == 0)
862 if (strcmp(proto, "udp") == 0)
864 if (strcmp(proto, "tcp") == 0)
867 if (strcmp(proto, "bdg") == 0)
883 main(int argc, char *argv[])
891 while ((c = getopt(argc, argv, "dilmnrsp:w:")) != -1) {
894 case 'd': /* print deltas in stats every w seconds */
898 wflag = atoi(optarg);
900 case 'n': /* ignored, just for compatibility with std netstat */
931 rflag = 1; /* default */
939 printf("\033[H\033[J");
944 gettimeofday(&t, NULL);
945 printf("\033[H%s", ctime(&t.tv_sec));
947 print_routing(proto);
958 print_load_stats(void)
960 static u_int32_t cp_time[5];
961 u_int32_t new_cp_time[5];
966 if (!lflag || !wflag)
968 l = sizeof(new_cp_time) ;
969 bzero(new_cp_time, l);
970 if (sysctlbyname("kern.cp_time", new_cp_time, &l, NULL, 0) < 0) {
971 warn("sysctl: retrieving cp_time length");
977 bzero (&ci, sizeof(ci));
979 if (sysctlbyname("kern.clockrate", &ci, &l, NULL, 0) < 0) {
980 warn("sysctl: retrieving clockinfo length");
984 bcopy(new_cp_time, cp_time, sizeof(cp_time));
986 shz = stathz * wflag ;
989 #define X(i) ( (double)(new_cp_time[i] - cp_time[i])*100/shz )
990 printf("\nUSER %5.2f%% NICE %5.2f%% SYS %5.2f%% "
991 "INTR %5.2f%% IDLE %5.2f%%\n",
992 X(0), X(1), X(2), X(3), X(4) );
993 bcopy(new_cp_time, cp_time, sizeof(cp_time));
997 /* print bridge statistics */
1012 if (sysctl(mib, 4, &s, &slen, NULL, 0) == -1) {
1013 return 0; /* no bridging */
1015 printf("-- Bridging statistics --\n");
1017 "Name In Out Forward Drop Bcast"
1018 "Mcast Local Unknown\n");
1019 for (i = 0; i < 16; i++) {
1021 printf("%-6s %9d%9d%9d%9d%9d%9d%9d%9d\n",
1023 s.s[i].p_in[(int)BDG_IN],
1024 s.s[i].p_in[(int)BDG_OUT],
1025 s.s[i].p_in[(int)BDG_FORWARD],
1026 s.s[i].p_in[(int)BDG_DROP],
1027 s.s[i].p_in[(int)BDG_BCAST],
1028 s.s[i].p_in[(int)BDG_MCAST],
1029 s.s[i].p_in[(int)BDG_LOCAL],
1030 s.s[i].p_in[(int)BDG_UNKNOWN]);