Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
     5         kx /*
     5         kx  * netstat    This file contains an implementation of the command
     5         kx  *              that helps in debugging the networking modules.
     5         kx  *
     5         kx  * NET-TOOLS    A collection of programs that form the base set of the
     5         kx  *              NET-3 Networking Distribution for the LINUX operating
     5         kx  *              system.
     5         kx  *
     5         kx  * Version:     $Id: netstat.c,v 1.73 2011-04-20 01:35:22 ecki Exp $
     5         kx  *
     5         kx  * Authors:     Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
     5         kx  *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
     5         kx  *              Phil Packer, <pep@wicked.demon.co.uk>
     5         kx  *              Johannes Stille, <johannes@titan.os.open.de>
     5         kx  *              Bernd Eckenfels, <net-tools@lina.inka.de>
     5         kx  *              Phil Blundell <philb@gnu.org>
     5         kx  *              Tuan Hoang <tqhoang@bigfoot.com>
     5         kx  *
     5         kx  * Tuned for NET3 by:
     5         kx  *              Alan Cox, <A.Cox@swansea.ac.uk>
     5         kx  *              Copyright (c) 1993  Fred Baumgarten
     5         kx  *
     5         kx  * Modified:
     5         kx  *
     5         kx  *960116 {1.01} Bernd Eckenfels:        verbose, cleanups
     5         kx  *960204 {1.10} Bernd Eckenfels:        aftrans, usage, new route_info,
     5         kx  *                                      DLFT_AF
     5         kx  *960204 {1.11} Bernd Eckenfels:        netlink support
     5         kx  *960204 {1.12} Bernd Eckenfels:        route_init()
     5         kx  *960215 {1.13} Bernd Eckenfels:        netlink_print honors HAVE_
     5         kx  *960217 {1.14} Bernd Eckenfels:        masq_info from Jos Vos and
     5         kx  *                                      ax25_info from Jonathan Naylor.
     5         kx  *960218 {1.15} Bernd Eckenfels:        ipx_info rewritten, -e for tcp/ipx
     5         kx  *960220 {1.16} Bernd Eckenfels:        minor output reformats, -a for -x
     5         kx  *960221 {1.17} Bernd Eckenfels:        route_init->getroute_init
     5         kx  *960426 {1.18} Bernd Eckenfels:        new RTACTION, SYM/NUM, FIB/CACHE
     5         kx  *960517 {1.19} Bernd Eckenfels:        usage() spelling fix and --unix inode,
     5         kx  *                                      ':' is part of sock_addr for --inet
     5         kx  *960822 {x.xx} Frank Strauss:          INET6 support
     5         kx  *
     5         kx  *970406 {1.33} Philip Copeland         Added snmp reporting support module -s
     5         kx  *                                      code provided by Andi Kleen
     5         kx  *                                      (relly needs to be kernel hooked but
     5         kx  *                                      this will do in the meantime)
     5         kx  *                                      minor header file misplacement tidy up.
     5         kx  *980815 {1.xx} Stephane Fillod:       X.25 support
     5         kx  *980411 {1.34} Arnaldo Carvalho        i18n: catgets -> gnu gettext, substitution
     5         kx  *                                      of sprintf for snprintf
     5         kx  *10/1998	Andi Kleen              Use new interface primitives.
     5         kx  *990101 {1.36}	Bernd Eckenfels		usage updated to include -s and -C -F,
     5         kx  *					fixed netstat -rC output (lib/inet_gr.c)
     5         kx  *					removed broken NETLINK Support
     5         kx  *					fixed format for /proc/net/udp|tcp|raw
     5         kx  *					added -w,-t,-u TcpExt support to -s
     5         kx  *990131 {1.37} Jan Kratochvil          added -p for prg_cache() & friends
     5         kx  *                                      Flames to <short@ucw.cz>.
     5         kx  *              Tuan Hoang              added IGMP support for IPv4 and IPv6
     5         kx  *
     5         kx  *990420 {1.38} Tuan Hoang              removed a useless assignment from igmp_do_one()
     5         kx  *20010404 {1.39} Arnaldo Carvalho de Melo - use setlocale
     5         kx  *20081201 {1.42} Brian Micek           added -L|--udplite options for RFC 3828
     5         kx  *20020722 {1.51} Thomas Preusser       added SCTP over IPv4 support
     5         kx  *
     5         kx  *              This program is free software; you can redistribute it
     5         kx  *              and/or  modify it under  the terms of  the GNU General
     5         kx  *              Public  License as  published  by  the  Free  Software
     5         kx  *              Foundation;  either  version 2 of the License, or  (at
     5         kx  *              your option) any later version.
     5         kx  *
     5         kx  */
     5         kx #include <errno.h>
     5         kx #include <stdio.h>
     5         kx #include <stdlib.h>
     5         kx #include <string.h>
     5         kx #include <strings.h>
     5         kx #include <unistd.h>
     5         kx #include <ctype.h>
     5         kx #include <fcntl.h>
     5         kx #include <netdb.h>
     5         kx #include <paths.h>
     5         kx #include <pwd.h>
     5         kx #include <getopt.h>
     5         kx #include <sys/param.h>
     5         kx #include <sys/socket.h>
     5         kx #include <arpa/inet.h>
     5         kx #include <netinet/in.h>
     5         kx #include <sys/ioctl.h>
     5         kx #include <sys/stat.h>
     5         kx #include <net/if.h>
     5         kx #include <dirent.h>
     5         kx 
     5         kx #include "net-support.h"
     5         kx #include "pathnames.h"
     5         kx #include "version.h"
     5         kx #include "config.h"
     5         kx #include "intl.h"
     5         kx #include "sockets.h"
     5         kx #include "interface.h"
     5         kx #include "util.h"
     5         kx #include "proc.h"
     5         kx 
     5         kx #if HAVE_SELINUX
     5         kx #include <selinux/selinux.h>
     5         kx #endif
     5         kx 
     5         kx #if HAVE_AFBLUETOOTH
     5         kx /*
     5         kx    Only following stuff is needed from
     5         kx    kernel:   net/bluetooth/bluetooth.h
     5         kx    or bluez: bluetooth/bluetooth.h
     5         kx  */
     5         kx #define BT_SECURITY_SDP         0
     5         kx #define BT_SECURITY_LOW         1
     5         kx #define BT_SECURITY_MEDIUM      2
     5         kx #define BT_SECURITY_HIGH        3
     5         kx #define BT_SECURITY_FIPS        4
     5         kx 
     5         kx /* Connection and socket states */
     5         kx enum {
     5         kx   BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
     5         kx   BT_OPEN,
     5         kx   BT_BOUND,
     5         kx   BT_LISTEN,
     5         kx   BT_CONNECT,
     5         kx   BT_CONNECT2,
     5         kx   BT_CONFIG,
     5         kx   BT_DISCONN,
     5         kx   BT_CLOSED
     5         kx };
     5         kx #endif
     5         kx 
     5         kx #define PROGNAME_WIDTH 20
     5         kx #define SELINUX_WIDTH 50
     5         kx 
     5         kx #if !defined(s6_addr32) && defined(in6a_words)
     5         kx #define s6_addr32 in6a_words	/* libinet6			*/
     5         kx #endif
     5         kx 
     5         kx /* prototypes for statistics.c */
     5         kx void parsesnmp(int, int, int, int);
     5         kx void parsesnmp6(int, int, int);
     5         kx 
     5         kx typedef enum {
     5         kx     SS_FREE = 0,		/* not allocated                */
     5         kx     SS_UNCONNECTED,		/* unconnected to any socket    */
     5         kx     SS_CONNECTING,		/* in process of connecting     */
     5         kx     SS_CONNECTED,		/* connected to socket          */
     5         kx     SS_DISCONNECTING		/* in process of disconnecting  */
     5         kx } socket_state;
     5         kx 
     5         kx #define SO_ACCEPTCON    (1<<16)	/* performed a listen           */
     5         kx #define SO_WAITDATA     (1<<17)	/* wait data to read            */
     5         kx #define SO_NOSPACE      (1<<18)	/* no space to write            */
     5         kx 
     5         kx #define DFLT_AF "inet"
     5         kx 
     5         kx #define FEATURE_NETSTAT
     5         kx #include "lib/net-features.h"
     5         kx 
     5         kx static char *Release = RELEASE, *Signature = "Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang, Brian Micek and others";
     5         kx 
     5         kx 
     5         kx #define E_READ  -1
     5         kx #define E_IOCTL -3
     5         kx 
     5         kx int flag_int = 0;
     5         kx int flag_rou = 0;
     5         kx int flag_mas = 0;
     5         kx int flag_sta = 0;
     5         kx 
     5         kx int flag_all = 0;
     5         kx int flag_lst = 0;
     5         kx int flag_cnt = 0;
     5         kx int flag_deb = 0;
     5         kx int flag_not = 0;
     5         kx int flag_cf  = 0;
     5         kx int flag_opt = 0;
     5         kx int flag_raw = 0;
     5         kx int flag_tcp = 0;
     5         kx int flag_sctp= 0;
     5         kx int flag_udp = 0;
     5         kx int flag_udplite = 0;
     5         kx int flag_igmp= 0;
     5         kx int flag_rom = 0;
     5         kx int flag_exp = 1;
     5         kx int flag_wide= 0;
     5         kx int flag_prg = 0;
     5         kx int flag_arg = 0;
     5         kx int flag_noprot = 0;
     5         kx int flag_ver = 0;
     5         kx int flag_l2cap = 0;
     5         kx int flag_rfcomm = 0;
     5         kx int flag_selinux = 0;
     5         kx 
     5         kx FILE *procinfo;
     5         kx 
     5         kx #define INFO_GUTS1(file,name,proc,prot)			\
     5         kx   procinfo = proc_fopen((file));			\
     5         kx   if (procinfo == NULL) {				\
     5         kx     if (errno != ENOENT && errno != EACCES) {		\
     5         kx       perror((file));					\
     5         kx       return -1;					\
     5         kx     }							\
     5         kx     if (!flag_noprot && (flag_arg || flag_ver))		\
     5         kx       ESYSNOT("netstat", (name));			\
     5         kx     if (!flag_noprot && flag_arg)			\
     5         kx       rc = 1;						\
     5         kx   } else {						\
     5         kx     do {						\
     5         kx       if (fgets(buffer, sizeof(buffer), procinfo))	\
     5         kx         (proc)(lnr++, buffer,prot);			\
     5         kx     } while (!feof(procinfo));				\
     5         kx     fclose(procinfo);					\
     5         kx   }
     5         kx 
     5         kx #if HAVE_AFINET6
     5         kx #define INFO_GUTS2(file,proc,prot)			\
     5         kx   lnr = 0;						\
     5         kx   procinfo = proc_fopen((file));		       	\
     5         kx   if (procinfo != NULL) {				\
     5         kx     do {						\
     5         kx       if (fgets(buffer, sizeof(buffer), procinfo))	\
     5         kx 	(proc)(lnr++, buffer,prot);			\
     5         kx     } while (!feof(procinfo));				\
     5         kx     fclose(procinfo);					\
     5         kx   }
     5         kx #else
     5         kx #define INFO_GUTS2(file,proc,prot)
     5         kx #endif
     5         kx 
     5         kx #define INFO_GUTS3					\
     5         kx  return rc;
     5         kx 
     5         kx #define INFO_GUTS6(file,file6,name,proc,prot4,prot6)	\
     5         kx  char buffer[8192];					\
     5         kx  int rc = 0;						\
     5         kx  int lnr = 0;						\
     5         kx  if (!flag_arg || flag_inet) {				\
     5         kx     INFO_GUTS1(file,name,proc,prot4)			\
     5         kx  }							\
     5         kx  if (!flag_arg || flag_inet6) {				\
     5         kx     INFO_GUTS2(file6,proc,prot6)			\
     5         kx  }							\
     5         kx  INFO_GUTS3
     5         kx 
     5         kx #define INFO_GUTS(file,name,proc,prot)			\
     5         kx  char buffer[8192];					\
     5         kx  int rc = 0;						\
     5         kx  int lnr = 0;						\
     5         kx  INFO_GUTS1(file,name,proc,prot)			\
     5         kx  INFO_GUTS3
     5         kx 
     5         kx #define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
     5         kx #define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)
     5         kx #define PROGNAME_WIDTH2(s) #s
     5         kx 
     5         kx #define SELINUX_WIDTHs SELINUX_WIDTH1(SELINUX_WIDTH)
     5         kx #define SELINUX_WIDTH1(s) SELINUX_WIDTH2(s)
     5         kx #define SELINUX_WIDTH2(s) #s
     5         kx 
     5         kx #define PRG_HASH_SIZE 211
     5         kx 
     5         kx static struct prg_node {
     5         kx     struct prg_node *next;
     5         kx     unsigned long inode;
     5         kx     char name[PROGNAME_WIDTH];
     5         kx     char scon[SELINUX_WIDTH];
     5         kx } *prg_hash[PRG_HASH_SIZE];
     5         kx 
     5         kx static char prg_cache_loaded = 0;
     5         kx 
     5         kx #define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE)
     5         kx 
     5         kx #define PROGNAME_BANNER "PID/Program name"
     5         kx #define SELINUX_BANNER "Security Context"
     5         kx 
     5         kx #define print_progname_banner() do { if (flag_prg) printf(" %-" PROGNAME_WIDTHs "s",PROGNAME_BANNER); } while (0)
     5         kx 
     5         kx #define print_selinux_banner() do { if (flag_selinux) printf("%-" SELINUX_WIDTHs "s"," " SELINUX_BANNER); } while (0)
     5         kx 
     5         kx #define PRG_LOCAL_ADDRESS "local_address"
     5         kx #define PRG_INODE	 "inode"
     5         kx #define PRG_SOCKET_PFX    "socket:["
     5         kx #define PRG_SOCKET_PFXl (strlen(PRG_SOCKET_PFX))
     5         kx #define PRG_SOCKET_PFX2   "[0000]:"
     5         kx #define PRG_SOCKET_PFX2l  (strlen(PRG_SOCKET_PFX2))
     5         kx 
     5         kx 
     5         kx #ifndef LINE_MAX
     5         kx #define LINE_MAX 4096
     5         kx #endif
     5         kx 
     5         kx #define PATH_PROC	   "/proc"
     5         kx #define PATH_FD_SUFF	"fd"
     5         kx #define PATH_FD_SUFFl       strlen(PATH_FD_SUFF)
     5         kx #define PATH_PROC_X_FD      PATH_PROC "/%s/" PATH_FD_SUFF
     5         kx #define PATH_CMDLINE	"cmdline"
     5         kx #define PATH_CMDLINEl       strlen(PATH_CMDLINE)
     5         kx 
     5         kx static void prg_cache_add(unsigned long inode, char *name, const char *scon)
     5         kx {
     5         kx     unsigned hi = PRG_HASHIT(inode);
     5         kx     struct prg_node **pnp,*pn;
     5         kx 
     5         kx     prg_cache_loaded = 2;
     5         kx     for (pnp = prg_hash + hi; (pn = *pnp); pnp = &pn->next) {
     5         kx 	if (pn->inode == inode) {
     5         kx 	    /* Some warning should be appropriate here
     5         kx 	       as we got multiple processes for one i-node */
     5         kx 	    return;
     5         kx 	}
     5         kx     }
     5         kx     if (!(*pnp = malloc(sizeof(**pnp))))
     5         kx 	return;
     5         kx     pn = *pnp;
     5         kx     pn->next = NULL;
     5         kx     pn->inode = inode;
     5         kx     safe_strncpy(pn->name, name, sizeof(pn->name));
     5         kx 
     5         kx     {
     5         kx 	int len = (strlen(scon) - sizeof(pn->scon)) + 1;
     5         kx 	if (len > 0)
     5         kx             safe_strncpy(pn->scon, &scon[len + 1], sizeof(pn->scon));
     5         kx 	else
     5         kx             safe_strncpy(pn->scon, scon, sizeof(pn->scon));
     5         kx     }
     5         kx 
     5         kx }
     5         kx 
     5         kx static const char *prg_cache_get(unsigned long inode)
     5         kx {
     5         kx     unsigned hi = PRG_HASHIT(inode);
     5         kx     struct prg_node *pn;
     5         kx 
     5         kx     for (pn = prg_hash[hi]; pn; pn = pn->next)
     5         kx 	if (pn->inode == inode)
     5         kx 	    return (pn->name);
     5         kx     return ("-");
     5         kx }
     5         kx 
     5         kx static const char *prg_cache_get_con(unsigned long inode)
     5         kx {
     5         kx     unsigned hi = PRG_HASHIT(inode);
     5         kx     struct prg_node *pn;
     5         kx 
     5         kx     for (pn = prg_hash[hi]; pn; pn = pn->next)
     5         kx 	if (pn->inode == inode)
     5         kx 	    return (pn->scon);
     5         kx     return ("-");
     5         kx }
     5         kx 
     5         kx static void prg_cache_clear(void)
     5         kx {
     5         kx     struct prg_node **pnp,*pn;
     5         kx 
     5         kx     if (prg_cache_loaded == 2)
     5         kx 	for (pnp = prg_hash; pnp < prg_hash + PRG_HASH_SIZE; pnp++)
     5         kx 	    while ((pn = *pnp)) {
     5         kx 		*pnp = pn->next;
     5         kx 		free(pn);
     5         kx 	    }
     5         kx     prg_cache_loaded = 0;
     5         kx }
     5         kx 
     5         kx static void wait_continous(void)
     5         kx {
     5         kx     fflush(stdout);
     5         kx     sleep(1);
     5         kx }
     5         kx 
     5         kx static int extract_type_1_socket_inode(const char lname[], unsigned long * inode_p) {
     5         kx 
     5         kx     /* If lname is of the form "socket:[12345]", extract the "12345"
     5         kx        as *inode_p.  Otherwise, return -1 as *inode_p.
     5         kx        */
     5         kx 
     5         kx     if (strlen(lname) < PRG_SOCKET_PFXl+3) return(-1);
     5         kx 
     5         kx     if (memcmp(lname, PRG_SOCKET_PFX, PRG_SOCKET_PFXl)) return(-1);
     5         kx     if (lname[strlen(lname)-1] != ']') return(-1);
     5         kx 
     5         kx     {
     5         kx         char inode_str[strlen(lname + 1)];  /* e.g. "12345" */
     5         kx         const int inode_str_len = strlen(lname) - PRG_SOCKET_PFXl - 1;
     5         kx         char *serr;
     5         kx 
     5         kx         strncpy(inode_str, lname+PRG_SOCKET_PFXl, inode_str_len);
     5         kx         inode_str[inode_str_len] = '\0';
     5         kx         *inode_p = strtoul(inode_str, &serr, 0);
     5         kx         if (!serr || *serr || *inode_p == ~0)
     5         kx             return(-1);
     5         kx     }
     5         kx     return(0);
     5         kx }
     5         kx 
     5         kx 
     5         kx 
     5         kx static int extract_type_2_socket_inode(const char lname[], unsigned long * inode_p) {
     5         kx 
     5         kx     /* If lname is of the form "[0000]:12345", extract the "12345"
     5         kx        as *inode_p.  Otherwise, return -1 as *inode_p.
     5         kx        */
     5         kx 
     5         kx     if (strlen(lname) < PRG_SOCKET_PFX2l+1) return(-1);
     5         kx     if (memcmp(lname, PRG_SOCKET_PFX2, PRG_SOCKET_PFX2l)) return(-1);
     5         kx 
     5         kx     {
     5         kx         char *serr;
     5         kx 
     5         kx         *inode_p = strtoul(lname + PRG_SOCKET_PFX2l, &serr, 0);
     5         kx         if (!serr || *serr || *inode_p == ~0)
     5         kx             return(-1);
     5         kx     }
     5         kx     return(0);
     5         kx }
     5         kx 
     5         kx 
     5         kx 
     5         kx 
     5         kx static void prg_cache_load(void)
     5         kx {
     5         kx     char line[LINE_MAX], eacces=0;
     5         kx     int procfdlen, fd, cmdllen, lnamelen;
     5         kx     char lname[30], cmdlbuf[512], finbuf[PROGNAME_WIDTH];
     5         kx     unsigned long inode;
     5         kx     const char *cs, *cmdlp;
     5         kx     DIR *dirproc = NULL, *dirfd = NULL;
     5         kx     struct dirent *direproc, *direfd;
     5         kx #if HAVE_SELINUX
     5         kx     security_context_t scon = NULL;
     5         kx #endif
     5         kx 
     5         kx     if (prg_cache_loaded || !flag_prg) return;
     5         kx     prg_cache_loaded = 1;
     5         kx     cmdlbuf[sizeof(cmdlbuf) - 1] = '\0';
     5         kx     if (!(dirproc=opendir(PATH_PROC))) goto fail;
     5         kx     while (errno = 0, direproc = readdir(dirproc)) {
     5         kx 	for (cs = direproc->d_name; *cs; cs++)
     5         kx 	    if (!isdigit(*cs))
     5         kx 		break;
     5         kx 	if (*cs)
     5         kx 	    continue;
     5         kx 	procfdlen = snprintf(line,sizeof(line),PATH_PROC_X_FD,direproc->d_name);
     5         kx 	if (procfdlen <= 0 || procfdlen >= sizeof(line) - 5)
     5         kx 	    continue;
     5         kx 	errno = 0;
     5         kx 	dirfd = opendir(line);
     5         kx 	if (! dirfd) {
     5         kx 	    if (errno == EACCES)
     5         kx 		eacces = 1;
     5         kx 	    continue;
     5         kx 	}
     5         kx 	line[procfdlen] = '/';
     5         kx 	cmdlp = NULL;
     5         kx 	while ((direfd = readdir(dirfd))) {
     5         kx            /* Skip . and .. */
     5         kx            if (!isdigit(direfd->d_name[0]))
     5         kx                continue;
     5         kx 	    if (procfdlen + 1 + strlen(direfd->d_name) + 1 > sizeof(line))
     5         kx 		continue;
     5         kx 	    memcpy(line + procfdlen - PATH_FD_SUFFl, PATH_FD_SUFF "/",
     5         kx 		   PATH_FD_SUFFl + 1);
     5         kx         safe_strncpy(line + procfdlen + 1, direfd->d_name,
     5         kx                         sizeof(line) - procfdlen - 1);
     5         kx 	    lnamelen = readlink(line, lname, sizeof(lname) - 1);
     5         kx 	    if (lnamelen == -1)
     5         kx 		    continue;
     5         kx             lname[lnamelen] = '\0';  /*make it a null-terminated string*/
     5         kx 
     5         kx             if (extract_type_1_socket_inode(lname, &inode) < 0)
     5         kx               if (extract_type_2_socket_inode(lname, &inode) < 0)
     5         kx                 continue;
     5         kx 
     5         kx 	    if (!cmdlp) {
     5         kx 		if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >=
     5         kx 		    sizeof(line) - 5)
     5         kx 		    continue;
     5         kx         safe_strncpy(line + procfdlen - PATH_FD_SUFFl, PATH_CMDLINE,
     5         kx                         sizeof(line) - procfdlen + PATH_FD_SUFFl);
     5         kx 		fd = open(line, O_RDONLY);
     5         kx 		if (fd < 0)
     5         kx 		    continue;
     5         kx 		cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1);
     5         kx 		if (close(fd))
     5         kx 		    continue;
     5         kx 		if (cmdllen == -1)
     5         kx 		    continue;
     5         kx 		if (cmdllen < sizeof(cmdlbuf) - 1)
     5         kx 		    cmdlbuf[cmdllen]='\0';
     5         kx 		if (cmdlbuf[0] == '/' && (cmdlp = strrchr(cmdlbuf, '/')))
     5         kx 		    cmdlp++;
     5         kx 		else
     5         kx 		    cmdlp = cmdlbuf;
     5         kx 	    }
     5         kx 
     5         kx 	    snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp);
     5         kx #if HAVE_SELINUX
     5         kx 	    if (getpidcon(atoi(direproc->d_name), &scon) == -1) {
     5         kx 		    scon=xstrdup("-");
     5         kx 	    }
     5         kx 	    prg_cache_add(inode, finbuf, scon);
     5         kx 	    freecon(scon);
     5         kx #else
     5         kx 	    prg_cache_add(inode, finbuf, "-");
     5         kx #endif
     5         kx 	}
     5         kx 	closedir(dirfd);
     5         kx 	dirfd = NULL;
     5         kx     }
     5         kx     if (dirproc)
     5         kx 	closedir(dirproc);
     5         kx     if (dirfd)
     5         kx 	closedir(dirfd);
     5         kx     if (!eacces)
     5         kx 	return;
     5         kx     if (prg_cache_loaded == 1) {
     5         kx     fail:
     5         kx 	fprintf(stderr,_("(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n"),
     5         kx 		geteuid());
     5         kx     }
     5         kx     else
     5         kx 	fprintf(stderr, _("(Not all processes could be identified, non-owned process info\n"
     5         kx 			 " will not be shown, you would have to be root to see it all.)\n"));
     5         kx }
     5         kx 
     5         kx #if HAVE_AFNETROM
     5         kx static const char *netrom_state[] =
     5         kx {
     5         kx     N_("LISTENING"),
     5         kx     N_("CONN SENT"),
     5         kx     N_("DISC SENT"),
     5         kx     N_("ESTABLISHED")
     5         kx };
     5         kx 
     5         kx static int netrom_info(void)
     5         kx {
     5         kx     FILE *f;
     5         kx     char buffer[256], dev[16];
     5         kx     int st, vs, vr, sendq, recvq, ret;
     5         kx 
     5         kx     f = proc_fopen(_PATH_PROCNET_NR);
     5         kx     if (f == NULL) {
     5         kx 	if (errno != ENOENT) {
     5         kx 	    perror(_PATH_PROCNET_NR);
     5         kx 	    return (-1);
     5         kx 	}
     5         kx 	if (flag_arg || flag_ver)
     5         kx 	    ESYSNOT("netstat", "AF NETROM");
     5         kx 	if (flag_arg)
     5         kx 	    return (1);
     5         kx 	else
     5         kx 	    return (0);
     5         kx     }
     5         kx     printf(_("Active NET/ROM sockets\n"));
     5         kx     printf(_("User       Dest       Source     Device  State        Vr/Vs    Send-Q  Recv-Q\n"));
     5         kx     if (fgets(buffer, 256, f))
     5         kx 	/* eat line */;
     5         kx 
     5         kx     while (fgets(buffer, 256, f)) {
     5         kx 	buffer[9] = 0;
     5         kx 	buffer[19] = 0;
     5         kx 	buffer[29] = 0;
     5         kx 	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",
     5         kx 	       dev, &st, &vs, &vr, &sendq, &recvq);
     5         kx 	if (ret != 6) {
     5         kx 	    printf(_("Problem reading data from %s\n"), _PATH_PROCNET_NR);
     5         kx 	    continue;
     5         kx 	}
     5         kx 	printf("%-9s  %-9s  %-9s  %-6s  %-11s  %03d/%03d  %-6d  %-6d\n",
     5         kx 	       buffer, buffer + 10, buffer + 20,
     5         kx 	       dev,
     5         kx 	       _(netrom_state[st]),
     5         kx 	       vr, vs, sendq, recvq);
     5         kx     }
     5         kx     fclose(f);
     5         kx     return 0;
     5         kx }
     5         kx #endif
     5         kx 
     5         kx #if HAVE_AFROSE
     5         kx static const char * const rose_state[] =
     5         kx {
     5         kx     N_("LISTENING"),
     5         kx     N_("CONN SENT"),
     5         kx     N_("DISC SENT"),
     5         kx     N_("ESTABLISHED"),
     5         kx };
     5         kx 
     5         kx static int rose_info(void)
     5         kx {
     5         kx     FILE *f;
     5         kx     char buffer[256], dev[6];
     5         kx     int ret, st, lci, neigh;
     5         kx     char src_addr[10], src_call[9], dest_addr[10], dest_call[9];
     5         kx 
     5         kx     f = fopen(_PATH_PROCNET_ROSE, "r");
     5         kx     if (f == NULL) {
     5         kx 	if (errno != ENOENT) {
     5         kx 	    perror(_PATH_PROCNET_ROSE);
     5         kx 	    return (-1);
     5         kx 	}
     5         kx 	if (flag_arg || flag_ver)
     5         kx 	    ESYSNOT("netstat", "AF ROSE");
     5         kx 	if (flag_arg)
     5         kx 	    return (1);
     5         kx 	else
     5         kx 	    return (0);
     5         kx     }
     5         kx     printf(_("Active ROSE sockets\n"));
     5         kx     printf(_("dest_addr   dest_call  src_addr    src_call  dev   lci neigh   state\n"));
     5         kx     if (fgets(buffer, 256, f))
     5         kx 	/* eat line */;
     5         kx 
     5         kx     while (fgets(buffer, 256, f)) {
     5         kx 	ret = sscanf(buffer, "%s %s %s %s %s %d %d %d",
     5         kx 		dest_addr, dest_call, src_addr, src_call, dev, &lci, &neigh, &st);
     5         kx 	if (ret != 8) {
     5         kx 	    printf(_("Problem reading data from %s\n"), _PATH_PROCNET_ROSE);
     5         kx 	    continue;
     5         kx 	}
     5         kx 	printf("%-10s  %-9s  %-10s  %-9s %-5s %3d %5d   %s\n",
     5         kx 		dest_addr, dest_call, src_addr, src_call, dev, lci, neigh, _(rose_state[st]));
     5         kx     }
     5         kx     fclose(f);
     5         kx     return 0;
     5         kx }
     5         kx #endif
     5         kx 
     5         kx /* These enums are used by IPX too. :-( */
     5         kx enum {
     5         kx     TCP_ESTABLISHED = 1,
     5         kx     TCP_SYN_SENT,
     5         kx     TCP_SYN_RECV,
     5         kx     TCP_FIN_WAIT1,
     5         kx     TCP_FIN_WAIT2,
     5         kx     TCP_TIME_WAIT,
     5         kx     TCP_CLOSE,
     5         kx     TCP_CLOSE_WAIT,
     5         kx     TCP_LAST_ACK,
     5         kx     TCP_LISTEN,
     5         kx     TCP_CLOSING			/* now a valid state */
     5         kx };
     5         kx 
     5         kx #if HAVE_AFINET || HAVE_AFINET6
     5         kx 
     5         kx static const char *tcp_state[] =
     5         kx {
     5         kx     "",
     5         kx     N_("ESTABLISHED"),
     5         kx     N_("SYN_SENT"),
     5         kx     N_("SYN_RECV"),
     5         kx     N_("FIN_WAIT1"),
     5         kx     N_("FIN_WAIT2"),
     5         kx     N_("TIME_WAIT"),
     5         kx     N_("CLOSE"),
     5         kx     N_("CLOSE_WAIT"),
     5         kx     N_("LAST_ACK"),
     5         kx     N_("LISTEN"),
     5         kx     N_("CLOSING")
     5         kx };
     5         kx 
     5         kx static void finish_this_one(int uid, unsigned long inode, const char *timers)
     5         kx {
     5         kx     struct passwd *pw;
     5         kx 
     5         kx     if (flag_exp > 1) {
     5         kx 	if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
     5         kx 	    printf(" %-10s ", pw->pw_name);
     5         kx 	else
     5         kx 	    printf(" %-10d ", uid);
     5         kx 	printf("%-10lu",inode);
     5         kx     }
     5         kx     if (flag_prg)
     5         kx 	printf(" %-" PROGNAME_WIDTHs "s",prg_cache_get(inode));
     5         kx     if (flag_selinux)
     5         kx 	printf(" %-" SELINUX_WIDTHs "s",prg_cache_get_con(inode));
     5         kx 
     5         kx     if (flag_opt)
     5         kx 	printf(" %s", timers);
     5         kx     putchar('\n');
     5         kx }
     5         kx 
     5         kx static void igmp_do_one(int lnr, const char *line,const char *prot)
     5         kx {
     5         kx     char mcast_addr[128];
     5         kx     struct sockaddr_storage sas;
     5         kx     struct sockaddr_in *sin = (struct sockaddr_in *)&sas;
     5         kx #if HAVE_AFINET6
     5         kx     char addr6[INET6_ADDRSTRLEN];
     5         kx     struct in6_addr in6;
     5         kx     extern struct aftype inet6_aftype;
     5         kx #endif
     5         kx     const struct aftype *ap;
     5         kx     static int idx_flag = 0;
     5         kx     static int igmp6_flag = 0;
     5         kx     static char device[16];
     5         kx     int num, idx, refcnt;
     5         kx     char* offset;
     5         kx 
     5         kx     if (lnr == 0) {
     5         kx 	/* IPV6 ONLY */
     5         kx 	/* igmp6 file does not have any comments on first line */
     5         kx 	if ( strstr( line, "Device" ) == NULL ) {
     5         kx 	    igmp6_flag = 1;
     5         kx 	} else {
     5         kx 	    /* IPV4 ONLY */
     5         kx 	    /* 2.1.x kernels and up have Idx field */
     5         kx 	    /* 2.0.x and below do not have Idx field */
     5         kx 	    if ( strncmp( line, "Idx", strlen("Idx") ) == 0 )
     5         kx 		idx_flag = 1;
     5         kx 	    else
     5         kx 		idx_flag = 0;
     5         kx 	    return;
     5         kx 	}
     5         kx     }
     5         kx 
     5         kx     if (igmp6_flag) {    /* IPV6 */
     5         kx #if HAVE_AFINET6
     5         kx 	num = sscanf( line, "%d %15s %64[0-9A-Fa-f] %d", &idx, device, mcast_addr, &refcnt );
     5         kx 	if (num == 4) {
     5         kx 	    /* Demangle what the kernel gives us */
     5         kx 	    sscanf(mcast_addr, "%08X%08X%08X%08X",
     5         kx 		   &in6.s6_addr32[0], &in6.s6_addr32[1],
     5         kx            &in6.s6_addr32[2], &in6.s6_addr32[3]);
     5         kx 	    in6.s6_addr32[0] = htonl(in6.s6_addr32[0]);
     5         kx 	    in6.s6_addr32[1] = htonl(in6.s6_addr32[1]);
     5         kx 	    in6.s6_addr32[2] = htonl(in6.s6_addr32[2]);
     5         kx 	    in6.s6_addr32[3] = htonl(in6.s6_addr32[3]);
     5         kx         inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
     5         kx 	    inet6_aftype.input(1, addr6, &sas);
     5         kx 	    sas.ss_family = AF_INET6;
     5         kx 	} else {
     5         kx 	    fprintf(stderr, _("warning, got bogus igmp6 line %d.\n"), lnr);
     5         kx 	    return;
     5         kx 	}
     5         kx 
     5         kx 	if ((ap = get_afntype(sas.ss_family)) == NULL) {
     5         kx 	    fprintf(stderr, _("netstat: unsupported address family %d !\n"),
     5         kx 		    sas.ss_family);
     5         kx 	    return;
     5         kx 	}
     5         kx 	safe_strncpy(mcast_addr, ap->sprint(&sas, flag_not & FLAG_NUM_HOST),
     5         kx 		sizeof(mcast_addr));
     5         kx 	printf("%-15s %-6d %s\n", device, refcnt, mcast_addr);
     5         kx #endif
     5         kx     } else {    /* IPV4 */
     5         kx #if HAVE_AFINET
     5         kx 	if (line[0] != '\t') {
     5         kx 	    if (idx_flag) {
     5         kx 		if ((num = sscanf(line, "%d\t%15c", &idx, device)) < 2) {
     5         kx 		    fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
     5         kx 		    return;
     5         kx 		}
     5         kx 	    } else {
     5         kx 		if ((num = sscanf(line, "%15c", device)) < 1 ) {
     5         kx 		    fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
     5         kx 		    return;
     5         kx 		}
     5         kx 	    }
     5         kx 
     5         kx 	    offset = strrchr(device, ':');
     5         kx 	    if (offset)
     5         kx 		*offset = 0;
     5         kx 
     5         kx 	    return;
     5         kx 	} else if ( line[0] == '\t' ) {
     5         kx 	    if ( (num = sscanf(line, "\t%8[0-9A-Fa-f] %d", mcast_addr, &refcnt)) < 2 ) {
     5         kx 		fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
     5         kx 		return;
     5         kx 	    }
     5         kx 	    sscanf(mcast_addr, "%X", &sin->sin_addr.s_addr);
     5         kx 	    sas.ss_family = AF_INET;
     5         kx 	} else {
     5         kx 	    fprintf(stderr, _("warning, got bogus igmp line %d.\n"), lnr);
     5         kx 	    return;
     5         kx 	}
     5         kx 
     5         kx 	if ((ap = get_afntype(sas.ss_family)) == NULL) {
     5         kx 	    fprintf(stderr, _("netstat: unsupported address family %d !\n"),
     5         kx 		    sas.ss_family);
     5         kx 	    return;
     5         kx 	}
     5         kx 	safe_strncpy(mcast_addr, ap->sprint(&sas, flag_not & FLAG_NUM_HOST),
     5         kx 		sizeof(mcast_addr));
     5         kx 	printf("%-15s %-6d %s\n", device, refcnt, mcast_addr );
     5         kx #endif
     5         kx     }    /* IPV4 */
     5         kx }
     5         kx 
     5         kx #if HAVE_AFX25
     5         kx static int x25_info(void)
     5         kx {
     5         kx        FILE *f=proc_fopen(_PATH_PROCNET_X25);
     5         kx        char buffer[256],dev[16];
     5         kx        int st,vs,vr,sendq,recvq,lci;
     5         kx        static char *x25_state[5]=
     5         kx        {
     5         kx                "LISTENING",
     5         kx                "SABM_SENT",
     5         kx                "DISC_SENT",
     5         kx                "ESTABLISHED",
     5         kx                "RECOVERY"
     5         kx        };
     5         kx        if(!f)
     5         kx        {
     5         kx                if (errno != ENOENT) {
     5         kx                        perror(_PATH_PROCNET_X25);
     5         kx                        return(-1);
     5         kx                }
     5         kx                if (flag_arg || flag_ver)
     5         kx                        ESYSNOT("netstat","AF X25");
     5         kx                if (flag_arg)
     5         kx                        return(1);
     5         kx                else
     5         kx                        return(0);
     5         kx        }
     5         kx        printf( _("Active X.25 sockets\n"));
     5         kx        /* IMHO, Vr/Vs is not very usefull --SF */
     5         kx        printf( _("Dest         Source          Device  LCI  State        Vr/Vs  Send-Q  Recv-Q\n"));
     5         kx        if (fgets(buffer,256,f))
     5         kx                /* eat line */;
     5         kx        while(fgets(buffer,256,f))
     5         kx        {
     5         kx                buffer[10]=0;
     5         kx                buffer[20]=0;
     5         kx                sscanf(buffer+22,"%s %d %d %d %d %*d %*d %*d %*d %*d %*d %d %d %*d",
     5         kx                        dev,&lci,&st,&vs,&vr,&sendq,&recvq);
     5         kx                if (!(flag_all || lci))
     5         kx                        continue;
     5         kx                printf("%-15s %-15s %-7s %-3d  %-11s  %02d/%02d  %-6d  %-6d\n",
     5         kx                        buffer,buffer+11,
     5         kx                        dev,
     5         kx                        lci,
     5         kx                        x25_state[st],
     5         kx                        vr,vs,sendq,recvq);
     5         kx        }
     5         kx        fclose(f);
     5         kx        return 0;
     5         kx }
     5         kx #endif
     5         kx 
     5         kx static int igmp_info(void)
     5         kx {
     5         kx     INFO_GUTS6(_PATH_PROCNET_IGMP, _PATH_PROCNET_IGMP6, "AF INET (igmp)",
     5         kx 	       igmp_do_one, "igmp", "igmp6");
     5         kx }
     5         kx 
     5         kx static const char *sctp_socket_state_str(int state)
     5         kx {
     5         kx     if (state >= 0 && state < ARRAY_SIZE(tcp_state))
     5         kx 	return tcp_state[state];
     5         kx     else {
     5         kx 	static char state_str_buf[64];
     5         kx 	sprintf(state_str_buf, "UNKNOWN(%d)", state);
     5         kx 	return state_str_buf;
     5         kx     }
     5         kx }
     5         kx 
     5         kx static const struct aftype *process_sctp_addr_str(const char *addr_str, struct sockaddr_storage *sas)
     5         kx {
     5         kx     if (strchr(addr_str,':')) {
     5         kx #if HAVE_AFINET6
     5         kx 	extern struct aftype inet6_aftype;
     5         kx 	/* Demangle what the kernel gives us */
     5         kx 	struct in6_addr in6;
     5         kx 	char addr6_str[INET6_ADDRSTRLEN];
     5         kx 	unsigned u0, u1, u2, u3, u4, u5, u6, u7;
     5         kx 	sscanf(addr_str, "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",
     5         kx 	       &u0, &u1, &u2, &u3, &u4, &u5, &u6, &u7);
     5         kx 	in6.s6_addr16[0] = htons(u0);
     5         kx 	in6.s6_addr16[1] = htons(u1);
     5         kx 	in6.s6_addr16[2] = htons(u2);
     5         kx 	in6.s6_addr16[3] = htons(u3);
     5         kx 	in6.s6_addr16[4] = htons(u4);
     5         kx 	in6.s6_addr16[5] = htons(u5);
     5         kx 	in6.s6_addr16[6] = htons(u6);
     5         kx 	in6.s6_addr16[7] = htons(u7);
     5         kx 
     5         kx 	inet_ntop(AF_INET6, &in6, addr6_str, sizeof(addr6_str));
     5         kx 	inet6_aftype.input(1, addr6_str, sas);
     5         kx 	sas->ss_family = AF_INET6;
     5         kx #endif
     5         kx     } else {
     5         kx 	struct sockaddr_in *sin = (struct sockaddr_in *)sas;
     5         kx 	sin->sin_addr.s_addr = inet_addr(addr_str);
     5         kx 	sas->ss_family = AF_INET;
     5         kx     }
     5         kx     return get_afntype(sas->ss_family);
     5         kx }
     5         kx 
     5         kx static void sctp_eps_do_one(int lnr, char *line, const char *proto)
     5         kx {
     5         kx     char buffer[1024];
     5         kx     int state, port;
     5         kx     int uid;
     5         kx     unsigned long inode;
     5         kx     const struct aftype *ap;
     5         kx     struct sockaddr_storage localsas;
     5         kx     const char *sst_str;
     5         kx     const char *lport_str;
     5         kx     const char *uid_str;
     5         kx     const char *inode_str;
     5         kx     char *laddrs_str;
     5         kx 
     5         kx     if (lnr == 0) {
     5         kx 	/* ENDPT     SOCK   STY SST HBKT LPORT   UID INODE LADDRS */
     5         kx 	return;
     5         kx     }
     5         kx     strtok(line, " \t\n");	/* skip endpt */
     5         kx     strtok(0, " \t\n");		/* skip sock */
     5         kx     strtok(0, " \t\n");		/* skip sty */
     5         kx     sst_str = strtok(0, " \t\n");
     5         kx     strtok(0, " \t\n");		/* skip hash bucket */
     5         kx     lport_str = strtok(0, " \t\n");
     5         kx     uid_str = strtok(0, " \t\n");
     5         kx     inode_str = strtok(0, " \t\n");
     5         kx     laddrs_str = strtok(0, "\t\n");
     5         kx 
     5         kx     if (!sst_str || !lport_str || !uid_str || !inode_str) {
     5         kx 	fprintf(stderr, _("warning, got bogus sctp eps line.\n"));
     5         kx 	return;
     5         kx     }
     5         kx     state = atoi(sst_str);
     5         kx     port = atoi(lport_str);
     5         kx     uid = atoi(uid_str);
     5         kx     inode = strtoul(inode_str,0,0);
     5         kx 
     5         kx     const char *this_local_addr;
     5         kx     int first = 1;
     5         kx     char local_port[16];
     5         kx     snprintf(local_port, sizeof(local_port), "%s",
     5         kx         get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT));
     5         kx     for (this_local_addr = strtok(laddrs_str, " \t\n");
     5         kx          this_local_addr;
     5         kx          this_local_addr = strtok(0, " \t\n")) {
     5         kx 	char local_addr[64];
     5         kx 	ap = process_sctp_addr_str(this_local_addr, &localsas);
     5         kx 	if (ap)
     5         kx 	    safe_strncpy(local_addr, ap->sprint(&localsas, flag_not), sizeof(local_addr));
     5         kx 	else
     5         kx 	    sprintf(local_addr, _("unsupported address family %d"), localsas.ss_family);
     5         kx 
     5         kx 	if (first)
     5         kx 	    printf("sctp                ");
     5         kx 	else
     5         kx 	    printf("\n                    ");
     5         kx 	sprintf(buffer, "%s:%s", local_addr, local_port);
     5         kx 	printf("%-47s", buffer);
     5         kx 	printf(" %-11s", first ? sctp_socket_state_str(state) : "");
     5         kx 	first = 0;
     5         kx     }
     5         kx     finish_this_one(uid, inode, "");
     5         kx }
     5         kx 
     5         kx static void sctp_assoc_do_one(int lnr, char *line, const char *proto)
     5         kx {
     5         kx     char buffer[1024];
     5         kx     int state, lport,rport;
     5         kx     int uid;
     5         kx     unsigned rxqueue,txqueue;
     5         kx     unsigned long inode;
     5         kx 
     5         kx     const struct aftype *ap;
     5         kx     struct sockaddr_storage localsas, remotesas;
     5         kx     const char *sst_str;
     5         kx     const char *txqueue_str;
     5         kx     const char *rxqueue_str;
     5         kx     const char *lport_str, *rport_str;
     5         kx     const char *uid_str;
     5         kx     const char *inode_str;
     5         kx     char *laddrs_str;
     5         kx     char *raddrs_str;
     5         kx 
     5         kx     if (lnr == 0) {
     5         kx 	/* ASSOC     SOCK   STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT RPORT LADDRS <-> RADDRS */
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx     strtok(line, " \t\n");	/* skip assoc */
     5         kx     strtok(0, " \t\n");		/* skip sock */
     5         kx     strtok(0, " \t\n");		/* skip sty */
     5         kx     sst_str = strtok(0, " \t\n");
     5         kx     strtok(0, " \t\n");
     5         kx     strtok(0, " \t\n");		/* skip hash bucket */
     5         kx     strtok(0, " \t\n");		/* skip hash assoc-id */
     5         kx     txqueue_str =  strtok(0, " \t\n");
     5         kx     rxqueue_str =  strtok(0, " \t\n");
     5         kx     uid_str = strtok(0, " \t\n");
     5         kx     inode_str = strtok(0, " \t\n");
     5         kx     lport_str = strtok(0, " \t\n");
     5         kx     rport_str = strtok(0, " \t\n");
     5         kx     laddrs_str = strtok(0, "<->\t\n");
     5         kx     raddrs_str = strtok(0, "<->\t\n");
     5         kx 
     5         kx     if (!sst_str || !txqueue_str || !rxqueue_str || !uid_str ||
     5         kx         !inode_str || !lport_str || !rport_str) {
     5         kx 	fprintf(stderr, _("warning, got bogus sctp assoc line.\n"));
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx     state = atoi(sst_str);
     5         kx     txqueue = atoi(txqueue_str);
     5         kx     rxqueue = atoi(rxqueue_str);
     5         kx     uid = atoi(uid_str);
     5         kx     inode = strtoul(inode_str, 0, 0);
     5         kx     lport = atoi(lport_str);
     5         kx     rport = atoi(rport_str);
     5         kx 
     5         kx     /*print all addresses*/
     5         kx     const char *this_local_addr;
     5         kx     const char *this_remote_addr;
     5         kx     char *ss1, *ss2;
     5         kx     int first = 1;
     5         kx     char local_port[16];
     5         kx     char remote_port[16];
     5         kx     snprintf(local_port, sizeof(local_port), "%s",
     5         kx              get_sname(htons(lport), proto,
     5         kx              flag_not & FLAG_NUM_PORT));
     5         kx     snprintf(remote_port, sizeof(remote_port), "%s",
     5         kx              get_sname(htons(rport), proto,
     5         kx              flag_not & FLAG_NUM_PORT));
     5         kx 
     5         kx     this_local_addr = strtok_r(laddrs_str, " \t\n", &ss1);
     5         kx     this_remote_addr = strtok_r(raddrs_str, " \t\n", &ss2);
     5         kx     while (this_local_addr || this_remote_addr) {
     5         kx 	char local_addr[64];
     5         kx 	char remote_addr[64];
     5         kx 
     5         kx 	if (this_local_addr) {
     5         kx 	    if (this_local_addr[0] == '*') {
     5         kx 		/* skip * */
     5         kx 		this_local_addr++;
     5         kx 	    }
     5         kx 	    ap = process_sctp_addr_str(this_local_addr, &localsas);
     5         kx 	    if (ap)
     5         kx 		safe_strncpy(local_addr,
     5         kx 		             ap->sprint(&localsas, flag_not), sizeof(local_addr));
     5         kx 	    else
     5         kx 		sprintf(local_addr, _("unsupported address family %d"), localsas.ss_family);
     5         kx 	}
     5         kx 	if (this_remote_addr) {
     5         kx 	    if (this_remote_addr[0] == '*') {
     5         kx 		/* skip * */
     5         kx 		this_remote_addr++;
     5         kx 	    }
     5         kx 	    ap = process_sctp_addr_str(this_remote_addr, &remotesas);
     5         kx 	    if (ap)
     5         kx 		safe_strncpy(remote_addr,
     5         kx 		             ap->sprint(&remotesas, flag_not), sizeof(remote_addr));
     5         kx 	    else
     5         kx 		sprintf(remote_addr, _("unsupported address family %d"), remotesas.ss_family);
     5         kx 	}
     5         kx 
     5         kx 	if (first)
     5         kx 	    printf("sctp  %6u %6u ", rxqueue, txqueue);
     5         kx 	else
     5         kx 	    printf("\n                    ");
     5         kx 	if (this_local_addr) {
     5         kx 	    if (first)
     5         kx 		sprintf(buffer, "%s:%s", local_addr, local_port);
     5         kx 	    else
     5         kx 		sprintf(buffer, "%s", local_addr);
     5         kx 	    printf("%-23s", buffer);
     5         kx 	} else
     5         kx 	    printf("%-23s", "");
     5         kx 	printf(" ");
     5         kx 	if (this_remote_addr) {
     5         kx 	    if (first)
     5         kx 		sprintf(buffer, "%s:%s", remote_addr, remote_port);
     5         kx 	    else
     5         kx 		sprintf(buffer, "%s", remote_addr);
     5         kx 	    printf("%-23s", buffer);
     5         kx 	} else
     5         kx 	    printf("%-23s", "");
     5         kx 
     5         kx        printf(" %-11s", first ? sctp_socket_state_str(state) : "");
     5         kx 
     5         kx        first = 0;
     5         kx        this_local_addr = strtok_r(0, " \t\n", &ss1);
     5         kx        this_remote_addr = strtok_r(0, " \t\n", &ss2);
     5         kx     }
     5         kx     finish_this_one(uid, inode, "");
     5         kx }
     5         kx 
     5         kx static int sctp_info_eps(void)
     5         kx {
     5         kx     INFO_GUTS6(_PATH_PROCNET_SCTPEPTS, _PATH_PROCNET_SCTP6EPTS, "AF INET (sctp)",
     5         kx                sctp_eps_do_one, "sctp", "sctp6");
     5         kx }
     5         kx 
     5         kx static int sctp_info_assocs(void)
     5         kx {
     5         kx     INFO_GUTS6(_PATH_PROCNET_SCTPASSOCS, _PATH_PROCNET_SCTP6ASSOCS, "AF INET (sctp)",
     5         kx                sctp_assoc_do_one, "sctp", "sctp6");
     5         kx }
     5         kx 
     5         kx static int sctp_info(void)
     5         kx {
     5         kx     int res;
     5         kx 
     5         kx     if (flag_all || flag_lst) {
     5         kx 	res = sctp_info_eps();
     5         kx 	if (res)
     5         kx 	    return res;
     5         kx     }
     5         kx 
     5         kx     if (flag_all || !flag_lst) {
     5         kx 	res = sctp_info_assocs();
     5         kx     }
     5         kx 
     5         kx     return res;
     5         kx }
     5         kx 
     5         kx static void addr_do_one(char *buf, size_t buf_len, size_t short_len, const struct aftype *ap,
     5         kx 			const struct sockaddr_storage *addr,
     5         kx 			int port, const char *proto
     5         kx )
     5         kx {
     5         kx     const char *sport, *saddr;
     5         kx     size_t port_len, addr_len;
     5         kx 
     5         kx     saddr = ap->sprint(addr, flag_not & FLAG_NUM_HOST);
     5         kx     sport = get_sname(htons(port), proto, flag_not & FLAG_NUM_PORT);
     5         kx     addr_len = strlen(saddr);
     5         kx     port_len = strlen(sport);
     5         kx     if (!flag_wide && (addr_len + port_len > short_len)) {
     5         kx 	/* Assume port name is short */
     5         kx 	port_len = netmin(port_len, short_len - 4);
     5         kx 	addr_len = short_len - port_len;
     5         kx 	strncpy(buf, saddr, addr_len);
     5         kx 	buf[addr_len] = '\0';
     5         kx 	strcat(buf, ":");
     5         kx 	strncat(buf, sport, port_len);
     5         kx     } else
     5         kx 	snprintf(buf, buf_len, "%s:%s", saddr, sport);
     5         kx }
     5         kx 
     5         kx static void tcp_do_one(int lnr, const char *line, const char *prot)
     5         kx {
     5         kx     unsigned long rxq, txq, time_len, retr, inode;
     5         kx     int num, local_port, rem_port, d, state, uid, timer_run, timeout;
     5         kx     char rem_addr[128], local_addr[128], timers[64];
     5         kx     const struct aftype *ap;
     5         kx     struct sockaddr_storage localsas, remsas;
     5         kx     struct sockaddr_in *localaddr = (struct sockaddr_in *)&localsas;
     5         kx     struct sockaddr_in *remaddr = (struct sockaddr_in *)&remsas;
     5         kx #if HAVE_AFINET6
     5         kx     char addr6[INET6_ADDRSTRLEN];
     5         kx     struct in6_addr in6;
     5         kx     extern struct aftype inet6_aftype;
     5         kx #endif
     5         kx     long clk_tck = ticks_per_second();
     5         kx 
     5         kx     if (lnr == 0)
     5         kx 	return;
     5         kx 
     5         kx     num = sscanf(line,
     5         kx     "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %*s\n",
     5         kx 		 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
     5         kx 		 &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode);
     5         kx 
     5         kx     if (num < 11) {
     5         kx 	fprintf(stderr, _("warning, got bogus tcp line.\n"));
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx     if (!flag_all && ((flag_lst && rem_port) || (!flag_lst && !rem_port)))
     5         kx       return;
     5         kx 
     5         kx     if (strlen(local_addr) > 8) {
     5         kx #if HAVE_AFINET6
     5         kx 	/* Demangle what the kernel gives us */
     5         kx 	sscanf(local_addr, "%08X%08X%08X%08X",
     5         kx 	       &in6.s6_addr32[0], &in6.s6_addr32[1],
     5         kx            &in6.s6_addr32[2], &in6.s6_addr32[3]);
     5         kx 	inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
     5         kx 	inet6_aftype.input(1, addr6, &localsas);
     5         kx 	sscanf(rem_addr, "%08X%08X%08X%08X",
     5         kx 	       &in6.s6_addr32[0], &in6.s6_addr32[1],
     5         kx 	       &in6.s6_addr32[2], &in6.s6_addr32[3]);
     5         kx 	inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
     5         kx 	inet6_aftype.input(1, addr6, &remsas);
     5         kx 	localsas.ss_family = AF_INET6;
     5         kx 	remsas.ss_family = AF_INET6;
     5         kx #endif
     5         kx     } else {
     5         kx 	sscanf(local_addr, "%X", &localaddr->sin_addr.s_addr);
     5         kx 	sscanf(rem_addr, "%X", &remaddr->sin_addr.s_addr);
     5         kx 	localsas.ss_family = AF_INET;
     5         kx 	remsas.ss_family = AF_INET;
     5         kx     }
     5         kx 
     5         kx     if ((ap = get_afntype(localsas.ss_family)) == NULL) {
     5         kx 	fprintf(stderr, _("netstat: unsupported address family %d !\n"),
     5         kx 		localsas.ss_family);
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx 	addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localsas, local_port, "tcp");
     5         kx 	addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remsas, rem_port, "tcp");
     5         kx 
     5         kx 	timers[0] = '\0';
     5         kx 	if (flag_opt)
     5         kx 	    switch (timer_run) {
     5         kx 	    case 0:
     5         kx 		snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    case 1:
     5         kx 		snprintf(timers, sizeof(timers), _("on (%2.2f/%ld/%d)"),
     5         kx 			 (double) time_len / clk_tck, retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    case 2:
     5         kx 		snprintf(timers, sizeof(timers), _("keepalive (%2.2f/%ld/%d)"),
     5         kx 			 (double) time_len / clk_tck, retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    case 3:
     5         kx 		snprintf(timers, sizeof(timers), _("timewait (%2.2f/%ld/%d)"),
     5         kx 			 (double) time_len / clk_tck, retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    case 4:
     5         kx 		snprintf(timers, sizeof(timers), _("probe (%2.2f/%ld/%d)"),
     5         kx 			 (double) time_len / clk_tck, retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    default:
     5         kx 		snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
     5         kx 			 timer_run, (double) time_len / clk_tck, retr, timeout);
     5         kx 		break;
     5         kx 	    }
     5         kx 
     5         kx 	printf("%-4s  %6ld %6ld %-*s %-*s %-11s",
     5         kx 	       prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
     5         kx 
     5         kx 	finish_this_one(uid,inode,timers);
     5         kx }
     5         kx 
     5         kx static int tcp_info(void)
     5         kx {
     5         kx     INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
     5         kx 	       tcp_do_one, "tcp", "tcp6");
     5         kx }
     5         kx 
     5         kx static int notnull(const struct sockaddr_storage *sas)
     5         kx {
     5         kx     const struct sockaddr_in *sin = (const struct sockaddr_in *)sas;
     5         kx 
     5         kx #if HAVE_AFINET6
     5         kx     const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sas;
     5         kx 
     5         kx     if (sin6->sin6_family == AF_INET6) {
     5         kx 	return sin6->sin6_addr.s6_addr32[0] ||
     5         kx 		sin6->sin6_addr.s6_addr32[1] ||
     5         kx 		sin6->sin6_addr.s6_addr32[2] ||
     5         kx 		sin6->sin6_addr.s6_addr32[3];
     5         kx     }
     5         kx #endif
     5         kx 
     5         kx     return sin->sin_addr.s_addr;
     5         kx }
     5         kx 
     5         kx static void udp_do_one(int lnr, const char *line,const char *prot)
     5         kx {
     5         kx     char local_addr[128], rem_addr[128];
     5         kx     char *udp_state, timers[64];
     5         kx     int num, local_port, rem_port, d, state, timer_run, uid, timeout;
     5         kx     struct sockaddr_storage localsas, remsas;
     5         kx     struct sockaddr_in *localaddr = (struct sockaddr_in *)&localsas;
     5         kx     struct sockaddr_in *remaddr = (struct sockaddr_in *)&remsas;
     5         kx #if HAVE_AFINET6
     5         kx     char addr6[INET6_ADDRSTRLEN];
     5         kx     struct in6_addr in6;
     5         kx     extern struct aftype inet6_aftype;
     5         kx #endif
     5         kx     const struct aftype *ap;
     5         kx     unsigned long rxq, txq, time_len, retr, inode;
     5         kx 
     5         kx     if (lnr == 0)
     5         kx 	return;
     5         kx 
     5         kx     num = sscanf(line,
     5         kx 		 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %*s\n",
     5         kx 		 &d, local_addr, &local_port,
     5         kx 		 rem_addr, &rem_port, &state,
     5         kx 	  &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode);
     5         kx 
     5         kx     if (num < 10) {
     5         kx 	fprintf(stderr, _("warning, got bogus udp line.\n"));
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx     if (strlen(local_addr) > 8) {
     5         kx #if HAVE_AFINET6
     5         kx 	sscanf(local_addr, "%08X%08X%08X%08X",
     5         kx 	       &in6.s6_addr32[0], &in6.s6_addr32[1],
     5         kx 	       &in6.s6_addr32[2], &in6.s6_addr32[3]);
     5         kx 	inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
     5         kx 	inet6_aftype.input(1, addr6, &localsas);
     5         kx 	sscanf(rem_addr, "%08X%08X%08X%08X",
     5         kx 	       &in6.s6_addr32[0], &in6.s6_addr32[1],
     5         kx 	       &in6.s6_addr32[2], &in6.s6_addr32[3]);
     5         kx 	inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
     5         kx 	inet6_aftype.input(1, addr6, &remsas);
     5         kx 	localsas.ss_family = AF_INET6;
     5         kx 	remsas.ss_family = AF_INET6;
     5         kx #endif
     5         kx     } else {
     5         kx 	sscanf(local_addr, "%X", &localaddr->sin_addr.s_addr);
     5         kx 	sscanf(rem_addr, "%X", &remaddr->sin_addr.s_addr);
     5         kx 	localsas.ss_family = AF_INET;
     5         kx 	remsas.ss_family = AF_INET;
     5         kx     }
     5         kx 
     5         kx     retr = 0L;
     5         kx 
     5         kx     if ((ap = get_afntype(localsas.ss_family)) == NULL) {
     5         kx 	fprintf(stderr, _("netstat: unsupported address family %d !\n"),
     5         kx 		localsas.ss_family);
     5         kx 	return;
     5         kx     }
     5         kx     switch (state) {
     5         kx     case TCP_ESTABLISHED:
     5         kx 	udp_state = _("ESTABLISHED");
     5         kx 	break;
     5         kx 
     5         kx     case TCP_CLOSE:
     5         kx 	udp_state = "";
     5         kx 	break;
     5         kx 
     5         kx     default:
     5         kx 	udp_state = _("UNKNOWN");
     5         kx 	break;
     5         kx     }
     5         kx 
     5         kx     if (flag_all || (notnull(&remsas) && !flag_lst) || (!notnull(&remsas) && flag_lst))
     5         kx     {
     5         kx 	addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localsas, local_port, "udp");
     5         kx 	addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remsas, rem_port, "udp");
     5         kx 
     5         kx 	timers[0] = '\0';
     5         kx 	if (flag_opt)
     5         kx 	    switch (timer_run) {
     5         kx 	    case 0:
     5         kx 		snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    case 1:
     5         kx 	    case 2:
     5         kx 		snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100, retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    default:
     5         kx 		snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
     5         kx 			 retr, timeout);
     5         kx 		break;
     5         kx 	    }
     5         kx 	printf("%-5s %6ld %6ld %-23s %-23s %-11s",
     5         kx 	       prot, rxq, txq, local_addr, rem_addr, udp_state);
     5         kx 
     5         kx 	finish_this_one(uid,inode,timers);
     5         kx     }
     5         kx }
     5         kx 
     5         kx static int udp_info(void)
     5         kx {
     5         kx     INFO_GUTS6(_PATH_PROCNET_UDP, _PATH_PROCNET_UDP6, "AF INET (udp)",
     5         kx 	       udp_do_one, "udp", "udp6");
     5         kx }
     5         kx 
     5         kx static int udplite_info(void)
     5         kx {
     5         kx     INFO_GUTS6(_PATH_PROCNET_UDPLITE, _PATH_PROCNET_UDPLITE6,
     5         kx                "AF INET (udplite)", udp_do_one, "udpl", "udpl6" );
     5         kx }
     5         kx 
     5         kx static void raw_do_one(int lnr, const char *line,const char *prot)
     5         kx {
     5         kx     char local_addr[128], rem_addr[128];
     5         kx     char timers[64];
     5         kx     int num, local_port, rem_port, d, state, timer_run, uid, timeout;
     5         kx     struct sockaddr_storage localsas, remsas;
     5         kx     struct sockaddr_in *localaddr = (struct sockaddr_in *)&localsas;
     5         kx     struct sockaddr_in *remaddr = (struct sockaddr_in *)&remsas;
     5         kx #if HAVE_AFINET6
     5         kx     char addr6[INET6_ADDRSTRLEN];
     5         kx     struct in6_addr in6;
     5         kx     extern struct aftype inet6_aftype;
     5         kx #endif
     5         kx     const struct aftype *ap;
     5         kx     unsigned long rxq, txq, time_len, retr, inode;
     5         kx 
     5         kx     if (lnr == 0)
     5         kx 	return;
     5         kx 
     5         kx     num = sscanf(line,
     5         kx 		 "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %*s\n",
     5         kx 		 &d, local_addr, &local_port, rem_addr, &rem_port, &state,
     5         kx 	  &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode);
     5         kx 
     5         kx     if (num < 10) {
     5         kx     	fprintf(stderr, _("warning, got bogus raw line.\n"));
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx     if (strlen(local_addr) > 8) {
     5         kx #if HAVE_AFINET6
     5         kx 	sscanf(local_addr, "%08X%08X%08X%08X",
     5         kx 	       &in6.s6_addr32[0], &in6.s6_addr32[1],
     5         kx            &in6.s6_addr32[2], &in6.s6_addr32[3]);
     5         kx     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
     5         kx 	inet6_aftype.input(1, addr6, &localsas);
     5         kx 	sscanf(rem_addr, "%08X%08X%08X%08X",
     5         kx 	       &in6.s6_addr32[0], &in6.s6_addr32[1],
     5         kx            &in6.s6_addr32[2], &in6.s6_addr32[3]);
     5         kx     inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6));
     5         kx 	inet6_aftype.input(1, addr6, &remsas);
     5         kx 	localsas.ss_family = AF_INET6;
     5         kx 	remsas.ss_family = AF_INET6;
     5         kx #endif
     5         kx     } else {
     5         kx 	sscanf(local_addr, "%X", &localaddr->sin_addr.s_addr);
     5         kx 	sscanf(rem_addr, "%X", &remaddr->sin_addr.s_addr);
     5         kx 	localsas.ss_family = AF_INET;
     5         kx 	remsas.ss_family = AF_INET;
     5         kx     }
     5         kx 
     5         kx     if ((ap = get_afntype(localsas.ss_family)) == NULL) {
     5         kx 	fprintf(stderr, _("netstat: unsupported address family %d !\n"), localsas.ss_family);
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx     if (flag_all || (notnull(&remsas) && !flag_lst) || (!notnull(&remsas) && flag_lst))
     5         kx     {
     5         kx 	addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localsas, local_port, "raw");
     5         kx 	addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remsas, rem_port, "raw");
     5         kx 
     5         kx 	timers[0] = '\0';
     5         kx 	if (flag_opt)
     5         kx 	    switch (timer_run) {
     5         kx 	    case 0:
     5         kx 		snprintf(timers, sizeof(timers), _("off (0.00/%ld/%d)"), retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    case 1:
     5         kx             case 2:
     5         kx 		snprintf(timers, sizeof(timers), _("on%d (%2.2f/%ld/%d)"), timer_run, (double) time_len / 100,
     5         kx 			 retr, timeout);
     5         kx 		break;
     5         kx 
     5         kx 	    default:
     5         kx 		snprintf(timers, sizeof(timers), _("unkn-%d (%2.2f/%ld/%d)"),
     5         kx 			 timer_run, (double) time_len / 100,
     5         kx 			 retr, timeout);
     5         kx 		break;
     5         kx 	    }
     5         kx 	printf("%-4s  %6ld %6ld %-23s %-23s %-11d",
     5         kx 	       prot, rxq, txq, local_addr, rem_addr, state);
     5         kx 
     5         kx 	finish_this_one(uid,inode,timers);
     5         kx     }
     5         kx }
     5         kx 
     5         kx static int raw_info(void)
     5         kx {
     5         kx     INFO_GUTS6(_PATH_PROCNET_RAW, _PATH_PROCNET_RAW6, "AF INET (raw)",
     5         kx 	       raw_do_one, "raw", "raw6");
     5         kx }
     5         kx 
     5         kx #endif
     5         kx 
     5         kx 
     5         kx #if HAVE_AFUNIX
     5         kx 
     5         kx #define HAS_INODE 1
     5         kx 
     5         kx static void unix_do_one(int nr, const char *line, const char *prot)
     5         kx {
     5         kx     static int has = 0;
     5         kx     char path[MAXPATHLEN], ss_flags[32];
     5         kx     char *ss_proto, *ss_state, *ss_type;
     5         kx     int num, state, type;
     5         kx     void *d;
     5         kx     unsigned long refcnt, proto, flags, inode;
     5         kx 
     5         kx     if (nr == 0) {
     5         kx 	if (strstr(line, "Inode"))
     5         kx 	    has |= HAS_INODE;
     5         kx 	return;
     5         kx     }
     5         kx     path[0] = '\0';
     5         kx     num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %s",
     5         kx 		 &d, &refcnt, &proto, &flags, &type, &state, &inode, path);
     5         kx     if (num < 6) {
     5         kx 	fprintf(stderr, _("warning, got bogus unix line.\n"));
     5         kx 	return;
     5         kx     }
     5         kx     if (!(has & HAS_INODE))
     5         kx 	snprintf(path,sizeof(path),"%lu",inode);
     5         kx 
     5         kx     if (!flag_all) {
     5         kx     	if ((state == SS_UNCONNECTED) && (flags & SO_ACCEPTCON)) {
     5         kx     		if (!flag_lst)
     5         kx     			return;
     5         kx     	} else {
     5         kx     		if (flag_lst)
     5         kx     			return;
     5         kx     	}
     5         kx     }
     5         kx 
     5         kx     switch (proto) {
     5         kx     case 0:
     5         kx 	ss_proto = "unix";
     5         kx 	break;
     5         kx 
     5         kx     default:
     5         kx 	ss_proto = "??";
     5         kx     }
     5         kx 
     5         kx     switch (type) {
     5         kx     case SOCK_STREAM:
     5         kx 	ss_type = _("STREAM");
     5         kx 	break;
     5         kx 
     5         kx     case SOCK_DGRAM:
     5         kx 	ss_type = _("DGRAM");
     5         kx 	break;
     5         kx 
     5         kx     case SOCK_RAW:
     5         kx 	ss_type = _("RAW");
     5         kx 	break;
     5         kx 
     5         kx     case SOCK_RDM:
     5         kx 	ss_type = _("RDM");
     5         kx 	break;
     5         kx 
     5         kx     case SOCK_SEQPACKET:
     5         kx 	ss_type = _("SEQPACKET");
     5         kx 	break;
     5         kx 
     5         kx     default:
     5         kx 	ss_type = _("UNKNOWN");
     5         kx     }
     5         kx 
     5         kx     switch (state) {
     5         kx     case SS_FREE:
     5         kx 	ss_state = _("FREE");
     5         kx 	break;
     5         kx 
     5         kx     case SS_UNCONNECTED:
     5         kx 	/*
     5         kx 	 * Unconnected sockets may be listening
     5         kx 	 * for something.
     5         kx 	 */
     5         kx 	if (flags & SO_ACCEPTCON) {
     5         kx 	    ss_state = _("LISTENING");
     5         kx 	} else {
     5         kx 	    ss_state = "";
     5         kx 	}
     5         kx 	break;
     5         kx 
     5         kx     case SS_CONNECTING:
     5         kx 	ss_state = _("CONNECTING");
     5         kx 	break;
     5         kx 
     5         kx     case SS_CONNECTED:
     5         kx 	ss_state = _("CONNECTED");
     5         kx 	break;
     5         kx 
     5         kx     case SS_DISCONNECTING:
     5         kx 	ss_state = _("DISCONNECTING");
     5         kx 	break;
     5         kx 
     5         kx     default:
     5         kx 	ss_state = _("UNKNOWN");
     5         kx     }
     5         kx 
     5         kx     safe_strncpy(ss_flags, "[ ", sizeof(ss_flags));
     5         kx     if (flags & SO_ACCEPTCON)
     5         kx 	strcat(ss_flags, "ACC ");
     5         kx     if (flags & SO_WAITDATA)
     5         kx 	strcat(ss_flags, "W ");
     5         kx     if (flags & SO_NOSPACE)
     5         kx 	strcat(ss_flags, "N ");
     5         kx 
     5         kx     strcat(ss_flags, "]");
     5         kx 
     5         kx     printf("%-5s %-6ld %-11s %-10s %-13s ",
     5         kx 	   ss_proto, refcnt, ss_flags, ss_type, ss_state);
     5         kx     if (has & HAS_INODE)
     5         kx 	printf("%-8lu",inode);
     5         kx     else
     5         kx 	printf("-       ");
     5         kx     if (flag_prg)
     5         kx 	printf(" %-" PROGNAME_WIDTHs "s",(has & HAS_INODE?prg_cache_get(inode):"-"));
     5         kx     if (flag_selinux)
     5         kx 	printf(" %-" SELINUX_WIDTHs "s",(has & HAS_INODE?prg_cache_get_con(inode):"-"));
     5         kx 
     5         kx     printf(" %s\n", path);
     5         kx }
     5         kx 
     5         kx static int unix_info(void)
     5         kx {
     5         kx 
     5         kx     printf(_("Active UNIX domain sockets "));
     5         kx     if (flag_all)
     5         kx 	printf(_("(servers and established)"));
     5         kx     else {
     5         kx       if (flag_lst)
     5         kx 	printf(_("(only servers)"));
     5         kx       else
     5         kx 	printf(_("(w/o servers)"));
     5         kx     }
     5         kx 
     5         kx     printf(_("\nProto RefCnt Flags       Type       State         I-Node  "));
     5         kx     print_progname_banner();
     5         kx     print_selinux_banner();
     5         kx     printf(_(" Path\n"));	/* xxx */
     5         kx 
     5         kx     {
     5         kx 	INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one, "unix");
     5         kx     }
     5         kx }
     5         kx #endif
     5         kx 
     5         kx 
     5         kx #if HAVE_AFAX25
     5         kx static int ax25_info(void)
     5         kx {
     5         kx     FILE *f;
     5         kx     char buffer[256], buf[16];
     5         kx     char *src, *dst, *dev, *p;
     5         kx     int st, vs, vr, sendq, recvq, ret;
     5         kx     int new = -1;		/* flag for new (2.1.x) kernels */
     5         kx     static char *ax25_state[5] =
     5         kx     {
     5         kx 	N_("LISTENING"),
     5         kx 	N_("SABM SENT"),
     5         kx 	N_("DISC SENT"),
     5         kx 	N_("ESTABLISHED"),
     5         kx 	N_("RECOVERY")
     5         kx     };
     5         kx     if (!(f = proc_fopen(_PATH_PROCNET_AX25))) {
     5         kx 	if (errno != ENOENT) {
     5         kx 	    perror(_PATH_PROCNET_AX25);
     5         kx 	    return (-1);
     5         kx 	}
     5         kx 	if (flag_arg || flag_ver)
     5         kx 	    ESYSNOT("netstat", "AF AX25");
     5         kx 	if (flag_arg)
     5         kx 	    return (1);
     5         kx 	else
     5         kx 	    return (0);
     5         kx     }
     5         kx     printf(_("Active AX.25 sockets\n"));
     5         kx     printf(_("Dest       Source     Device  State        Vr/Vs    Send-Q  Recv-Q\n"));
     5         kx     while (fgets(buffer, 256, f)) {
     5         kx 	if (new == -1) {
     5         kx 	    if (!strncmp(buffer, "dest_addr", 9)) {
     5         kx 		new = 0;
     5         kx 		continue;	/* old kernels have a header line */
     5         kx 	    } else
     5         kx 		new = 1;
     5         kx 	}
     5         kx 	/*
     5         kx 	 * In a network connection with no user socket the Snd-Q, Rcv-Q
     5         kx 	 * and Inode fields are empty in 2.0.x and '*' in 2.1.x
     5         kx 	 */
     5         kx 	sendq = 0;
     5         kx 	recvq = 0;
     5         kx 	if (new == 0) {
     5         kx 	    dst = buffer;
     5         kx 	    src = buffer + 10;
     5         kx 	    dst[9] = 0;
     5         kx 	    src[9] = 0;
     5         kx 	    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",
     5         kx 		   buf, &st, &vs, &vr, &sendq, &recvq);
     5         kx 	    if (ret != 4 && ret != 6) {
     5         kx 		printf(_("Problem reading data from %s\n"), _PATH_PROCNET_AX25);
     5         kx 		continue;
     5         kx 	    }
     5         kx 	    dev = buf;
     5         kx 	} else {
     5         kx 	    p = buffer;
     5         kx 	    while (*p != ' ') p++;
     5         kx 	    p++;
     5         kx 	    dev = p;
     5         kx 	    while (*p != ' ') p++;
     5         kx 	    *p++ = 0;
     5         kx 	    src = p;
     5         kx 	    while (*p != ' ') p++;
     5         kx 	    *p++ = 0;
     5         kx 	    dst = p;
     5         kx 	    while (*p != ' ') p++;
     5         kx 	    *p++ = 0;
     5         kx 	    ret = sscanf(p, "%d %d %d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %*d",
     5         kx 		   &st, &vs, &vr, &sendq, &recvq);
     5         kx 	    if (ret != 3 && ret != 5) {
     5         kx 		    printf(_("problem reading data from %s\n"), _PATH_PROCNET_AX25);
     5         kx 		    continue;
     5         kx 	    }
     5         kx 	    /*
     5         kx 	     * FIXME: digipeaters should be handled somehow.
     5         kx 	     * For now we just strip them.
     5         kx 	     */
     5         kx 	    p = dst;
     5         kx 	    while (*p && *p != ',') p++;
     5         kx 	    *p = 0;
     5         kx 	}
     5         kx 	printf("%-9s  %-9s  %-6s  %-11s  %03d/%03d  %-6d  %-6d\n",
     5         kx 	       dst, src,
     5         kx 	       dev,
     5         kx 	       _(ax25_state[st]),
     5         kx 	       vr, vs, sendq, recvq);
     5         kx     }
     5         kx     fclose(f);
     5         kx     return 0;
     5         kx }
     5         kx #endif
     5         kx 
     5         kx 
     5         kx #if HAVE_AFIPX
     5         kx static int ipx_info(void)
     5         kx {
     5         kx     FILE *f;
     5         kx     char buf[256];
     5         kx     unsigned long txq, rxq;
     5         kx     unsigned int state;
     5         kx     unsigned int uid;
     5         kx     char *st;
     5         kx     int nc;
     5         kx     const struct aftype *ap;
     5         kx     struct passwd *pw;
     5         kx     char sad[50], dad[50];
     5         kx     struct sockaddr_storage sa;
     5         kx     unsigned sport = 0, dport = 0;
     5         kx     struct stat s;
     5         kx 
     5         kx     f = proc_fopen(_PATH_PROCNET_IPX_SOCKET1);
     5         kx     if (!f) {
     5         kx         if (errno != ENOENT) {
     5         kx             perror(_PATH_PROCNET_IPX_SOCKET1);
     5         kx             return (-1);
     5         kx         }
     5         kx         f = proc_fopen(_PATH_PROCNET_IPX_SOCKET2);
     5         kx 
     5         kx         /* We need to check for directory */
     5         kx         if (f) {
     5         kx             if (fstat (fileno(f), &s) == -1 ||
     5         kx                 !S_ISREG(s.st_mode)) {
     5         kx                 fclose(f);
     5         kx                 f=NULL;
     5         kx             }
     5         kx         }
     5         kx 
     5         kx         if (!f) {
     5         kx             if (errno != ENOENT) {
     5         kx 	        perror(_PATH_PROCNET_IPX_SOCKET2);
     5         kx 	        return (-1);
     5         kx 	    }
     5         kx 	    if (flag_arg || flag_ver)
     5         kx 	        ESYSNOT("netstat", "AF IPX");
     5         kx 	    if (flag_arg)
     5         kx 	        return (1);
     5         kx  	    else
     5         kx 	        return (0);
     5         kx         }
     5         kx     }
     5         kx     printf(_("Active IPX sockets\nProto Recv-Q Send-Q Local Address              Foreign Address            State"));	/* xxx */
     5         kx     if (flag_exp > 1)
     5         kx 	printf(_(" User"));	/* xxx */
     5         kx     printf("\n");
     5         kx     if ((ap = get_afntype(AF_IPX)) == NULL) {
     5         kx 	EINTERN("netstat.c", "AF_IPX missing");
     5         kx 	fclose(f);
     5         kx 	return (-1);
     5         kx     }
     5         kx     if (fgets(buf, 255, f))
     5         kx 	/* eat line */;
     5         kx 
     5         kx     while (fgets(buf, 255, f) != NULL) {
     5         kx 	sscanf(buf, "%s %s %lX %lX %u %u",
     5         kx 	       sad, dad, &txq, &rxq, &state, &uid);
     5         kx 	if ((st = rindex(sad, ':'))) {
     5         kx 	    *st++ = '\0';
     5         kx 	    sscanf(st, "%X", &sport);	/* net byt order */
     5         kx 	    sport = ntohs(sport);
     5         kx 	} else {
     5         kx 	    EINTERN("netstat.c", "ipx socket format error in source port");
     5         kx 	    fclose(f);
     5         kx 	    return (-1);
     5         kx 	}
     5         kx 	nc = 0;
     5         kx 	if (strcmp(dad, "Not_Connected") != 0) {
     5         kx 	    if ((st = rindex(dad, ':'))) {
     5         kx 		*st++ = '\0';
     5         kx 		sscanf(st, "%X", &dport);	/* net byt order */
     5         kx 		dport = ntohs(dport);
     5         kx 	    } else {
     5         kx 		EINTERN("netstat.c", "ipx socket format error in destination port");
     5         kx 		fclose(f);
     5         kx 		return (-1);
     5         kx 	    }
     5         kx 	} else
     5         kx 	    nc = 1;
     5         kx 
     5         kx 	switch (state) {
     5         kx 	case TCP_ESTABLISHED:
     5         kx 	    st = _("ESTAB");
     5         kx 	    break;
     5         kx 
     5         kx 	case TCP_CLOSE:
     5         kx 	    st = "";
     5         kx 	    break;
     5         kx 
     5         kx 	default:
     5         kx 	    st = _("UNK.");
     5         kx 	    break;
     5         kx 	}
     5         kx 
     5         kx 	/* Fetch and resolve the Source */
     5         kx 	(void) ap->input(0, sad, &sa);
     5         kx 	safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
     5         kx 	snprintf(sad, sizeof(sad), "%s:%04X", buf, sport);
     5         kx 
     5         kx 	if (!nc) {
     5         kx 	    /* Fetch and resolve the Destination */
     5         kx 	    (void) ap->input(0, dad, &sa);
     5         kx 	    safe_strncpy(buf, ap->sprint(&sa, flag_not & FLAG_NUM_HOST), sizeof(buf));
     5         kx 	    snprintf(dad, sizeof(dad), "%s:%04X", buf, dport);
     5         kx 	} else
     5         kx         safe_strncpy(dad, "-", sizeof(dad));
     5         kx 
     5         kx 	printf("IPX   %6ld %6ld %-26s %-26s %-5s", txq, rxq, sad, dad, st);
     5         kx 	if (flag_exp > 1) {
     5         kx 	    if (!(flag_not & FLAG_NUM_USER) && ((pw = getpwuid(uid)) != NULL))
     5         kx 		printf(" %-10s", pw->pw_name);
     5         kx 	    else
     5         kx 		printf(" %-10d", uid);
     5         kx 	}
     5         kx 	printf("\n");
     5         kx     }
     5         kx     fclose(f);
     5         kx     return 0;
     5         kx }
     5         kx #endif
     5         kx 
     5         kx #if HAVE_AFBLUETOOTH
     5         kx const char *bluetooth_state(int state)
     5         kx {
     5         kx     switch (state) {
     5         kx 	case BT_CONNECTED:
     5         kx 	    return _("CONNECTED");
     5         kx 	case BT_OPEN:
     5         kx 	    return _("OPEN");
     5         kx 	case BT_BOUND:
     5         kx 	    return _("BOUND");
     5         kx 	case BT_LISTEN:
     5         kx 	    return _("LISTEN");
     5         kx 	case BT_CONNECT:
     5         kx 	    return _("CONNECT");
     5         kx 	case BT_CONNECT2:
     5         kx 	    return _("CONNECT2");
     5         kx 	case BT_CONFIG:
     5         kx 	    return _("CONFIG");
     5         kx 	case BT_DISCONN:
     5         kx 	    return _("DISCONN");
     5         kx 	case BT_CLOSED:
     5         kx 	    return _("CLOSED");
     5         kx 	default:
     5         kx 	    return _("UNKNOWN");
     5         kx     }
     5         kx }
     5         kx 
     5         kx static void l2cap_do_one(int nr, const char *line, const char *prot)
     5         kx {
     5         kx     char daddr[18], saddr[18];
     5         kx     unsigned dtype, stype, state, psm, dcid, scid, imtu, omtu, sec_level;
     5         kx     int num;
     5         kx     const char *bt_state, *bt_sec_level;
     5         kx 
     5         kx     num = sscanf(line, "%17s (%u) %17s (%u) %d %d 0x%04x 0x%04x %d %d %d",
     5         kx 	daddr, &dtype, saddr, &stype, &state, &psm, &dcid, &scid, &imtu, &omtu, &sec_level);
     5         kx 
     5         kx     if (num != 11) {
     5         kx 	num = sscanf(line, "%17s %17s %d %d 0x%04x 0x%04x %d %d %d",
     5         kx 	    daddr, saddr, &state, &psm, &dcid, &scid, &imtu, &omtu, &sec_level);
     5         kx 
     5         kx 	if (num != 9) {
     5         kx 	    fprintf(stderr, _("warning, got bogus l2cap line.\n"));
     5         kx 	    return;
     5         kx 	}
     5         kx     }
     5         kx 
     5         kx     if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
     5         kx 	return;
     5         kx     if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
     5         kx 	return;
     5         kx 
     5         kx     bt_state = bluetooth_state(state);
     5         kx     switch (sec_level) {
     5         kx 	case BT_SECURITY_SDP:
     5         kx 	    bt_sec_level = _("SDP");
     5         kx 	    break;
     5         kx 	case BT_SECURITY_LOW:
     5         kx 	    bt_sec_level = _("LOW");
     5         kx 	    break;
     5         kx 	case BT_SECURITY_MEDIUM:
     5         kx 	    bt_sec_level = _("MEDIUM");
     5         kx 	    break;
     5         kx 	case BT_SECURITY_HIGH:
     5         kx 	    bt_sec_level = _("HIGH");
     5         kx 	    break;
     5         kx 	default:
     5         kx 	    bt_sec_level = _("UNKNOWN");
     5         kx     }
     5         kx 
     5         kx     printf("l2cap  %-17s %-17s %-9s %7d 0x%04x 0x%04x %7d %7d %-7s\n",
     5         kx 	(strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
     5         kx 	(strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
     5         kx 	bt_state, psm, dcid, scid, imtu, omtu, bt_sec_level);
     5         kx }
     5         kx 
     5         kx static int l2cap_info(void)
     5         kx {
     5         kx     printf("%-6s %-17s %-17s %-9s %7s %-6s %-6s %7s %7s %-7s\n",
     5         kx 	"Proto", "Destination", "Source", "State", "PSM", "DCID", "SCID", "IMTU", "OMTU", "Security");
     5         kx     INFO_GUTS(_PATH_SYS_BLUETOOTH_L2CAP, "BTPROTO L2CAP", l2cap_do_one, "l2cap");
     5         kx }
     5         kx 
     5         kx static void rfcomm_do_one(int nr, const char *line, const char *prot)
     5         kx {
     5         kx     char daddr[18], saddr[18];
     5         kx     unsigned state, channel;
     5         kx     int num;
     5         kx     const char *bt_state;
     5         kx 
     5         kx     num = sscanf(line, "%17s %17s %d %d", daddr, saddr, &state, &channel);
     5         kx     if (num < 4) {
     5         kx 	fprintf(stderr, _("warning, got bogus rfcomm line.\n"));
     5         kx 	return;
     5         kx     }
     5         kx 
     5         kx     if (flag_lst && !(state == BT_LISTEN || state == BT_BOUND))
     5         kx 	return;
     5         kx     if (!(flag_all || flag_lst) && (state == BT_LISTEN || state == BT_BOUND))
     5         kx 	return;
     5         kx 
     5         kx     bt_state = bluetooth_state(state);
     5         kx     printf("rfcomm %-17s %-17s %-9s %7d\n",
     5         kx 	(strcmp (daddr, "00:00:00:00:00:00") == 0 ? "*" : daddr),
     5         kx 	(strcmp (saddr, "00:00:00:00:00:00") == 0 ? "*" : saddr),
     5         kx 	bt_state, channel);
     5         kx }
     5         kx 
     5         kx static int rfcomm_info(void)
     5         kx {
     5         kx     printf("%-6s %-17s %-17s %-9s %7s\n", "Proto", "Destination", "Source", "State", "Channel");
     5         kx     INFO_GUTS(_PATH_SYS_BLUETOOTH_RFCOMM, "BTPROTO RFCOMM", rfcomm_do_one, "rfcomm");
     5         kx }
     5         kx #endif
     5         kx 
     5         kx static int iface_info(void)
     5         kx {
     5         kx     if (skfd < 0) {
     5         kx 	if ((skfd = sockets_open(0)) < 0) {
     5         kx 	    perror("socket");
     5         kx 	    exit(1);
     5         kx 	}
     5         kx 	printf(_("Kernel Interface table\n"));
     5         kx     }
     5         kx     if (flag_exp < 2) {
     5         kx 	ife_short = 1;
     5         kx 	printf(_("Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
     5         kx     }
     5         kx 
     5         kx     if (for_all_interfaces(do_if_print, &flag_all) < 0) {
     5         kx 	perror(_("missing interface information"));
     5         kx 	exit(1);
     5         kx     }
     5         kx     if (flag_cnt)
     5         kx 	if_cache_free();
     5         kx     else {
     5         kx 	close(skfd);
     5         kx 	skfd = -1;
     5         kx     }
     5         kx 
     5         kx     return 0;
     5         kx }
     5         kx 
     5         kx 
     5         kx static void version(void)
     5         kx {
     5         kx     printf("%s\n%s\n%s\n", Release, Signature, Features);
     5         kx     exit(E_VERSION);
     5         kx }
     5         kx 
     5         kx 
     5         kx static void usage(int rc)
     5         kx {
     5         kx     FILE *fp = rc ? stderr : stdout;
     5         kx     fprintf(fp, _("usage: netstat [-vWeenNcCF] [<Af>] -r         netstat {-V|--version|-h|--help}\n"));
     5         kx     fprintf(fp, _("       netstat [-vWnNcaeol] [<Socket> ...]\n"));
     5         kx     fprintf(fp, _("       netstat { [-vWeenNac] -i | [-cnNe] -M | -s [-6tuw] }\n\n"));
     5         kx 
     5         kx     fprintf(fp, _("        -r, --route              display routing table\n"));
     5         kx     fprintf(fp, _("        -i, --interfaces         display interface table\n"));
     5         kx     fprintf(fp, _("        -g, --groups             display multicast group memberships\n"));
     5         kx     fprintf(fp, _("        -s, --statistics         display networking statistics (like SNMP)\n"));
     5         kx #if HAVE_FW_MASQUERADE
     5         kx     fprintf(fp, _("        -M, --masquerade         display masqueraded connections\n\n"));
     5         kx #endif
     5         kx 
     5         kx     fprintf(fp, _("        -v, --verbose            be verbose\n"));
     5         kx     fprintf(fp, _("        -W, --wide               don't truncate IP addresses\n"));
     5         kx     fprintf(fp, _("        -n, --numeric            don't resolve names\n"));
     5         kx     fprintf(fp, _("        --numeric-hosts          don't resolve host names\n"));
     5         kx     fprintf(fp, _("        --numeric-ports          don't resolve port names\n"));
     5         kx     fprintf(fp, _("        --numeric-users          don't resolve user names\n"));
     5         kx     fprintf(fp, _("        -N, --symbolic           resolve hardware names\n"));
     5         kx     fprintf(fp, _("        -e, --extend             display other/more information\n"));
     5         kx     fprintf(fp, _("        -p, --programs           display PID/Program name for sockets\n"));
     5         kx     fprintf(fp, _("        -o, --timers             display timers\n"));
     5         kx     fprintf(fp, _("        -c, --continuous         continuous listing\n\n"));
     5         kx     fprintf(fp, _("        -l, --listening          display listening server sockets\n"));
     5         kx     fprintf(fp, _("        -a, --all                display all sockets (default: connected)\n"));
     5         kx     fprintf(fp, _("        -F, --fib                display Forwarding Information Base (default)\n"));
     5         kx     fprintf(fp, _("        -C, --cache              display routing cache instead of FIB\n"));
     5         kx #if HAVE_SELINUX
     5         kx     fprintf(fp, _("        -Z, --context            display SELinux security context for sockets\n"));
     5         kx #endif
     5         kx 
     5         kx     fprintf(fp, _("\n  <Socket>={-t|--tcp} {-u|--udp} {-U|--udplite} {-S|--sctp} {-w|--raw}\n"));
     5         kx     fprintf(fp, _("           {-x|--unix} --ax25 --ipx --netrom\n"));
     5         kx     fprintf(fp, _("  <AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
     5         kx     fprintf(fp, _("  List of possible address families (which support routing):\n"));
     5         kx     print_aflist(1); /* 1 = routeable */
     5         kx     exit(rc);
     5         kx }
     5         kx 
     5         kx 
     5         kx int main
     5         kx  (int argc, char *argv[]) {
     5         kx     int i;
     5         kx     int lop;
     5         kx     static struct option longopts[] =
     5         kx     {
     5         kx 	AFTRANS_OPTS,
     5         kx 	{"version", 0, 0, 'V'},
     5         kx 	{"interfaces", 0, 0, 'i'},
     5         kx 	{"help", 0, 0, 'h'},
     5         kx 	{"route", 0, 0, 'r'},
     5         kx #if HAVE_FW_MASQUERADE
     5         kx 	{"masquerade", 0, 0, 'M'},
     5         kx #endif
     5         kx 	{"protocol", 1, 0, 'A'},
     5         kx 	{"tcp", 0, 0, 't'},
     5         kx 	{"sctp", 0, 0, 'S'},
     5         kx 	{"udp", 0, 0, 'u'},
     5         kx         {"udplite", 0, 0, 'U'},
     5         kx 	{"raw", 0, 0, 'w'},
     5         kx 	{"unix", 0, 0, 'x'},
     5         kx 	{"l2cap", 0, 0, '2'},
     5         kx 	{"rfcomm", 0, 0, 'f'},
     5         kx 	{"listening", 0, 0, 'l'},
     5         kx 	{"all", 0, 0, 'a'},
     5         kx 	{"timers", 0, 0, 'o'},
     5         kx 	{"continuous", 0, 0, 'c'},
     5         kx 	{"extend", 0, 0, 'e'},
     5         kx 	{"programs", 0, 0, 'p'},
     5         kx 	{"verbose", 0, 0, 'v'},
     5         kx 	{"statistics", 0, 0, 's'},
     5         kx 	{"wide", 0, 0, 'W'},
     5         kx 	{"numeric", 0, 0, 'n'},
     5         kx 	{"numeric-hosts", 0, 0, '!'},
     5         kx 	{"numeric-ports", 0, 0, '@'},
     5         kx 	{"numeric-users", 0, 0, '#'},
     5         kx 	{"symbolic", 0, 0, 'N'},
     5         kx 	{"cache", 0, 0, 'C'},
     5         kx 	{"fib", 0, 0, 'F'},
     5         kx 	{"groups", 0, 0, 'g'},
     5         kx 	{"context", 0, 0, 'Z'},
     5         kx 	{NULL, 0, 0, 0}
     5         kx     };
     5         kx 
     5         kx #if I18N
     5         kx     setlocale (LC_ALL, "");
     5         kx     bindtextdomain("net-tools", "/usr/share/locale");
     5         kx     textdomain("net-tools");
     5         kx #endif
     5         kx     getroute_init();		/* Set up AF routing support */
     5         kx 
     5         kx     afname[0] = '\0';
     5         kx     while ((i = getopt_long(argc, argv, "A:CFMacdeghilnNoprsStuUvVWw2fx64?Z", longopts, &lop)) != EOF)
     5         kx 	switch (i) {
     5         kx 	case -1:
     5         kx 	    break;
     5         kx 	case 1:
     5         kx 	    if (lop < 0 || lop >= AFTRANS_CNT) {
     5         kx 		EINTERN("netstat.c", "longopts 1 range");
     5         kx 		break;
     5         kx 	    }
     5         kx 	    if (aftrans_opt(longopts[lop].name))
     5         kx 		exit(1);
     5         kx 	    break;
     5         kx 	case 'A':
     5         kx 	    if (aftrans_opt(optarg))
     5         kx 		exit(1);
     5         kx 	    break;
     5         kx 	case 'M':
     5         kx 	    flag_mas++;
     5         kx 	    break;
     5         kx 	case 'a':
     5         kx 	    flag_all++;
     5         kx 	    break;
     5         kx 	case 'l':
     5         kx 	    flag_lst++;
     5         kx 	    break;
     5         kx 	case 'c':
     5         kx 	    flag_cnt++;
     5         kx 	    break;
     5         kx 
     5         kx 	case 'd':
     5         kx 	    flag_deb++;
     5         kx 	    break;
     5         kx 	case 'g':
     5         kx 	    flag_igmp++;
     5         kx 	    break;
     5         kx 	case 'e':
     5         kx 	    flag_exp++;
     5         kx 	    break;
     5         kx 	case 'p':
     5         kx 	    flag_prg++;
     5         kx 	    break;
     5         kx 	case 'i':
     5         kx 	    flag_int++;
     5         kx 	    break;
     5         kx 	case 'W':
     5         kx 	    flag_wide++;
     5         kx 	    break;
     5         kx 	case 'n':
     5         kx 	    flag_not |= FLAG_NUM;
     5         kx 	    break;
     5         kx 	case '!':
     5         kx 	    flag_not |= FLAG_NUM_HOST;
     5         kx 	    break;
     5         kx 	case '@':
     5         kx 	    flag_not |= FLAG_NUM_PORT;
     5         kx 	    break;
     5         kx 	case '#':
     5         kx 	    flag_not |= FLAG_NUM_USER;
     5         kx 	    break;
     5         kx 	case 'N':
     5         kx 	    flag_not |= FLAG_SYM;
     5         kx 	    break;
     5         kx 	case 'C':
     5         kx 	    flag_cf |= FLAG_CACHE;
     5         kx 	    break;
     5         kx 	case 'F':
     5         kx 	    flag_cf |= FLAG_FIB;
     5         kx 	    break;
     5         kx 	case 'o':
     5         kx 	    flag_opt++;
     5         kx 	    break;
     5         kx 	case '6':
     5         kx 	    if (aftrans_opt("inet6"))
     5         kx 		exit(1);
     5         kx 	    break;
     5         kx 	case '4':
     5         kx 	    if (aftrans_opt("inet"))
     5         kx 		exit(1);
     5         kx 	    break;
     5         kx 	case 'V':
     5         kx 	    version();
     5         kx 	    /*NOTREACHED */
     5         kx 	case 'v':
     5         kx 	    flag_ver |= FLAG_VERBOSE;
     5         kx 	    break;
     5         kx 	case 'r':
     5         kx 	    flag_rou++;
     5         kx 	    break;
     5         kx 	case 't':
     5         kx 	    flag_tcp++;
     5         kx 	    break;
     5         kx 	case 'S':
     5         kx 	    flag_sctp++;
     5         kx 	    break;
     5         kx 	case 'u':
     5         kx 	    flag_udp++;
     5         kx 	    break;
     5         kx         case 'U':
     5         kx 	    flag_udplite++;
     5         kx 	    break;
     5         kx 	case 'w':
     5         kx 	    flag_raw++;
     5         kx 	    break;
     5         kx         case '2':
     5         kx 	    flag_l2cap++;
     5         kx 	    break;
     5         kx         case 'f':
     5         kx 	    flag_rfcomm++;
     5         kx 	    break;
     5         kx 	case 'x':
     5         kx 	    if (aftrans_opt("unix"))
     5         kx 		exit(1);
     5         kx 	    break;
     5         kx 	case 'Z':
     5         kx #if HAVE_SELINUX
     5         kx 	    if (is_selinux_enabled() <= 0) {
     5         kx 		fprintf(stderr, _("SELinux is not enabled on this machine.\n"));
     5         kx 		exit(1);
     5         kx 	    }
     5         kx 	    flag_prg++;
     5         kx 	    flag_selinux++;
     5         kx #else
     5         kx             fprintf(stderr, _("SELinux is not enabled for this application.\n"));
     5         kx 	    exit(1);
     5         kx #endif
     5         kx 
     5         kx 	    break;
     5         kx 	case '?':
     5         kx 	    usage(E_OPTERR);
     5         kx 	case 'h':
     5         kx 	    usage(E_USAGE);
     5         kx 	case 's':
     5         kx 	    flag_sta++;
     5         kx 	}
     5         kx 
     5         kx     if (flag_int + flag_rou + flag_mas + flag_sta > 1)
     5         kx 	usage(E_OPTERR);
     5         kx 
     5         kx     if ((flag_inet || flag_inet6 || flag_sta) &&
     5         kx         !(flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw))
     5         kx 	   flag_noprot = flag_tcp = flag_sctp = flag_udp = flag_udplite = flag_raw = 1;
     5         kx 
     5         kx     if ((flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw || flag_igmp) &&
     5         kx         !(flag_inet || flag_inet6))
     5         kx         flag_inet = flag_inet6 = 1;
     5         kx 
     5         kx     if (flag_bluetooth && !(flag_l2cap || flag_rfcomm))
     5         kx 	   flag_l2cap = flag_rfcomm = 1;
     5         kx 
     5         kx     flag_arg = flag_tcp + flag_sctp + flag_udplite + flag_udp + flag_raw + flag_unx
     5         kx         + flag_ipx + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose
     5         kx 	+ flag_l2cap + flag_rfcomm;
     5         kx 
     5         kx     if (flag_mas) {
     5         kx #if HAVE_FW_MASQUERADE && HAVE_AFINET
     5         kx #if MORE_THAN_ONE_MASQ_AF
     5         kx 	if (!afname[0])
     5         kx         safe_strncpy(afname, DFLT_AF, sizeof(afname));
     5         kx #endif
     5         kx 	for (;;) {
     5         kx 	    i = ip_masq_info(flag_not & FLAG_NUM_HOST,
     5         kx 			     flag_not & FLAG_NUM_PORT, flag_exp);
     5         kx 	    if (i || !flag_cnt)
     5         kx 		break;
     5         kx 	    wait_continous();
     5         kx 	}
     5         kx #else
     5         kx 	ENOSUPP("netstat", "FW_MASQUERADE");
     5         kx 	i = -1;
     5         kx #endif
     5         kx 	return (i);
     5         kx     }
     5         kx 
     5         kx     if (flag_sta) {
     5         kx         if (!afname[0])
     5         kx             safe_strncpy(afname, DFLT_AF, sizeof(afname));
     5         kx 
     5         kx         if (!strcmp(afname, "inet")) {
     5         kx #if HAVE_AFINET
     5         kx             parsesnmp(flag_raw, flag_tcp, flag_udp, flag_sctp);
     5         kx #else
     5         kx             ENOSUPP("netstat", "AF INET");
     5         kx             exit(1);
     5         kx #endif
     5         kx         } else if(!strcmp(afname, "inet6")) {
     5         kx #if HAVE_AFINET6
     5         kx             parsesnmp6(flag_raw, flag_tcp, flag_udp);
     5         kx #else
     5         kx             ENOSUPP("netstat", "AF INET6");
     5         kx             exit(1);
     5         kx #endif
     5         kx         } else {
     5         kx           printf(_("netstat: No statistics support for specified address family: %s\n"), afname);
     5         kx           exit(1);
     5         kx         }
     5         kx         exit(0);
     5         kx     }
     5         kx 
     5         kx     if (flag_rou) {
     5         kx 	int options = 0;
     5         kx 
     5         kx 	if (!afname[0])
     5         kx         safe_strncpy(afname, DFLT_AF, sizeof(afname));
     5         kx 
     5         kx 	if (flag_exp == 2)
     5         kx 	    flag_exp = 1;
     5         kx 	else if (flag_exp == 1)
     5         kx 	    flag_exp = 2;
     5         kx 
     5         kx 	options = (flag_exp & FLAG_EXT) | flag_not | flag_cf | flag_ver;
     5         kx 	if (!flag_cf)
     5         kx 	    options |= FLAG_FIB;
     5         kx 
     5         kx 	for (;;) {
     5         kx 	    i = route_info(afname, options);
     5         kx 	    if (i || !flag_cnt)
     5         kx 		break;
     5         kx             wait_continous();
     5         kx 	}
     5         kx 	return (i);
     5         kx     }
     5         kx     if (flag_int) {
     5         kx 	for (;;) {
     5         kx 	    i = iface_info();
     5         kx 	    if (!flag_cnt || i)
     5         kx 		break;
     5         kx             wait_continous();
     5         kx 	}
     5         kx 	return (i);
     5         kx     }
     5         kx     for (;;) {
     5         kx 	if (!flag_arg || flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw) {
     5         kx #if HAVE_AFINET
     5         kx 	    prg_cache_load();
     5         kx 	    printf(_("Active Internet connections "));	/* xxx */
     5         kx 
     5         kx 	    if (flag_all)
     5         kx 		printf(_("(servers and established)"));
     5         kx 	    else {
     5         kx 	      if (flag_lst)
     5         kx 		printf(_("(only servers)"));
     5         kx 	      else
     5         kx 		printf(_("(w/o servers)"));
     5         kx 	    }
     5         kx 	    printf(_("\nProto Recv-Q Send-Q Local Address           Foreign Address         State      "));	/* xxx */
     5         kx 	    if (flag_exp > 1)
     5         kx 		printf(_(" User       Inode     "));
     5         kx 	    print_progname_banner();
     5         kx 	    print_selinux_banner();
     5         kx 	    if (flag_opt)
     5         kx 		printf(_(" Timer"));	/* xxx */
     5         kx 	    printf("\n");
     5         kx #else
     5         kx 	    if (flag_arg) {
     5         kx 		i = 1;
     5         kx 		ENOSUPP("netstat", "AF INET");
     5         kx 	    }
     5         kx #endif
     5         kx 	}
     5         kx #if HAVE_AFINET
     5         kx 	if (!flag_arg || flag_tcp) {
     5         kx 	    i = tcp_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx 	}
     5         kx 
     5         kx 	if (!flag_arg || flag_sctp) {
     5         kx 	    i = sctp_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx 	}
     5         kx 
     5         kx 	if (!flag_arg || flag_udp) {
     5         kx 	    i = udp_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx 	}
     5         kx 
     5         kx 	if (!flag_arg || flag_udplite) {
     5         kx 	    i = udplite_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx 	}
     5         kx 
     5         kx 	if (!flag_arg || flag_raw) {
     5         kx 	    i = raw_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx 	}
     5         kx 
     5         kx 	if (flag_igmp) {
     5         kx #if HAVE_AFINET6
     5         kx 	    printf( "IPv6/");
     5         kx #endif
     5         kx 	    printf( _("IPv4 Group Memberships\n") );
     5         kx 	    printf( _("Interface       RefCnt Group\n") );
     5         kx 	    printf( "--------------- ------ ---------------------\n" );
     5         kx 	    i = igmp_info();
     5         kx 	    if (i)
     5         kx 	        return (i);
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx 	if (!flag_arg || flag_unx) {
     5         kx #if HAVE_AFUNIX
     5         kx 	    prg_cache_load();
     5         kx 	    i = unix_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx #else
     5         kx 	    if (flag_arg) {
     5         kx 		i = 1;
     5         kx 		ENOSUPP("netstat", "AF UNIX");
     5         kx 	    }
     5         kx #endif
     5         kx 	}
     5         kx 	if (!flag_arg || flag_ipx) {
     5         kx #if HAVE_AFIPX
     5         kx 	    i = ipx_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx #else
     5         kx 	    if (flag_arg) {
     5         kx 		i = 1;
     5         kx 		ENOSUPP("netstat", "AF IPX");
     5         kx 	    }
     5         kx #endif
     5         kx 	}
     5         kx 	if (!flag_arg || flag_ax25) {
     5         kx #if HAVE_AFAX25
     5         kx 	    i = ax25_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx #else
     5         kx 	    if (flag_arg) {
     5         kx 		i = 1;
     5         kx 		ENOSUPP("netstat", "AF AX25");
     5         kx 	    }
     5         kx #endif
     5         kx 	}
     5         kx 	if(!flag_arg || flag_x25) {
     5         kx #if HAVE_AFX25
     5         kx 	    /* FIXME */
     5         kx 	    i = x25_info();
     5         kx 	    if (i)
     5         kx 		return(i);
     5         kx #else
     5         kx 	    if (flag_arg) {
     5         kx 		i = 1;
     5         kx 		ENOSUPP("netstat", "AF X25");
     5         kx 	    }
     5         kx #endif
     5         kx 	}
     5         kx 	if (!flag_arg || flag_netrom) {
     5         kx #if HAVE_AFNETROM
     5         kx 	    i = netrom_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx #else
     5         kx 	    if (flag_arg) {
     5         kx 		i = 1;
     5         kx 		ENOSUPP("netstat", "AF NETROM");
     5         kx 	    }
     5         kx #endif
     5         kx 	}
     5         kx 	if (!flag_arg || flag_rose) {
     5         kx #if HAVE_AFROSE
     5         kx           i = rose_info();
     5         kx           if (i)
     5         kx             return (i);
     5         kx #else
     5         kx           if (flag_arg) {
     5         kx             i = 1;
     5         kx             ENOSUPP("netstat", "AF ROSE");
     5         kx           }
     5         kx #endif
     5         kx         }
     5         kx 
     5         kx 	if (!flag_arg || flag_l2cap || flag_rfcomm) {
     5         kx #if HAVE_AFBLUETOOTH
     5         kx 	    printf(_("Active Bluetooth connections "));	/* xxx */
     5         kx 
     5         kx 	    if (flag_all)
     5         kx 		printf(_("(servers and established)"));
     5         kx 	    else {
     5         kx 	      if (flag_lst)
     5         kx 		printf(_("(only servers)"));
     5         kx 	      else
     5         kx 		printf(_("(w/o servers)"));
     5         kx 	    }
     5         kx 	    printf("\n");
     5         kx #else
     5         kx 	    if (flag_arg) {
     5         kx 		i = 1;
     5         kx 		ENOSUPP("netstat", "AF BLUETOOTH");
     5         kx 	    }
     5         kx #endif
     5         kx 	}
     5         kx #if HAVE_AFBLUETOOTH
     5         kx 	if (!flag_arg || flag_l2cap) {
     5         kx 	    i = l2cap_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx 	}
     5         kx 	if (!flag_arg || flag_rfcomm) {
     5         kx 	    i = rfcomm_info();
     5         kx 	    if (i)
     5         kx 		return (i);
     5         kx 	}
     5         kx #endif
     5         kx 
     5         kx 	if (!flag_cnt || i)
     5         kx 	    break;
     5         kx         wait_continous();
     5         kx 	prg_cache_clear();
     5         kx     }
     5         kx     return (i);
     5         kx }