/*
* netstat This file contains an implementation of the command
* that helps in debugging the networking modules.
*
* NET-TOOLS A collection of programs that form the base set of the
* NET-3 Networking Distribution for the LINUX operating
* system.
*
* Version: $Id: netstat.c,v 1.73 2011-04-20 01:35:22 ecki Exp $
*
* Authors: Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
* Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Phil Packer, <pep@wicked.demon.co.uk>
* Johannes Stille, <johannes@titan.os.open.de>
* Bernd Eckenfels, <net-tools@lina.inka.de>
* Phil Blundell <philb@gnu.org>
* Tuan Hoang <tqhoang@bigfoot.com>
*
* Tuned for NET3 by:
* Alan Cox, <A.Cox@swansea.ac.uk>
* Copyright (c) 1993 Fred Baumgarten
*
* Modified:
*
*960116 {1.01} Bernd Eckenfels: verbose, cleanups
*960204 {1.10} Bernd Eckenfels: aftrans, usage, new route_info,
* DLFT_AF
*960204 {1.11} Bernd Eckenfels: netlink support
*960204 {1.12} Bernd Eckenfels: route_init()
*960215 {1.13} Bernd Eckenfels: netlink_print honors HAVE_
*960217 {1.14} Bernd Eckenfels: masq_info from Jos Vos and
* ax25_info from Jonathan Naylor.
*960218 {1.15} Bernd Eckenfels: ipx_info rewritten, -e for tcp/ipx
*960220 {1.16} Bernd Eckenfels: minor output reformats, -a for -x
*960221 {1.17} Bernd Eckenfels: route_init->getroute_init
*960426 {1.18} Bernd Eckenfels: new RTACTION, SYM/NUM, FIB/CACHE
*960517 {1.19} Bernd Eckenfels: usage() spelling fix and --unix inode,
* ':' is part of sock_addr for --inet
*960822 {x.xx} Frank Strauss: INET6 support
*
*970406 {1.33} Philip Copeland Added snmp reporting support module -s
* code provided by Andi Kleen
* (relly needs to be kernel hooked but
* this will do in the meantime)
* minor header file misplacement tidy up.
*980815 {1.xx} Stephane Fillod: X.25 support
*980411 {1.34} Arnaldo Carvalho i18n: catgets -> gnu gettext, substitution
* of sprintf for snprintf
*10/1998 Andi Kleen Use new interface primitives.
*990101 {1.36} Bernd Eckenfels usage updated to include -s and -C -F,
* fixed netstat -rC output (lib/inet_gr.c)
* removed broken NETLINK Support
* fixed format for /proc/net/udp|tcp|raw
* added -w,-t,-u TcpExt support to -s
*990131 {1.37} Jan Kratochvil added -p for prg_cache() & friends
* Flames to <short@ucw.cz>.
* Tuan Hoang added IGMP support for IPv4 and IPv6
*
*990420 {1.38} Tuan Hoang removed a useless assignment from igmp_do_one()
*20010404 {1.39} Arnaldo Carvalho de Melo - use setlocale
*20081201 {1.42} Brian Micek added -L|--udplite options for RFC 3828
*20020722 {1.51} Thomas Preusser added SCTP over IPv4 support
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at
* your option) any later version.
*
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <netdb.h>
#include <paths.h>
#include <pwd.h>
#include <getopt.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <net/if.h>
#include <dirent.h>
#include "net-support.h"
#include "pathnames.h"
#include "config.h"
#include "intl.h"
#include "sockets.h"
#include "interface.h"
#include "util.h"
#include "proc.h"
#if HAVE_SELINUX
#include <selinux/selinux.h>
#endif
#if HAVE_AFBLUETOOTH
#include <bluetooth/bluetooth.h>
#endif
#define PROGNAME_WIDTH 20
#define SELINUX_WIDTH 50
#if !defined(s6_addr32) && defined(in6a_words)
#define s6_addr32 in6a_words /* libinet6 */
#endif
/* prototypes for statistics.c */
void parsesnmp(int, int, int, int);
void parsesnmp6(int, int, int);
typedef enum {
SS_FREE = 0, /* not allocated */
SS_UNCONNECTED, /* unconnected to any socket */
SS_CONNECTING, /* in process of connecting */
SS_CONNECTED, /* connected to socket */
SS_DISCONNECTING /* in process of disconnecting */
} socket_state;
#define SO_ACCEPTCON (1<<16) /* performed a listen */
#define SO_WAITDATA (1<<17) /* wait data to read */
#define SO_NOSPACE (1<<18) /* no space to write */
#define DFLT_AF "inet"
#define FEATURE_NETSTAT
#include "net-features.h"
static char *Release = "3.0", *Signature = "Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang, Brian Micek and others";
#define E_READ -1
#define E_IOCTL -3
int flag_int = 0;
int flag_rou = 0;
int flag_mas = 0;
int flag_sta = 0;
int flag_all = 0;
int flag_lst = 0;
int flag_cnt = 0;
int flag_deb = 0;
int flag_not = 0;
int flag_cf = 0;
int flag_opt = 0;
int flag_raw = 0;
int flag_tcp = 0;
int flag_sctp= 0;
int flag_udp = 0;
int flag_udplite = 0;
int flag_igmp= 0;
int flag_rom = 0;
int flag_exp = 1;
int flag_wide= 0;
int flag_prg = 0;
int flag_arg = 0;
int flag_noprot = 0;
int flag_ver = 0;
int flag_l2cap = 0;
int flag_rfcomm = 0;
int flag_selinux = 0;
FILE *procinfo;
#define INFO_GUTS1(file,name,proc,prot) \
procinfo = proc_fopen((file)); \
if (procinfo == NULL) { \
if (errno != ENOENT && errno != EACCES) { \
perror((file)); \
return -1; \
} \
if (!flag_noprot && (flag_arg || flag_ver)) \
ESYSNOT("netstat", (name)); \
if (!flag_noprot && flag_arg) \
rc = 1; \
} else { \
do { \
if (fgets(buffer, sizeof(buffer), procinfo)) \
(proc)(lnr++, buffer,prot); \
} while (!feof(procinfo)); \
fclose(procinfo); \
}
#if HAVE_AFINET6
#define INFO_GUTS2(file,proc,prot) \
lnr = 0; \
procinfo = proc_fopen((file)); \
if (procinfo != NULL) { \
do { \
if (fgets(buffer, sizeof(buffer), procinfo)) \
(proc)(lnr++, buffer,prot); \
} while (!feof(procinfo)); \
fclose(procinfo); \
}
#else
#define INFO_GUTS2(file,proc,prot)
#endif
#define INFO_GUTS3 \
return rc;
#define INFO_GUTS6(file,file6,name,proc,prot4,prot6) \
char buffer[8192]; \
int rc = 0; \
int lnr = 0; \
if (!flag_arg || flag_inet) { \
INFO_GUTS1(file,name,proc,prot4) \
} \
if (!flag_arg || flag_inet6) { \
INFO_GUTS2(file6,proc,prot6) \
} \
INFO_GUTS3
#define INFO_GUTS(file,name,proc,prot) \
char buffer[8192]; \
int rc = 0; \
int lnr = 0; \
INFO_GUTS1(file,name,proc,prot) \
INFO_GUTS3
#define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
#define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)
#define PROGNAME_WIDTH2(s) #s
#define SELINUX_WIDTHs SELINUX_WIDTH1(SELINUX_WIDTH)
#define SELINUX_WIDTH1(s) SELINUX_WIDTH2(s)
#define SELINUX_WIDTH2(s) #s
#define PRG_HASH_SIZE 211
static struct prg_node {
struct prg_node *next;
unsigned long inode;
char name[PROGNAME_WIDTH];
char scon[SELINUX_WIDTH];
} *prg_hash[PRG_HASH_SIZE];
static char prg_cache_loaded = 0;
#define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE)
#define PROGNAME_BANNER "PID/Program name"
#define SELINUX_BANNER "Security Context"
#define print_progname_banner() do { if (f