diff options
-rw-r--r-- | usr.bin/netstat/inet.c | 75 | ||||
-rw-r--r-- | usr.bin/netstat/main.c | 88 | ||||
-rw-r--r-- | usr.bin/netstat/netstat.h | 5 |
3 files changed, 134 insertions, 34 deletions
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index f1ea35fe8f9..77fe4f45cc2 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inet.c,v 1.95 2005/04/05 20:27:35 markus Exp $ */ +/* $OpenBSD: inet.c,v 1.96 2005/06/15 10:53:23 markus Exp $ */ /* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94"; #else -static const char *rcsid = "$OpenBSD: inet.c,v 1.95 2005/04/05 20:27:35 markus Exp $"; +static const char *rcsid = "$OpenBSD: inet.c,v 1.96 2005/06/15 10:53:23 markus Exp $"; #endif #endif /* not lint */ @@ -1026,3 +1026,74 @@ ipcomp_stats(u_long off, char *name) #undef p } + +/* + * Dump the contents of a TCPCB + */ +void +tcp_dump(u_long off) +{ + struct tcpcb tcpcb; + + if (off == 0) + return; + kread(off, (char *)&tcpcb, sizeof (tcpcb)); + +#define p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); + printf("pcb %p, ", off); + p("%p", t_inpcb, "\n"); + p("%d", t_state, ""); + if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES) + printf(" (%s)", tcpstates[tcpcb.t_state]); + printf("\n"); + p("%d", t_rxtshift, ", "); + p("%d", t_rxtcur, ", "); + p("%d", t_dupacks, "\n"); + p("%u", t_maxseg, ", "); + p("%u", t_maxopd, ", "); + p("%u", t_peermss, "\n"); + p("0x%x", t_flags, ", "); + p("%u", t_force, "\n"); + p("%u", iss, "\n"); + p("%u", snd_una, ", "); + p("%u", snd_nxt, ", "); + p("%u", snd_up, "\n"); + p("%u", snd_wl1, ", "); + p("%u", snd_wl2, ", "); + p("%lu", snd_wnd, "\n"); + p("%d", sack_enable, ", "); + p("%d", snd_numholes, ", "); + p("%u", snd_fack, ", "); + p("%lu",snd_awnd, "\n"); + p("%u", retran_data, ", "); + p("%u", snd_last, "\n"); + p("%u", irs, "\n"); + p("%u", rcv_nxt, ", "); + p("%u", rcv_up, ", "); + p("%lu", rcv_wnd, "\n"); + p("%u", rcv_lastsack, "\n"); + p("%d", rcv_numsacks, "\n"); + p("%u", rcv_adv, ", "); + p("%u", snd_max, "\n"); + p("%lu", snd_cwnd, ", "); + p("%lu", snd_ssthresh, ", "); + p("%lu", max_sndwnd, "\n"); + p("%u", t_rcvtime, ", "); + p("%u", t_rtttime, ", "); + p("%u", t_rtseq, "\n"); + p("%u", t_srtt, ", "); + p("%u", t_rttvar, ", "); + p("%u", t_rttmin, "\n"); + p("%u", t_oobflags, ", "); + p("%u", t_iobc, "\n"); + p("%u", t_softerror, "\n"); + p("%u", snd_scale, ", "); + p("%u", rcv_scale, ", "); + p("%u", request_r_scale, ", "); + p("%u", requested_s_scale, "\n"); + p("%u", ts_recent, ", "); + p("%u", ts_recent_age, "\n"); + p("%u", last_ack_sent, "\n"); + p("%u", pf, "\n"); +#undef p +}; diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 7287e129af2..32041ee9f53 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.58 2005/06/08 04:47:04 henning Exp $ */ +/* $OpenBSD: main.c,v 1.59 2005/06/15 10:53:23 markus Exp $ */ /* $NetBSD: main.c,v 1.9 1996/05/07 02:55:02 thorpej Exp $ */ /* @@ -40,7 +40,7 @@ char copyright[] = #if 0 static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94"; #else -static char *rcsid = "$OpenBSD: main.c,v 1.58 2005/06/08 04:47:04 henning Exp $"; +static char *rcsid = "$OpenBSD: main.c,v 1.59 2005/06/15 10:53:23 markus Exp $"; #endif #endif /* not lint */ @@ -160,71 +160,72 @@ struct protox { u_char pr_wanted; /* 1 if wanted, 0 otherwise */ void (*pr_cblocks)(u_long, char *); /* control blocks printing routine */ void (*pr_stats)(u_long, char *); /* statistics printing routine */ + void (*pr_dump)(u_long); /* pcb printing routine */ char *pr_name; /* well-known name */ } protox[] = { { N_TCBTABLE, N_TCPSTAT, 1, protopr, - tcp_stats, "tcp" }, + tcp_stats, tcp_dump, "tcp" }, { N_UDBTABLE, N_UDPSTAT, 1, protopr, - udp_stats, "udp" }, + udp_stats, 0, "udp" }, { N_RAWIPTABLE, N_IPSTAT, 1, protopr, - ip_stats, "ip" }, + ip_stats, 0, "ip" }, { -1, N_ICMPSTAT, 1, 0, - icmp_stats, "icmp" }, + icmp_stats, 0, "icmp" }, { -1, N_IGMPSTAT, 1, 0, - igmp_stats, "igmp" }, + igmp_stats, 0, "igmp" }, { -1, N_AHSTAT, 1, 0, - ah_stats, "ah" }, + ah_stats, 0, "ah" }, { -1, N_ESPSTAT, 1, 0, - esp_stats, "esp" }, + esp_stats, 0, "esp" }, { -1, N_IP4STAT, 1, 0, - ipip_stats, "ipencap" }, + ipip_stats, 0, "ipencap" }, { -1, N_ETHERIPSTAT, 1, 0, - etherip_stats,"etherip" }, + etherip_stats,0, "etherip" }, { -1, N_IPCOMPSTAT, 1, 0, - ipcomp_stats, "ipcomp" }, + ipcomp_stats, 0, "ipcomp" }, { -1, N_CARPSTAT, 1, 0, - carp_stats, "carp" }, + carp_stats, 0, "carp" }, { -1, N_PFSYNCSTAT, 1, 0, - pfsync_stats, "pfsync" }, + pfsync_stats, 0, "pfsync" }, { -1, N_PIMSTAT, 1, 0, - pim_stats, "pim" }, + pim_stats, 0, "pim" }, { -1, -1, 0, 0, - 0, 0 } + 0, 0, 0 } }; #ifdef INET6 struct protox ip6protox[] = { { N_TCBTABLE, N_TCPSTAT, 1, ip6protopr, - 0, "tcp" }, + 0, tcp_dump, "tcp" }, { N_UDBTABLE, N_UDPSTAT, 1, ip6protopr, - 0, "udp" }, + 0, 0, "udp" }, { N_RAWIP6TABLE,N_IP6STAT, 1, ip6protopr, - ip6_stats, "ip6" }, + ip6_stats, 0, "ip6" }, { -1, N_ICMP6STAT, 1, 0, - icmp6_stats, "icmp6" }, + icmp6_stats, 0, "icmp6" }, { -1, N_PIM6STAT, 1, 0, - pim6_stats, "pim6" }, + pim6_stats, 0, "pim6" }, { -1, N_RIP6STAT, 1, 0, - rip6_stats, "rip6" }, + rip6_stats, 0, "rip6" }, { -1, -1, 0, 0, - 0, 0 } + 0, 0, 0 } }; #endif struct protox ipxprotox[] = { { N_IPX, N_IPXSTAT, 1, ipxprotopr, - ipx_stats, "ipx" }, + ipx_stats, 0, "ipx" }, { N_IPX, N_SPXSTAT, 1, ipxprotopr, - spx_stats, "spx" }, + spx_stats, 0, "spx" }, { -1, -1, 0, 0, - 0, 0 } + 0, 0, 0 } }; struct protox atalkprotox[] = { { N_DDPCB, N_DDPSTAT, 1, atalkprotopr, - ddp_stats, "ddp" }, + ddp_stats, 0, "ddp" }, { -1, -1, 0, 0, - 0, 0 } + 0, 0, 0 } }; #ifndef INET6 @@ -252,12 +253,13 @@ main(int argc, char *argv[]) struct protoent *p; struct protox *tp = NULL; /* for printing cblocks & stats */ int ch; - char *nlistf = NULL, *memf = NULL; + char *nlistf = NULL, *memf = NULL, *ep; char buf[_POSIX2_LINE_MAX]; + u_long pcbaddr = 0; af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "Aabdf:gI:ilM:mN:np:qrstuvW:w:")) != -1) + while ((ch = getopt(argc, argv, "Aabdf:gI:ilM:mN:np:P:qrstuvW:w:")) != -1) switch (ch) { case 'A': Aflag = 1; @@ -327,6 +329,18 @@ main(int argc, char *argv[]) } pflag = 1; break; + case 'P': + errno = 0; + pcbaddr = strtoul(optarg, &ep, 16); + if (optarg[0] == '\0' || *ep != '\0' || + errno == ERANGE) { + (void)fprintf(stderr, + "%s: %s: invalid PCB address\n", + __progname, optarg); + exit(1); + } + Pflag = 1; + break; case 'q': qflag = 1; break; @@ -374,8 +388,9 @@ main(int argc, char *argv[]) /* * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. + * Dumping PCB info is also restricted. */ - if (nlistf != NULL || memf != NULL) { + if (nlistf != NULL || memf != NULL || Pflag) { setegid(getgid()); setgid(getgid()); } @@ -423,6 +438,17 @@ main(int argc, char *argv[]) printproto(tp, tp->pr_name); exit(0); } + if (Pflag) { + if (tp == NULL && (tp = name2protox("tcp")) == NULL) { + (void)fprintf(stderr, + "%s: %s: unknown protocol\n", + __progname, "tcp"); + exit(1); + } + if (tp->pr_dump) + (tp->pr_dump)(pcbaddr); + exit(0); + } /* * Keep file descriptors open to avoid overhead * of open/close on each call to get* routines. diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index 5f8c6ada545..a3d3f5c7351 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: netstat.h,v 1.34 2005/04/12 14:11:49 reyk Exp $ */ +/* $OpenBSD: netstat.h,v 1.35 2005/06/15 10:53:23 markus Exp $ */ /* $NetBSD: netstat.h,v 1.6 1996/05/07 02:55:05 thorpej Exp $ */ /* @@ -47,6 +47,7 @@ int lflag; /* show routing table with use and ref */ int mflag; /* show memory stats */ int nflag; /* show addresses numerically */ int pflag; /* show given protocol */ +int Pflag; /* show given PCB */ int qflag; /* only display non-zero values for output */ int rflag; /* show routing tables (or routing stats) */ int sflag; /* show protocol statistics */ @@ -86,6 +87,8 @@ void etherip_stats(u_long, char *); void protopr(u_long, char *); void ipcomp_stats(u_long, char *); +void tcp_dump(u_long); + void mbpr(u_long, u_long, u_long); void hostpr(u_long, u_long); |