2 * netstat This file contains an implementation of the command
3 * that helps in debugging the networking modules.
5 * NET-TOOLS A collection of programs that form the base set of the
6 * NET-3 Networking Distribution for the LINUX operating
9 * Version: $Id: netstat.c,v 1.73 2011-04-20 01:35:22 ecki Exp $
11 * Authors: Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
12 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
13 * Phil Packer, <pep@wicked.demon.co.uk>
14 * Johannes Stille, <johannes@titan.os.open.de>
15 * Bernd Eckenfels, <net-tools@lina.inka.de>
16 * Phil Blundell <philb@gnu.org>
17 * Tuan Hoang <tqhoang@bigfoot.com>
20 * Alan Cox, <A.Cox@swansea.ac.uk>
21 * Copyright (c) 1993 Fred Baumgarten
25 *960116 {1.01} Bernd Eckenfels: verbose, cleanups
26 *960204 {1.10} Bernd Eckenfels: aftrans, usage, new route_info,
28 *960204 {1.11} Bernd Eckenfels: netlink support
29 *960204 {1.12} Bernd Eckenfels: route_init()
30 *960215 {1.13} Bernd Eckenfels: netlink_print honors HAVE_
31 *960217 {1.14} Bernd Eckenfels: masq_info from Jos Vos and
32 * ax25_info from Jonathan Naylor.
33 *960218 {1.15} Bernd Eckenfels: ipx_info rewritten, -e for tcp/ipx
34 *960220 {1.16} Bernd Eckenfels: minor output reformats, -a for -x
35 *960221 {1.17} Bernd Eckenfels: route_init->getroute_init
36 *960426 {1.18} Bernd Eckenfels: new RTACTION, SYM/NUM, FIB/CACHE
37 *960517 {1.19} Bernd Eckenfels: usage() spelling fix and --unix inode,
38 * ':' is part of sock_addr for --inet
39 *960822 {x.xx} Frank Strauss: INET6 support
41 *970406 {1.33} Philip Copeland Added snmp reporting support module -s
42 * code provided by Andi Kleen
43 * (relly needs to be kernel hooked but
44 * this will do in the meantime)
45 * minor header file misplacement tidy up.
46 *980815 {1.xx} Stephane Fillod: X.25 support
47 *980411 {1.34} Arnaldo Carvalho i18n: catgets -> gnu gettext, substitution
48 * of sprintf for snprintf
49 *10/1998 Andi Kleen Use new interface primitives.
50 *990101 {1.36} Bernd Eckenfels usage updated to include -s and -C -F,
51 * fixed netstat -rC output (lib/inet_gr.c)
52 * removed broken NETLINK Support
53 * fixed format for /proc/net/udp|tcp|raw
54 * added -w,-t,-u TcpExt support to -s
55 *990131 {1.37} Jan Kratochvil added -p for prg_cache() & friends
56 * Flames to <short@ucw.cz>.
57 * Tuan Hoang added IGMP support for IPv4 and IPv6
59 *990420 {1.38} Tuan Hoang removed a useless assignment from igmp_do_one()
60 *20010404 {1.39} Arnaldo Carvalho de Melo - use setlocale
61 *20081201 {1.42} Brian Micek added -L|--udplite options for RFC 3828
62 *20020722 {1.51} Thomas Preusser added SCTP over IPv4 support
64 * This program is free software; you can redistribute it
65 * and/or modify it under the terms of the GNU General
66 * Public License as published by the Free Software
67 * Foundation; either version 2 of the License, or (at
68 * your option) any later version.
83 #include <sys/param.h>
84 #include <sys/socket.h>
85 #include <arpa/inet.h>
86 #include <netinet/in.h>
87 #include <sys/ioctl.h>
92 #include "net-support.h"
93 #include "pathnames.h"
98 #include "interface.h"
103 #include <bluetooth/bluetooth.h>
106 #define PROGNAME_WIDTH 20
108 #if !defined(s6_addr32) && defined(in6a_words)
109 #define s6_addr32 in6a_words /* libinet6 */
112 /* prototypes for statistics.c */
113 void parsesnmp(int, int, int);
115 void parsesnmp6(int, int, int);
119 SS_FREE = 0, /* not allocated */
120 SS_UNCONNECTED, /* unconnected to any socket */
121 SS_CONNECTING, /* in process of connecting */
122 SS_CONNECTED, /* connected to socket */
123 SS_DISCONNECTING /* in process of disconnecting */
126 #define SO_ACCEPTCON (1<<16) /* performed a listen */
127 #define SO_WAITDATA (1<<17) /* wait data to read */
128 #define SO_NOSPACE (1<<18) /* no space to write */
130 #define DFLT_AF "inet"
132 #define FEATURE_NETSTAT
133 #include "lib/net-features.h"
135 char *Release = RELEASE, *Version = "netstat 1.42 (2001-04-15)", *Signature = "Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang, Brian Micek and others";
157 int flag_udplite = 0;
170 #define INFO_GUTS1(file,name,proc,prot) \
171 procinfo = proc_fopen((file)); \
172 if (procinfo == NULL) { \
173 if (errno != ENOENT) { \
177 if (flag_arg || flag_ver) \
178 ESYSNOT("netstat", (name)); \
183 if (fgets(buffer, sizeof(buffer), procinfo)) \
184 (proc)(lnr++, buffer,prot); \
185 } while (!feof(procinfo)); \
190 #define INFO_GUTS2(file,proc,prot) \
192 procinfo = proc_fopen((file)); \
193 if (procinfo != NULL) { \
195 if (fgets(buffer, sizeof(buffer), procinfo)) \
196 (proc)(lnr++, buffer,prot); \
197 } while (!feof(procinfo)); \
201 #define INFO_GUTS2(file,proc,prot)
207 #define INFO_GUTS6(file,file6,name,proc,prot4,prot6) \
211 if (!flag_arg || flag_inet) { \
212 INFO_GUTS1(file,name,proc,prot4) \
214 if (!flag_arg || flag_inet6) { \
215 INFO_GUTS2(file6,proc,prot6) \
219 #define INFO_GUTS(file,name,proc,prot) \
223 INFO_GUTS1(file,name,proc,prot) \
226 #define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
227 #define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)
228 #define PROGNAME_WIDTH2(s) #s
230 #define PRG_HASH_SIZE 211
232 static struct prg_node {
233 struct prg_node *next;
235 char name[PROGNAME_WIDTH];
236 } *prg_hash[PRG_HASH_SIZE];
238 static char prg_cache_loaded = 0;
240 #define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE)
242 #define PROGNAME_BANNER "PID/Program name"
244 #define print_progname_banner() do { if (flag_prg) printf(" %-" PROGNAME_WIDTHs "s",PROGNAME_BANNER); } while (0)
246 #define PRG_LOCAL_ADDRESS "local_address"
247 #define PRG_INODE "inode"
248 #define PRG_SOCKET_PFX "socket:["
249 #define PRG_SOCKET_PFXl (strlen(PRG_SOCKET_PFX))
250 #define PRG_SOCKET_PFX2 "[0000]:"
251 #define PRG_SOCKET_PFX2l (strlen(PRG_SOCKET_PFX2))
255 #define LINE_MAX 4096
258 #define PATH_PROC "/proc"
259 #define PATH_FD_SUFF "fd"
260 #define PATH_FD_SUFFl strlen(PATH_FD_SUFF)
261 #define PATH_PROC_X_FD PATH_PROC "/%s/" PATH_FD_SUFF
262 #define PATH_CMDLINE "cmdline"
263 #define PATH_CMDLINEl strlen(PATH_CMDLINE)
265 static void prg_cache_add(unsigned long inode, char *name)
267 unsigned hi = PRG_HASHIT(inode);
268 struct prg_node **pnp,*pn;
271 for (pnp=prg_hash+hi;(pn=*pnp);pnp=&pn->next) {
272 if (pn->inode==inode) {
273 /* Some warning should be appropriate here
274 as we got multiple processes for one i-node */
278 if (!(*pnp=malloc(sizeof(**pnp))))
283 if (strlen(name)>sizeof(pn->name)-1)
284 name[sizeof(pn->name)-1]='\0';
285 strcpy(pn->name,name);
288 static const char *prg_cache_get(unsigned long inode)
290 unsigned hi=PRG_HASHIT(inode);
293 for (pn=prg_hash[hi];pn;pn=pn->next)
294 if (pn->inode==inode) return(pn->name);
298 static void prg_cache_clear(void)
300 struct prg_node **pnp,*pn;
302 if (prg_cache_loaded == 2)
303 for (pnp=prg_hash;pnp<prg_hash+PRG_HASH_SIZE;pnp++)
311 static void wait_continous(void)
317 static int extract_type_1_socket_inode(const char lname[], unsigned long * inode_p) {
319 /* If lname is of the form "socket:[12345]", extract the "12345"
320 as *inode_p. Otherwise, return -1 as *inode_p.
323 if (strlen(lname) < PRG_SOCKET_PFXl+3) return(-1);
325 if (memcmp(lname, PRG_SOCKET_PFX, PRG_SOCKET_PFXl)) return(-1);
326 if (lname[strlen(lname)-1] != ']') return(-1);
329 char inode_str[strlen(lname + 1)]; /* e.g. "12345" */
330 const int inode_str_len = strlen(lname) - PRG_SOCKET_PFXl - 1;
333 strncpy(inode_str, lname+PRG_SOCKET_PFXl, inode_str_len);
334 inode_str[inode_str_len] = '\0';
335 *inode_p = strtoul(inode_str, &serr, 0);
336 if (!serr || *serr || *inode_p == ~0)
344 static int extract_type_2_socket_inode(const char lname[], unsigned long * inode_p) {
346 /* If lname is of the form "[0000]:12345", extract the "12345"
347 as *inode_p. Otherwise, return -1 as *inode_p.
350 if (strlen(lname) < PRG_SOCKET_PFX2l+1) return(-1);
351 if (memcmp(lname, PRG_SOCKET_PFX2, PRG_SOCKET_PFX2l)) return(-1);
356 *inode_p = strtoul(lname + PRG_SOCKET_PFX2l, &serr, 0);
357 if (!serr || *serr || *inode_p == ~0)
366 static void prg_cache_load(void)
368 char line[LINE_MAX],eacces=0;
369 int procfdlen,fd,cmdllen,lnamelen;
370 char lname[30],cmdlbuf[512],finbuf[PROGNAME_WIDTH];
372 const char *cs,*cmdlp;
373 DIR *dirproc=NULL,*dirfd=NULL;
374 struct dirent *direproc,*direfd;
376 if (prg_cache_loaded || !flag_prg) return;
378 cmdlbuf[sizeof(cmdlbuf)-1]='\0';
379 if (!(dirproc=opendir(PATH_PROC))) goto fail;
380 while (errno=0,direproc=readdir(dirproc)) {
381 for (cs=direproc->d_name;*cs;cs++)
386 procfdlen=snprintf(line,sizeof(line),PATH_PROC_X_FD,direproc->d_name);
387 if (procfdlen<=0 || procfdlen>=sizeof(line)-5)
396 line[procfdlen] = '/';
398 while ((direfd = readdir(dirfd))) {
400 if (!isdigit(direfd->d_name[0]))
402 if (procfdlen+1+strlen(direfd->d_name)+1>sizeof(line))
404 memcpy(line + procfdlen - PATH_FD_SUFFl, PATH_FD_SUFF "/",
406 strcpy(line + procfdlen + 1, direfd->d_name);
407 lnamelen=readlink(line,lname,sizeof(lname)-1);
408 lname[lnamelen] = '\0'; /*make it a null-terminated string*/
410 if (extract_type_1_socket_inode(lname, &inode) < 0)
411 if (extract_type_2_socket_inode(lname, &inode) < 0)
415 if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >=
418 strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_CMDLINE);
419 fd = open(line, O_RDONLY);
422 cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1);
427 if (cmdllen < sizeof(cmdlbuf) - 1)
428 cmdlbuf[cmdllen]='\0';
429 if (cmdlbuf[0] == '/' && (cmdlp = strrchr(cmdlbuf, '/')))
435 snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp);
436 prg_cache_add(inode, finbuf);
447 if (prg_cache_loaded == 1) {
449 fprintf(stderr,_("(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n"),
453 fprintf(stderr, _("(Not all processes could be identified, non-owned process info\n"
454 " will not be shown, you would have to be root to see it all.)\n"));
458 static const char *netrom_state[] =
466 static int netrom_info(void)
469 char buffer[256], dev[16];
470 int st, vs, vr, sendq, recvq, ret;
472 f = proc_fopen(_PATH_PROCNET_NR);
474 if (errno != ENOENT) {
475 perror(_PATH_PROCNET_NR);
478 if (flag_arg || flag_ver)
479 ESYSNOT("netstat", "AF NETROM");
485 printf(_("Active NET/ROM sockets\n"));
486 printf(_("User Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
487 if (fgets(buffer, 256, f))
490 while (fgets(buffer, 256, f)) {
494 ret = sscanf(buffer + 30, "%s %*x/%*x %*x/%*x %d %d %d %*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d %d %d %*d",
495 dev, &st, &vs, &vr, &sendq, &recvq);
497 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_NR);
500 printf("%-9s %-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
501 buffer, buffer + 10, buffer + 20,
504 vr, vs, sendq, recvq);
511 /* These enums are used by IPX too. :-( */
523 TCP_CLOSING /* now a valid state */
526 #if HAVE_AFINET || HAVE_AFINET6
528 static const char *tcp_state[] =
544 static void finish_this_one(int uid, unsigned long inode, const char *timers)
549 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
550 printf(" %-10s ", pw->pw_name);
552 printf(" %-10d ", uid);
553 printf("%-10lu",inode);
556 printf(" %-" PROGNAME_WIDTHs "s",prg_cache_get(inode));
558 printf(" %s", timers);
562 static void igmp_do_one(int lnr, const char *line,const char *prot)
564 char mcast_addr[128];
566 struct sockaddr_in6 mcastaddr;
567 char addr6[INET6_ADDRSTRLEN];
569 extern struct aftype inet6_aftype;
571 struct sockaddr_in mcastaddr;
574 static int idx_flag = 0;
575 static int igmp6_flag = 0;
576 static char device[16];
577 int num, idx, refcnt;
581 /* igmp6 file does not have any comments on first line */
582 if ( strstr( line, "Device" ) == NULL ) {
586 /* 2.1.x kernels and up have Idx field */
587 /* 2.0.x and below do not have Idx field */
588 if ( strncmp( line, "Idx", strlen("Idx") ) == 0 )
596 if (igmp6_flag) { /* IPV6 */
598 num = sscanf( line, "%d %15s %64[0-9A-Fa-f] %d", &idx, device, mcast_addr, &refcnt );
600 /* Demangle what the kernel gives us */
601 sscanf(mcast_addr, "%08X%08X%08X%08X",
602 &in6.s6_addr32[0], &in6.s6_addr32[1],
603 &in6.s6_addr32[2], &in6.s6_addr32[3]);
604 in6.s6_addr32[0] = htonl(in6.s6_addr32[0]);
605 in6.s6_addr32[1] = htonl(in6.s6_addr32[1]);
606 in6.s6_addr32[2] = htonl(in6.s6_addr32[2]);
607 in6.s6_addr32[3] = htonl(in6.s6_addr32[3]);
608 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
609 inet6_aftype.input(1, addr6, (struct sockaddr *) &mcastaddr);
610 mcastaddr.sin6_family = AF_INET6;
612 fprintf(stderr, _("warning, got bogus igmp6 line %d.\n"), lnr);
616 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
617 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
618 ((struct sockaddr *) &mcastaddr)->sa_family);
621 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
622 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
623 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr);
627 if (line[0] != '\t') {
629 if ((num = sscanf( line, "%d\t%10c", &idx, device)) < 2) {
630 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
634 if ( (num = sscanf( line, "%10c", device )) < 1 ) {
635 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
641 } else if ( line[0] == '\t' ) {
642 if ( (num = sscanf(line, "\t%8[0-9A-Fa-f] %d", mcast_addr, &refcnt)) < 2 ) {
643 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
646 sscanf( mcast_addr, "%X",
647 &((struct sockaddr_in *) &mcastaddr)->sin_addr.s_addr );
648 ((struct sockaddr *) &mcastaddr)->sa_family = AF_INET;
650 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
654 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
655 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
656 ((struct sockaddr *) &mcastaddr)->sa_family);
659 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
660 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
661 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr );
667 static int x25_info(void)
669 FILE *f=proc_fopen(_PATH_PROCNET_X25);
670 char buffer[256],dev[16];
671 int st,vs,vr,sendq,recvq,lci;
672 static char *x25_state[5]=
680 if(!(f=proc_fopen(_PATH_PROCNET_X25)))
682 if (errno != ENOENT) {
683 perror(_PATH_PROCNET_X25);
686 if (flag_arg || flag_ver)
687 ESYSNOT("netstat","AF X25");
693 printf( _("Active X.25 sockets\n"));
694 /* IMHO, Vr/Vs is not very usefull --SF */
695 printf( _("Dest Source Device LCI State Vr/Vs Send-Q Recv-Q\n"));
696 if (fgets(buffer,256,f))
698 while(fgets(buffer,256,f))
702 sscanf(buffer+22,"%s %d %d %d %d %*d %*d %*d %*d %*d %*d %d %d %*d",
703 dev,&lci,&st,&vs,&vr,&sendq,&recvq);
704 if (!(flag_all || lci))
706 printf("%-15s %-15s %-7s %-3d %-11s %02d/%02d %-6d %-6d\n",
718 static int igmp_info(void)
720 INFO_GUTS6(_PATH_PROCNET_IGMP, _PATH_PROCNET_IGMP6, "AF INET (igmp)",
721 igmp_do_one, "igmp", "igmp6");
724 static int ip_parse_dots(uint32_t *addr, char const *src) {
726 unsigned ret = 4-sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d);
727 *addr = htonl((a << 24)|(b << 16)|(c << 8)|d);
731 static void print_ip_service(struct sockaddr_in *addr, char const *protname,
732 char *buf, unsigned size) {
735 if(size == 0) return;
738 if((ap = get_afntype(addr->sin_family)) == NULL) {
739 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
743 safe_strncpy(buf, ap->sprint((struct sockaddr*)addr, flag_not), size);
746 if(flag_all || (flag_lst && !addr->sin_port) || (!flag_lst && addr->sin_port)) {
749 snprintf(bfs, sizeof(bfs), "%s",
750 get_sname(addr->sin_port, (char*)protname, flag_not & FLAG_NUM_PORT));
752 /* check if we must cut on host and/or service name */
754 unsigned const bufl = strlen(buf);
755 unsigned const bfsl = strlen(bfs);
757 if(bufl+bfsl+2 > size) {
758 unsigned const half = (size-2)>>1;
761 buf[size-2-half] = '\0';
764 else buf[size-2-bfsl] = '\0';
766 else bfs[size-2-bufl] = '\0';
774 /* process single SCTP endpoint */
775 static void sctp_do_ept(int lnr, char const *line, const char *prot)
777 struct sockaddr_in laddr, raddr;
780 char l_addr[23], r_addr[23];
782 /* fill sockaddr_in structures */
788 if(sscanf(line, "%*X %*X %*u %*u %*u %u %u %u %n",
789 &lport, &uid, &inode, &ate) < 3) goto err;
791 /* decode IP address */
792 if(ip_parse_dots(&laddr.sin_addr.s_addr, line+ate)) goto err;
793 raddr.sin_addr.s_addr = htonl(0);
794 laddr.sin_family = raddr.sin_family = AF_INET;
795 laddr.sin_port = htons(lport);
796 raddr.sin_port = htons(0);
799 /* print IP:service to l_addr and r_addr */
800 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
801 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
804 printf("%-4s %6d %6d %-*s %-*s %-11s",
806 (int)netmax(23,strlen(l_addr)), l_addr,
807 (int)netmax(23,strlen(r_addr)), r_addr,
808 _(tcp_state[TCP_LISTEN]));
809 finish_this_one(uid, inode, "");
812 fprintf(stderr, "SCTP error in line: %d\n", lnr);
815 /* process single SCTP association */
816 static void sctp_do_assoc(int lnr, char const *line, const char *prot)
818 struct sockaddr_in laddr, raddr;
819 unsigned long rxq, txq;
822 char l_addr[23], r_addr[23];
824 /* fill sockaddr_in structures */
826 unsigned lport, rport;
831 if(sscanf(line, "%*X %*X %*u %*u %*u %*u %*u %lu %lu %u %u %u %u %n",
832 &txq, &rxq, &uid, &inode, &lport, &rport, &ate) < 6) goto err;
834 /* decode IP addresses */
835 addr = strchr(line+ate, '*');
836 if(addr == 0) goto err;
837 if(ip_parse_dots(&laddr.sin_addr.s_addr, ++addr)) goto err;
838 addr = strchr(addr, '*');
839 if(addr == 0) goto err;
840 if(ip_parse_dots(&raddr.sin_addr.s_addr, ++addr)) goto err;
842 /* complete sockaddr_in structures */
843 laddr.sin_family = raddr.sin_family = AF_INET;
844 laddr.sin_port = htons(lport);
845 raddr.sin_port = htons(rport);
848 /* print IP:service to l_addr and r_addr */
849 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
850 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
853 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
855 (int)netmax(23,strlen(l_addr)), l_addr,
856 (int)netmax(23,strlen(r_addr)), r_addr,
857 _(tcp_state[TCP_ESTABLISHED]));
858 finish_this_one(uid, inode, "");
861 fprintf(stderr, "SCTP error in line: %d\n", lnr);
864 static int sctp_info_epts(void) {
865 INFO_GUTS6(_PATH_PROCNET_SCTPEPTS, _PATH_PROCNET_SCTP6EPTS, "AF INET (sctp)",
866 sctp_do_ept, "sctp", "sctp6");
869 static int sctp_info_assocs(void) {
870 INFO_GUTS6(_PATH_PROCNET_SCTPASSOCS, _PATH_PROCNET_SCTP6ASSOCS, "AF INET (sctp)",
871 sctp_do_assoc, "sctp", "sctp6");
874 static int sctp_info(void) {
876 res = sctp_info_epts();
878 return sctp_info_assocs();
881 static void addr_do_one(char *buf, size_t buf_len, size_t short_len, struct aftype *ap,
883 struct sockaddr_in6 *addr,
885 struct sockaddr_in *addr,
887 int port, const char *proto
890 const char *sport, *saddr;
891 size_t port_len, addr_len;
893 saddr = ap->sprint((struct sockaddr *)addr, flag_not & FLAG_NUM_HOST);
894 sport = get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT);
895 addr_len = strlen(saddr);
896 port_len = strlen(sport);
897 if (!flag_wide && (addr_len + port_len > short_len)) {
898 /* Assume port name is short */
899 port_len = netmin(port_len, short_len - 4);
900 addr_len = short_len - port_len;
901 strncpy(buf, saddr, addr_len);
902 buf[addr_len] = '\0';
904 strncat(buf, sport, port_len);
906 snprintf(buf, buf_len, "%s:%s", saddr, sport);
909 static void tcp_do_one(int lnr, const char *line, const char *prot)
911 unsigned long rxq, txq, time_len, retr, inode;
912 int num, local_port, rem_port, d, state, uid, timer_run, timeout;
913 char rem_addr[128], local_addr[128], timers[64], more[512];
916 struct sockaddr_in6 localaddr, remaddr;
917 char addr6[INET6_ADDRSTRLEN];
919 extern struct aftype inet6_aftype;
921 struct sockaddr_in localaddr, remaddr;
928 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %512s\n",
929 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
930 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
932 if (!flag_all && ((flag_lst && rem_port) || (!flag_lst && !rem_port)))
935 if (strlen(local_addr) > 8) {
937 /* Demangle what the kernel gives us */
938 sscanf(local_addr, "%08X%08X%08X%08X",
939 &in6.s6_addr32[0], &in6.s6_addr32[1],
940 &in6.s6_addr32[2], &in6.s6_addr32[3]);
941 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
942 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
943 sscanf(rem_addr, "%08X%08X%08X%08X",
944 &in6.s6_addr32[0], &in6.s6_addr32[1],
945 &in6.s6_addr32[2], &in6.s6_addr32[3]);
946 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
947 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
948 localaddr.sin6_family = AF_INET6;
949 remaddr.sin6_family = AF_INET6;
952 sscanf(local_addr, "%X",
953 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
954 sscanf(rem_addr, "%X",
955 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
956 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
957 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
961 fprintf(stderr, _("warning, got bogus tcp line.\n"));
964 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
965 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
966 ((struct sockaddr *) &localaddr)->sa_family);
970 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "tcp");
971 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "tcp");
977 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
981 snprintf(timers, sizeof(timers), _("on (%2.2f/%ld/%d)"),
982 (double) time_len / HZ, retr, timeout);
986 snprintf(timers, sizeof(timers), _("keepalive (%2.2f/%ld/%d)"),
987 (double) time_len / HZ, retr, timeout);
991 snprintf(timers, sizeof(timers), _("timewait (%2.2f/%ld/%d)"),
992 (double) time_len / HZ, retr, timeout);
996 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
997 timer_run, (double) time_len / HZ, retr, timeout);
1001 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
1002 prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
1004 finish_this_one(uid,inode,timers);
1007 static int tcp_info(void)
1009 INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
1010 tcp_do_one, "tcp", "tcp6");
1013 static void udp_do_one(int lnr, const char *line,const char *prot)
1015 char local_addr[64], rem_addr[64];
1016 char *udp_state, timers[64], more[512];
1017 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1019 struct sockaddr_in6 localaddr, remaddr;
1020 char addr6[INET6_ADDRSTRLEN];
1021 struct in6_addr in6;
1022 extern struct aftype inet6_aftype;
1024 struct sockaddr_in localaddr, remaddr;
1027 unsigned long rxq, txq, time_len, retr, inode;
1034 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1035 &d, local_addr, &local_port,
1036 rem_addr, &rem_port, &state,
1037 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1039 if (strlen(local_addr) > 8) {
1041 sscanf(local_addr, "%08X%08X%08X%08X",
1042 &in6.s6_addr32[0], &in6.s6_addr32[1],
1043 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1044 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1045 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1046 sscanf(rem_addr, "%08X%08X%08X%08X",
1047 &in6.s6_addr32[0], &in6.s6_addr32[1],
1048 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1049 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1050 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1051 localaddr.sin6_family = AF_INET6;
1052 remaddr.sin6_family = AF_INET6;
1055 sscanf(local_addr, "%X",
1056 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1057 sscanf(rem_addr, "%X",
1058 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1059 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1060 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1068 fprintf(stderr, _("warning, got bogus udp line.\n"));
1071 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
1072 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
1073 ((struct sockaddr *) &localaddr)->sa_family);
1077 case TCP_ESTABLISHED:
1078 udp_state = _("ESTABLISHED");
1086 udp_state = _("UNKNOWN");
1091 #define notnull(A) (((A.sin6_family == AF_INET6) && \
1092 ((A.sin6_addr.s6_addr32[0]) || \
1093 (A.sin6_addr.s6_addr32[1]) || \
1094 (A.sin6_addr.s6_addr32[2]) || \
1095 (A.sin6_addr.s6_addr32[3]))) || \
1096 ((A.sin6_family == AF_INET) && \
1097 ((struct sockaddr_in *) &A)->sin_addr.s_addr))
1099 #define notnull(A) (A.sin_addr.s_addr)
1102 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1104 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "udp");
1105 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "udp");
1109 switch (timer_run) {
1111 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1116 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100, retr, timeout);
1120 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1124 printf("%-5s %6ld %6ld %-23s %-23s %-11s",
1125 prot, rxq, txq, local_addr, rem_addr, udp_state);
1127 finish_this_one(uid,inode,timers);
1131 static int udp_info(void)
1133 INFO_GUTS6(_PATH_PROCNET_UDP, _PATH_PROCNET_UDP6, "AF INET (udp)",
1134 udp_do_one, "udp", "udp6");
1137 static int udplite_info(void)
1139 INFO_GUTS6(_PATH_PROCNET_UDPLITE, _PATH_PROCNET_UDPLITE6,
1140 "AF INET (udplite)", udp_do_one, "udpl", "udpl6" );
1143 static void raw_do_one(int lnr, const char *line,const char *prot)
1145 char local_addr[64], rem_addr[64];
1146 char timers[64], more[512];
1147 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1149 struct sockaddr_in6 localaddr, remaddr;
1150 char addr6[INET6_ADDRSTRLEN];
1151 struct in6_addr in6;
1152 extern struct aftype inet6_aftype;
1154 struct sockaddr_in localaddr, remaddr;
1157 unsigned long rxq, txq, time_len, retr, inode;
1164 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1165 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
1166 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1168 if (strlen(local_addr) > 8) {
1170 sscanf(local_addr, "%08X%08X%08X%08X",
1171 &in6.s6_addr32[0], &in6.s6_addr32[1],
1172 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1173 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1174 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1175 sscanf(rem_addr, "%08X%08X%08X%08X",
1176 &in6.s6_addr32[0], &in6.s6_addr32[1],
1177 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1178 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1179 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1180 localaddr.sin6_family = AF_INET6;
1181 remaddr.sin6_family = AF_INET6;
1184 sscanf(local_addr, "%X",
1185 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1186 sscanf(rem_addr, "%X",
1187 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1188 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1189 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1192 if ((ap = get_afntype(localaddr.sin6_family)) == NULL) {
1193 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin6_family);
1197 if ((ap = get_afntype(localaddr.sin_family)) == NULL) {
1198 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin_family);
1207 fprintf(stderr, _("warning, got bogus raw line.\n"));
1211 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1213 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "raw");
1214 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "raw");
1218 switch (timer_run) {
1220 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1225 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1230 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
1231 timer_run, (double) time_len / 100,
1235 printf("%-4s %6ld %6ld %-23s %-23s %-11d",
1236 prot, rxq, txq, local_addr, rem_addr, state);
1238 finish_this_one(uid,inode,timers);
1242 static int raw_info(void)
1244 INFO_GUTS6(_PATH_PROCNET_RAW, _PATH_PROCNET_RAW6, "AF INET (raw)",
1245 raw_do_one, "raw", "raw6");
1255 static void unix_do_one(int nr, const char *line, const char *prot)
1258 char path[MAXPATHLEN], ss_flags[32];
1259 char *ss_proto, *ss_state, *ss_type;
1260 int num, state, type;
1262 unsigned long refcnt, proto, flags, inode;
1265 if (strstr(line, "Inode"))
1270 num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %s",
1271 &d, &refcnt, &proto, &flags, &type, &state, &inode, path);
1273 fprintf(stderr, _("warning, got bogus unix line.\n"));
1276 if (!(has & HAS_INODE))
1277 snprintf(path,sizeof(path),"%lu",inode);
1280 if ((state == SS_UNCONNECTED) && (flags & SO_ACCEPTCON)) {
1300 ss_type = _("STREAM");
1304 ss_type = _("DGRAM");
1315 case SOCK_SEQPACKET:
1316 ss_type = _("SEQPACKET");
1320 ss_type = _("UNKNOWN");
1325 ss_state = _("FREE");
1328 case SS_UNCONNECTED:
1330 * Unconnected sockets may be listening
1333 if (flags & SO_ACCEPTCON) {
1334 ss_state = _("LISTENING");
1341 ss_state = _("CONNECTING");
1345 ss_state = _("CONNECTED");
1348 case SS_DISCONNECTING:
1349 ss_state = _("DISCONNECTING");
1353 ss_state = _("UNKNOWN");
1356 strcpy(ss_flags, "[ ");
1357 if (flags & SO_ACCEPTCON)
1358 strcat(ss_flags, "ACC ");
1359 if (flags & SO_WAITDATA)
1360 strcat(ss_flags, "W ");
1361 if (flags & SO_NOSPACE)
1362 strcat(ss_flags, "N ");
1364 strcat(ss_flags, "]");
1366 printf("%-5s %-6ld %-11s %-10s %-13s ",
1367 ss_proto, refcnt, ss_flags, ss_type, ss_state);
1368 if (has & HAS_INODE)
1369 printf("%-8lu",inode);
1373 printf(" %-" PROGNAME_WIDTHs "s",(has & HAS_INODE?prg_cache_get(inode):"-"));
1375 printf(" %s\n", path);
1378 static int unix_info(void)
1381 printf(_("Active UNIX domain sockets "));
1383 printf(_("(servers and established)"));
1386 printf(_("(only servers)"));
1388 printf(_("(w/o servers)"));
1391 printf(_("\nProto RefCnt Flags Type State I-Node "));
1392 print_progname_banner();
1393 printf(_(" Path\n")); /* xxx */
1396 INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one, "unix");
1403 static int ax25_info(void)
1406 char buffer[256], buf[16];
1407 char *src, *dst, *dev, *p;
1408 int st, vs, vr, sendq, recvq, ret;
1409 int new = -1; /* flag for new (2.1.x) kernels */
1410 static char *ax25_state[5] =
1418 if (!(f = proc_fopen(_PATH_PROCNET_AX25))) {
1419 if (errno != ENOENT) {
1420 perror(_PATH_PROCNET_AX25);
1423 if (flag_arg || flag_ver)
1424 ESYSNOT("netstat", "AF AX25");
1430 printf(_("Active AX.25 sockets\n"));
1431 printf(_("Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
1432 while (fgets(buffer, 256, f)) {
1434 if (!strncmp(buffer, "dest_addr", 9)) {
1436 continue; /* old kernels have a header line */
1441 * In a network connection with no user socket the Snd-Q, Rcv-Q
1442 * and Inode fields are empty in 2.0.x and '*' in 2.1.x
1451 ret = sscanf(buffer + 20, "%s %d %d %d %*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d/%*d %*d %*d %*d %d %d %*d",
1452 buf, &st, &vs, &vr, &sendq, &recvq);
1453 if (ret != 4 && ret != 6) {
1454 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_AX25);
1460 while (*p != ' ') p++;
1463 while (*p != ' ') p++;
1466 while (*p != ' ') p++;
1469 while (*p != ' ') p++;
1471 ret = sscanf(p, "%d %d %d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %*d",
1472 &st, &vs, &vr, &sendq, &recvq);
1473 if (ret != 3 && ret != 5) {
1474 printf(_("problem reading data from %s\n"), _PATH_PROCNET_AX25);
1478 * FIXME: digipeaters should be handled somehow.
1479 * For now we just strip them.
1482 while (*p && *p != ',') p++;
1485 printf("%-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
1489 vr, vs, sendq, recvq);
1498 static int ipx_info(void)
1502 unsigned long txq, rxq;
1509 char sad[50], dad[50];
1511 unsigned sport = 0, dport = 0;
1514 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET1);
1516 if (errno != ENOENT) {
1517 perror(_PATH_PROCNET_IPX_SOCKET1);
1520 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET2);
1522 /* We need to check for directory */
1524 fstat(fileno(f), &s);
1525 if (!S_ISREG(s.st_mode)) {
1532 if (errno != ENOENT) {
1533 perror(_PATH_PROCNET_IPX_SOCKET2);
1536 if (flag_arg || flag_ver)
1537 ESYSNOT("netstat", "AF IPX");
1544 printf(_("Active IPX sockets\nProto Recv-Q Send-Q Local Address Foreign Address State")); /* xxx */
1546 printf(_(" User")); /* xxx */
1548 if ((ap = get_afntype(AF_IPX)) == NULL) {
1549 EINTERN("netstat.c", "AF_IPX missing");
1552 if (fgets(buf, 255, f))
1555 while (fgets(buf, 255, f) != NULL) {
1556 sscanf(buf, "%s %s %lX %lX %d %d",
1557 sad, dad, &txq, &rxq, &state, &uid);
1558 if ((st = rindex(sad, ':'))) {
1560 sscanf(st, "%X", &sport); /* net byt order */
1561 sport = ntohs(sport);
1563 EINTERN("netstat.c", "ipx socket format error in source port");
1567 if (strcmp(dad, "Not_Connected") != 0) {
1568 if ((st = rindex(dad, ':'))) {
1570 sscanf(st, "%X", &dport); /* net byt order */
1571 dport = ntohs(dport);
1573 EINTERN("netstat.c", "ipx soket format error in destination port");
1580 case TCP_ESTABLISHED:
1593 /* Fetch and resolve the Source */
1594 (void) ap->input(4, sad, &sa);
1595 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1596 snprintf(sad, sizeof(sad), "%s:%04X", buf, sport);
1599 /* Fetch and resolve the Destination */
1600 (void) ap->input(4, dad, &sa);
1601 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1602 snprintf(dad, sizeof(dad), "%s:%04X", buf, dport);
1606 printf("IPX %6ld %6ld %-26s %-26s %-5s", txq, rxq, sad, dad, st);
1608 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
1609 printf(" %-10s", pw->pw_name);
1611 printf(" %-10d", uid);
1621 const char *bluetooth_state(int state)
1625 return _("CONNECTED");
1633 return _("CONNECT");
1635 return _("CONNECT2");
1639 return _("DISCONN");
1643 return _("UNKNOWN");
1647 static void l2cap_do_one(int nr, const char *line, const char *prot)
1649 char daddr[18], saddr[18];
1650 unsigned state, psm, dcid, scid, imtu, omtu, sec_level;
1652 const char *bt_state, *bt_sec_level;
1654 num = sscanf(line, "%17s %17s %d %d 0x%04x 0x%04x %d %d %d",
1655 daddr, saddr, &state, &psm, &dcid, &scid, &imtu, &omtu, &sec_level);
1658 fprintf(stderr, _("warning, got bogus l2cap line.\n"));
1662 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1664 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1667 bt_state = bluetooth_state(state);
1668 switch (sec_level) {
1669 case BT_SECURITY_SDP:
1670 bt_sec_level = _("SDP");
1672 case BT_SECURITY_LOW:
1673 bt_sec_level = _("LOW");
1675 case BT_SECURITY_MEDIUM:
1676 bt_sec_level = _("MEDIUM");
1678 case BT_SECURITY_HIGH:
1679 bt_sec_level = _("HIGH");
1682 bt_sec_level = _("UNKNOWN");
1685 printf("l2cap %-17s %-17s %-9s %7d 0x%04x 0x%04x %7d %7d %-7s\n",
1686 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1687 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1688 bt_state, psm, dcid, scid, imtu, omtu, bt_sec_level);
1691 static int l2cap_info(void)
1693 printf("%-6s %-17s %-17s %-9s %7s %-6s %-6s %7s %7s %-7s\n",
1694 "Proto", "Destination", "Source", "State", "PSM", "DCID", "SCID", "IMTU", "OMTU", "Security");
1695 INFO_GUTS(_PATH_SYS_BLUETOOTH_L2CAP, "AF BLUETOOTH", l2cap_do_one, "l2cap");
1698 static void rfcomm_do_one(int nr, const char *line, const char *prot)
1700 char daddr[18], saddr[18];
1701 unsigned state, channel;
1703 const char *bt_state;
1705 num = sscanf(line, "%17s %17s %d %d", daddr, saddr, &state, &channel);
1707 fprintf(stderr, _("warning, got bogus rfcomm line.\n"));
1711 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1713 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1716 bt_state = bluetooth_state(state);
1717 printf("rfcomm %-17s %-17s %-9s %7d\n",
1718 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1719 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1723 static int rfcomm_info(void)
1725 printf("%-6s %-17s %-17s %-9s %7s\n", "Proto", "Destination", "Source", "State", "Channel");
1726 INFO_GUTS(_PATH_SYS_BLUETOOTH_RFCOMM, "AF BLUETOOTH", rfcomm_do_one, "rfcomm");
1730 static int iface_info(void)
1733 if ((skfd = sockets_open(0)) < 0) {
1737 printf(_("Kernel Interface table\n"));
1741 printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
1744 if (for_all_interfaces(do_if_print, &flag_all) < 0) {
1745 perror(_("missing interface information"));
1759 static void version(void)
1761 printf("%s\n%s\n%s\n%s\n", Release, Version, Signature, Features);
1766 static void usage(void)
1768 fprintf(stderr, _("usage: netstat [-vWeenNcCF] [<Af>] -r netstat {-V|--version|-h|--help}\n"));
1769 fprintf(stderr, _(" netstat [-vWnNcaeol] [<Socket> ...]\n"));
1770 fprintf(stderr, _(" netstat { [-vWeenNac] -i | [-cnNe] -M | -s [-6tuw] }\n\n"));
1772 fprintf(stderr, _(" -r, --route display routing table\n"));
1773 fprintf(stderr, _(" -i, --interfaces display interface table\n"));
1774 fprintf(stderr, _(" -g, --groups display multicast group memberships\n"));
1775 fprintf(stderr, _(" -s, --statistics display networking statistics (like SNMP)\n"));
1776 #if HAVE_FW_MASQUERADE
1777 fprintf(stderr, _(" -M, --masquerade display masqueraded connections\n\n"));
1779 fprintf(stderr, _(" -v, --verbose be verbose\n"));
1780 fprintf(stderr, _(" -W, --wide don't truncate IP addresses\n"));
1781 fprintf(stderr, _(" -n, --numeric don't resolve names\n"));
1782 fprintf(stderr, _(" --numeric-hosts don't resolve host names\n"));
1783 fprintf(stderr, _(" --numeric-ports don't resolve port names\n"));
1784 fprintf(stderr, _(" --numeric-users don't resolve user names\n"));
1785 fprintf(stderr, _(" -N, --symbolic resolve hardware names\n"));
1786 fprintf(stderr, _(" -e, --extend display other/more information\n"));
1787 fprintf(stderr, _(" -p, --programs display PID/Program name for sockets\n"));
1788 fprintf(stderr, _(" -c, --continuous continuous listing\n\n"));
1789 fprintf(stderr, _(" -l, --listening display listening server sockets\n"));
1790 fprintf(stderr, _(" -a, --all, --listening display all sockets (default: connected)\n"));
1791 fprintf(stderr, _(" -o, --timers display timers\n"));
1792 fprintf(stderr, _(" -F, --fib display Forwarding Information Base (default)\n"));
1793 fprintf(stderr, _(" -C, --cache display routing cache instead of FIB\n\n"));
1795 fprintf(stderr, _(" <Socket>={-t|--tcp} {-u|--udp} {-U|--udplite} {-w|--raw} {-x|--unix} --ax25 --ipx --netrom\n"));
1796 fprintf(stderr, _(" <AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
1797 fprintf(stderr, _(" List of possible address families (which support routing):\n"));
1798 print_aflist(1); /* 1 = routeable */
1804 (int argc, char *argv[]) {
1807 static struct option longopts[] =
1810 {"version", 0, 0, 'V'},
1811 {"interfaces", 0, 0, 'i'},
1812 {"help", 0, 0, 'h'},
1813 {"route", 0, 0, 'r'},
1814 #if HAVE_FW_MASQUERADE
1815 {"masquerade", 0, 0, 'M'},
1817 {"protocol", 1, 0, 'A'},
1819 {"sctp", 0, 0, 'S'},
1821 {"udplite", 0, 0, 'U'},
1823 {"unix", 0, 0, 'x'},
1824 {"l2cap", 0, 0, '2'},
1825 {"rfcomm", 0, 0, 'f'},
1826 {"listening", 0, 0, 'l'},
1828 {"timers", 0, 0, 'o'},
1829 {"continuous", 0, 0, 'c'},
1830 {"extend", 0, 0, 'e'},
1831 {"programs", 0, 0, 'p'},
1832 {"verbose", 0, 0, 'v'},
1833 {"statistics", 0, 0, 's'},
1834 {"wide", 0, 0, 'W'},
1835 {"numeric", 0, 0, 'n'},
1836 {"numeric-hosts", 0, 0, '!'},
1837 {"numeric-ports", 0, 0, '@'},
1838 {"numeric-users", 0, 0, '#'},
1839 {"symbolic", 0, 0, 'N'},
1840 {"cache", 0, 0, 'C'},
1842 {"groups", 0, 0, 'g'},
1847 setlocale (LC_ALL, "");
1848 bindtextdomain("net-tools", "/usr/share/locale");
1849 textdomain("net-tools");
1851 getroute_init(); /* Set up AF routing support */
1854 while ((i = getopt_long(argc, argv, "A:CFMacdeghilnNoprsStuUvVWwx64?", longopts, &lop)) != EOF)
1859 if (lop < 0 || lop >= AFTRANS_CNT) {
1860 EINTERN("netstat.c", "longopts 1 range");
1863 if (aftrans_opt(longopts[lop].name))
1867 if (aftrans_opt(optarg))
1902 flag_not |= FLAG_NUM;
1905 flag_not |= FLAG_NUM_HOST;
1908 flag_not |= FLAG_NUM_PORT;
1911 flag_not |= FLAG_NUM_USER;
1914 flag_not |= FLAG_SYM;
1917 flag_cf |= FLAG_CACHE;
1920 flag_cf |= FLAG_FIB;
1926 if (aftrans_opt("inet6"))
1930 if (aftrans_opt("inet"))
1937 flag_ver |= FLAG_VERBOSE;
1964 if (aftrans_opt("unix"))
1974 if (flag_int + flag_rou + flag_mas + flag_sta > 1)
1977 if ((flag_inet || flag_inet6 || flag_sta) &&
1978 !(flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw))
1979 flag_tcp = flag_sctp = flag_udp = flag_udplite = flag_raw = 1;
1981 if ((flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw || flag_igmp) &&
1982 !(flag_inet || flag_inet6))
1983 flag_inet = flag_inet6 = 1;
1985 if (flag_bluetooth && !(flag_l2cap || flag_rfcomm))
1986 flag_l2cap = flag_rfcomm = 1;
1988 flag_arg = flag_tcp + flag_sctp + flag_udplite + flag_udp + flag_raw + flag_unx
1989 + flag_ipx + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose
1990 + flag_l2cap + flag_rfcomm;
1993 #if HAVE_FW_MASQUERADE && HAVE_AFINET
1994 #if MORE_THAN_ONE_MASQ_AF
1996 strcpy(afname, DFLT_AF);
1999 i = ip_masq_info(flag_not & FLAG_NUM_HOST,
2000 flag_not & FLAG_NUM_PORT, flag_exp);
2006 ENOSUPP("netstat", "FW_MASQUERADE");
2014 strcpy(afname, DFLT_AF);
2016 if (!strcmp(afname, "inet")) {
2019 parsesnmp(flag_raw, flag_tcp, flag_udp);
2021 ENOSUPP("netstat", "AF INET");
2023 } else if(!strcmp(afname, "inet6")) {
2026 parsesnmp6(flag_raw, flag_tcp, flag_udp);
2028 ENOSUPP("netstat", "AF INET6");
2031 printf(_("netstat: No statistics support for specified address family: %s\n"), afname);
2041 strcpy(afname, DFLT_AF);
2045 else if (flag_exp == 1)
2048 options = (flag_exp & FLAG_EXT) | flag_not | flag_cf | flag_ver;
2050 options |= FLAG_FIB;
2053 i = route_info(afname, options);
2070 if (!flag_arg || flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw) {
2073 printf(_("Active Internet connections ")); /* xxx */
2076 printf(_("(servers and established)"));
2079 printf(_("(only servers)"));
2081 printf(_("(w/o servers)"));
2083 printf(_("\nProto Recv-Q Send-Q Local Address Foreign Address State ")); /* xxx */
2085 printf(_(" User Inode "));
2086 print_progname_banner();
2088 printf(_(" Timer")); /* xxx */
2093 ENOSUPP("netstat", "AF INET");
2098 if (!flag_arg || flag_tcp) {
2104 if (!flag_arg || flag_sctp) {
2110 if (!flag_arg || flag_udp) {
2116 if (!flag_arg || flag_udplite) {
2122 if (!flag_arg || flag_raw) {
2132 printf( _("IPv4 Group Memberships\n") );
2133 printf( _("Interface RefCnt Group\n") );
2134 printf( "--------------- ------ ---------------------\n" );
2141 if (!flag_arg || flag_unx) {
2150 ENOSUPP("netstat", "AF UNIX");
2154 if (!flag_arg || flag_ipx) {
2162 ENOSUPP("netstat", "AF IPX");
2166 if (!flag_arg || flag_ax25) {
2174 ENOSUPP("netstat", "AF AX25");
2178 if(!flag_arg || flag_x25) {
2187 ENOSUPP("netstat", "AF X25");
2191 if (!flag_arg || flag_netrom) {
2199 ENOSUPP("netstat", "AF NETROM");
2203 if (!flag_arg || flag_rose) {
2204 #if 0 && HAVE_AFROSE
2211 ENOSUPP("netstat", "AF ROSE");
2216 if (!flag_arg || flag_l2cap || flag_rfcomm) {
2218 printf(_("Active Bluetooth connections ")); /* xxx */
2221 printf(_("(servers and established)"));
2224 printf(_("(only servers)"));
2226 printf(_("(w/o servers)"));
2232 ENOSUPP("netstat", "AF BLUETOOTH");
2237 if (!flag_arg || flag_l2cap) {
2242 if (!flag_arg || flag_rfcomm) {