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>
93 #include <selinux/selinux.h>
95 #include "net-support.h"
96 #include "pathnames.h"
101 #include "interface.h"
106 #include <bluetooth/bluetooth.h>
109 #define PROGNAME_WIDTH 20
110 #define SELINUX_WIDTH 50
112 #if !defined(s6_addr32) && defined(in6a_words)
113 #define s6_addr32 in6a_words /* libinet6 */
116 /* prototypes for statistics.c */
117 void parsesnmp(int, int, int);
119 void parsesnmp6(int, int, int);
123 SS_FREE = 0, /* not allocated */
124 SS_UNCONNECTED, /* unconnected to any socket */
125 SS_CONNECTING, /* in process of connecting */
126 SS_CONNECTED, /* connected to socket */
127 SS_DISCONNECTING /* in process of disconnecting */
130 #define SO_ACCEPTCON (1<<16) /* performed a listen */
131 #define SO_WAITDATA (1<<17) /* wait data to read */
132 #define SO_NOSPACE (1<<18) /* no space to write */
134 #define DFLT_AF "inet"
136 #define FEATURE_NETSTAT
137 #include "lib/net-features.h"
139 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";
161 int flag_udplite = 0;
171 int flag_selinux = 0;
175 #define INFO_GUTS1(file,name,proc,prot) \
176 procinfo = proc_fopen((file)); \
177 if (procinfo == NULL) { \
178 if (errno != ENOENT) { \
182 if (flag_arg || flag_ver) \
183 ESYSNOT("netstat", (name)); \
188 if (fgets(buffer, sizeof(buffer), procinfo)) \
189 (proc)(lnr++, buffer,prot); \
190 } while (!feof(procinfo)); \
195 #define INFO_GUTS2(file,proc,prot) \
197 procinfo = proc_fopen((file)); \
198 if (procinfo != NULL) { \
200 if (fgets(buffer, sizeof(buffer), procinfo)) \
201 (proc)(lnr++, buffer,prot); \
202 } while (!feof(procinfo)); \
206 #define INFO_GUTS2(file,proc,prot)
212 #define INFO_GUTS6(file,file6,name,proc,prot4,prot6) \
216 if (!flag_arg || flag_inet) { \
217 INFO_GUTS1(file,name,proc,prot4) \
219 if (!flag_arg || flag_inet6) { \
220 INFO_GUTS2(file6,proc,prot6) \
224 #define INFO_GUTS(file,name,proc,prot) \
228 INFO_GUTS1(file,name,proc,prot) \
231 #define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
232 #define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)
233 #define PROGNAME_WIDTH2(s) #s
235 #define SELINUX_WIDTHs SELINUX_WIDTH1(SELINUX_WIDTH)
236 #define SELINUX_WIDTH1(s) SELINUX_WIDTH2(s)
237 #define SELINUX_WIDTH2(s) #s
239 #define PRG_HASH_SIZE 211
241 static struct prg_node {
242 struct prg_node *next;
244 char name[PROGNAME_WIDTH];
245 char scon[SELINUX_WIDTH];
246 } *prg_hash[PRG_HASH_SIZE];
248 static char prg_cache_loaded = 0;
250 #define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE)
252 #define PROGNAME_BANNER "PID/Program name"
253 #define SELINUX_BANNER "Security Context"
255 #define print_progname_banner() do { if (flag_prg) printf(" %-" PROGNAME_WIDTHs "s",PROGNAME_BANNER); } while (0)
257 #define print_selinux_banner() do { if (flag_selinux) printf("%-" SELINUX_WIDTHs "s"," " SELINUX_BANNER); } while (0)
259 #define PRG_LOCAL_ADDRESS "local_address"
260 #define PRG_INODE "inode"
261 #define PRG_SOCKET_PFX "socket:["
262 #define PRG_SOCKET_PFXl (strlen(PRG_SOCKET_PFX))
263 #define PRG_SOCKET_PFX2 "[0000]:"
264 #define PRG_SOCKET_PFX2l (strlen(PRG_SOCKET_PFX2))
268 #define LINE_MAX 4096
271 #define PATH_PROC "/proc"
272 #define PATH_FD_SUFF "fd"
273 #define PATH_FD_SUFFl strlen(PATH_FD_SUFF)
274 #define PATH_PROC_X_FD PATH_PROC "/%s/" PATH_FD_SUFF
275 #define PATH_CMDLINE "cmdline"
276 #define PATH_CMDLINEl strlen(PATH_CMDLINE)
278 static void prg_cache_add(unsigned long inode, char *name, const char *scon)
280 unsigned hi = PRG_HASHIT(inode);
281 struct prg_node **pnp,*pn;
283 prg_cache_loaded = 2;
284 for (pnp = prg_hash + hi; (pn = *pnp); pnp = &pn->next) {
285 if (pn->inode == inode) {
286 /* Some warning should be appropriate here
287 as we got multiple processes for one i-node */
291 if (!(*pnp = malloc(sizeof(**pnp))))
296 if (strlen(name) > sizeof(pn->name) - 1)
297 name[sizeof(pn->name) - 1] = '\0';
298 strcpy(pn->name, name);
301 int len = (strlen(scon) - sizeof(pn->scon)) + 1;
303 strcpy(pn->scon, &scon[len + 1]);
305 strcpy(pn->scon, scon);
310 static const char *prg_cache_get(unsigned long inode)
312 unsigned hi = PRG_HASHIT(inode);
315 for (pn = prg_hash[hi]; pn; pn = pn->next)
316 if (pn->inode == inode)
321 static const char *prg_cache_get_con(unsigned long inode)
323 unsigned hi = PRG_HASHIT(inode);
326 for (pn = prg_hash[hi]; pn; pn = pn->next)
327 if (pn->inode == inode)
332 static void prg_cache_clear(void)
334 struct prg_node **pnp,*pn;
336 if (prg_cache_loaded == 2)
337 for (pnp = prg_hash; pnp < prg_hash + PRG_HASH_SIZE; pnp++)
338 while ((pn = *pnp)) {
342 prg_cache_loaded = 0;
345 static void wait_continous(void)
351 static int extract_type_1_socket_inode(const char lname[], unsigned long * inode_p) {
353 /* If lname is of the form "socket:[12345]", extract the "12345"
354 as *inode_p. Otherwise, return -1 as *inode_p.
357 if (strlen(lname) < PRG_SOCKET_PFXl+3) return(-1);
359 if (memcmp(lname, PRG_SOCKET_PFX, PRG_SOCKET_PFXl)) return(-1);
360 if (lname[strlen(lname)-1] != ']') return(-1);
363 char inode_str[strlen(lname + 1)]; /* e.g. "12345" */
364 const int inode_str_len = strlen(lname) - PRG_SOCKET_PFXl - 1;
367 strncpy(inode_str, lname+PRG_SOCKET_PFXl, inode_str_len);
368 inode_str[inode_str_len] = '\0';
369 *inode_p = strtoul(inode_str, &serr, 0);
370 if (!serr || *serr || *inode_p == ~0)
378 static int extract_type_2_socket_inode(const char lname[], unsigned long * inode_p) {
380 /* If lname is of the form "[0000]:12345", extract the "12345"
381 as *inode_p. Otherwise, return -1 as *inode_p.
384 if (strlen(lname) < PRG_SOCKET_PFX2l+1) return(-1);
385 if (memcmp(lname, PRG_SOCKET_PFX2, PRG_SOCKET_PFX2l)) return(-1);
390 *inode_p = strtoul(lname + PRG_SOCKET_PFX2l, &serr, 0);
391 if (!serr || *serr || *inode_p == ~0)
400 static void prg_cache_load(void)
402 char line[LINE_MAX], eacces=0;
403 int procfdlen, fd, cmdllen, lnamelen;
404 char lname[30], cmdlbuf[512], finbuf[PROGNAME_WIDTH];
406 const char *cs, *cmdlp;
407 DIR *dirproc = NULL, *dirfd = NULL;
408 struct dirent *direproc, *direfd;
410 security_context_t scon = NULL;
413 if (prg_cache_loaded || !flag_prg) return;
414 prg_cache_loaded = 1;
415 cmdlbuf[sizeof(cmdlbuf) - 1] = '\0';
416 if (!(dirproc=opendir(PATH_PROC))) goto fail;
417 while (errno = 0, direproc = readdir(dirproc)) {
418 for (cs = direproc->d_name; *cs; cs++)
423 procfdlen = snprintf(line,sizeof(line),PATH_PROC_X_FD,direproc->d_name);
424 if (procfdlen <= 0 || procfdlen >= sizeof(line) - 5)
427 dirfd = opendir(line);
433 line[procfdlen] = '/';
435 while ((direfd = readdir(dirfd))) {
437 if (!isdigit(direfd->d_name[0]))
439 if (procfdlen + 1 + strlen(direfd->d_name) + 1 > sizeof(line))
441 memcpy(line + procfdlen - PATH_FD_SUFFl, PATH_FD_SUFF "/",
443 strcpy(line + procfdlen + 1, direfd->d_name);
444 lnamelen = readlink(line, lname, sizeof(lname) - 1);
447 lname[lnamelen] = '\0'; /*make it a null-terminated string*/
449 if (extract_type_1_socket_inode(lname, &inode) < 0)
450 if (extract_type_2_socket_inode(lname, &inode) < 0)
454 if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >=
457 strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_CMDLINE);
458 fd = open(line, O_RDONLY);
461 cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1);
466 if (cmdllen < sizeof(cmdlbuf) - 1)
467 cmdlbuf[cmdllen]='\0';
468 if (cmdlbuf[0] == '/' && (cmdlp = strrchr(cmdlbuf, '/')))
474 snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp);
476 if (getpidcon(atoi(direproc->d_name), &scon) == -1) {
479 prg_cache_add(inode, finbuf, scon);
482 prg_cache_add(inode, finbuf, "-");
494 if (prg_cache_loaded == 1) {
496 fprintf(stderr,_("(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n"),
500 fprintf(stderr, _("(Not all processes could be identified, non-owned process info\n"
501 " will not be shown, you would have to be root to see it all.)\n"));
505 static const char *netrom_state[] =
513 static int netrom_info(void)
516 char buffer[256], dev[16];
517 int st, vs, vr, sendq, recvq, ret;
519 f = proc_fopen(_PATH_PROCNET_NR);
521 if (errno != ENOENT) {
522 perror(_PATH_PROCNET_NR);
525 if (flag_arg || flag_ver)
526 ESYSNOT("netstat", "AF NETROM");
532 printf(_("Active NET/ROM sockets\n"));
533 printf(_("User Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
534 if (fgets(buffer, 256, f))
537 while (fgets(buffer, 256, f)) {
541 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",
542 dev, &st, &vs, &vr, &sendq, &recvq);
544 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_NR);
547 printf("%-9s %-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
548 buffer, buffer + 10, buffer + 20,
551 vr, vs, sendq, recvq);
558 /* These enums are used by IPX too. :-( */
570 TCP_CLOSING /* now a valid state */
573 #if HAVE_AFINET || HAVE_AFINET6
575 static const char *tcp_state[] =
591 static void finish_this_one(int uid, unsigned long inode, const char *timers)
596 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
597 printf(" %-10s ", pw->pw_name);
599 printf(" %-10d ", uid);
600 printf("%-10lu",inode);
603 printf(" %-" PROGNAME_WIDTHs "s",prg_cache_get(inode));
605 printf(" %-" SELINUX_WIDTHs "s",prg_cache_get_con(inode));
608 printf(" %s", timers);
612 static void igmp_do_one(int lnr, const char *line,const char *prot)
614 char mcast_addr[128];
616 struct sockaddr_in6 mcastaddr;
617 char addr6[INET6_ADDRSTRLEN];
619 extern struct aftype inet6_aftype;
621 struct sockaddr_in mcastaddr;
624 static int idx_flag = 0;
625 static int igmp6_flag = 0;
626 static char device[16];
627 int num, idx, refcnt;
631 /* igmp6 file does not have any comments on first line */
632 if ( strstr( line, "Device" ) == NULL ) {
636 /* 2.1.x kernels and up have Idx field */
637 /* 2.0.x and below do not have Idx field */
638 if ( strncmp( line, "Idx", strlen("Idx") ) == 0 )
646 if (igmp6_flag) { /* IPV6 */
648 num = sscanf( line, "%d %15s %64[0-9A-Fa-f] %d", &idx, device, mcast_addr, &refcnt );
650 /* Demangle what the kernel gives us */
651 sscanf(mcast_addr, "%08X%08X%08X%08X",
652 &in6.s6_addr32[0], &in6.s6_addr32[1],
653 &in6.s6_addr32[2], &in6.s6_addr32[3]);
654 in6.s6_addr32[0] = htonl(in6.s6_addr32[0]);
655 in6.s6_addr32[1] = htonl(in6.s6_addr32[1]);
656 in6.s6_addr32[2] = htonl(in6.s6_addr32[2]);
657 in6.s6_addr32[3] = htonl(in6.s6_addr32[3]);
658 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
659 inet6_aftype.input(1, addr6, (struct sockaddr *) &mcastaddr);
660 mcastaddr.sin6_family = AF_INET6;
662 fprintf(stderr, _("warning, got bogus igmp6 line %d.\n"), lnr);
666 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
667 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
668 ((struct sockaddr *) &mcastaddr)->sa_family);
671 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
672 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
673 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr);
677 if (line[0] != '\t') {
679 if ((num = sscanf( line, "%d\t%10c", &idx, device)) < 2) {
680 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
684 if ( (num = sscanf( line, "%10c", device )) < 1 ) {
685 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
691 } else if ( line[0] == '\t' ) {
692 if ( (num = sscanf(line, "\t%8[0-9A-Fa-f] %d", mcast_addr, &refcnt)) < 2 ) {
693 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
696 sscanf( mcast_addr, "%X",
697 &((struct sockaddr_in *) &mcastaddr)->sin_addr.s_addr );
698 ((struct sockaddr *) &mcastaddr)->sa_family = AF_INET;
700 fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
704 if ((ap = get_afntype(((struct sockaddr *) &mcastaddr)->sa_family)) == NULL) {
705 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
706 ((struct sockaddr *) &mcastaddr)->sa_family);
709 safe_strncpy(mcast_addr, ap->sprint((struct sockaddr *) &mcastaddr,
710 flag_not & FLAG_NUM_HOST), sizeof(mcast_addr));
711 printf("%-15s %-6d %s\n", device, refcnt, mcast_addr );
717 static int x25_info(void)
719 FILE *f=proc_fopen(_PATH_PROCNET_X25);
720 char buffer[256],dev[16];
721 int st,vs,vr,sendq,recvq,lci;
722 static char *x25_state[5]=
732 if (errno != ENOENT) {
733 perror(_PATH_PROCNET_X25);
736 if (flag_arg || flag_ver)
737 ESYSNOT("netstat","AF X25");
743 printf( _("Active X.25 sockets\n"));
744 /* IMHO, Vr/Vs is not very usefull --SF */
745 printf( _("Dest Source Device LCI State Vr/Vs Send-Q Recv-Q\n"));
746 if (fgets(buffer,256,f))
748 while(fgets(buffer,256,f))
752 sscanf(buffer+22,"%s %d %d %d %d %*d %*d %*d %*d %*d %*d %d %d %*d",
753 dev,&lci,&st,&vs,&vr,&sendq,&recvq);
754 if (!(flag_all || lci))
756 printf("%-15s %-15s %-7s %-3d %-11s %02d/%02d %-6d %-6d\n",
768 static int igmp_info(void)
770 INFO_GUTS6(_PATH_PROCNET_IGMP, _PATH_PROCNET_IGMP6, "AF INET (igmp)",
771 igmp_do_one, "igmp", "igmp6");
774 static int ip_parse_dots(uint32_t *addr, char const *src) {
776 unsigned ret = 4-sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d);
777 *addr = htonl((a << 24)|(b << 16)|(c << 8)|d);
781 static void print_ip_service(struct sockaddr_in *addr, char const *protname,
782 char *buf, unsigned size) {
785 if(size == 0) return;
788 if((ap = get_afntype(addr->sin_family)) == NULL) {
789 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
793 safe_strncpy(buf, ap->sprint((struct sockaddr*)addr, flag_not), size);
796 if(flag_all || (flag_lst && !addr->sin_port) || (!flag_lst && addr->sin_port)) {
799 snprintf(bfs, sizeof(bfs), "%s",
800 get_sname(addr->sin_port, (char*)protname, flag_not & FLAG_NUM_PORT));
802 /* check if we must cut on host and/or service name */
804 unsigned const bufl = strlen(buf);
805 unsigned const bfsl = strlen(bfs);
807 if(bufl+bfsl+2 > size) {
808 unsigned const half = (size-2)>>1;
811 buf[size-2-half] = '\0';
814 else buf[size-2-bfsl] = '\0';
816 else bfs[size-2-bufl] = '\0';
824 /* process single SCTP endpoint */
825 static void sctp_do_ept(int lnr, char const *line, const char *prot)
827 struct sockaddr_in laddr, raddr;
830 char l_addr[23], r_addr[23];
832 /* fill sockaddr_in structures */
838 if(sscanf(line, "%*X %*X %*u %*u %*u %u %u %u %n",
839 &lport, &uid, &inode, &ate) < 3) goto err;
841 /* decode IP address */
842 if(ip_parse_dots(&laddr.sin_addr.s_addr, line+ate)) goto err;
843 raddr.sin_addr.s_addr = htonl(0);
844 laddr.sin_family = raddr.sin_family = AF_INET;
845 laddr.sin_port = htons(lport);
846 raddr.sin_port = htons(0);
849 /* print IP:service to l_addr and r_addr */
850 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
851 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
854 printf("%-4s %6d %6d %-*s %-*s %-11s",
856 (int)netmax(23,strlen(l_addr)), l_addr,
857 (int)netmax(23,strlen(r_addr)), r_addr,
858 _(tcp_state[TCP_LISTEN]));
859 finish_this_one(uid, inode, "");
862 fprintf(stderr, "SCTP error in line: %d\n", lnr);
865 /* process single SCTP association */
866 static void sctp_do_assoc(int lnr, char const *line, const char *prot)
868 struct sockaddr_in laddr, raddr;
869 unsigned long rxq, txq;
872 char l_addr[23], r_addr[23];
874 /* fill sockaddr_in structures */
876 unsigned lport, rport;
881 if(sscanf(line, "%*X %*X %*u %*u %*u %*u %*u %lu %lu %u %u %u %u %n",
882 &txq, &rxq, &uid, &inode, &lport, &rport, &ate) < 6) goto err;
884 /* decode IP addresses */
885 addr = strchr(line+ate, '*');
886 if(addr == 0) goto err;
887 if(ip_parse_dots(&laddr.sin_addr.s_addr, ++addr)) goto err;
888 addr = strchr(addr, '*');
889 if(addr == 0) goto err;
890 if(ip_parse_dots(&raddr.sin_addr.s_addr, ++addr)) goto err;
892 /* complete sockaddr_in structures */
893 laddr.sin_family = raddr.sin_family = AF_INET;
894 laddr.sin_port = htons(lport);
895 raddr.sin_port = htons(rport);
898 /* print IP:service to l_addr and r_addr */
899 print_ip_service(&laddr, prot, l_addr, sizeof(l_addr));
900 print_ip_service(&raddr, prot, r_addr, sizeof(r_addr));
903 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
905 (int)netmax(23,strlen(l_addr)), l_addr,
906 (int)netmax(23,strlen(r_addr)), r_addr,
907 _(tcp_state[TCP_ESTABLISHED]));
908 finish_this_one(uid, inode, "");
911 fprintf(stderr, "SCTP error in line: %d\n", lnr);
914 static int sctp_info_epts(void) {
915 INFO_GUTS6(_PATH_PROCNET_SCTPEPTS, _PATH_PROCNET_SCTP6EPTS, "AF INET (sctp)",
916 sctp_do_ept, "sctp", "sctp6");
919 static int sctp_info_assocs(void) {
920 INFO_GUTS6(_PATH_PROCNET_SCTPASSOCS, _PATH_PROCNET_SCTP6ASSOCS, "AF INET (sctp)",
921 sctp_do_assoc, "sctp", "sctp6");
924 static int sctp_info(void) {
926 res = sctp_info_epts();
928 return sctp_info_assocs();
931 static void addr_do_one(char *buf, size_t buf_len, size_t short_len, struct aftype *ap,
933 struct sockaddr_in6 *addr,
935 struct sockaddr_in *addr,
937 int port, const char *proto
940 const char *sport, *saddr;
941 size_t port_len, addr_len;
943 saddr = ap->sprint((struct sockaddr *)addr, flag_not & FLAG_NUM_HOST);
944 sport = get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT);
945 addr_len = strlen(saddr);
946 port_len = strlen(sport);
947 if (!flag_wide && (addr_len + port_len > short_len)) {
948 /* Assume port name is short */
949 port_len = netmin(port_len, short_len - 4);
950 addr_len = short_len - port_len;
951 strncpy(buf, saddr, addr_len);
952 buf[addr_len] = '\0';
954 strncat(buf, sport, port_len);
956 snprintf(buf, buf_len, "%s:%s", saddr, sport);
959 static void tcp_do_one(int lnr, const char *line, const char *prot)
961 unsigned long rxq, txq, time_len, retr, inode;
962 int num, local_port, rem_port, d, state, uid, timer_run, timeout;
963 char rem_addr[128], local_addr[128], timers[64], more[512];
966 struct sockaddr_in6 localaddr, remaddr;
967 char addr6[INET6_ADDRSTRLEN];
969 extern struct aftype inet6_aftype;
971 struct sockaddr_in localaddr, remaddr;
978 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %512s\n",
979 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
980 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
982 if (!flag_all && ((flag_lst && rem_port) || (!flag_lst && !rem_port)))
985 if (strlen(local_addr) > 8) {
987 /* Demangle what the kernel gives us */
988 sscanf(local_addr, "%08X%08X%08X%08X",
989 &in6.s6_addr32[0], &in6.s6_addr32[1],
990 &in6.s6_addr32[2], &in6.s6_addr32[3]);
991 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
992 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
993 sscanf(rem_addr, "%08X%08X%08X%08X",
994 &in6.s6_addr32[0], &in6.s6_addr32[1],
995 &in6.s6_addr32[2], &in6.s6_addr32[3]);
996 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
997 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
998 localaddr.sin6_family = AF_INET6;
999 remaddr.sin6_family = AF_INET6;
1002 sscanf(local_addr, "%X",
1003 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1004 sscanf(rem_addr, "%X",
1005 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1006 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1007 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1011 fprintf(stderr, _("warning, got bogus tcp line.\n"));
1014 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
1015 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
1016 ((struct sockaddr *) &localaddr)->sa_family);
1020 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "tcp");
1021 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "tcp");
1025 switch (timer_run) {
1027 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1031 snprintf(timers, sizeof(timers), _("on (%2.2f/%ld/%d)"),
1032 (double) time_len / HZ, retr, timeout);
1036 snprintf(timers, sizeof(timers), _("keepalive (%2.2f/%ld/%d)"),
1037 (double) time_len / HZ, retr, timeout);
1041 snprintf(timers, sizeof(timers), _("timewait (%2.2f/%ld/%d)"),
1042 (double) time_len / HZ, retr, timeout);
1046 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
1047 timer_run, (double) time_len / HZ, retr, timeout);
1051 printf("%-4s %6ld %6ld %-*s %-*s %-11s",
1052 prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
1054 finish_this_one(uid,inode,timers);
1057 static int tcp_info(void)
1059 INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
1060 tcp_do_one, "tcp", "tcp6");
1063 static void udp_do_one(int lnr, const char *line,const char *prot)
1065 char local_addr[64], rem_addr[64];
1066 char *udp_state, timers[64], more[512];
1067 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1069 struct sockaddr_in6 localaddr, remaddr;
1070 char addr6[INET6_ADDRSTRLEN];
1071 struct in6_addr in6;
1072 extern struct aftype inet6_aftype;
1074 struct sockaddr_in localaddr, remaddr;
1077 unsigned long rxq, txq, time_len, retr, inode;
1084 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1085 &d, local_addr, &local_port,
1086 rem_addr, &rem_port, &state,
1087 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1089 if (strlen(local_addr) > 8) {
1091 sscanf(local_addr, "%08X%08X%08X%08X",
1092 &in6.s6_addr32[0], &in6.s6_addr32[1],
1093 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1094 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1095 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1096 sscanf(rem_addr, "%08X%08X%08X%08X",
1097 &in6.s6_addr32[0], &in6.s6_addr32[1],
1098 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1099 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1100 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1101 localaddr.sin6_family = AF_INET6;
1102 remaddr.sin6_family = AF_INET6;
1105 sscanf(local_addr, "%X",
1106 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1107 sscanf(rem_addr, "%X",
1108 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1109 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1110 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1118 fprintf(stderr, _("warning, got bogus udp line.\n"));
1121 if ((ap = get_afntype(((struct sockaddr *) &localaddr)->sa_family)) == NULL) {
1122 fprintf(stderr, _("netstat: unsupported address family %d !\n"),
1123 ((struct sockaddr *) &localaddr)->sa_family);
1127 case TCP_ESTABLISHED:
1128 udp_state = _("ESTABLISHED");
1136 udp_state = _("UNKNOWN");
1141 #define notnull(A) (((A.sin6_family == AF_INET6) && \
1142 ((A.sin6_addr.s6_addr32[0]) || \
1143 (A.sin6_addr.s6_addr32[1]) || \
1144 (A.sin6_addr.s6_addr32[2]) || \
1145 (A.sin6_addr.s6_addr32[3]))) || \
1146 ((A.sin6_family == AF_INET) && \
1147 ((struct sockaddr_in *) &A)->sin_addr.s_addr))
1149 #define notnull(A) (A.sin_addr.s_addr)
1152 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1154 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "udp");
1155 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "udp");
1159 switch (timer_run) {
1161 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1166 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100, retr, timeout);
1170 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1174 printf("%-5s %6ld %6ld %-23s %-23s %-11s",
1175 prot, rxq, txq, local_addr, rem_addr, udp_state);
1177 finish_this_one(uid,inode,timers);
1181 static int udp_info(void)
1183 INFO_GUTS6(_PATH_PROCNET_UDP, _PATH_PROCNET_UDP6, "AF INET (udp)",
1184 udp_do_one, "udp", "udp6");
1187 static int udplite_info(void)
1189 INFO_GUTS6(_PATH_PROCNET_UDPLITE, _PATH_PROCNET_UDPLITE6,
1190 "AF INET (udplite)", udp_do_one, "udpl", "udpl6" );
1193 static void raw_do_one(int lnr, const char *line,const char *prot)
1195 char local_addr[64], rem_addr[64];
1196 char timers[64], more[512];
1197 int num, local_port, rem_port, d, state, timer_run, uid, timeout;
1199 struct sockaddr_in6 localaddr, remaddr;
1200 char addr6[INET6_ADDRSTRLEN];
1201 struct in6_addr in6;
1202 extern struct aftype inet6_aftype;
1204 struct sockaddr_in localaddr, remaddr;
1207 unsigned long rxq, txq, time_len, retr, inode;
1214 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %511s\n",
1215 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
1216 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
1218 if (strlen(local_addr) > 8) {
1220 sscanf(local_addr, "%08X%08X%08X%08X",
1221 &in6.s6_addr32[0], &in6.s6_addr32[1],
1222 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1223 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1224 inet6_aftype.input(1, addr6, (struct sockaddr *) &localaddr);
1225 sscanf(rem_addr, "%08X%08X%08X%08X",
1226 &in6.s6_addr32[0], &in6.s6_addr32[1],
1227 &in6.s6_addr32[2], &in6.s6_addr32[3]);
1228 inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
1229 inet6_aftype.input(1, addr6, (struct sockaddr *) &remaddr);
1230 localaddr.sin6_family = AF_INET6;
1231 remaddr.sin6_family = AF_INET6;
1234 sscanf(local_addr, "%X",
1235 &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
1236 sscanf(rem_addr, "%X",
1237 &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);
1238 ((struct sockaddr *) &localaddr)->sa_family = AF_INET;
1239 ((struct sockaddr *) &remaddr)->sa_family = AF_INET;
1242 if ((ap = get_afntype(localaddr.sin6_family)) == NULL) {
1243 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin6_family);
1247 if ((ap = get_afntype(localaddr.sin_family)) == NULL) {
1248 fprintf(stderr, _("netstat: unsupported address family %d !\n"), localaddr.sin_family);
1257 fprintf(stderr, _("warning, got bogus raw line.\n"));
1261 if (flag_all || (notnull(remaddr) && !flag_lst) || (!notnull(remaddr) && flag_lst))
1263 addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localaddr, local_port, "raw");
1264 addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remaddr, rem_port, "raw");
1268 switch (timer_run) {
1270 snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
1275 snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
1280 snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
1281 timer_run, (double) time_len / 100,
1285 printf("%-4s %6ld %6ld %-23s %-23s %-11d",
1286 prot, rxq, txq, local_addr, rem_addr, state);
1288 finish_this_one(uid,inode,timers);
1292 static int raw_info(void)
1294 INFO_GUTS6(_PATH_PROCNET_RAW, _PATH_PROCNET_RAW6, "AF INET (raw)",
1295 raw_do_one, "raw", "raw6");
1305 static void unix_do_one(int nr, const char *line, const char *prot)
1308 char path[MAXPATHLEN], ss_flags[32];
1309 char *ss_proto, *ss_state, *ss_type;
1310 int num, state, type;
1312 unsigned long refcnt, proto, flags, inode;
1315 if (strstr(line, "Inode"))
1320 num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %s",
1321 &d, &refcnt, &proto, &flags, &type, &state, &inode, path);
1323 fprintf(stderr, _("warning, got bogus unix line.\n"));
1326 if (!(has & HAS_INODE))
1327 snprintf(path,sizeof(path),"%lu",inode);
1330 if ((state == SS_UNCONNECTED) && (flags & SO_ACCEPTCON)) {
1350 ss_type = _("STREAM");
1354 ss_type = _("DGRAM");
1365 case SOCK_SEQPACKET:
1366 ss_type = _("SEQPACKET");
1370 ss_type = _("UNKNOWN");
1375 ss_state = _("FREE");
1378 case SS_UNCONNECTED:
1380 * Unconnected sockets may be listening
1383 if (flags & SO_ACCEPTCON) {
1384 ss_state = _("LISTENING");
1391 ss_state = _("CONNECTING");
1395 ss_state = _("CONNECTED");
1398 case SS_DISCONNECTING:
1399 ss_state = _("DISCONNECTING");
1403 ss_state = _("UNKNOWN");
1406 strcpy(ss_flags, "[ ");
1407 if (flags & SO_ACCEPTCON)
1408 strcat(ss_flags, "ACC ");
1409 if (flags & SO_WAITDATA)
1410 strcat(ss_flags, "W ");
1411 if (flags & SO_NOSPACE)
1412 strcat(ss_flags, "N ");
1414 strcat(ss_flags, "]");
1416 printf("%-5s %-6ld %-11s %-10s %-13s ",
1417 ss_proto, refcnt, ss_flags, ss_type, ss_state);
1418 if (has & HAS_INODE)
1419 printf("%-8lu",inode);
1423 printf(" %-" PROGNAME_WIDTHs "s",(has & HAS_INODE?prg_cache_get(inode):"-"));
1425 printf(" %-" SELINUX_WIDTHs "s",(has & HAS_INODE?prg_cache_get_con(inode):"-"));
1427 printf(" %s\n", path);
1430 static int unix_info(void)
1433 printf(_("Active UNIX domain sockets "));
1435 printf(_("(servers and established)"));
1438 printf(_("(only servers)"));
1440 printf(_("(w/o servers)"));
1443 printf(_("\nProto RefCnt Flags Type State I-Node "));
1444 print_progname_banner();
1445 print_selinux_banner();
1446 printf(_(" Path\n")); /* xxx */
1449 INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one, "unix");
1456 static int ax25_info(void)
1459 char buffer[256], buf[16];
1460 char *src, *dst, *dev, *p;
1461 int st, vs, vr, sendq, recvq, ret;
1462 int new = -1; /* flag for new (2.1.x) kernels */
1463 static char *ax25_state[5] =
1471 if (!(f = proc_fopen(_PATH_PROCNET_AX25))) {
1472 if (errno != ENOENT) {
1473 perror(_PATH_PROCNET_AX25);
1476 if (flag_arg || flag_ver)
1477 ESYSNOT("netstat", "AF AX25");
1483 printf(_("Active AX.25 sockets\n"));
1484 printf(_("Dest Source Device State Vr/Vs Send-Q Recv-Q\n"));
1485 while (fgets(buffer, 256, f)) {
1487 if (!strncmp(buffer, "dest_addr", 9)) {
1489 continue; /* old kernels have a header line */
1494 * In a network connection with no user socket the Snd-Q, Rcv-Q
1495 * and Inode fields are empty in 2.0.x and '*' in 2.1.x
1504 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",
1505 buf, &st, &vs, &vr, &sendq, &recvq);
1506 if (ret != 4 && ret != 6) {
1507 printf(_("Problem reading data from %s\n"), _PATH_PROCNET_AX25);
1513 while (*p != ' ') p++;
1516 while (*p != ' ') p++;
1519 while (*p != ' ') p++;
1522 while (*p != ' ') p++;
1524 ret = sscanf(p, "%d %d %d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %*d",
1525 &st, &vs, &vr, &sendq, &recvq);
1526 if (ret != 3 && ret != 5) {
1527 printf(_("problem reading data from %s\n"), _PATH_PROCNET_AX25);
1531 * FIXME: digipeaters should be handled somehow.
1532 * For now we just strip them.
1535 while (*p && *p != ',') p++;
1538 printf("%-9s %-9s %-6s %-11s %03d/%03d %-6d %-6d\n",
1542 vr, vs, sendq, recvq);
1551 static int ipx_info(void)
1555 unsigned long txq, rxq;
1562 char sad[50], dad[50];
1564 unsigned sport = 0, dport = 0;
1567 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET1);
1569 if (errno != ENOENT) {
1570 perror(_PATH_PROCNET_IPX_SOCKET1);
1573 f = proc_fopen(_PATH_PROCNET_IPX_SOCKET2);
1575 /* We need to check for directory */
1577 fstat(fileno(f), &s);
1578 if (!S_ISREG(s.st_mode)) {
1585 if (errno != ENOENT) {
1586 perror(_PATH_PROCNET_IPX_SOCKET2);
1589 if (flag_arg || flag_ver)
1590 ESYSNOT("netstat", "AF IPX");
1597 printf(_("Active IPX sockets\nProto Recv-Q Send-Q Local Address Foreign Address State")); /* xxx */
1599 printf(_(" User")); /* xxx */
1601 if ((ap = get_afntype(AF_IPX)) == NULL) {
1602 EINTERN("netstat.c", "AF_IPX missing");
1606 if (fgets(buf, 255, f))
1609 while (fgets(buf, 255, f) != NULL) {
1610 sscanf(buf, "%s %s %lX %lX %d %d",
1611 sad, dad, &txq, &rxq, &state, &uid);
1612 if ((st = rindex(sad, ':'))) {
1614 sscanf(st, "%X", &sport); /* net byt order */
1615 sport = ntohs(sport);
1617 EINTERN("netstat.c", "ipx socket format error in source port");
1622 if (strcmp(dad, "Not_Connected") != 0) {
1623 if ((st = rindex(dad, ':'))) {
1625 sscanf(st, "%X", &dport); /* net byt order */
1626 dport = ntohs(dport);
1628 EINTERN("netstat.c", "ipx soket format error in destination port");
1636 case TCP_ESTABLISHED:
1649 /* Fetch and resolve the Source */
1650 (void) ap->input(4, sad, &sa);
1651 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1652 snprintf(sad, sizeof(sad), "%s:%04X", buf, sport);
1655 /* Fetch and resolve the Destination */
1656 (void) ap->input(4, dad, &sa);
1657 safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
1658 snprintf(dad, sizeof(dad), "%s:%04X", buf, dport);
1662 printf("IPX %6ld %6ld %-26s %-26s %-5s", txq, rxq, sad, dad, st);
1664 if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
1665 printf(" %-10s", pw->pw_name);
1667 printf(" %-10d", uid);
1676 #if HAVE_AFBLUETOOTH
1677 const char *bluetooth_state(int state)
1681 return _("CONNECTED");
1689 return _("CONNECT");
1691 return _("CONNECT2");
1695 return _("DISCONN");
1699 return _("UNKNOWN");
1703 static void l2cap_do_one(int nr, const char *line, const char *prot)
1705 char daddr[18], saddr[18];
1706 unsigned state, psm, dcid, scid, imtu, omtu, sec_level;
1708 const char *bt_state, *bt_sec_level;
1710 num = sscanf(line, "%17s %17s %d %d 0x%04x 0x%04x %d %d %d",
1711 daddr, saddr, &state, &psm, &dcid, &scid, &imtu, &omtu, &sec_level);
1714 fprintf(stderr, _("warning, got bogus l2cap line.\n"));
1718 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1720 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1723 bt_state = bluetooth_state(state);
1724 switch (sec_level) {
1725 case BT_SECURITY_SDP:
1726 bt_sec_level = _("SDP");
1728 case BT_SECURITY_LOW:
1729 bt_sec_level = _("LOW");
1731 case BT_SECURITY_MEDIUM:
1732 bt_sec_level = _("MEDIUM");
1734 case BT_SECURITY_HIGH:
1735 bt_sec_level = _("HIGH");
1738 bt_sec_level = _("UNKNOWN");
1741 printf("l2cap %-17s %-17s %-9s %7d 0x%04x 0x%04x %7d %7d %-7s\n",
1742 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1743 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1744 bt_state, psm, dcid, scid, imtu, omtu, bt_sec_level);
1747 static int l2cap_info(void)
1749 printf("%-6s %-17s %-17s %-9s %7s %-6s %-6s %7s %7s %-7s\n",
1750 "Proto", "Destination", "Source", "State", "PSM", "DCID", "SCID", "IMTU", "OMTU", "Security");
1751 INFO_GUTS(_PATH_SYS_BLUETOOTH_L2CAP, "AF BLUETOOTH", l2cap_do_one, "l2cap");
1754 static void rfcomm_do_one(int nr, const char *line, const char *prot)
1756 char daddr[18], saddr[18];
1757 unsigned state, channel;
1759 const char *bt_state;
1761 num = sscanf(line, "%17s %17s %d %d", daddr, saddr, &state, &channel);
1763 fprintf(stderr, _("warning, got bogus rfcomm line.\n"));
1767 if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
1769 if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
1772 bt_state = bluetooth_state(state);
1773 printf("rfcomm %-17s %-17s %-9s %7d\n",
1774 (strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
1775 (strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
1779 static int rfcomm_info(void)
1781 printf("%-6s %-17s %-17s %-9s %7s\n", "Proto", "Destination", "Source", "State", "Channel");
1782 INFO_GUTS(_PATH_SYS_BLUETOOTH_RFCOMM, "AF BLUETOOTH", rfcomm_do_one, "rfcomm");
1786 static int iface_info(void)
1789 if ((skfd = sockets_open(0)) < 0) {
1793 printf(_("Kernel Interface table\n"));
1797 printf(_("Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
1800 if (for_all_interfaces(do_if_print, &flag_all) < 0) {
1801 perror(_("missing interface information"));
1815 static void version(void)
1817 printf("%s\n%s\n%s\n%s\n", Release, Version, Signature, Features);
1822 static void usage(void)
1824 fprintf(stderr, _("usage: netstat [-vWeenNcCF] [<Af>] -r netstat {-V|--version|-h|--help}\n"));
1825 fprintf(stderr, _(" netstat [-vWnNcaeol] [<Socket> ...]\n"));
1826 fprintf(stderr, _(" netstat { [-vWeenNac] -i | [-cnNe] -M | -s [-6tuw] }\n\n"));
1828 fprintf(stderr, _(" -r, --route display routing table\n"));
1829 fprintf(stderr, _(" -i, --interfaces display interface table\n"));
1830 fprintf(stderr, _(" -g, --groups display multicast group memberships\n"));
1831 fprintf(stderr, _(" -s, --statistics display networking statistics (like SNMP)\n"));
1832 #if HAVE_FW_MASQUERADE
1833 fprintf(stderr, _(" -M, --masquerade display masqueraded connections\n\n"));
1836 fprintf(stderr, _(" -v, --verbose be verbose\n"));
1837 fprintf(stderr, _(" -W, --wide don't truncate IP addresses\n"));
1838 fprintf(stderr, _(" -n, --numeric don't resolve names\n"));
1839 fprintf(stderr, _(" --numeric-hosts don't resolve host names\n"));
1840 fprintf(stderr, _(" --numeric-ports don't resolve port names\n"));
1841 fprintf(stderr, _(" --numeric-users don't resolve user names\n"));
1842 fprintf(stderr, _(" -N, --symbolic resolve hardware names\n"));
1843 fprintf(stderr, _(" -e, --extend display other/more information\n"));
1844 fprintf(stderr, _(" -p, --programs display PID/Program name for sockets\n"));
1845 fprintf(stderr, _(" -o, --timers display timers\n"));
1846 fprintf(stderr, _(" -c, --continuous continuous listing\n\n"));
1847 fprintf(stderr, _(" -l, --listening display listening server sockets\n"));
1848 fprintf(stderr, _(" -a, --all display all sockets (default: connected)\n"));
1849 fprintf(stderr, _(" -F, --fib display Forwarding Information Base (default)\n"));
1850 fprintf(stderr, _(" -C, --cache display routing cache instead of FIB\n"));
1852 fprintf(stderr, _(" -Z, --context display SELinux security context for sockets\n"));
1855 fprintf(stderr, _("\n <Socket>={-t|--tcp} {-u|--udp} {-U|--udplite} {-w|--raw} {-x|--unix}\n"));
1856 fprintf(stderr, _(" --ax25 --ipx --netrom\n"));
1857 fprintf(stderr, _(" <AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
1858 fprintf(stderr, _(" List of possible address families (which support routing):\n"));
1859 print_aflist(1); /* 1 = routeable */
1865 (int argc, char *argv[]) {
1868 static struct option longopts[] =
1871 {"version", 0, 0, 'V'},
1872 {"interfaces", 0, 0, 'i'},
1873 {"help", 0, 0, 'h'},
1874 {"route", 0, 0, 'r'},
1875 #if HAVE_FW_MASQUERADE
1876 {"masquerade", 0, 0, 'M'},
1878 {"protocol", 1, 0, 'A'},
1880 {"sctp", 0, 0, 'S'},
1882 {"udplite", 0, 0, 'U'},
1884 {"unix", 0, 0, 'x'},
1885 {"l2cap", 0, 0, '2'},
1886 {"rfcomm", 0, 0, 'f'},
1887 {"listening", 0, 0, 'l'},
1889 {"timers", 0, 0, 'o'},
1890 {"continuous", 0, 0, 'c'},
1891 {"extend", 0, 0, 'e'},
1892 {"programs", 0, 0, 'p'},
1893 {"verbose", 0, 0, 'v'},
1894 {"statistics", 0, 0, 's'},
1895 {"wide", 0, 0, 'W'},
1896 {"numeric", 0, 0, 'n'},
1897 {"numeric-hosts", 0, 0, '!'},
1898 {"numeric-ports", 0, 0, '@'},
1899 {"numeric-users", 0, 0, '#'},
1900 {"symbolic", 0, 0, 'N'},
1901 {"cache", 0, 0, 'C'},
1903 {"groups", 0, 0, 'g'},
1904 {"context", 0, 0, 'Z'},
1909 setlocale (LC_ALL, "");
1910 bindtextdomain("net-tools", "/usr/share/locale");
1911 textdomain("net-tools");
1913 getroute_init(); /* Set up AF routing support */
1916 while ((i = getopt_long(argc, argv, "A:CFMacdeghilnNoprsStuUvVWwx64?Z", longopts, &lop)) != EOF)
1921 if (lop < 0 || lop >= AFTRANS_CNT) {
1922 EINTERN("netstat.c", "longopts 1 range");
1925 if (aftrans_opt(longopts[lop].name))
1929 if (aftrans_opt(optarg))
1964 flag_not |= FLAG_NUM;
1967 flag_not |= FLAG_NUM_HOST;
1970 flag_not |= FLAG_NUM_PORT;
1973 flag_not |= FLAG_NUM_USER;
1976 flag_not |= FLAG_SYM;
1979 flag_cf |= FLAG_CACHE;
1982 flag_cf |= FLAG_FIB;
1988 if (aftrans_opt("inet6"))
1992 if (aftrans_opt("inet"))
1999 flag_ver |= FLAG_VERBOSE;
2026 if (aftrans_opt("unix"))
2031 if (is_selinux_enabled() <= 0) {
2032 fprintf(stderr, _("SELinux is not enabled on this machine.\n"));
2038 fprintf(stderr, _("SELinux is not enabled for this application.\n"));
2050 if (flag_int + flag_rou + flag_mas + flag_sta > 1)
2053 if ((flag_inet || flag_inet6 || flag_sta) &&
2054 !(flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw))
2055 flag_tcp = flag_sctp = flag_udp = flag_udplite = flag_raw = 1;
2057 if ((flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw || flag_igmp) &&
2058 !(flag_inet || flag_inet6))
2059 flag_inet = flag_inet6 = 1;
2061 if (flag_bluetooth && !(flag_l2cap || flag_rfcomm))
2062 flag_l2cap = flag_rfcomm = 1;
2064 flag_arg = flag_tcp + flag_sctp + flag_udplite + flag_udp + flag_raw + flag_unx
2065 + flag_ipx + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose
2066 + flag_l2cap + flag_rfcomm;
2069 #if HAVE_FW_MASQUERADE && HAVE_AFINET
2070 #if MORE_THAN_ONE_MASQ_AF
2072 strcpy(afname, DFLT_AF);
2075 i = ip_masq_info(flag_not & FLAG_NUM_HOST,
2076 flag_not & FLAG_NUM_PORT, flag_exp);
2082 ENOSUPP("netstat", "FW_MASQUERADE");
2090 strcpy(afname, DFLT_AF);
2092 if (!strcmp(afname, "inet")) {
2095 parsesnmp(flag_raw, flag_tcp, flag_udp);
2097 ENOSUPP("netstat", "AF INET");
2099 } else if(!strcmp(afname, "inet6")) {
2102 parsesnmp6(flag_raw, flag_tcp, flag_udp);
2104 ENOSUPP("netstat", "AF INET6");
2107 printf(_("netstat: No statistics support for specified address family: %s\n"), afname);
2117 strcpy(afname, DFLT_AF);
2121 else if (flag_exp == 1)
2124 options = (flag_exp & FLAG_EXT) | flag_not | flag_cf | flag_ver;
2126 options |= FLAG_FIB;
2129 i = route_info(afname, options);
2146 if (!flag_arg || flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw) {
2149 printf(_("Active Internet connections ")); /* xxx */
2152 printf(_("(servers and established)"));
2155 printf(_("(only servers)"));
2157 printf(_("(w/o servers)"));
2159 printf(_("\nProto Recv-Q Send-Q Local Address Foreign Address State ")); /* xxx */
2161 printf(_(" User Inode "));
2162 print_progname_banner();
2163 print_selinux_banner();
2165 printf(_(" Timer")); /* xxx */
2170 ENOSUPP("netstat", "AF INET");
2175 if (!flag_arg || flag_tcp) {
2181 if (!flag_arg || flag_sctp) {
2187 if (!flag_arg || flag_udp) {
2193 if (!flag_arg || flag_udplite) {
2199 if (!flag_arg || flag_raw) {
2209 printf( _("IPv4 Group Memberships\n") );
2210 printf( _("Interface RefCnt Group\n") );
2211 printf( "--------------- ------ ---------------------\n" );
2218 if (!flag_arg || flag_unx) {
2227 ENOSUPP("netstat", "AF UNIX");
2231 if (!flag_arg || flag_ipx) {
2239 ENOSUPP("netstat", "AF IPX");
2243 if (!flag_arg || flag_ax25) {
2251 ENOSUPP("netstat", "AF AX25");
2255 if(!flag_arg || flag_x25) {
2264 ENOSUPP("netstat", "AF X25");
2268 if (!flag_arg || flag_netrom) {
2276 ENOSUPP("netstat", "AF NETROM");
2280 if (!flag_arg || flag_rose) {
2281 #if 0 && HAVE_AFROSE
2288 ENOSUPP("netstat", "AF ROSE");
2293 if (!flag_arg || flag_l2cap || flag_rfcomm) {
2294 #if HAVE_AFBLUETOOTH
2295 printf(_("Active Bluetooth connections ")); /* xxx */
2298 printf(_("(servers and established)"));
2301 printf(_("(only servers)"));
2303 printf(_("(w/o servers)"));
2309 ENOSUPP("netstat", "AF BLUETOOTH");
2313 #if HAVE_AFBLUETOOTH
2314 if (!flag_arg || flag_l2cap) {
2319 if (!flag_arg || flag_rfcomm) {