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>
91 #include <attr/xattr.h>
94 #include <selinux/selinux.h>
96 #include "net-support.h"
97 #include "pathnames.h"
102 #include "interface.h"
107 #include <bluetooth/bluetooth.h>
110 #define PROGNAME_WIDTH 20
111 #define SELINUX_WIDTH 50
114 #define SMK_BANNER_IN "IPIN"
115 #define SMK_BANNER_OUT "IPOUT"
116 #define SMK_LABELLEN 256
117 #define SMK_ATTR_IN "security.SMACK64IPIN"
118 #define SMK_ATTR_OUT "security.SMACK64IPOUT"
120 #if !defined(s6_addr32) && defined(in6a_words)
121 #define s6_addr32 in6a_words /* libinet6 */
124 /* prototypes for statistics.c */
125 void parsesnmp(int, int, int);
127 void parsesnmp6(int, int, int);
131 SS_FREE = 0, /* not allocated */
132 SS_UNCONNECTED, /* unconnected to any socket */
133 SS_CONNECTING, /* in process of connecting */
134 SS_CONNECTED, /* connected to socket */
135 SS_DISCONNECTING /* in process of disconnecting */
138 #define SO_ACCEPTCON (1<<16) /* performed a listen */
139 #define SO_WAITDATA (1<<17) /* wait data to read */
140 #define SO_NOSPACE (1<<18) /* no space to write */
142 #define DFLT_AF "inet"
144 #define FEATURE_NETSTAT
145 #include "lib/net-features.h"
147 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";
169 int flag_udplite = 0;
179 int flag_selinux = 0;
184 #define INFO_GUTS1(file,name,proc,prot) \
185 procinfo = proc_fopen((file)); \
186 if (procinfo == NULL) { \
187 if (errno != ENOENT) { \
191 if (flag_arg || flag_ver) \
192 ESYSNOT("netstat", (name)); \
197 if (fgets(buffer, sizeof(buffer), procinfo)) \
198 (proc)(lnr++, buffer,prot); \
199 } while (!feof(procinfo)); \
204 #define INFO_GUTS2(file,proc,prot) \
206 procinfo = proc_fopen((file)); \
207 if (procinfo != NULL) { \
209 if (fgets(buffer, sizeof(buffer), procinfo)) \
210 (proc)(lnr++, buffer,prot); \
211 } while (!feof(procinfo)); \
215 #define INFO_GUTS2(file,proc,prot)
221 #define INFO_GUTS6(file,file6,name,proc,prot4,prot6) \
225 if (!flag_arg || flag_inet) { \
226 INFO_GUTS1(file,name,proc,prot4) \
228 if (!flag_arg || flag_inet6) { \
229 INFO_GUTS2(file6,proc,prot6) \
233 #define INFO_GUTS(file,name,proc,prot) \
237 INFO_GUTS1(file,name,proc,prot) \
240 #define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
241 #define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)
242 #define PROGNAME_WIDTH2(s) #s
244 #define SELINUX_WIDTHs SELINUX_WIDTH1(SELINUX_WIDTH)
245 #define SELINUX_WIDTH1(s) SELINUX_WIDTH2(s)
246 #define SELINUX_WIDTH2(s) #s
248 #define SMK_WIDTHs SMK_WIDTH1(SMK_WIDTH)
249 #define SMK_WIDTH1(s) SMK_WIDTH2(s)
250 #define SMK_WIDTH2(s) #s
252 #define PRG_HASH_SIZE 211
255 char in[SMK_LABELLEN];
256 char out[SMK_LABELLEN];
259 static struct prg_node {
260 struct prg_node *next;
262 char name[PROGNAME_WIDTH];
263 char scon[SELINUX_WIDTH];
264 struct smk smk_labels;
265 } *prg_hash[PRG_HASH_SIZE];
267 static char prg_cache_loaded = 0;
269 #define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE)
271 #define PROGNAME_BANNER "PID/Program name"
272 #define SELINUX_BANNER "Security Context"
274 #define print_progname_banner() do { if (flag_prg) printf(" %-" PROGNAME_WIDTHs "s",PROGNAME_BANNER); } while (0)
276 #define print_selinux_banner() do { if (flag_selinux) printf("%-" SELINUX_WIDTHs "s"," " SELINUX_BANNER); } while (0)
278 #define print_smack_banner() do { if (flag_smack) printf(" %-" SMK_WIDTHs "s" " " "%-" SMK_WIDTHs "s", SMK_BANNER_IN, SMK_BANNER_OUT); } while (0)
280 #define PRG_LOCAL_ADDRESS "local_address"
281 #define PRG_INODE "inode"
282 #define PRG_SOCKET_PFX "socket:["
283 #define PRG_SOCKET_PFXl (strlen(PRG_SOCKET_PFX))
284 #define PRG_SOCKET_PFX2 "[0000]:"
285 #define PRG_SOCKET_PFX2l (strlen(PRG_SOCKET_PFX2))
289 #define LINE_MAX 4096
292 #define PATH_PROC "/proc"
293 #define PATH_FD_SUFF "fd"
294 #define PATH_FD_SUFFl strlen(PATH_FD_SUFF)
295 #define PATH_PROC_X_FD PATH_PROC "/%s/" PATH_FD_SUFF
296 #define PATH_CMDLINE "cmdline"
297 #define PATH_CMDLINEl strlen(PATH_CMDLINE)
299 static void prg_cache_add(unsigned long inode, char *name, const char *scon, struct smk *const smk_labels)
301 unsigned hi = PRG_HASHIT(inode);
302 struct prg_node **pnp,*pn;
304 prg_cache_loaded = 2;
305 for (pnp = prg_hash + hi; (pn = *pnp); pnp = &pn->next) {
306 if (pn->inode == inode) {
307 /* Some warning should be appropriate here
308 as we got multiple processes for one i-node */
312 if (!(*pnp = malloc(sizeof(**pnp))))
317 if (strlen(name) > sizeof(pn->name) - 1)
318 name[sizeof(pn->name) - 1] = '\0';
319 strcpy(pn->name, name);
322 int len = (strlen(scon) - sizeof(pn->scon)) + 1;
324 strcpy(pn->scon, &scon[len + 1]);
326 strcpy(pn->scon, scon);
329 strncpy(pn->smk_labels.in, smk_labels->in, SMK_LABELLEN);
330 strncpy(pn->smk_labels.out, smk_labels->out, SMK_LABELLEN);
333 static const char *prg_cache_get(unsigned long inode)
335 unsigned hi = PRG_HASHIT(inode);
338 for (pn = prg_hash[hi]; pn; pn = pn->next)
339 if (pn->inode == inode)
344 static const char *prg_cache_get_con(unsigned long inode)
346 unsigned hi = PRG_HASHIT(inode);
349 for (pn = prg_hash[hi]; pn; pn = pn->next)
350 if (pn->inode == inode)
355 static const char *prg_cache_get_smkin(unsigned long inode)
357 unsigned hi = PRG_HASHIT(inode);
360 for (pn = prg_hash[hi]; pn; pn = pn->next)
361 if (pn->inode == inode)
362 return pn->smk_labels.in;
366 static const char *prg_cache_get_smkout(unsigned long inode)
368 unsigned hi = PRG_HASHIT(inode);
371 for (pn = prg_hash[hi]; pn; pn = pn->next)
372 if (pn->inode == inode)
373 return pn->smk_labels.out;
377 static void prg_cache_clear(void)
379 struct prg_node **pnp,*pn;
381 if (prg_cache_loaded == 2)
382 for (pnp = prg_hash; pnp < prg_hash + PRG_HASH_SIZE; pnp++)
383 while ((pn = *pnp)) {
387 prg_cache_loaded = 0;
390 static void wait_continous(void)
396 static int extract_type_1_socket_inode(const char lname[], unsigned long * inode_p) {
398 /* If lname is of the form "socket:[12345]", extract the "12345"
399 as *inode_p. Otherwise, return -1 as *inode_p.
402 if (strlen(lname) < PRG_SOCKET_PFXl+3) return(-1);
404 if (memcmp(lname, PRG_SOCKET_PFX, PRG_SOCKET_PFXl)) return(-1);
405 if (lname[strlen(lname)-1] != ']') return(-1);
408 char inode_str[strlen(lname + 1)]; /* e.g. "12345" */
409 const int inode_str_len = strlen(lname) - PRG_SOCKET_PFXl - 1;
412 strncpy(inode_str, lname+PRG_SOCKET_PFXl, inode_str_len);
413 inode_str[inode_str_len] = '\0';
414 *inode_p = strtoul(inode_str, &serr, 0);
415 if (!serr || *serr || *inode_p == ~0)
423 static int extract_type_2_socket_inode(const char lname[], unsigned long * inode_p) {
425 /* If lname is of the form "[0000]:12345", extract the "12345"
426 as *inode_p. Otherwise, return -1 as *inode_p.
429 if (strlen(lname) < PRG_SOCKET_PFX2l+1) return(-1);
430 if (memcmp(lname, PRG_SOCKET_PFX2, PRG_SOCKET_PFX2l)) return(-1);
435 *inode_p = strtoul(lname + PRG_SOCKET_PFX2l, &serr, 0);
436 if (!serr || *serr || *inode_p == ~0)
443 static void get_smack_labels(const char *line, struct smk *smk_labels) {
446 ret = getxattr(line, SMK_ATTR_OUT, smk_labels->out, SMK_LABELLEN);
448 smk_labels->out[0] = '\0';
450 smk_labels->out[ret] = '\0';
452 ret = getxattr(line, SMK_ATTR_IN, smk_labels->in, SMK_LABELLEN);
454 smk_labels->in[0] = '\0';
456 smk_labels->in[ret] = '\0';
459 static void prg_cache_load(void)
461 char line[LINE_MAX], eacces=0;
462 int procfdlen, fd, cmdllen, lnamelen;
463 char lname[30], cmdlbuf[512], finbuf[PROGNAME_WIDTH];
465 const char *cs, *cmdlp;
466 DIR *dirproc = NULL, *dirfd = NULL;
467 struct dirent *direproc, *direfd;
469 security_context_t scon = NULL;
471 struct smk smk_labels;
473 if (prg_cache_loaded || !flag_prg) return;
474 prg_cache_loaded = 1;
475 cmdlbuf[sizeof(cmdlbuf) - 1] = '\0';
476 if (!(dirproc=opendir(PATH_PROC))) goto fail;
477 while (errno = 0, direproc = readdir(dirproc)) {
478 for (cs = direproc->d_name; *cs; cs++)
483 procfdlen = snprintf(line,sizeof(line),PATH_PROC_X_FD,direproc->d_name);
484 if (procfdlen <= 0 || procfdlen >= sizeof(line) - 5)
487 dirfd = opendir(line);
493 line[procfdlen] = '/';
495 while ((direfd = readdir(dirfd))) {
497 if (!isdigit(direfd->d_name[0]))
499 if (procfdlen + 1 + strlen(direfd->d_name) + 1 > sizeof(line))
501 memcpy(line + procfdlen - PATH_FD_SUFFl, PATH_FD_SUFF "/",
503 strcpy(line + procfdlen + 1, direfd->d_name);
504 lnamelen = readlink(line, lname, sizeof(lname) - 1);
507 lname[lnamelen] = '\0'; /*make it a null-terminated string*/
509 if (extract_type_1_socket_inode(lname, &inode) < 0)
510 if (extract_type_2_socket_inode(lname, &inode) < 0)
513 get_smack_labels(line, &smk_labels);
516 if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >=
519 strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_CMDLINE);
520 fd = open(line, O_RDONLY);
523 cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1);
528 if (cmdllen < sizeof(cmdlbuf) - 1)
529 cmdlbuf[cmdllen]='\0';
530 if (cmdlbuf[0] == '/' && (cmdlp = strrchr(cmdlbuf, '/')))
536 snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp);
538 if (getpidcon(atoi(direproc->d_name), &scon) == -1) {
541 prg_cache_add(inode, finbuf, scon, &smk_labels);
544 prg_cache_add(inode, finbuf, "-", &smk_labels);
546 smk_labels.in[0] = '\0';
547 smk_labels.out[0] = '\0';
558 if (prg_cache_loaded == 1) {
560 fprintf(stderr,_("(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n"),
564 fprintf(stderr, _("(Not all processes could be identified, non-owned process info\n"
565 " will not be shown, you would have to be root to see it all.)\n"));
569 static const char *netrom_state[] =
577 static int netrom_info(void)
580 char buffer[256], dev[16];
581 int st, vs, vr, sendq, recvq, ret;
583 f = proc_fopen(_PATH_PROCNET_NR);
585 if (errno != ENOENT) {
586 perror(_PATH_PROCNET_NR);
589 if (flag_arg || flag_ver)
590 ESYSNOT("netstat", "AF NETROM");
596 printf(_("Active NET/ROM sockets\n"));
597 printf(_("User Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
598 if (fgets(buffer, 256, f))
601 while (fgets(buffer, 256, f)) {
605 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",
606 dev, &st, &vs, &vr, &sendq, &recvq);
608 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_NR);
611 printf("%-9s %-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
612 buffer, buffer + 10, buffer + 20,
615 vr, vs, sendq, recvq);
622 /* These enums are used by IPX too. :-( */
634 TCP_CLOSING /* now a valid state */
637 #if HAVE_AFINET || HAVE_AFINET6
639 static const char *tcp_state[] =
655 static void finish_this_one(int uid, unsigned long inode, const char *timers)
660 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
661 printf(" %-10s ", pw->pw_name);
663 printf(" %-10d ", uid);
664 printf("%-10lu",inode);
667 printf(" %-" PROGNAME_WIDTHs "s",prg_cache_get(inode));
669 printf(" %-" SELINUX_WIDTHs "s",prg_cache_get_con(inode));
672 printf(" %s", timers);
676 static void igmp_do_one(int lnr, const char *line,const char *prot)
678 char mcast_addr[128];
680 struct sockaddr_in6 mcastaddr;
681 char addr6[INET6_ADDRSTRLEN];
683 extern struct aftype inet6_aftype;
685 struct sockaddr_in mcastaddr;
688 static int idx_flag = 0;
689 static int igmp6_flag = 0;
690 static char device[16];
691 int num, idx, refcnt;
695 /* igmp6 file does not have any comments on first line */
696 if ( strstr( line, "Device" ) == NULL ) {
700 /* 2.1.x kernels and up have Idx field */
701 /* 2.0.x and below do not have Idx field */
702 if ( strncmp( line, "Idx", strlen("Idx") ) == 0 )
710 if (igmp6_flag) { /* IPV6 */
712 num = sscanf( line, "%d %15s %64[0-9A-Fa-f] %d", &idx, device, mcast_addr, &refcnt );
714 /* Demangle what the kernel gives us */
715 sscanf(mcast_addr, "%08X%08X%08X%08X",
716 &in6.s6_addr32[0], &in6.s6_addr32[1],
717 &in6.s6_addr32[2], &in6.s6_addr32[3]);
718 in6.s6_addr32[0] = htonl(in6.s6_addr32[0]);
719 in6.s6_addr32[1] = htonl(in6.s6_addr32[1]);
720 in6.s6_addr32[2] = htonl(in6.s6_addr32[2]);
721 in6.s6_addr32[3] = htonl(in6.s6_addr32[3]);
722 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
723 inet6_aftype.input(1, addr6, (struct sockaddr *) &mcastaddr);
724 mcastaddr.sin6_family = AF_INET6;
726 fprintf(stderr, _("warning, got bogus igmp6 line %d.\n"), lnr);
730 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
731 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
732 ((struct sockaddr *) &mcastaddr)->sa_family);
735 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
736 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
737 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr);
741 if (line[0] != '\t') {
743 if ((num = sscanf( line, "%d\t%10c", &idx, device)) < 2) {
744 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
748 if ( (num = sscanf( line, "%10c", device )) < 1 ) {
749 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
755 } else if ( line[0] == '\t' ) {
756 if ( (num = sscanf(line, "\t%8[0-9A-Fa-f] %d", mcast_addr, &refcnt)) < 2 ) {
757 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
760 sscanf( mcast_addr, "%X",
761 &((struct sockaddr_in *) &mcastaddr)->sin_addr.s_addr );
762 ((struct sockaddr *) &mcastaddr)->sa_family = AF_INET;
764 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
768 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
769 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
770 ((struct sockaddr *) &mcastaddr)->sa_family);
773 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
774 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
775 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr );
781 static int x25_info(void)
783 FILE *f=proc_fopen(_PATH_PROCNET_X25);
784 char buffer[256],dev[16];
785 int st,vs,vr,sendq,recvq,lci;
786 static char *x25_state[5]=
796 if (errno != ENOENT) {
797 perror(_PATH_PROCNET_X25);
800 if (flag_arg || flag_ver)
801 ESYSNOT("netstat","AF X25");
807 printf( _("Active X.25 sockets\n"));
808 /* IMHO, Vr/Vs is not very usefull --SF */
809 printf( _("Dest Source Device LCI State Vr/Vs Send-Q Recv-Q\n"));
810 if (fgets(buffer,256,f))
812 while(fgets(buffer,256,f))
816 sscanf(buffer+22,"%s %d %d %d %d %*d %*d %*d %*d %*d %*d %d %d %*d",
817 dev,&lci,&st,&vs,&vr,&sendq,&recvq);
818 if (!(flag_all || lci))
820 printf("%-15s %-15s %-7s %-3d %-11s %02d/%02d %-6d %-6d\n",
832 static int igmp_info(void)
834 INFO_GUTS6(_PATH_PROCNET_IGMP, _PATH_PROCNET_IGMP6, "AF INET (igmp)",
835 igmp_do_one, "igmp", "igmp6");
838 static int ip_parse_dots(uint32_t *addr, char const *src) {
840 unsigned ret = 4-sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d);
841 *addr = htonl((a << 24)|(b << 16)|(c << 8)|d);
845 static void print_ip_service(struct sockaddr_in *addr, char const *protname,
846 char *buf, unsigned size) {
849 if(size == 0) return;
852 if((ap = get_afntype(addr->sin_family)) == NULL) {
853 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
857 safe_strncpy(buf, ap->sprint((struct sockaddr*)addr, flag_not), size);
860 if(flag_all || (flag_lst && !addr->sin_port) || (!flag_lst && addr->sin_port)) {
863 snprintf(bfs, sizeof(bfs), "%s",
864 get_sname(addr->sin_port, (char*)protname, flag_not & FLAG_NUM_PORT));
866 /* check if we must cut on host and/or service name */
868 unsigned const bufl = strlen(buf);
869 unsigned const bfsl = strlen(bfs);
871 if(bufl+bfsl+2 > size) {
872 unsigned const half = (size-2)>>1;
875 buf[size-2-half] = '\0';
878 else buf[size-2-bfsl] = '\0';
880 else bfs[size-2-bufl] = '\0';
888 /* process single SCTP endpoint */
889 static void sctp_do_ept(int lnr, char const *line, const char *prot)
891 struct sockaddr_in laddr, raddr;
894 char l_addr[23], r_addr[23];
896 /* fill sockaddr_in structures */
902 if(sscanf(line, "%*X %*X %*u %*u %*u %u %u %u %n",
903 &lport, &uid, &inode, &ate) < 3) goto err;
905 /* decode IP address */
906 if(ip_parse_dots(&laddr.sin_addr.s_addr, line+ate)) goto err;
907 raddr.sin_addr.s_addr = htonl(0);
908 laddr.sin_family = raddr.sin_family = AF_INET;
909 laddr.sin_port = htons(lport);
910 raddr.sin_port = htons(0);
913 /* print IP:service to l_addr and r_addr */
914 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
915 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
918 printf("%-4s %6d %6d %-*s %-*s %-11s",
920 (int)netmax(23,strlen(l_addr)), l_addr,
921 (int)netmax(23,strlen(r_addr)), r_addr,
922 _(tcp_state[TCP_LISTEN]));
923 finish_this_one(uid, inode, "");
926 fprintf(stderr, "SCTP error in line: %d\n", lnr);
929 /* process single SCTP association */
930 static void sctp_do_assoc(int lnr, char const *line, const char *prot)
932 struct sockaddr_in laddr, raddr;
933 unsigned long rxq, txq;
936 char l_addr[23], r_addr[23];
938 /* fill sockaddr_in structures */
940 unsigned lport, rport;
945 if(sscanf(line, "%*X %*X %*u %*u %*u %*u %*u %lu %lu %u %u %u %u %n",
946 &txq, &rxq, &uid, &inode, &lport, &rport, &ate) < 6) goto err;
948 /* decode IP addresses */
949 addr = strchr(line+ate, '*');
950 if(addr == 0) goto err;
951 if(ip_parse_dots(&laddr.sin_addr.s_addr, ++addr)) goto err;
952 addr = strchr(addr, '*');
953 if(addr == 0) goto err;
954 if(ip_parse_dots(&raddr.sin_addr.s_addr, ++addr)) goto err;
956 /* complete sockaddr_in structures */
957 laddr.sin_family = raddr.sin_family = AF_INET;
958 laddr.sin_port = htons(lport);
959 raddr.sin_port = htons(rport);
962 /* print IP:service to l_addr and r_addr */
963 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
964 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
967 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
969 (int)netmax(23,strlen(l_addr)), l_addr,
970 (int)netmax(23,strlen(r_addr)), r_addr,
971 _(tcp_state[TCP_ESTABLISHED]));
972 finish_this_one(uid, inode, "");
975 fprintf(stderr, "SCTP error in line: %d\n", lnr);
978 static int sctp_info_epts(void) {
979 INFO_GUTS6(_PATH_PROCNET_SCTPEPTS, _PATH_PROCNET_SCTP6EPTS, "AF INET (sctp)",
980 sctp_do_ept, "sctp", "sctp6");
983 static int sctp_info_assocs(void) {
984 INFO_GUTS6(_PATH_PROCNET_SCTPASSOCS, _PATH_PROCNET_SCTP6ASSOCS, "AF INET (sctp)",
985 sctp_do_assoc, "sctp", "sctp6");
988 static int sctp_info(void) {
990 res = sctp_info_epts();
992 return sctp_info_assocs();
995 static void addr_do_one(char *buf, size_t buf_len, size_t short_len, struct aftype *ap,
997 struct sockaddr_in6 *addr,
999 struct sockaddr_in *addr,
1001 int port, const char *proto
1004 const char *sport, *saddr;
1005 size_t port_len, addr_len;
1007 saddr = ap->sprint((struct sockaddr *)addr, flag_not & FLAG_NUM_HOST);
1008 sport = get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT);
1009 addr_len = strlen(saddr);
1010 port_len = strlen(sport);
1011 if (!flag_wide && (addr_len + port_len > short_len)) {
1012 /* Assume port name is short */
1013 port_len = netmin(port_len, short_len - 4);
1014 addr_len = short_len - port_len;
1015 strncpy(buf, saddr, addr_len);
1016 buf[addr_len] = '\0';
1018 strncat(buf, sport, port_len);
1020 snprintf(buf, buf_len, "%s:%s", saddr, sport);
1023 static void tcp_do_one(int lnr, const char *line, const char *prot)
1025 unsigned long rxq, txq, time_len, retr, inode;
1026 int num, local_port, rem_port, d, state, uid, timer_run, timeout;
1027 char rem_addr[128], local_addr[128], timers[64], more[512];
1030 struct sockaddr_in6 localaddr, remaddr;
1031 char addr6[INET6_ADDRSTRLEN];
1032 struct in6_addr in6;
1033 extern struct aftype inet6_aftype;
1035 struct sockaddr_in localaddr, remaddr;
1042 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %512s\n",
1043 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
1044 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1046 if (!flag_all && ((flag_lst && rem_port) || (!flag_lst && !rem_port)))
1049 if (strlen(local_addr) > 8) {
1051 /* Demangle what the kernel gives us */
1052 sscanf(local_addr, "%08X%08X%08X%08X",
1053 &in6.s6_addr32[0], &in6.s6_addr32[1],
1054 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1055 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1056 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1057 sscanf(rem_addr, "%08X%08X%08X%08X",
1058 &in6.s6_addr32[0], &in6.s6_addr32[1],
1059 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1060 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1061 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1062 localaddr.sin6_family = AF_INET6;
1063 remaddr.sin6_family = AF_INET6;
1066 sscanf(local_addr, "%X",
1067 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1068 sscanf(rem_addr, "%X",
1069 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1070 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1071 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1075 fprintf(stderr, _("warning, got bogus tcp line.\n"));
1078 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
1079 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
1080 ((struct sockaddr *) &localaddr)->sa_family);
1084 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "tcp");
1085 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "tcp");
1089 switch (timer_run) {
1091 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1095 snprintf(timers, sizeof(timers), _("on (%2.2f/%ld/%d)"),
1096 (double) time_len / HZ, retr, timeout);
1100 snprintf(timers, sizeof(timers), _("keepalive (%2.2f/%ld/%d)"),
1101 (double) time_len / HZ, retr, timeout);
1105 snprintf(timers, sizeof(timers), _("timewait (%2.2f/%ld/%d)"),
1106 (double) time_len / HZ, retr, timeout);
1110 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
1111 timer_run, (double) time_len / HZ, retr, timeout);
1115 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
1116 prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
1118 finish_this_one(uid,inode,timers);
1121 static int tcp_info(void)
1123 INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
1124 tcp_do_one, "tcp", "tcp6");
1127 static void udp_do_one(int lnr, const char *line,const char *prot)
1129 char local_addr[64], rem_addr[64];
1130 char *udp_state, timers[64], more[512];
1131 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1133 struct sockaddr_in6 localaddr, remaddr;
1134 char addr6[INET6_ADDRSTRLEN];
1135 struct in6_addr in6;
1136 extern struct aftype inet6_aftype;
1138 struct sockaddr_in localaddr, remaddr;
1141 unsigned long rxq, txq, time_len, retr, inode;
1148 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1149 &d, local_addr, &local_port,
1150 rem_addr, &rem_port, &state,
1151 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1153 if (strlen(local_addr) > 8) {
1155 sscanf(local_addr, "%08X%08X%08X%08X",
1156 &in6.s6_addr32[0], &in6.s6_addr32[1],
1157 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1158 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1159 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1160 sscanf(rem_addr, "%08X%08X%08X%08X",
1161 &in6.s6_addr32[0], &in6.s6_addr32[1],
1162 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1163 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1164 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1165 localaddr.sin6_family = AF_INET6;
1166 remaddr.sin6_family = AF_INET6;
1169 sscanf(local_addr, "%X",
1170 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1171 sscanf(rem_addr, "%X",
1172 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1173 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1174 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1182 fprintf(stderr, _("warning, got bogus udp line.\n"));
1185 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
1186 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
1187 ((struct sockaddr *) &localaddr)->sa_family);
1191 case TCP_ESTABLISHED:
1192 udp_state = _("ESTABLISHED");
1200 udp_state = _("UNKNOWN");
1205 #define notnull(A) (((A.sin6_family == AF_INET6) && \
1206 ((A.sin6_addr.s6_addr32[0]) || \
1207 (A.sin6_addr.s6_addr32[1]) || \
1208 (A.sin6_addr.s6_addr32[2]) || \
1209 (A.sin6_addr.s6_addr32[3]))) || \
1210 ((A.sin6_family == AF_INET) && \
1211 ((struct sockaddr_in *) &A)->sin_addr.s_addr))
1213 #define notnull(A) (A.sin_addr.s_addr)
1216 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1218 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "udp");
1219 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "udp");
1223 switch (timer_run) {
1225 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1230 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100, retr, timeout);
1234 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1238 printf("%-5s %6ld %6ld %-23s %-23s %-11s",
1239 prot, rxq, txq, local_addr, rem_addr, udp_state);
1241 finish_this_one(uid,inode,timers);
1245 static int udp_info(void)
1247 INFO_GUTS6(_PATH_PROCNET_UDP, _PATH_PROCNET_UDP6, "AF INET (udp)",
1248 udp_do_one, "udp", "udp6");
1251 static int udplite_info(void)
1253 INFO_GUTS6(_PATH_PROCNET_UDPLITE, _PATH_PROCNET_UDPLITE6,
1254 "AF INET (udplite)", udp_do_one, "udpl", "udpl6" );
1257 static void raw_do_one(int lnr, const char *line,const char *prot)
1259 char local_addr[64], rem_addr[64];
1260 char timers[64], more[512];
1261 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1263 struct sockaddr_in6 localaddr, remaddr;
1264 char addr6[INET6_ADDRSTRLEN];
1265 struct in6_addr in6;
1266 extern struct aftype inet6_aftype;
1268 struct sockaddr_in localaddr, remaddr;
1271 unsigned long rxq, txq, time_len, retr, inode;
1278 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1279 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
1280 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1282 if (strlen(local_addr) > 8) {
1284 sscanf(local_addr, "%08X%08X%08X%08X",
1285 &in6.s6_addr32[0], &in6.s6_addr32[1],
1286 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1287 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1288 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1289 sscanf(rem_addr, "%08X%08X%08X%08X",
1290 &in6.s6_addr32[0], &in6.s6_addr32[1],
1291 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1292 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1293 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1294 localaddr.sin6_family = AF_INET6;
1295 remaddr.sin6_family = AF_INET6;
1298 sscanf(local_addr, "%X",
1299 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1300 sscanf(rem_addr, "%X",
1301 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1302 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1303 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1306 if ((ap = get_afntype(localaddr.sin6_family)) == NULL) {
1307 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin6_family);
1311 if ((ap = get_afntype(localaddr.sin_family)) == NULL) {
1312 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin_family);
1321 fprintf(stderr, _("warning, got bogus raw line.\n"));
1325 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1327 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "raw");
1328 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "raw");
1332 switch (timer_run) {
1334 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1339 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1344 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
1345 timer_run, (double) time_len / 100,
1349 printf("%-4s %6ld %6ld %-23s %-23s %-11d",
1350 prot, rxq, txq, local_addr, rem_addr, state);
1352 finish_this_one(uid,inode,timers);
1356 static int raw_info(void)
1358 INFO_GUTS6(_PATH_PROCNET_RAW, _PATH_PROCNET_RAW6, "AF INET (raw)",
1359 raw_do_one, "raw", "raw6");
1369 static void unix_do_one(int nr, const char *line, const char *prot)
1372 char path[MAXPATHLEN], ss_flags[32];
1373 char *ss_proto, *ss_state, *ss_type;
1374 int num, state, type;
1376 unsigned long refcnt, proto, flags, inode;
1379 if (strstr(line, "Inode"))
1384 num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %s",
1385 &d, &refcnt, &proto, &flags, &type, &state, &inode, path);
1387 fprintf(stderr, _("warning, got bogus unix line.\n"));
1390 if (!(has & HAS_INODE))
1391 snprintf(path,sizeof(path),"%lu",inode);
1394 if ((state == SS_UNCONNECTED) && (flags & SO_ACCEPTCON)) {
1414 ss_type = _("STREAM");
1418 ss_type = _("DGRAM");
1429 case SOCK_SEQPACKET:
1430 ss_type = _("SEQPACKET");
1434 ss_type = _("UNKNOWN");
1439 ss_state = _("FREE");
1442 case SS_UNCONNECTED:
1444 * Unconnected sockets may be listening
1447 if (flags & SO_ACCEPTCON) {
1448 ss_state = _("LISTENING");
1455 ss_state = _("CONNECTING");
1459 ss_state = _("CONNECTED");
1462 case SS_DISCONNECTING:
1463 ss_state = _("DISCONNECTING");
1467 ss_state = _("UNKNOWN");
1470 strcpy(ss_flags, "[ ");
1471 if (flags & SO_ACCEPTCON)
1472 strcat(ss_flags, "ACC ");
1473 if (flags & SO_WAITDATA)
1474 strcat(ss_flags, "W ");
1475 if (flags & SO_NOSPACE)
1476 strcat(ss_flags, "N ");
1478 strcat(ss_flags, "]");
1480 printf("%-5s %-6ld %-11s %-10s %-13s ",
1481 ss_proto, refcnt, ss_flags, ss_type, ss_state);
1482 if (has & HAS_INODE)
1483 printf("%-8lu",inode);
1487 printf(" %-" PROGNAME_WIDTHs "s",(has & HAS_INODE?prg_cache_get(inode):"-"));
1489 printf(" %-" SELINUX_WIDTHs "s",(has & HAS_INODE?prg_cache_get_con(inode):"-"));
1491 printf(" %-" SMK_WIDTHs "s",
1492 (has & HAS_INODE ? prg_cache_get_smkin(inode) : "-"));
1493 printf(" %-" SMK_WIDTHs "s",
1494 (has & HAS_INODE ? prg_cache_get_smkout(inode) : "-"));
1497 printf(" %s\n", path);
1500 static int unix_info(void)
1503 printf(_("Active UNIX domain sockets "));
1505 printf(_("(servers and established)"));
1508 printf(_("(only servers)"));
1510 printf(_("(w/o servers)"));
1513 printf(_("\nProto RefCnt Flags Type State I-Node "));
1514 print_progname_banner();
1515 print_selinux_banner();
1516 print_smack_banner();
1517 printf(_(" Path\n")); /* xxx */
1520 INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one, "unix");
1527 static int ax25_info(void)
1530 char buffer[256], buf[16];
1531 char *src, *dst, *dev, *p;
1532 int st, vs, vr, sendq, recvq, ret;
1533 int new = -1; /* flag for new (2.1.x) kernels */
1534 static char *ax25_state[5] =
1542 if (!(f = proc_fopen(_PATH_PROCNET_AX25))) {
1543 if (errno != ENOENT) {
1544 perror(_PATH_PROCNET_AX25);
1547 if (flag_arg || flag_ver)
1548 ESYSNOT("netstat", "AF AX25");
1554 printf(_("Active AX.25 sockets\n"));
1555 printf(_("Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
1556 while (fgets(buffer, 256, f)) {
1558 if (!strncmp(buffer, "dest_addr", 9)) {
1560 continue; /* old kernels have a header line */
1565 * In a network connection with no user socket the Snd-Q, Rcv-Q
1566 * and Inode fields are empty in 2.0.x and '*' in 2.1.x
1575 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",
1576 buf, &st, &vs, &vr, &sendq, &recvq);
1577 if (ret != 4 && ret != 6) {
1578 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_AX25);
1584 while (*p != ' ') p++;
1587 while (*p != ' ') p++;
1590 while (*p != ' ') p++;
1593 while (*p != ' ') p++;
1595 ret = sscanf(p, "%d %d %d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %*d",
1596 &st, &vs, &vr, &sendq, &recvq);
1597 if (ret != 3 && ret != 5) {
1598 printf(_("problem reading data from %s\n"), _PATH_PROCNET_AX25);
1602 * FIXME: digipeaters should be handled somehow.
1603 * For now we just strip them.
1606 while (*p && *p != ',') p++;
1609 printf("%-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
1613 vr, vs, sendq, recvq);
1622 static int ipx_info(void)
1626 unsigned long txq, rxq;
1633 char sad[50], dad[50];
1635 unsigned sport = 0, dport = 0;
1638 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET1);
1640 if (errno != ENOENT) {
1641 perror(_PATH_PROCNET_IPX_SOCKET1);
1644 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET2);
1646 /* We need to check for directory */
1648 fstat(fileno(f), &s);
1649 if (!S_ISREG(s.st_mode)) {
1656 if (errno != ENOENT) {
1657 perror(_PATH_PROCNET_IPX_SOCKET2);
1660 if (flag_arg || flag_ver)
1661 ESYSNOT("netstat", "AF IPX");
1668 printf(_("Active IPX sockets\nProto Recv-Q Send-Q Local Address Foreign Address State")); /* xxx */
1670 printf(_(" User")); /* xxx */
1672 if ((ap = get_afntype(AF_IPX)) == NULL) {
1673 EINTERN("netstat.c", "AF_IPX missing");
1677 if (fgets(buf, 255, f))
1680 while (fgets(buf, 255, f) != NULL) {
1681 sscanf(buf, "%s %s %lX %lX %d %d",
1682 sad, dad, &txq, &rxq, &state, &uid);
1683 if ((st = rindex(sad, ':'))) {
1685 sscanf(st, "%X", &sport); /* net byt order */
1686 sport = ntohs(sport);
1688 EINTERN("netstat.c", "ipx socket format error in source port");
1693 if (strcmp(dad, "Not_Connected") != 0) {
1694 if ((st = rindex(dad, ':'))) {
1696 sscanf(st, "%X", &dport); /* net byt order */
1697 dport = ntohs(dport);
1699 EINTERN("netstat.c", "ipx soket format error in destination port");
1707 case TCP_ESTABLISHED:
1720 /* Fetch and resolve the Source */
1721 (void) ap->input(4, sad, &sa);
1722 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1723 snprintf(sad, sizeof(sad), "%s:%04X", buf, sport);
1726 /* Fetch and resolve the Destination */
1727 (void) ap->input(4, dad, &sa);
1728 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1729 snprintf(dad, sizeof(dad), "%s:%04X", buf, dport);
1733 printf("IPX %6ld %6ld %-26s %-26s %-5s", txq, rxq, sad, dad, st);
1735 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
1736 printf(" %-10s", pw->pw_name);
1738 printf(" %-10d", uid);
1747 #if HAVE_AFBLUETOOTH
1748 const char *bluetooth_state(int state)
1752 return _("CONNECTED");
1760 return _("CONNECT");
1762 return _("CONNECT2");
1766 return _("DISCONN");
1770 return _("UNKNOWN");
1774 static void l2cap_do_one(int nr, const char *line, const char *prot)
1776 char daddr[18], saddr[18];
1777 unsigned state, psm, dcid, scid, imtu, omtu, sec_level;
1779 const char *bt_state, *bt_sec_level;
1781 num = sscanf(line, "%17s %17s %d %d 0x%04x 0x%04x %d %d %d",
1782 daddr, saddr, &state, &psm, &dcid, &scid, &imtu, &omtu, &sec_level);
1785 fprintf(stderr, _("warning, got bogus l2cap line.\n"));
1789 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1791 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1794 bt_state = bluetooth_state(state);
1795 switch (sec_level) {
1796 case BT_SECURITY_SDP:
1797 bt_sec_level = _("SDP");
1799 case BT_SECURITY_LOW:
1800 bt_sec_level = _("LOW");
1802 case BT_SECURITY_MEDIUM:
1803 bt_sec_level = _("MEDIUM");
1805 case BT_SECURITY_HIGH:
1806 bt_sec_level = _("HIGH");
1809 bt_sec_level = _("UNKNOWN");
1812 printf("l2cap %-17s %-17s %-9s %7d 0x%04x 0x%04x %7d %7d %-7s\n",
1813 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1814 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1815 bt_state, psm, dcid, scid, imtu, omtu, bt_sec_level);
1818 static int l2cap_info(void)
1820 printf("%-6s %-17s %-17s %-9s %7s %-6s %-6s %7s %7s %-7s\n",
1821 "Proto", "Destination", "Source", "State", "PSM", "DCID", "SCID", "IMTU", "OMTU", "Security");
1822 INFO_GUTS(_PATH_SYS_BLUETOOTH_L2CAP, "AF BLUETOOTH", l2cap_do_one, "l2cap");
1825 static void rfcomm_do_one(int nr, const char *line, const char *prot)
1827 char daddr[18], saddr[18];
1828 unsigned state, channel;
1830 const char *bt_state;
1832 num = sscanf(line, "%17s %17s %d %d", daddr, saddr, &state, &channel);
1834 fprintf(stderr, _("warning, got bogus rfcomm line.\n"));
1838 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1840 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1843 bt_state = bluetooth_state(state);
1844 printf("rfcomm %-17s %-17s %-9s %7d\n",
1845 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1846 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1850 static int rfcomm_info(void)
1852 printf("%-6s %-17s %-17s %-9s %7s\n", "Proto", "Destination", "Source", "State", "Channel");
1853 INFO_GUTS(_PATH_SYS_BLUETOOTH_RFCOMM, "AF BLUETOOTH", rfcomm_do_one, "rfcomm");
1857 static int iface_info(void)
1860 if ((skfd = sockets_open(0)) < 0) {
1864 printf(_("Kernel Interface table\n"));
1868 printf(_("Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
1871 if (for_all_interfaces(do_if_print, &flag_all) < 0) {
1872 perror(_("missing interface information"));
1886 static void version(void)
1888 printf("%s\n%s\n%s\n%s\n", Release, Version, Signature, Features);
1893 static void usage(void)
1895 fprintf(stderr, _("usage: netstat [-vWeenNcCF] [<Af>] -r netstat {-V|--version|-h|--help}\n"));
1896 fprintf(stderr, _(" netstat [-vWnNcaeol] [<Socket> ...]\n"));
1897 fprintf(stderr, _(" netstat { [-vWeenNac] -i | [-cnNe] -M | -s [-6tuw] }\n\n"));
1899 fprintf(stderr, _(" -r, --route display routing table\n"));
1900 fprintf(stderr, _(" -i, --interfaces display interface table\n"));
1901 fprintf(stderr, _(" -g, --groups display multicast group memberships\n"));
1902 fprintf(stderr, _(" -s, --statistics display networking statistics (like SNMP)\n"));
1903 #if HAVE_FW_MASQUERADE
1904 fprintf(stderr, _(" -M, --masquerade display masqueraded connections\n\n"));
1907 fprintf(stderr, _(" -v, --verbose be verbose\n"));
1908 fprintf(stderr, _(" -W, --wide don't truncate IP addresses\n"));
1909 fprintf(stderr, _(" -n, --numeric don't resolve names\n"));
1910 fprintf(stderr, _(" --numeric-hosts don't resolve host names\n"));
1911 fprintf(stderr, _(" --numeric-ports don't resolve port names\n"));
1912 fprintf(stderr, _(" --numeric-users don't resolve user names\n"));
1913 fprintf(stderr, _(" -N, --symbolic resolve hardware names\n"));
1914 fprintf(stderr, _(" -e, --extend display other/more information\n"));
1915 fprintf(stderr, _(" -p, --programs display PID/Program name for sockets\n"));
1916 fprintf(stderr, _(" -o, --timers display timers\n"));
1917 fprintf(stderr, _(" -c, --continuous continuous listing\n\n"));
1918 fprintf(stderr, _(" -l, --listening display listening server sockets\n"));
1919 fprintf(stderr, _(" -a, --all display all sockets (default: connected)\n"));
1920 fprintf(stderr, _(" -F, --fib display Forwarding Information Base (default)\n"));
1921 fprintf(stderr, _(" -C, --cache display routing cache instead of FIB\n"));
1923 fprintf(stderr, _(" -Z, --context display SELinux security context for sockets\n"));
1926 fprintf(stderr, _(" -X, --smack display Smack labels for sockets\n"));
1927 fprintf(stderr, _("\n <Socket>={-t|--tcp} {-u|--udp} {-U|--udplite} {-w|--raw} {-x|--unix}\n"));
1928 fprintf(stderr, _(" --ax25 --ipx --netrom\n"));
1929 fprintf(stderr, _(" <AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
1930 fprintf(stderr, _(" List of possible address families (which support routing):\n"));
1931 print_aflist(1); /* 1 = routeable */
1937 (int argc, char *argv[]) {
1940 static struct option longopts[] =
1943 {"version", 0, 0, 'V'},
1944 {"interfaces", 0, 0, 'i'},
1945 {"help", 0, 0, 'h'},
1946 {"route", 0, 0, 'r'},
1947 #if HAVE_FW_MASQUERADE
1948 {"masquerade", 0, 0, 'M'},
1950 {"protocol", 1, 0, 'A'},
1952 {"sctp", 0, 0, 'S'},
1954 {"udplite", 0, 0, 'U'},
1956 {"unix", 0, 0, 'x'},
1957 {"l2cap", 0, 0, '2'},
1958 {"rfcomm", 0, 0, 'f'},
1959 {"listening", 0, 0, 'l'},
1961 {"timers", 0, 0, 'o'},
1962 {"continuous", 0, 0, 'c'},
1963 {"extend", 0, 0, 'e'},
1964 {"programs", 0, 0, 'p'},
1965 {"verbose", 0, 0, 'v'},
1966 {"statistics", 0, 0, 's'},
1967 {"wide", 0, 0, 'W'},
1968 {"numeric", 0, 0, 'n'},
1969 {"numeric-hosts", 0, 0, '!'},
1970 {"numeric-ports", 0, 0, '@'},
1971 {"numeric-users", 0, 0, '#'},
1972 {"symbolic", 0, 0, 'N'},
1973 {"cache", 0, 0, 'C'},
1975 {"groups", 0, 0, 'g'},
1976 {"context", 0, 0, 'Z'},
1977 {"smack", 0 , 0, 'X'},
1982 setlocale (LC_ALL, "");
1983 bindtextdomain("net-tools", "/usr/share/locale");
1984 textdomain("net-tools");
1986 getroute_init(); /* Set up AF routing support */
1989 while ((i = getopt_long(argc, argv, "A:CFMacdeghilnNoprsStuUvVWwx64?ZX", longopts, &lop)) != EOF)
1994 if (lop < 0 || lop >= AFTRANS_CNT) {
1995 EINTERN("netstat.c", "longopts 1 range");
1998 if (aftrans_opt(longopts[lop].name))
2002 if (aftrans_opt(optarg))
2037 flag_not |= FLAG_NUM;
2040 flag_not |= FLAG_NUM_HOST;
2043 flag_not |= FLAG_NUM_PORT;
2046 flag_not |= FLAG_NUM_USER;
2049 flag_not |= FLAG_SYM;
2052 flag_cf |= FLAG_CACHE;
2055 flag_cf |= FLAG_FIB;
2061 if (aftrans_opt("inet6"))
2065 if (aftrans_opt("inet"))
2072 flag_ver |= FLAG_VERBOSE;
2099 if (aftrans_opt("unix"))
2104 if (is_selinux_enabled() <= 0) {
2105 fprintf(stderr, _("SELinux is not enabled on this machine.\n"));
2111 fprintf(stderr, _("SELinux is not enabled for this application.\n"));
2127 if (flag_int + flag_rou + flag_mas + flag_sta > 1)
2130 if ((flag_inet || flag_inet6 || flag_sta) &&
2131 !(flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw))
2132 flag_tcp = flag_sctp = flag_udp = flag_udplite = flag_raw = 1;
2134 if ((flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw || flag_igmp) &&
2135 !(flag_inet || flag_inet6))
2136 flag_inet = flag_inet6 = 1;
2138 if (flag_bluetooth && !(flag_l2cap || flag_rfcomm))
2139 flag_l2cap = flag_rfcomm = 1;
2141 flag_arg = flag_tcp + flag_sctp + flag_udplite + flag_udp + flag_raw + flag_unx
2142 + flag_ipx + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose
2143 + flag_l2cap + flag_rfcomm;
2146 #if HAVE_FW_MASQUERADE && HAVE_AFINET
2147 #if MORE_THAN_ONE_MASQ_AF
2149 strcpy(afname, DFLT_AF);
2152 i = ip_masq_info(flag_not & FLAG_NUM_HOST,
2153 flag_not & FLAG_NUM_PORT, flag_exp);
2159 ENOSUPP("netstat", "FW_MASQUERADE");
2167 strcpy(afname, DFLT_AF);
2169 if (!strcmp(afname, "inet")) {
2172 parsesnmp(flag_raw, flag_tcp, flag_udp);
2174 ENOSUPP("netstat", "AF INET");
2176 } else if(!strcmp(afname, "inet6")) {
2179 parsesnmp6(flag_raw, flag_tcp, flag_udp);
2181 ENOSUPP("netstat", "AF INET6");
2184 printf(_("netstat: No statistics support for specified address family: %s\n"), afname);
2194 strcpy(afname, DFLT_AF);
2198 else if (flag_exp == 1)
2201 options = (flag_exp & FLAG_EXT) | flag_not | flag_cf | flag_ver;
2203 options |= FLAG_FIB;
2206 i = route_info(afname, options);
2223 if (!flag_arg || flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw) {
2226 printf(_("Active Internet connections ")); /* xxx */
2229 printf(_("(servers and established)"));
2232 printf(_("(only servers)"));
2234 printf(_("(w/o servers)"));
2236 printf(_("\nProto Recv-Q Send-Q Local Address Foreign Address State ")); /* xxx */
2238 printf(_(" User Inode "));
2239 print_progname_banner();
2240 print_selinux_banner();
2242 printf(_(" Timer")); /* xxx */
2247 ENOSUPP("netstat", "AF INET");
2252 if (!flag_arg || flag_tcp) {
2258 if (!flag_arg || flag_sctp) {
2264 if (!flag_arg || flag_udp) {
2270 if (!flag_arg || flag_udplite) {
2276 if (!flag_arg || flag_raw) {
2286 printf( _("IPv4 Group Memberships\n") );
2287 printf( _("Interface RefCnt Group\n") );
2288 printf( "--------------- ------ ---------------------\n" );
2295 if (!flag_arg || flag_unx) {
2304 ENOSUPP("netstat", "AF UNIX");
2308 if (!flag_arg || flag_ipx) {
2316 ENOSUPP("netstat", "AF IPX");
2320 if (!flag_arg || flag_ax25) {
2328 ENOSUPP("netstat", "AF AX25");
2332 if(!flag_arg || flag_x25) {
2341 ENOSUPP("netstat", "AF X25");
2345 if (!flag_arg || flag_netrom) {
2353 ENOSUPP("netstat", "AF NETROM");
2357 if (!flag_arg || flag_rose) {
2358 #if 0 && HAVE_AFROSE
2365 ENOSUPP("netstat", "AF ROSE");
2370 if (!flag_arg || flag_l2cap || flag_rfcomm) {
2371 #if HAVE_AFBLUETOOTH
2372 printf(_("Active Bluetooth connections ")); /* xxx */
2375 printf(_("(servers and established)"));
2378 printf(_("(only servers)"));
2380 printf(_("(w/o servers)"));
2386 ENOSUPP("netstat", "AF BLUETOOTH");
2390 #if HAVE_AFBLUETOOTH
2391 if (!flag_arg || flag_l2cap) {
2396 if (!flag_arg || flag_rfcomm) {