⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netstat.c

📁 Linux下网络相关工具源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * 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.27 1999/04/20 14:28:14 philip 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. *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() * *              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 <netinet/in.h>#include <sys/ioctl.h>#include <net/if.h>#include <dirent.h>#include "net-support.h"#include "pathnames.h"#include "version.h"#include "config.h"#include "intl.h"#include "sockets.h"#include "interface.h"#define PROGNAME_WIDTH 20#if !defined(s6_addr32) && defined(in6a_words)#define s6_addr32 in6a_words	/* libinet6			*/#endif/* prototypes for statistics.c */void parsesnmp(int, int, int);void inittab(void);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 "lib/net-features.h"char *Release = RELEASE, *Version = "netstat 1.38 (1999-04-20)", *Signature = "Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang and others";#define E_READ  -1#define E_IOCTL -3int 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_udp = 0;int flag_igmp= 0;int flag_rom = 0;int flag_exp = 1;int flag_prg = 0;int flag_arg = 0;int flag_ver = 0;FILE *procinfo;#define INFO_GUTS1(file,name,proc)			\  procinfo = fopen((file), "r");			\  if (procinfo == NULL) {				\    if (errno != ENOENT) {				\      perror((file));					\      return -1;					\    }							\    if (flag_arg || flag_ver)				\      ESYSNOT("netstat", (name));			\    if (flag_arg)					\      rc = 1;						\  } else {						\    do {						\      if (fgets(buffer, sizeof(buffer), procinfo))	\        (proc)(lnr++, buffer);				\    } while (!feof(procinfo));				\    fclose(procinfo);					\  }#if HAVE_AFINET6#define INFO_GUTS2(file,proc)				\  lnr = 0;						\  procinfo = fopen((file), "r");		       	\  if (procinfo != NULL) {				\    do {						\      if (fgets(buffer, sizeof(buffer), procinfo))	\	(proc)(lnr++, buffer);				\    } while (!feof(procinfo));				\    fclose(procinfo);					\  }#else#define INFO_GUTS2(file,proc)#endif#define INFO_GUTS3					\ return rc;#define INFO_GUTS6(file,file6,name,proc)		\ char buffer[8192];					\ int rc = 0;						\ int lnr = 0;						\ if (!flag_arg || flag_inet) {				\    INFO_GUTS1(file,name,proc)				\ }							\ if (!flag_arg || flag_inet6) {				\    INFO_GUTS2(file6,proc)				\ }							\ INFO_GUTS3#define INFO_GUTS(file,name,proc)			\ char buffer[8192];					\ int rc = 0;						\ int lnr = 0;						\ INFO_GUTS1(file,name,proc)				\ INFO_GUTS3#define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)#define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s)#define PROGNAME_WIDTH2(s) #s#define PRG_HASH_SIZE 211static struct prg_node {    struct prg_node *next;    int inode;    char name[PROGNAME_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 print_progname_banner() do { if (flag_prg) printf("%-" PROGNAME_WIDTHs "s"," " PROGNAME_BANNER); } while (0)#define PRG_LOCAL_ADDRESS "local_address"#define PRG_INODE	 "inode"#define PRG_SOCKET_PFX    "socket:["#define PRG_SOCKET_PFXl (strlen(PRG_SOCKET_PFX))#ifndef LINE_MAX#define LINE_MAX 4096#endif#define PATH_PROC	   "/proc"#define PATH_FD_SUFF	"fd"#define PATH_FD_SUFFl       strlen(PATH_FD_SUFF)#define PATH_PROC_X_FD      PATH_PROC "/%s/" PATH_FD_SUFF#define PATH_CMDLINE	"cmdline"#define PATH_CMDLINEl       strlen(PATH_CMDLINE)/* NOT working as of glibc-2.0.7: */#undef  DIRENT_HAVE_D_TYPE_WORKSstatic void prg_cache_add(int inode, char *name){    unsigned hi = PRG_HASHIT(inode);    struct prg_node **pnp,*pn;    prg_cache_loaded=2;    for (pnp=prg_hash+hi;(pn=*pnp);pnp=&pn->next) {	if (pn->inode==inode) {	    /* Some warning should be appropriate here	       as we got multiple processes for one i-node */	    return;	}    }    if (!(*pnp=malloc(sizeof(**pnp)))) 	return;    pn=*pnp;    pn->next=NULL;    pn->inode=inode;    if (strlen(name)>sizeof(pn->name)-1) 	name[sizeof(pn->name)-1]='\0';    strcpy(pn->name,name);}static const char *prg_cache_get(int inode){    unsigned hi=PRG_HASHIT(inode);    struct prg_node *pn;    for (pn=prg_hash[hi];pn;pn=pn->next)	if (pn->inode==inode) return(pn->name);    return("-");}static void prg_cache_clear(void){    struct prg_node **pnp,*pn;    if (prg_cache_loaded == 2)	for (pnp=prg_hash;pnp<prg_hash+PRG_HASH_SIZE;pnp++)	    while ((pn=*pnp)) {		*pnp=pn->next;		free(pn);	    }    prg_cache_loaded=0;}static void prg_cache_load(void){    char line[LINE_MAX],*serr,eacces=0;    int procfdlen,fd,cmdllen,lnamelen;    char lname[30],cmdlbuf[512],finbuf[PROGNAME_WIDTH];    long inode;    const char *cs,*cmdlp;    DIR *dirproc=NULL,*dirfd=NULL;    struct dirent *direproc,*direfd;    if (prg_cache_loaded || !flag_prg) return;    prg_cache_loaded=1;    cmdlbuf[sizeof(cmdlbuf)-1]='\0';    if (!(dirproc=opendir(PATH_PROC))) goto fail;    while (errno=0,direproc=readdir(dirproc)) {#ifdef DIRENT_HAVE_D_TYPE_WORKS	if (direproc->d_type!=DT_DIR) continue;#endif	for (cs=direproc->d_name;*cs;cs++)	    if (!isdigit(*cs)) 		break;	if (*cs) 	    continue;	procfdlen=snprintf(line,sizeof(line),PATH_PROC_X_FD,direproc->d_name);	if (procfdlen<=0 || procfdlen>=sizeof(line)-5) 	    continue;	errno=0;	dirfd=opendir(line);	if (! dirfd) {	    if (errno==EACCES) 		eacces=1;	    continue;	}	line[procfdlen] = '/';	cmdlp = NULL;	while ((direfd = readdir(dirfd))) {#ifdef DIRENT_HAVE_D_TYPE_WORKS	    if (direfd->d_type!=DT_LNK) 		continue;#endif	    if (procfdlen+1+strlen(direfd->d_name)+1>sizeof(line)) 		continue;	    memcpy(line + procfdlen - PATH_FD_SUFFl, PATH_FD_SUFF "/",		   PATH_FD_SUFFl+1);	    strcpy(line + procfdlen + 1, direfd->d_name);	    lnamelen=readlink(line,lname,sizeof(lname));	    if (lnamelen < strlen(PRG_SOCKET_PFX+2)) 		continue;	    if (memcmp(lname, PRG_SOCKET_PFX, PRG_SOCKET_PFXl)		|| lname[lnamelen-1]!=']') 		continue;	    lname[lnamelen-1]='\0';	    inode = strtol(lname+PRG_SOCKET_PFXl,&serr,0);	    if (!serr || *serr || inode < 0 || inode >= INT_MAX) 		continue;	    if (!cmdlp) {		if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >= 		    sizeof(line) - 5) 		    continue;		strcpy(line + procfdlen-PATH_FD_SUFFl, PATH_CMDLINE);		fd = open(line, O_RDONLY);		if (fd < 0) 		    continue;		cmdllen = read(fd, cmdlbuf, sizeof(cmdlbuf) - 1);		if (close(fd)) 		    continue;		if (cmdllen == -1) 		    continue;		if (cmdllen < sizeof(cmdlbuf) - 1) 		    cmdlbuf[cmdllen]='\0';		if ((cmdlp = strrchr(cmdlbuf, '/'))) 		    cmdlp++;		else 		    cmdlp = cmdlbuf;	    }	    snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp);	    prg_cache_add(inode, finbuf);	}	closedir(dirfd); 	dirfd = NULL;    }    if (dirproc) 	closedir(dirproc);    if (dirfd) 	closedir(dirfd);    if (!eacces) 	return;    if (prg_cache_loaded == 1) {    fail:	fprintf(stderr,_("(No info could be read for \"-p\": geteuid()=%d but you should be root.)\n"),		geteuid());    }    else	fprintf(stderr, _("(Not all processes could be identified, non-owned process info\n"			 " will not be shown, you would have to be root to see it all.)\n"));}#if HAVE_AFNETROMstatic const char *netrom_state[] ={    N_("LISTENING"),    N_("CONN SENT"),    N_("DISC SENT"),    N_("ESTABLISHED")};static int netrom_info(void){    FILE *f;    char buffer[256], dev[16];    int st, vs, vr, sendq, recvq, ret;    f = fopen(_PATH_PROCNET_NR, "r");    if (f == NULL) {	if (errno != ENOENT) {	    perror(_PATH_PROCNET_NR);	    return (-1);	}	if (flag_arg || flag_ver)	    ESYSNOT("netstat", "AF NETROM");	if (flag_arg)	    return (1);	else	    return (0);    }    printf(_("Active NET/ROM sockets\n"));    printf(_("User       Dest       Source     Device  State        Vr/Vs    Send-Q  Recv-Q\n"));    fgets(buffer, 256, f);    while (fgets(buffer, 256, f)) {	buffer[9] = 0;	buffer[19] = 0;	buffer[29] = 0;	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",	       dev, &st, &vs, &vr, &sendq, &recvq);	if (ret != 6) {	    printf(_("Problem reading data from %s\n"), _PATH_PROCNET_NR);	    continue;	}	printf("%-9s  %-9s  %-9s  %-6s  %-11s  %03d/%03d  %-6d  %-6d\n",	       buffer, buffer + 10, buffer + 20,	       dev,	       _(netrom_state[st]),	       vr, vs, sendq, recvq);    }    fclose(f);    return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -