Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/netstat Use sysctl to read live kernel PF_INET PCBs.
details: https://anonhg.NetBSD.org/src/rev/15cbc4987980
branches: trunk
changeset: 583468:15cbc4987980
user: elad <elad%NetBSD.org@localhost>
date: Sun Aug 07 17:10:36 2005 +0000
description:
Use sysctl to read live kernel PF_INET PCBs.
diffstat:
usr.bin/netstat/inet.c | 167 +++++++++++++++++++++++++++++++++++-------------
1 files changed, 121 insertions(+), 46 deletions(-)
diffs (220 lines):
diff -r e53b05149a9e -r 15cbc4987980 usr.bin/netstat/inet.c
--- a/usr.bin/netstat/inet.c Sun Aug 07 16:57:12 2005 +0000
+++ b/usr.bin/netstat/inet.c Sun Aug 07 17:10:36 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: inet.c,v 1.65 2005/08/06 17:58:13 elad Exp $ */
+/* $NetBSD: inet.c,v 1.66 2005/08/07 17:10:36 elad Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
#else
-__RCSID("$NetBSD: inet.c,v 1.65 2005/08/06 17:58:13 elad Exp $");
+__RCSID("$NetBSD: inet.c,v 1.66 2005/08/07 17:10:36 elad Exp $");
#endif
#endif /* not lint */
@@ -80,6 +80,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <stdlib.h>
#include <err.h>
#include "netstat.h"
@@ -97,6 +98,63 @@
* -a (all) flag is specified.
*/
static int width;
+static int compact;
+
+static void
+protoprhdr(void)
+{
+ printf("Active Internet connections");
+ if (aflag)
+ printf(" (including servers)");
+ putchar('\n');
+ if (Aflag)
+ printf("%-8.8s ", "PCB");
+ printf("%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %s\n",
+ "Proto", "Recv-Q", "Send-Q", compact ? "" : " ",
+ width, width, "Local Address",
+ width, width, "Foreign Address",
+ "State");
+}
+
+static void
+protopr0(caddr_t ppcb, u_long rcv_sb_cc, u_long snd_sb_cc,
+ struct in_addr *laddr, u_int16_t lport,
+ struct in_addr *faddr, u_int16_t fport,
+ short t_state, char *name)
+{
+ static char *shorttcpstates[] = {
+ "CLOSED", "LISTEN", "SYNSEN", "SYSRCV",
+ "ESTABL", "CLWAIT", "FWAIT1", "CLOSNG",
+ "LASTAK", "FWAIT2", "TMWAIT",
+ };
+ int istcp;
+
+ istcp = strcmp(name, "tcp") == 0;
+
+ if (Aflag) {
+ printf("%8lx ", (u_long) ppcb);
+ }
+ printf("%-5.5s %6ld %6ld%s", name, rcv_sb_cc, snd_sb_cc,
+ compact ? "" : " ");
+ if (numeric_port) {
+ inetprint(laddr, lport, name, 1);
+ inetprint(faddr, fport, name, 1);
+ } else if (inpcb.inp_flags & INP_ANONPORT) {
+ inetprint(laddr, lport, name, 1);
+ inetprint(faddr, fport, name, 0);
+ } else {
+ inetprint(laddr, lport, name, 0);
+ inetprint(faddr, fport, name, 0);
+ }
+ if (istcp) {
+ if (t_state < 0 || t_state >= TCP_NSTATES)
+ printf(" %d", t_state);
+ else
+ printf(" %s", compact ? shorttcpstates[t_state] :
+ tcpstates[t_state]);
+ }
+ putchar('\n');
+}
void
protopr(off, name)
@@ -106,13 +164,8 @@
struct inpcbtable table;
struct inpcb *head, *next, *prev;
struct inpcb inpcb;
- int istcp, compact;
+ int istcp;
static int first = 1;
- static char *shorttcpstates[] = {
- "CLOSED", "LISTEN", "SYNSEN", "SYSRCV",
- "ESTABL", "CLWAIT", "FWAIT1", "CLOSNG",
- "LASTAK", "FWAIT2", "TMWAIT",
- };
if (off == 0)
return;
@@ -132,6 +185,58 @@
}
} else
width = 22;
+
+ if (use_sysctl) {
+ struct kinfo_pcb *pcblist;
+ int mib[8];
+ size_t namelen = 0, size = 0, i;
+ char *mibname = NULL;
+
+ memset(mib, 0, sizeof(mib));
+
+ if (asprintf(&mibname, "net.inet.%s.pcblist", name) == -1)
+ err(1, "asprintf");
+
+ /* get dynamic pcblist node */
+ if (sysctlnametomib(mibname, mib, &namelen) == -1)
+ err(1, "sysctlnametomib");
+
+ if (sysctl(mib, sizeof(mib) / sizeof(*mib), NULL, &size,
+ NULL, 0) == -1)
+ err(1, "sysctl (query)");
+
+ pcblist = malloc(size);
+ memset(pcblist, 0, size);
+
+ mib[6] = sizeof(*pcblist);
+ mib[7] = size / sizeof(*pcblist);
+
+ if (sysctl(mib, sizeof(mib) / sizeof(*mib), pcblist,
+ &size, NULL, 0) == -1)
+ err(1, "sysctl (copy)");
+
+ for (i = 0; i < size / sizeof(*pcblist); i++) {
+ struct sockaddr_in src, dst;
+
+ memcpy(&src, &pcblist[i].ki_s, sizeof(src));
+ memcpy(&dst, &pcblist[i].ki_d, sizeof(dst));
+
+ if (first) {
+ protoprhdr();
+ first = 0;
+ }
+
+ protopr0((caddr_t) pcblist[i].ki_ppcbaddr,
+ pcblist[i].ki_rcvq, pcblist[i].ki_sndq,
+ &src.sin_addr, src.sin_port,
+ &dst.sin_addr, dst.sin_port,
+ pcblist[i].ki_tstate, name);
+ }
+
+ free(pcblist);
+ return;
+ }
+
while (next != head) {
kread((u_long)next, (char *)&inpcb, sizeof inpcb);
if ((struct inpcb *)inpcb.inp_queue.cqe_prev != prev) {
@@ -152,47 +257,17 @@
kread((u_long)inpcb.inp_ppcb,
(char *)&tcpcb, sizeof (tcpcb));
}
+
if (first) {
- printf("Active Internet connections");
- if (aflag)
- printf(" (including servers)");
- putchar('\n');
- if (Aflag)
- printf("%-8.8s ", "PCB");
- printf("%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %s\n",
- "Proto", "Recv-Q", "Send-Q",
- compact ? "" : " ",
- width, width, "Local Address",
- width, width, "Foreign Address", "State");
+ protoprhdr();
first = 0;
}
- if (Aflag) {
- if (istcp)
- printf("%8lx ", (u_long) inpcb.inp_ppcb);
- else
- printf("%8lx ", (u_long) prev);
- }
- printf("%-5.5s %6ld %6ld%s", name, sockb.so_rcv.sb_cc,
- sockb.so_snd.sb_cc, compact ? "" : " ");
- if (numeric_port) {
- inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name, 1);
- inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name, 1);
- } else if (inpcb.inp_flags & INP_ANONPORT) {
- inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name, 1);
- inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name, 0);
- } else {
- inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name, 0);
- inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name, 0);
- }
- if (istcp) {
- if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
- printf(" %d", tcpcb.t_state);
- else
- printf(" %s", compact ?
- shorttcpstates[tcpcb.t_state] :
- tcpstates[tcpcb.t_state]);
- }
- putchar('\n');
+
+ protopr0(istcp ? (caddr_t) inpcb.inp_ppcb : (caddr_t) prev,
+ sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc,
+ &inpcb.inp_laddr, inpcb.inp_lport,
+ &inpcb.inp_faddr, inpcb.inp_fport,
+ tcpcb.t_state, name);
}
}
Home |
Main Index |
Thread Index |
Old Index