summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/netstat/inet.c75
-rw-r--r--usr.bin/netstat/main.c88
-rw-r--r--usr.bin/netstat/netstat.h5
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);