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);
410 lname[lnamelen] = '\0'; /*make it a null-terminated string*/
412 if (extract_type_1_socket_inode(lname, &inode) < 0)
413 if (extract_type_2_socket_inode(lname, &inode) < 0)
417 if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >=
420 strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_CMDLINE);
421 fd = open(line, O_RDONLY);
424 cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1);
429 if (cmdllen < sizeof(cmdlbuf) - 1)
430 cmdlbuf[cmdllen]='\0';
431 if (cmdlbuf[0] == '/' && (cmdlp = strrchr(cmdlbuf, '/')))
437 snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp);
438 prg_cache_add(inode, finbuf);
449 if (prg_cache_loaded == 1) {
451 fprintf(stderr,_("(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n"),
455 fprintf(stderr, _("(Not all processes could be identified, non-owned process info\n"
456 " will not be shown, you would have to be root to see it all.)\n"));
460 static const char *netrom_state[] =
468 static int netrom_info(void)
471 char buffer[256], dev[16];
472 int st, vs, vr, sendq, recvq, ret;
474 f = proc_fopen(_PATH_PROCNET_NR);
476 if (errno != ENOENT) {
477 perror(_PATH_PROCNET_NR);
480 if (flag_arg || flag_ver)
481 ESYSNOT("netstat", "AF NETROM");
487 printf(_("Active NET/ROM sockets\n"));
488 printf(_("User Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
489 if (fgets(buffer, 256, f))
492 while (fgets(buffer, 256, f)) {
496 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",
497 dev, &st, &vs, &vr, &sendq, &recvq);
499 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_NR);
502 printf("%-9s %-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
503 buffer, buffer + 10, buffer + 20,
506 vr, vs, sendq, recvq);
513 /* These enums are used by IPX too. :-( */
525 TCP_CLOSING /* now a valid state */
528 #if HAVE_AFINET || HAVE_AFINET6
530 static const char *tcp_state[] =
546 static void finish_this_one(int uid, unsigned long inode, const char *timers)
551 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
552 printf(" %-10s ", pw->pw_name);
554 printf(" %-10d ", uid);
555 printf("%-10lu",inode);
558 printf(" %-" PROGNAME_WIDTHs "s",prg_cache_get(inode));
560 printf(" %s", timers);
564 static void igmp_do_one(int lnr, const char *line,const char *prot)
566 char mcast_addr[128];
568 struct sockaddr_in6 mcastaddr;
569 char addr6[INET6_ADDRSTRLEN];
571 extern struct aftype inet6_aftype;
573 struct sockaddr_in mcastaddr;
576 static int idx_flag = 0;
577 static int igmp6_flag = 0;
578 static char device[16];
579 int num, idx, refcnt;
583 /* igmp6 file does not have any comments on first line */
584 if ( strstr( line, "Device" ) == NULL ) {
588 /* 2.1.x kernels and up have Idx field */
589 /* 2.0.x and below do not have Idx field */
590 if ( strncmp( line, "Idx", strlen("Idx") ) == 0 )
598 if (igmp6_flag) { /* IPV6 */
600 num = sscanf( line, "%d %15s %64[0-9A-Fa-f] %d", &idx, device, mcast_addr, &refcnt );
602 /* Demangle what the kernel gives us */
603 sscanf(mcast_addr, "%08X%08X%08X%08X",
604 &in6.s6_addr32[0], &in6.s6_addr32[1],
605 &in6.s6_addr32[2], &in6.s6_addr32[3]);
606 in6.s6_addr32[0] = htonl(in6.s6_addr32[0]);
607 in6.s6_addr32[1] = htonl(in6.s6_addr32[1]);
608 in6.s6_addr32[2] = htonl(in6.s6_addr32[2]);
609 in6.s6_addr32[3] = htonl(in6.s6_addr32[3]);
610 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
611 inet6_aftype.input(1, addr6, (struct sockaddr *) &mcastaddr);
612 mcastaddr.sin6_family = AF_INET6;
614 fprintf(stderr, _("warning, got bogus igmp6 line %d.\n"), lnr);
618 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
619 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
620 ((struct sockaddr *) &mcastaddr)->sa_family);
623 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
624 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
625 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr);
629 if (line[0] != '\t') {
631 if ((num = sscanf( line, "%d\t%10c", &idx, device)) < 2) {
632 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
636 if ( (num = sscanf( line, "%10c", device )) < 1 ) {
637 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
643 } else if ( line[0] == '\t' ) {
644 if ( (num = sscanf(line, "\t%8[0-9A-Fa-f] %d", mcast_addr, &refcnt)) < 2 ) {
645 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
648 sscanf( mcast_addr, "%X",
649 &((struct sockaddr_in *) &mcastaddr)->sin_addr.s_addr );
650 ((struct sockaddr *) &mcastaddr)->sa_family = AF_INET;
652 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
656 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
657 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
658 ((struct sockaddr *) &mcastaddr)->sa_family);
661 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
662 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
663 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr );
669 static int x25_info(void)
671 FILE *f=proc_fopen(_PATH_PROCNET_X25);
672 char buffer[256],dev[16];
673 int st,vs,vr,sendq,recvq,lci;
674 static char *x25_state[5]=
684 if (errno != ENOENT) {
685 perror(_PATH_PROCNET_X25);
688 if (flag_arg || flag_ver)
689 ESYSNOT("netstat","AF X25");
695 printf( _("Active X.25 sockets\n"));
696 /* IMHO, Vr/Vs is not very usefull --SF */
697 printf( _("Dest Source Device LCI State Vr/Vs Send-Q Recv-Q\n"));
698 if (fgets(buffer,256,f))
700 while(fgets(buffer,256,f))
704 sscanf(buffer+22,"%s %d %d %d %d %*d %*d %*d %*d %*d %*d %d %d %*d",
705 dev,&lci,&st,&vs,&vr,&sendq,&recvq);
706 if (!(flag_all || lci))
708 printf("%-15s %-15s %-7s %-3d %-11s %02d/%02d %-6d %-6d\n",
720 static int igmp_info(void)
722 INFO_GUTS6(_PATH_PROCNET_IGMP, _PATH_PROCNET_IGMP6, "AF INET (igmp)",
723 igmp_do_one, "igmp", "igmp6");
726 static int ip_parse_dots(uint32_t *addr, char const *src) {
728 unsigned ret = 4-sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d);
729 *addr = htonl((a << 24)|(b << 16)|(c << 8)|d);
733 static void print_ip_service(struct sockaddr_in *addr, char const *protname,
734 char *buf, unsigned size) {
737 if(size == 0) return;
740 if((ap = get_afntype(addr->sin_family)) == NULL) {
741 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
745 safe_strncpy(buf, ap->sprint((struct sockaddr*)addr, flag_not), size);
748 if(flag_all || (flag_lst && !addr->sin_port) || (!flag_lst && addr->sin_port)) {
751 snprintf(bfs, sizeof(bfs), "%s",
752 get_sname(addr->sin_port, (char*)protname, flag_not & FLAG_NUM_PORT));
754 /* check if we must cut on host and/or service name */
756 unsigned const bufl = strlen(buf);
757 unsigned const bfsl = strlen(bfs);
759 if(bufl+bfsl+2 > size) {
760 unsigned const half = (size-2)>>1;
763 buf[size-2-half] = '\0';
766 else buf[size-2-bfsl] = '\0';
768 else bfs[size-2-bufl] = '\0';
776 /* process single SCTP endpoint */
777 static void sctp_do_ept(int lnr, char const *line, const char *prot)
779 struct sockaddr_in laddr, raddr;
782 char l_addr[23], r_addr[23];
784 /* fill sockaddr_in structures */
790 if(sscanf(line, "%*X %*X %*u %*u %*u %u %u %u %n",
791 &lport, &uid, &inode, &ate) < 3) goto err;
793 /* decode IP address */
794 if(ip_parse_dots(&laddr.sin_addr.s_addr, line+ate)) goto err;
795 raddr.sin_addr.s_addr = htonl(0);
796 laddr.sin_family = raddr.sin_family = AF_INET;
797 laddr.sin_port = htons(lport);
798 raddr.sin_port = htons(0);
801 /* print IP:service to l_addr and r_addr */
802 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
803 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
806 printf("%-4s %6d %6d %-*s %-*s %-11s",
808 (int)netmax(23,strlen(l_addr)), l_addr,
809 (int)netmax(23,strlen(r_addr)), r_addr,
810 _(tcp_state[TCP_LISTEN]));
811 finish_this_one(uid, inode, "");
814 fprintf(stderr, "SCTP error in line: %d\n", lnr);
817 /* process single SCTP association */
818 static void sctp_do_assoc(int lnr, char const *line, const char *prot)
820 struct sockaddr_in laddr, raddr;
821 unsigned long rxq, txq;
824 char l_addr[23], r_addr[23];
826 /* fill sockaddr_in structures */
828 unsigned lport, rport;
833 if(sscanf(line, "%*X %*X %*u %*u %*u %*u %*u %lu %lu %u %u %u %u %n",
834 &txq, &rxq, &uid, &inode, &lport, &rport, &ate) < 6) goto err;
836 /* decode IP addresses */
837 addr = strchr(line+ate, '*');
838 if(addr == 0) goto err;
839 if(ip_parse_dots(&laddr.sin_addr.s_addr, ++addr)) goto err;
840 addr = strchr(addr, '*');
841 if(addr == 0) goto err;
842 if(ip_parse_dots(&raddr.sin_addr.s_addr, ++addr)) goto err;
844 /* complete sockaddr_in structures */
845 laddr.sin_family = raddr.sin_family = AF_INET;
846 laddr.sin_port = htons(lport);
847 raddr.sin_port = htons(rport);
850 /* print IP:service to l_addr and r_addr */
851 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
852 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
855 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
857 (int)netmax(23,strlen(l_addr)), l_addr,
858 (int)netmax(23,strlen(r_addr)), r_addr,
859 _(tcp_state[TCP_ESTABLISHED]));
860 finish_this_one(uid, inode, "");
863 fprintf(stderr, "SCTP error in line: %d\n", lnr);
866 static int sctp_info_epts(void) {
867 INFO_GUTS6(_PATH_PROCNET_SCTPEPTS, _PATH_PROCNET_SCTP6EPTS, "AF INET (sctp)",
868 sctp_do_ept, "sctp", "sctp6");
871 static int sctp_info_assocs(void) {
872 INFO_GUTS6(_PATH_PROCNET_SCTPASSOCS, _PATH_PROCNET_SCTP6ASSOCS, "AF INET (sctp)",
873 sctp_do_assoc, "sctp", "sctp6");
876 static int sctp_info(void) {
878 res = sctp_info_epts();
880 return sctp_info_assocs();
883 static void addr_do_one(char *buf, size_t buf_len, size_t short_len, struct aftype *ap,
885 struct sockaddr_in6 *addr,
887 struct sockaddr_in *addr,
889 int port, const char *proto
892 const char *sport, *saddr;
893 size_t port_len, addr_len;
895 saddr = ap->sprint((struct sockaddr *)addr, flag_not & FLAG_NUM_HOST);
896 sport = get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT);
897 addr_len = strlen(saddr);
898 port_len = strlen(sport);
899 if (!flag_wide && (addr_len + port_len > short_len)) {
900 /* Assume port name is short */
901 port_len = netmin(port_len, short_len - 4);
902 addr_len = short_len - port_len;
903 strncpy(buf, saddr, addr_len);
904 buf[addr_len] = '\0';
906 strncat(buf, sport, port_len);
908 snprintf(buf, buf_len, "%s:%s", saddr, sport);
911 static void tcp_do_one(int lnr, const char *line, const char *prot)
913 unsigned long rxq, txq, time_len, retr, inode;
914 int num, local_port, rem_port, d, state, uid, timer_run, timeout;
915 char rem_addr[128], local_addr[128], timers[64], more[512];
918 struct sockaddr_in6 localaddr, remaddr;
919 char addr6[INET6_ADDRSTRLEN];
921 extern struct aftype inet6_aftype;
923 struct sockaddr_in localaddr, remaddr;
930 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %512s\n",
931 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
932 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
934 if (!flag_all && ((flag_lst && rem_port) || (!flag_lst && !rem_port)))
937 if (strlen(local_addr) > 8) {
939 /* Demangle what the kernel gives us */
940 sscanf(local_addr, "%08X%08X%08X%08X",
941 &in6.s6_addr32[0], &in6.s6_addr32[1],
942 &in6.s6_addr32[2], &in6.s6_addr32[3]);
943 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
944 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
945 sscanf(rem_addr, "%08X%08X%08X%08X",
946 &in6.s6_addr32[0], &in6.s6_addr32[1],
947 &in6.s6_addr32[2], &in6.s6_addr32[3]);
948 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
949 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
950 localaddr.sin6_family = AF_INET6;
951 remaddr.sin6_family = AF_INET6;
954 sscanf(local_addr, "%X",
955 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
956 sscanf(rem_addr, "%X",
957 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
958 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
959 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
963 fprintf(stderr, _("warning, got bogus tcp line.\n"));
966 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
967 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
968 ((struct sockaddr *) &localaddr)->sa_family);
972 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "tcp");
973 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "tcp");
979 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
983 snprintf(timers, sizeof(timers), _("on (%2.2f/%ld/%d)"),
984 (double) time_len / HZ, retr, timeout);
988 snprintf(timers, sizeof(timers), _("keepalive (%2.2f/%ld/%d)"),
989 (double) time_len / HZ, retr, timeout);
993 snprintf(timers, sizeof(timers), _("timewait (%2.2f/%ld/%d)"),
994 (double) time_len / HZ, retr, timeout);
998 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
999 timer_run, (double) time_len / HZ, retr, timeout);
1003 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
1004 prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
1006 finish_this_one(uid,inode,timers);
1009 static int tcp_info(void)
1011 INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
1012 tcp_do_one, "tcp", "tcp6");
1015 static void udp_do_one(int lnr, const char *line,const char *prot)
1017 char local_addr[64], rem_addr[64];
1018 char *udp_state, timers[64], more[512];
1019 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1021 struct sockaddr_in6 localaddr, remaddr;
1022 char addr6[INET6_ADDRSTRLEN];
1023 struct in6_addr in6;
1024 extern struct aftype inet6_aftype;
1026 struct sockaddr_in localaddr, remaddr;
1029 unsigned long rxq, txq, time_len, retr, inode;
1036 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1037 &d, local_addr, &local_port,
1038 rem_addr, &rem_port, &state,
1039 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1041 if (strlen(local_addr) > 8) {
1043 sscanf(local_addr, "%08X%08X%08X%08X",
1044 &in6.s6_addr32[0], &in6.s6_addr32[1],
1045 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1046 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1047 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1048 sscanf(rem_addr, "%08X%08X%08X%08X",
1049 &in6.s6_addr32[0], &in6.s6_addr32[1],
1050 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1051 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1052 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1053 localaddr.sin6_family = AF_INET6;
1054 remaddr.sin6_family = AF_INET6;
1057 sscanf(local_addr, "%X",
1058 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1059 sscanf(rem_addr, "%X",
1060 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1061 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1062 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1070 fprintf(stderr, _("warning, got bogus udp line.\n"));
1073 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
1074 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
1075 ((struct sockaddr *) &localaddr)->sa_family);
1079 case TCP_ESTABLISHED:
1080 udp_state = _("ESTABLISHED");
1088 udp_state = _("UNKNOWN");
1093 #define notnull(A) (((A.sin6_family == AF_INET6) && \
1094 ((A.sin6_addr.s6_addr32[0]) || \
1095 (A.sin6_addr.s6_addr32[1]) || \
1096 (A.sin6_addr.s6_addr32[2]) || \
1097 (A.sin6_addr.s6_addr32[3]))) || \
1098 ((A.sin6_family == AF_INET) && \
1099 ((struct sockaddr_in *) &A)->sin_addr.s_addr))
1101 #define notnull(A) (A.sin_addr.s_addr)
1104 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1106 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "udp");
1107 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "udp");
1111 switch (timer_run) {
1113 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1118 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100, retr, timeout);
1122 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1126 printf("%-5s %6ld %6ld %-23s %-23s %-11s",
1127 prot, rxq, txq, local_addr, rem_addr, udp_state);
1129 finish_this_one(uid,inode,timers);
1133 static int udp_info(void)
1135 INFO_GUTS6(_PATH_PROCNET_UDP, _PATH_PROCNET_UDP6, "AF INET (udp)",
1136 udp_do_one, "udp", "udp6");
1139 static int udplite_info(void)
1141 INFO_GUTS6(_PATH_PROCNET_UDPLITE, _PATH_PROCNET_UDPLITE6,
1142 "AF INET (udplite)", udp_do_one, "udpl", "udpl6" );
1145 static void raw_do_one(int lnr, const char *line,const char *prot)
1147 char local_addr[64], rem_addr[64];
1148 char timers[64], more[512];
1149 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1151 struct sockaddr_in6 localaddr, remaddr;
1152 char addr6[INET6_ADDRSTRLEN];
1153 struct in6_addr in6;
1154 extern struct aftype inet6_aftype;
1156 struct sockaddr_in localaddr, remaddr;
1159 unsigned long rxq, txq, time_len, retr, inode;
1166 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1167 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
1168 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1170 if (strlen(local_addr) > 8) {
1172 sscanf(local_addr, "%08X%08X%08X%08X",
1173 &in6.s6_addr32[0], &in6.s6_addr32[1],
1174 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1175 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1176 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1177 sscanf(rem_addr, "%08X%08X%08X%08X",
1178 &in6.s6_addr32[0], &in6.s6_addr32[1],
1179 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1180 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1181 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1182 localaddr.sin6_family = AF_INET6;
1183 remaddr.sin6_family = AF_INET6;
1186 sscanf(local_addr, "%X",
1187 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1188 sscanf(rem_addr, "%X",
1189 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1190 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1191 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1194 if ((ap = get_afntype(localaddr.sin6_family)) == NULL) {
1195 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin6_family);
1199 if ((ap = get_afntype(localaddr.sin_family)) == NULL) {
1200 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin_family);
1209 fprintf(stderr, _("warning, got bogus raw line.\n"));
1213 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1215 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "raw");
1216 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "raw");
1220 switch (timer_run) {
1222 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1227 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1232 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
1233 timer_run, (double) time_len / 100,
1237 printf("%-4s %6ld %6ld %-23s %-23s %-11d",
1238 prot, rxq, txq, local_addr, rem_addr, state);
1240 finish_this_one(uid,inode,timers);
1244 static int raw_info(void)
1246 INFO_GUTS6(_PATH_PROCNET_RAW, _PATH_PROCNET_RAW6, "AF INET (raw)",
1247 raw_do_one, "raw", "raw6");
1257 static void unix_do_one(int nr, const char *line, const char *prot)
1260 char path[MAXPATHLEN], ss_flags[32];
1261 char *ss_proto, *ss_state, *ss_type;
1262 int num, state, type;
1264 unsigned long refcnt, proto, flags, inode;
1267 if (strstr(line, "Inode"))
1272 num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %s",
1273 &d, &refcnt, &proto, &flags, &type, &state, &inode, path);
1275 fprintf(stderr, _("warning, got bogus unix line.\n"));
1278 if (!(has & HAS_INODE))
1279 snprintf(path,sizeof(path),"%lu",inode);
1282 if ((state == SS_UNCONNECTED) && (flags & SO_ACCEPTCON)) {
1302 ss_type = _("STREAM");
1306 ss_type = _("DGRAM");
1317 case SOCK_SEQPACKET:
1318 ss_type = _("SEQPACKET");
1322 ss_type = _("UNKNOWN");
1327 ss_state = _("FREE");
1330 case SS_UNCONNECTED:
1332 * Unconnected sockets may be listening
1335 if (flags & SO_ACCEPTCON) {
1336 ss_state = _("LISTENING");
1343 ss_state = _("CONNECTING");
1347 ss_state = _("CONNECTED");
1350 case SS_DISCONNECTING:
1351 ss_state = _("DISCONNECTING");
1355 ss_state = _("UNKNOWN");
1358 strcpy(ss_flags, "[ ");
1359 if (flags & SO_ACCEPTCON)
1360 strcat(ss_flags, "ACC ");
1361 if (flags & SO_WAITDATA)
1362 strcat(ss_flags, "W ");
1363 if (flags & SO_NOSPACE)
1364 strcat(ss_flags, "N ");
1366 strcat(ss_flags, "]");
1368 printf("%-5s %-6ld %-11s %-10s %-13s ",
1369 ss_proto, refcnt, ss_flags, ss_type, ss_state);
1370 if (has & HAS_INODE)
1371 printf("%-8lu",inode);
1375 printf(" %-" PROGNAME_WIDTHs "s",(has & HAS_INODE?prg_cache_get(inode):"-"));
1377 printf(" %s\n", path);
1380 static int unix_info(void)
1383 printf(_("Active UNIX domain sockets "));
1385 printf(_("(servers and established)"));
1388 printf(_("(only servers)"));
1390 printf(_("(w/o servers)"));
1393 printf(_("\nProto RefCnt Flags Type State I-Node "));
1394 print_progname_banner();
1395 printf(_(" Path\n")); /* xxx */
1398 INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one, "unix");
1405 static int ax25_info(void)
1408 char buffer[256], buf[16];
1409 char *src, *dst, *dev, *p;
1410 int st, vs, vr, sendq, recvq, ret;
1411 int new = -1; /* flag for new (2.1.x) kernels */
1412 static char *ax25_state[5] =
1420 if (!(f = proc_fopen(_PATH_PROCNET_AX25))) {
1421 if (errno != ENOENT) {
1422 perror(_PATH_PROCNET_AX25);
1425 if (flag_arg || flag_ver)
1426 ESYSNOT("netstat", "AF AX25");
1432 printf(_("Active AX.25 sockets\n"));
1433 printf(_("Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
1434 while (fgets(buffer, 256, f)) {
1436 if (!strncmp(buffer, "dest_addr", 9)) {
1438 continue; /* old kernels have a header line */
1443 * In a network connection with no user socket the Snd-Q, Rcv-Q
1444 * and Inode fields are empty in 2.0.x and '*' in 2.1.x
1453 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",
1454 buf, &st, &vs, &vr, &sendq, &recvq);
1455 if (ret != 4 && ret != 6) {
1456 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_AX25);
1462 while (*p != ' ') p++;
1465 while (*p != ' ') p++;
1468 while (*p != ' ') p++;
1471 while (*p != ' ') p++;
1473 ret = sscanf(p, "%d %d %d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %*d",
1474 &st, &vs, &vr, &sendq, &recvq);
1475 if (ret != 3 && ret != 5) {
1476 printf(_("problem reading data from %s\n"), _PATH_PROCNET_AX25);
1480 * FIXME: digipeaters should be handled somehow.
1481 * For now we just strip them.
1484 while (*p && *p != ',') p++;
1487 printf("%-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
1491 vr, vs, sendq, recvq);
1500 static int ipx_info(void)
1504 unsigned long txq, rxq;
1511 char sad[50], dad[50];
1513 unsigned sport = 0, dport = 0;
1516 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET1);
1518 if (errno != ENOENT) {
1519 perror(_PATH_PROCNET_IPX_SOCKET1);
1522 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET2);
1524 /* We need to check for directory */
1526 fstat(fileno(f), &s);
1527 if (!S_ISREG(s.st_mode)) {
1534 if (errno != ENOENT) {
1535 perror(_PATH_PROCNET_IPX_SOCKET2);
1538 if (flag_arg || flag_ver)
1539 ESYSNOT("netstat", "AF IPX");
1546 printf(_("Active IPX sockets\nProto Recv-Q Send-Q Local Address Foreign Address State")); /* xxx */
1548 printf(_(" User")); /* xxx */
1550 if ((ap = get_afntype(AF_IPX)) == NULL) {
1551 EINTERN("netstat.c", "AF_IPX missing");
1555 if (fgets(buf, 255, f))
1558 while (fgets(buf, 255, f) != NULL) {
1559 sscanf(buf, "%s %s %lX %lX %d %d",
1560 sad, dad, &txq, &rxq, &state, &uid);
1561 if ((st = rindex(sad, ':'))) {
1563 sscanf(st, "%X", &sport); /* net byt order */
1564 sport = ntohs(sport);
1566 EINTERN("netstat.c", "ipx socket format error in source port");
1571 if (strcmp(dad, "Not_Connected") != 0) {
1572 if ((st = rindex(dad, ':'))) {
1574 sscanf(st, "%X", &dport); /* net byt order */
1575 dport = ntohs(dport);
1577 EINTERN("netstat.c", "ipx soket format error in destination port");
1585 case TCP_ESTABLISHED:
1598 /* Fetch and resolve the Source */
1599 (void) ap->input(4, sad, &sa);
1600 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1601 snprintf(sad, sizeof(sad), "%s:%04X", buf, sport);
1604 /* Fetch and resolve the Destination */
1605 (void) ap->input(4, dad, &sa);
1606 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1607 snprintf(dad, sizeof(dad), "%s:%04X", buf, dport);
1611 printf("IPX %6ld %6ld %-26s %-26s %-5s", txq, rxq, sad, dad, st);
1613 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
1614 printf(" %-10s", pw->pw_name);
1616 printf(" %-10d", uid);
1625 #if HAVE_AFBLUETOOTH
1626 const char *bluetooth_state(int state)
1630 return _("CONNECTED");
1638 return _("CONNECT");
1640 return _("CONNECT2");
1644 return _("DISCONN");
1648 return _("UNKNOWN");
1652 static void l2cap_do_one(int nr, const char *line, const char *prot)
1654 char daddr[18], saddr[18];
1655 unsigned state, psm, dcid, scid, imtu, omtu, sec_level;
1657 const char *bt_state, *bt_sec_level;
1659 num = sscanf(line, "%17s %17s %d %d 0x%04x 0x%04x %d %d %d",
1660 daddr, saddr, &state, &psm, &dcid, &scid, &imtu, &omtu, &sec_level);
1663 fprintf(stderr, _("warning, got bogus l2cap line.\n"));
1667 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1669 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1672 bt_state = bluetooth_state(state);
1673 switch (sec_level) {
1674 case BT_SECURITY_SDP:
1675 bt_sec_level = _("SDP");
1677 case BT_SECURITY_LOW:
1678 bt_sec_level = _("LOW");
1680 case BT_SECURITY_MEDIUM:
1681 bt_sec_level = _("MEDIUM");
1683 case BT_SECURITY_HIGH:
1684 bt_sec_level = _("HIGH");
1687 bt_sec_level = _("UNKNOWN");
1690 printf("l2cap %-17s %-17s %-9s %7d 0x%04x 0x%04x %7d %7d %-7s\n",
1691 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1692 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1693 bt_state, psm, dcid, scid, imtu, omtu, bt_sec_level);
1696 static int l2cap_info(void)
1698 printf("%-6s %-17s %-17s %-9s %7s %-6s %-6s %7s %7s %-7s\n",
1699 "Proto", "Destination", "Source", "State", "PSM", "DCID", "SCID", "IMTU", "OMTU", "Security");
1700 INFO_GUTS(_PATH_SYS_BLUETOOTH_L2CAP, "AF BLUETOOTH", l2cap_do_one, "l2cap");
1703 static void rfcomm_do_one(int nr, const char *line, const char *prot)
1705 char daddr[18], saddr[18];
1706 unsigned state, channel;
1708 const char *bt_state;
1710 num = sscanf(line, "%17s %17s %d %d", daddr, saddr, &state, &channel);
1712 fprintf(stderr, _("warning, got bogus rfcomm line.\n"));
1716 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1718 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1721 bt_state = bluetooth_state(state);
1722 printf("rfcomm %-17s %-17s %-9s %7d\n",
1723 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1724 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1728 static int rfcomm_info(void)
1730 printf("%-6s %-17s %-17s %-9s %7s\n", "Proto", "Destination", "Source", "State", "Channel");
1731 INFO_GUTS(_PATH_SYS_BLUETOOTH_RFCOMM, "AF BLUETOOTH", rfcomm_do_one, "rfcomm");
1735 static int iface_info(void)
1738 if ((skfd = sockets_open(0)) < 0) {
1742 printf(_("Kernel Interface table\n"));
1746 printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
1749 if (for_all_interfaces(do_if_print, &flag_all) < 0) {
1750 perror(_("missing interface information"));
1764 static void version(void)
1766 printf("%s\n%s\n%s\n%s\n", Release, Version, Signature, Features);
1771 static void usage(void)
1773 fprintf(stderr, _("usage: netstat [-vWeenNcCF] [<Af>] -r netstat {-V|--version|-h|--help}\n"));
1774 fprintf(stderr, _(" netstat [-vWnNcaeol] [<Socket> ...]\n"));
1775 fprintf(stderr, _(" netstat { [-vWeenNac] -i | [-cnNe] -M | -s [-6tuw] }\n\n"));
1777 fprintf(stderr, _(" -r, --route display routing table\n"));
1778 fprintf(stderr, _(" -i, --interfaces display interface table\n"));
1779 fprintf(stderr, _(" -g, --groups display multicast group memberships\n"));
1780 fprintf(stderr, _(" -s, --statistics display networking statistics (like SNMP)\n"));
1781 #if HAVE_FW_MASQUERADE
1782 fprintf(stderr, _(" -M, --masquerade display masqueraded connections\n\n"));
1784 fprintf(stderr, _(" -v, --verbose be verbose\n"));
1785 fprintf(stderr, _(" -W, --wide don't truncate IP addresses\n"));
1786 fprintf(stderr, _(" -n, --numeric don't resolve names\n"));
1787 fprintf(stderr, _(" --numeric-hosts don't resolve host names\n"));
1788 fprintf(stderr, _(" --numeric-ports don't resolve port names\n"));
1789 fprintf(stderr, _(" --numeric-users don't resolve user names\n"));
1790 fprintf(stderr, _(" -N, --symbolic resolve hardware names\n"));
1791 fprintf(stderr, _(" -e, --extend display other/more information\n"));
1792 fprintf(stderr, _(" -p, --programs display PID/Program name for sockets\n"));
1793 fprintf(stderr, _(" -c, --continuous continuous listing\n\n"));
1794 fprintf(stderr, _(" -l, --listening display listening server sockets\n"));
1795 fprintf(stderr, _(" -a, --all, --listening display all sockets (default: connected)\n"));
1796 fprintf(stderr, _(" -o, --timers display timers\n"));
1797 fprintf(stderr, _(" -F, --fib display Forwarding Information Base (default)\n"));
1798 fprintf(stderr, _(" -C, --cache display routing cache instead of FIB\n\n"));
1800 fprintf(stderr, _(" <Socket>={-t|--tcp} {-u|--udp} {-U|--udplite} {-w|--raw} {-x|--unix} --ax25 --ipx --netrom\n"));
1801 fprintf(stderr, _(" <AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
1802 fprintf(stderr, _(" List of possible address families (which support routing):\n"));
1803 print_aflist(1); /* 1 = routeable */
1809 (int argc, char *argv[]) {
1812 static struct option longopts[] =
1815 {"version", 0, 0, 'V'},
1816 {"interfaces", 0, 0, 'i'},
1817 {"help", 0, 0, 'h'},
1818 {"route", 0, 0, 'r'},
1819 #if HAVE_FW_MASQUERADE
1820 {"masquerade", 0, 0, 'M'},
1822 {"protocol", 1, 0, 'A'},
1824 {"sctp", 0, 0, 'S'},
1826 {"udplite", 0, 0, 'U'},
1828 {"unix", 0, 0, 'x'},
1829 {"l2cap", 0, 0, '2'},
1830 {"rfcomm", 0, 0, 'f'},
1831 {"listening", 0, 0, 'l'},
1833 {"timers", 0, 0, 'o'},
1834 {"continuous", 0, 0, 'c'},
1835 {"extend", 0, 0, 'e'},
1836 {"programs", 0, 0, 'p'},
1837 {"verbose", 0, 0, 'v'},
1838 {"statistics", 0, 0, 's'},
1839 {"wide", 0, 0, 'W'},
1840 {"numeric", 0, 0, 'n'},
1841 {"numeric-hosts", 0, 0, '!'},
1842 {"numeric-ports", 0, 0, '@'},
1843 {"numeric-users", 0, 0, '#'},
1844 {"symbolic", 0, 0, 'N'},
1845 {"cache", 0, 0, 'C'},
1847 {"groups", 0, 0, 'g'},
1852 setlocale (LC_ALL, "");
1853 bindtextdomain("net-tools", "/usr/share/locale");
1854 textdomain("net-tools");
1856 getroute_init(); /* Set up AF routing support */
1859 while ((i = getopt_long(argc, argv, "A:CFMacdeghilnNoprsStuUvVWwx64?", longopts, &lop)) != EOF)
1864 if (lop < 0 || lop >= AFTRANS_CNT) {
1865 EINTERN("netstat.c", "longopts 1 range");
1868 if (aftrans_opt(longopts[lop].name))
1872 if (aftrans_opt(optarg))
1907 flag_not |= FLAG_NUM;
1910 flag_not |= FLAG_NUM_HOST;
1913 flag_not |= FLAG_NUM_PORT;
1916 flag_not |= FLAG_NUM_USER;
1919 flag_not |= FLAG_SYM;
1922 flag_cf |= FLAG_CACHE;
1925 flag_cf |= FLAG_FIB;
1931 if (aftrans_opt("inet6"))
1935 if (aftrans_opt("inet"))
1942 flag_ver |= FLAG_VERBOSE;
1969 if (aftrans_opt("unix"))
1979 if (flag_int + flag_rou + flag_mas + flag_sta > 1)
1982 if ((flag_inet || flag_inet6 || flag_sta) &&
1983 !(flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw))
1984 flag_tcp = flag_sctp = flag_udp = flag_udplite = flag_raw = 1;
1986 if ((flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw || flag_igmp) &&
1987 !(flag_inet || flag_inet6))
1988 flag_inet = flag_inet6 = 1;
1990 if (flag_bluetooth && !(flag_l2cap || flag_rfcomm))
1991 flag_l2cap = flag_rfcomm = 1;
1993 flag_arg = flag_tcp + flag_sctp + flag_udplite + flag_udp + flag_raw + flag_unx
1994 + flag_ipx + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose
1995 + flag_l2cap + flag_rfcomm;
1998 #if HAVE_FW_MASQUERADE && HAVE_AFINET
1999 #if MORE_THAN_ONE_MASQ_AF
2001 strcpy(afname, DFLT_AF);
2004 i = ip_masq_info(flag_not & FLAG_NUM_HOST,
2005 flag_not & FLAG_NUM_PORT, flag_exp);
2011 ENOSUPP("netstat", "FW_MASQUERADE");
2019 strcpy(afname, DFLT_AF);
2021 if (!strcmp(afname, "inet")) {
2024 parsesnmp(flag_raw, flag_tcp, flag_udp);
2026 ENOSUPP("netstat", "AF INET");
2028 } else if(!strcmp(afname, "inet6")) {
2031 parsesnmp6(flag_raw, flag_tcp, flag_udp);
2033 ENOSUPP("netstat", "AF INET6");
2036 printf(_("netstat: No statistics support for specified address family: %s\n"), afname);
2046 strcpy(afname, DFLT_AF);
2050 else if (flag_exp == 1)
2053 options = (flag_exp & FLAG_EXT) | flag_not | flag_cf | flag_ver;
2055 options |= FLAG_FIB;
2058 i = route_info(afname, options);
2075 if (!flag_arg || flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw) {
2078 printf(_("Active Internet connections ")); /* xxx */
2081 printf(_("(servers and established)"));
2084 printf(_("(only servers)"));
2086 printf(_("(w/o servers)"));
2088 printf(_("\nProto Recv-Q Send-Q Local Address Foreign Address State ")); /* xxx */
2090 printf(_(" User Inode "));
2091 print_progname_banner();
2093 printf(_(" Timer")); /* xxx */
2098 ENOSUPP("netstat", "AF INET");
2103 if (!flag_arg || flag_tcp) {
2109 if (!flag_arg || flag_sctp) {
2115 if (!flag_arg || flag_udp) {
2121 if (!flag_arg || flag_udplite) {
2127 if (!flag_arg || flag_raw) {
2137 printf( _("IPv4 Group Memberships\n") );
2138 printf( _("Interface RefCnt Group\n") );
2139 printf( "--------------- ------ ---------------------\n" );
2146 if (!flag_arg || flag_unx) {
2155 ENOSUPP("netstat", "AF UNIX");
2159 if (!flag_arg || flag_ipx) {
2167 ENOSUPP("netstat", "AF IPX");
2171 if (!flag_arg || flag_ax25) {
2179 ENOSUPP("netstat", "AF AX25");
2183 if(!flag_arg || flag_x25) {
2192 ENOSUPP("netstat", "AF X25");
2196 if (!flag_arg || flag_netrom) {
2204 ENOSUPP("netstat", "AF NETROM");
2208 if (!flag_arg || flag_rose) {
2209 #if 0 && HAVE_AFROSE
2216 ENOSUPP("netstat", "AF ROSE");
2221 if (!flag_arg || flag_l2cap || flag_rfcomm) {
2222 #if HAVE_AFBLUETOOTH
2223 printf(_("Active Bluetooth connections ")); /* xxx */
2226 printf(_("(servers and established)"));
2229 printf(_("(only servers)"));
2231 printf(_("(w/o servers)"));
2237 ENOSUPP("netstat", "AF BLUETOOTH");
2241 #if HAVE_AFBLUETOOTH
2242 if (!flag_arg || flag_l2cap) {
2247 if (!flag_arg || flag_rfcomm) {