aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2017-03-21 06:39:49 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2017-03-21 06:39:49 +0000
commitcc65eb4e792a203a8b4a17b0e3af7831e5044eca (patch)
tree969a970e8707f4144afbe92a15b95806217ec748
parent5a33a2afb3a35949545a572cffa0b8e637446d4a (diff)
Notes
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_tcp.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_udp.c12
-rw-r--r--contrib/ipfilter/ipsend/sock.c2
-rw-r--r--lib/libprocstat/libprocstat.c1
-rw-r--r--sys/netinet/in_pcb.c35
-rw-r--r--sys/netinet/in_pcb.h99
-rw-r--r--sys/netinet/ip_divert.c8
-rw-r--r--sys/netinet/raw_ip.c7
-rw-r--r--sys/netinet/tcp_subr.c74
-rw-r--r--sys/netinet/tcp_syncache.c14
-rw-r--r--sys/netinet/tcp_timer.c25
-rw-r--r--sys/netinet/tcp_timer.h2
-rw-r--r--sys/netinet/tcp_var.h243
-rw-r--r--sys/netinet/udp_usrreq.c8
-rw-r--r--sys/sys/param.h2
-rw-r--r--usr.bin/netstat/inet.c170
-rw-r--r--usr.bin/sockstat/sockstat.c53
-rw-r--r--usr.bin/systat/extern.h6
-rw-r--r--usr.bin/systat/netcmds.c10
-rw-r--r--usr.bin/systat/netstat.c65
-rw-r--r--usr.sbin/tcpdrop/tcpdrop.c16
-rw-r--r--usr.sbin/trpt/trpt.c1
22 files changed, 384 insertions, 471 deletions
diff --git a/contrib/bsnmp/snmp_mibII/mibII_tcp.c b/contrib/bsnmp/snmp_mibII/mibII_tcp.c
index e0a07a7d9ecf..e6d5920d9f88 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_tcp.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_tcp.c
@@ -310,7 +310,7 @@ op_tcpconn(struct snmp_context *ctx __unused, struct snmp_value *value,
switch (value->var.subs[sub - 1]) {
case LEAF_tcpConnState:
- switch (tcpoids[i].tp->xt_tp.t_state) {
+ switch (tcpoids[i].tp->t_state) {
case TCPS_CLOSED:
value->v.integer = 1;
diff --git a/contrib/bsnmp/snmp_mibII/mibII_udp.c b/contrib/bsnmp/snmp_mibII/mibII_udp.c
index 5682974a4d44..76dddfc0a1af 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_udp.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_udp.c
@@ -105,8 +105,8 @@ fetch_udp(void)
ptr->xig_len > sizeof(struct xinpgen);
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
inp = (struct xinpcb *)ptr;
- if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen ||
- (inp->xi_inp.inp_vflag & INP_IPV4) == 0)
+ if (inp->inp_gencnt > xinpgen->xig_gen ||
+ (inp->inp_vflag & INP_IPV4) == 0)
continue;
udp_total++;
@@ -128,17 +128,17 @@ fetch_udp(void)
ptr->xig_len > sizeof(struct xinpgen);
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
inp = (struct xinpcb *)ptr;
- if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen ||
- (inp->xi_inp.inp_vflag & INP_IPV4) == 0)
+ if (inp->inp_gencnt > xinpgen->xig_gen ||
+ (inp->inp_vflag & INP_IPV4) == 0)
continue;
oid->inp = inp;
oid->index.len = 5;
- inaddr = ntohl(inp->xi_inp.inp_laddr.s_addr);
+ inaddr = ntohl(inp->inp_laddr.s_addr);
oid->index.subs[0] = (inaddr >> 24) & 0xff;
oid->index.subs[1] = (inaddr >> 16) & 0xff;
oid->index.subs[2] = (inaddr >> 8) & 0xff;
oid->index.subs[3] = (inaddr >> 0) & 0xff;
- oid->index.subs[4] = ntohs(inp->xi_inp.inp_lport);
+ oid->index.subs[4] = ntohs(inp->inp_lport);
oid++;
}
diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c
index 81e8ec3ef65f..d9361dcd44e0 100644
--- a/contrib/ipfilter/ipsend/sock.c
+++ b/contrib/ipfilter/ipsend/sock.c
@@ -78,8 +78,10 @@ typedef int boolean_t;
# include <net/route.h>
#endif
#include <netinet/ip_var.h>
+#define _WANT_INPCB
#include <netinet/in_pcb.h>
#include <netinet/tcp_timer.h>
+#define _WANT_TCPCB
#include <netinet/tcp_var.h>
#include <stdio.h>
#include <unistd.h>
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 9dc980077ec8..85dcec07015d 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#define _WANT_INPCB
#include <netinet/in_pcb.h>
#include <assert.h>
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index ce1c627aabc4..59ff8e66f87c 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -2434,6 +2434,41 @@ so_sototcpcb(struct socket *so)
return (sototcpcb(so));
}
+/*
+ * Create an external-format (``xinpcb'') structure using the information in
+ * the kernel-format in_pcb structure pointed to by inp. This is done to
+ * reduce the spew of irrelevant information over this interface, to isolate
+ * user code from changes in the kernel structure, and potentially to provide
+ * information-hiding if we decide that some of this information should be
+ * hidden from users.
+ */
+void
+in_pcbtoxinpcb(const struct inpcb *inp, struct xinpcb *xi)
+{
+
+ xi->xi_len = sizeof(struct xinpcb);
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xi->xi_socket);
+ else
+ bzero(&xi->xi_socket, sizeof(struct xsocket));
+ bcopy(&inp->inp_inc, &xi->inp_inc, sizeof(struct in_conninfo));
+ xi->inp_gencnt = inp->inp_gencnt;
+ xi->inp_ppcb = inp->inp_ppcb;
+ xi->inp_flow = inp->inp_flow;
+ xi->inp_flowid = inp->inp_flowid;
+ xi->inp_flowtype = inp->inp_flowtype;
+ xi->inp_flags = inp->inp_flags;
+ xi->inp_flags2 = inp->inp_flags2;
+ xi->inp_rss_listen_bucket = inp->inp_rss_listen_bucket;
+ xi->in6p_cksum = inp->in6p_cksum;
+ xi->in6p_hops = inp->in6p_hops;
+ xi->inp_ip_tos = inp->inp_ip_tos;
+ xi->inp_vflag = inp->inp_vflag;
+ xi->inp_ip_ttl = inp->inp_ip_ttl;
+ xi->inp_ip_p = inp->inp_ip_p;
+ xi->inp_ip_minttl = inp->inp_ip_minttl;
+}
+
#ifdef DDB
static void
db_print_indent(int indent)
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 71fab5c6600e..79223532bee6 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -53,7 +53,6 @@
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
-struct inpcbpolicy;
/*
* struct inpcb is the common protocol control block structure used in most
@@ -65,7 +64,7 @@ struct inpcbpolicy;
*/
LIST_HEAD(inpcbhead, inpcb);
LIST_HEAD(inpcbporthead, inpcbport);
-typedef u_quad_t inp_gen_t;
+typedef uint64_t inp_gen_t;
/*
* PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
@@ -130,9 +129,8 @@ struct in_conninfo {
#define inc6_laddr inc_ie.ie6_laddr
#define inc6_zoneid inc_ie.ie6_zoneid
-struct icmp6_filter;
-
-/*-
+#if defined(_KERNEL) || defined(_WANT_INPCB)
+/*
* struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 and
* IPv6 sockets. In the case of TCP and UDP, further per-connection state is
* hung off of inp_ppcb most of the time. Almost all fields of struct inpcb
@@ -181,6 +179,8 @@ struct icmp6_filter;
* read-lock usage during modification, this model can be applied to other
* protocols (especially SCTP).
*/
+struct icmp6_filter;
+struct inpcbpolicy;
struct m_snd_tag;
struct inpcb {
LIST_ENTRY(inpcb) inp_hash; /* (h/i) hash list */
@@ -204,10 +204,8 @@ struct inpcb {
uint32_t inp_flowid; /* (x) flow id / queue id */
u_int inp_refcount; /* (i) refcount */
struct m_snd_tag *inp_snd_tag; /* (i) send tag for outgoing mbufs */
- void *inp_pspare[4]; /* (x) general use */
uint32_t inp_flowtype; /* (x) M_HASHTYPE value */
uint32_t inp_rss_listen_bucket; /* (x) overridden RSS listen bucket */
- u_int inp_ispare[4]; /* (x) user cookie / general use */
/* Local and foreign ports, local and foreign addr. */
struct in_conninfo inp_inc; /* (i) list for PCB's local port */
@@ -218,23 +216,23 @@ struct inpcb {
/* Protocol-dependent part; options. */
struct {
- u_char inp4_ip_tos; /* (i) type of service proto */
- struct mbuf *inp4_options; /* (i) IP options */
- struct ip_moptions *inp4_moptions; /* (i) IP mcast options */
- } inp_depend4;
+ u_char inp_ip_tos; /* (i) type of service proto */
+ struct mbuf *inp_options; /* (i) IP options */
+ struct ip_moptions *inp_moptions; /* (i) mcast options */
+ };
struct {
/* (i) IP options */
- struct mbuf *inp6_options;
+ struct mbuf *in6p_options;
/* (i) IP6 options for outgoing packets */
- struct ip6_pktopts *inp6_outputopts;
+ struct ip6_pktopts *in6p_outputopts;
/* (i) IP multicast options */
- struct ip6_moptions *inp6_moptions;
+ struct ip6_moptions *in6p_moptions;
/* (i) ICMPv6 code type filter */
- struct icmp6_filter *inp6_icmp6filt;
+ struct icmp6_filter *in6p_icmp6filt;
/* (i) IPV6_CHECKSUM setsockopt */
- int inp6_cksum;
- short inp6_hops;
- } inp_depend6;
+ int in6p_cksum;
+ short in6p_hops;
+ };
LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */
struct inpcbport *inp_phd; /* (i/h) head of this list */
#define inp_zero_size offsetof(struct inpcb, inp_gencnt)
@@ -249,24 +247,17 @@ struct inpcb {
#define inp_route inp_rtu.inpu_route
#define inp_route6 inp_rtu.inpu_route6
};
+#endif /* _KERNEL */
+
#define inp_fport inp_inc.inc_fport
#define inp_lport inp_inc.inc_lport
#define inp_faddr inp_inc.inc_faddr
#define inp_laddr inp_inc.inc_laddr
-#define inp_ip_tos inp_depend4.inp4_ip_tos
-#define inp_options inp_depend4.inp4_options
-#define inp_moptions inp_depend4.inp4_moptions
#define in6p_faddr inp_inc.inc6_faddr
#define in6p_laddr inp_inc.inc6_laddr
#define in6p_zoneid inp_inc.inc6_zoneid
-#define in6p_hops inp_depend6.inp6_hops /* default hop limit */
#define in6p_flowinfo inp_flow
-#define in6p_options inp_depend6.inp6_options
-#define in6p_outputopts inp_depend6.inp6_outputopts
-#define in6p_moptions inp_depend6.inp6_moptions
-#define in6p_icmp6filt inp_depend6.inp6_icmp6filt
-#define in6p_cksum inp_depend6.inp6_cksum
#define inp_vnet inp_pcbinfo->ipi_vnet
@@ -280,21 +271,53 @@ struct inpcb {
/*
* Interface exported to userland by various protocols which use inpcbs. Hack
* alert -- only define if struct xsocket is in scope.
+ * Fields prefixed with "xi_" are unique to this structure, and the rest
+ * match fields in the struct inpcb, to ease coding and porting.
+ *
+ * Legend:
+ * (s) - used by userland utilities in src
+ * (p) - used by utilities in ports
+ * (3) - is known to be used by third party software not in ports
+ * (n) - no known usage
*/
#ifdef _SYS_SOCKETVAR_H_
-struct xinpcb {
- size_t xi_len; /* length of this structure */
- struct inpcb xi_inp;
- struct xsocket xi_socket;
- u_quad_t xi_alignment_hack;
-};
+struct xinpcb {
+ size_t xi_len; /* length of this structure */
+ struct xsocket xi_socket; /* (s,p) */
+ struct in_conninfo inp_inc; /* (s,p) */
+ uint64_t inp_gencnt; /* (s,p) */
+ union {
+ void *inp_ppcb; /* (s) netstat(1) */
+ int64_t ph_ppcb;
+ };
+ int64_t inp_spare64[4];
+ uint32_t inp_flow; /* (s) */
+ uint32_t inp_flowid; /* (s) */
+ uint32_t inp_flowtype; /* (s) */
+ int32_t inp_flags; /* (s,p) */
+ int32_t inp_flags2; /* (s) */
+ int32_t inp_rss_listen_bucket; /* (n) */
+ int32_t in6p_cksum; /* (n) */
+ int32_t inp_spare32[4];
+ uint16_t in6p_hops; /* (n) */
+ uint8_t inp_ip_tos; /* (n) */
+ int8_t pad8;
+ uint8_t inp_vflag; /* (s,p) */
+ uint8_t inp_ip_ttl; /* (n) */
+ uint8_t inp_ip_p; /* (n) */
+ uint8_t inp_ip_minttl; /* (n) */
+ int8_t inp_spare8[4];
+} __aligned(8);
-struct xinpgen {
- size_t xig_len; /* length of this structure */
- u_int xig_count; /* number of PCBs at this time */
- inp_gen_t xig_gen; /* generation count at this time */
- so_gen_t xig_sogen; /* socket generation count at this time */
+struct xinpgen {
+ size_t xig_len; /* length of this structure */
+ u_int xig_count; /* number of PCBs at this time */
+ inp_gen_t xig_gen; /* generation count at this time */
+ so_gen_t xig_sogen; /* socket generation count this time */
};
+#ifdef _KERNEL
+void in_pcbtoxinpcb(const struct inpcb *, struct xinpcb *);
+#endif
#endif /* _SYS_SOCKETVAR_H_ */
struct inpcbport {
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index c0270005569e..be0bbf7f5648 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -691,12 +691,8 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
INP_RLOCK(inp);
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
- bzero(&xi, sizeof(xi));
- xi.xi_len = sizeof xi;
- /* XXX should avoid extra copy */
- bcopy(inp, &xi.xi_inp, sizeof *inp);
- if (inp->inp_socket)
- sotoxsocket(inp->inp_socket, &xi.xi_socket);
+
+ in_pcbtoxinpcb(inp, &xi);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xi, sizeof xi);
} else
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index de1ad26065c4..f36a8a936207 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1077,12 +1077,7 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
- bzero(&xi, sizeof(xi));
- xi.xi_len = sizeof xi;
- /* XXX should avoid extra copy */
- bcopy(inp, &xi.xi_inp, sizeof *inp);
- if (inp->inp_socket)
- sotoxsocket(inp->inp_socket, &xi.xi_socket);
+ in_pcbtoxinpcb(inp, &xi);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xi, sizeof xi);
} else
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 13102529ff0c..de11684a40f4 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1773,30 +1773,8 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
INP_RLOCK(inp);
if (inp->inp_gencnt <= gencnt) {
struct xtcpcb xt;
- void *inp_ppcb;
- bzero(&xt, sizeof(xt));
- xt.xt_len = sizeof xt;
- /* XXX should avoid extra copy */
- bcopy(inp, &xt.xt_inp, sizeof *inp);
- inp_ppcb = inp->inp_ppcb;
- if (inp_ppcb == NULL)
- bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
- else if (inp->inp_flags & INP_TIMEWAIT) {
- bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
- xt.xt_tp.t_state = TCPS_TIME_WAIT;
- } else {
- bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
- if (xt.xt_tp.t_timers)
- tcp_timer_to_xtimer(&xt.xt_tp, xt.xt_tp.t_timers, &xt.xt_timer);
- }
- if (inp->inp_socket != NULL)
- sotoxsocket(inp->inp_socket, &xt.xt_socket);
- else {
- bzero(&xt.xt_socket, sizeof xt.xt_socket);
- xt.xt_socket.xso_protocol = IPPROTO_TCP;
- }
- xt.xt_inp.inp_gencnt = inp->inp_gencnt;
+ tcp_inptoxtp(inp, &xt);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xt, sizeof xt);
} else
@@ -2765,3 +2743,53 @@ tcp_state_change(struct tcpcb *tp, int newstate)
tp->t_state = newstate;
TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate);
}
+
+/*
+ * Create an external-format (``xtcpcb'') structure using the information in
+ * the kernel-format tcpcb structure pointed to by tp. This is done to
+ * reduce the spew of irrelevant information over this interface, to isolate
+ * user code from changes in the kernel structure, and potentially to provide
+ * information-hiding if we decide that some of this information should be
+ * hidden from users.
+ */
+void
+tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt)
+{
+ struct tcpcb *tp = intotcpcb(inp);
+ sbintime_t now;
+
+ if (inp->inp_flags & INP_TIMEWAIT) {
+ bzero(xt, sizeof(struct xtcpcb));
+ xt->t_state = TCPS_TIME_WAIT;
+ } else {
+ xt->t_state = tp->t_state;
+ xt->t_flags = tp->t_flags;
+ xt->t_sndzerowin = tp->t_sndzerowin;
+ xt->t_sndrexmitpack = tp->t_sndrexmitpack;
+ xt->t_rcvoopack = tp->t_rcvoopack;
+
+ now = getsbinuptime();
+#define COPYTIMER(ttt) do { \
+ if (callout_active(&tp->t_timers->ttt)) \
+ xt->ttt = (tp->t_timers->ttt.c_time - now) / \
+ SBT_1MS; \
+ else \
+ xt->ttt = 0; \
+} while (0)
+ COPYTIMER(tt_delack);
+ COPYTIMER(tt_rexmt);
+ COPYTIMER(tt_persist);
+ COPYTIMER(tt_keep);
+ COPYTIMER(tt_2msl);
+#undef COPYTIMER
+ xt->t_rcvtime = 1000 * (ticks - tp->t_rcvtime) / hz;
+
+ bcopy(tp->t_fb->tfb_tcp_block_name, xt->xt_stack,
+ TCP_FUNCTION_NAME_LEN_MAX);
+ }
+
+ xt->xt_len = sizeof(struct xtcpcb);
+ in_pcbtoxinpcb(inp, &xt->xt_inp);
+ if (inp->inp_socket == NULL)
+ xt->xt_inp.xi_socket.xso_protocol = IPPROTO_TCP;
+}
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 66607ecab0fa..0299baf8821a 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -2217,13 +2217,13 @@ syncache_pcblist(struct sysctl_req *req, int max_pcbs, int *pcbs_exported)
xt.xt_inp.inp_vflag = INP_IPV6;
else
xt.xt_inp.inp_vflag = INP_IPV4;
- bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc, sizeof (struct in_conninfo));
- xt.xt_tp.t_inpcb = &xt.xt_inp;
- xt.xt_tp.t_state = TCPS_SYN_RECEIVED;
- xt.xt_socket.xso_protocol = IPPROTO_TCP;
- xt.xt_socket.xso_len = sizeof (struct xsocket);
- xt.xt_socket.so_type = SOCK_STREAM;
- xt.xt_socket.so_state = SS_ISCONNECTING;
+ bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc,
+ sizeof (struct in_conninfo));
+ xt.t_state = TCPS_SYN_RECEIVED;
+ xt.xt_inp.xi_socket.xso_protocol = IPPROTO_TCP;
+ xt.xt_inp.xi_socket.xso_len = sizeof (struct xsocket);
+ xt.xt_inp.xi_socket.so_type = SOCK_STREAM;
+ xt.xt_inp.xi_socket.so_state = SS_ISCONNECTING;
error = SYSCTL_OUT(req, &xt, sizeof xt);
if (error) {
SCH_UNLOCK(sch);
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 16e7e4486a14..0687b718ec6a 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -1006,28 +1006,3 @@ tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
tp->t_timers->tt_draincnt++;
}
}
-
-#define ticks_to_msecs(t) (1000*(t) / hz)
-
-void
-tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
- struct xtcp_timer *xtimer)
-{
- sbintime_t now;
-
- bzero(xtimer, sizeof(*xtimer));
- if (timer == NULL)
- return;
- now = getsbinuptime();
- if (callout_active(&timer->tt_delack))
- xtimer->tt_delack = (timer->tt_delack.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_rexmt))
- xtimer->tt_rexmt = (timer->tt_rexmt.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_persist))
- xtimer->tt_persist = (timer->tt_persist.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_keep))
- xtimer->tt_keep = (timer->tt_keep.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_2msl))
- xtimer->tt_2msl = (timer->tt_2msl.c_time - now) / SBT_1MS;
- xtimer->t_rcvtime = ticks_to_msecs(ticks - tp->t_rcvtime);
-}
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index 45eae6b6ad5c..f14f929a4f95 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -210,8 +210,6 @@ void tcp_timer_keep(void *xtp);
void tcp_timer_persist(void *xtp);
void tcp_timer_rexmt(void *xtp);
void tcp_timer_delack(void *xtp);
-void tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
- struct xtcp_timer *xtimer);
#endif /* _KERNEL */
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 0088b215f457..5705e553d1d3 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -39,15 +39,9 @@
#ifdef _KERNEL
#include <net/vnet.h>
#include <sys/mbuf.h>
+#endif
-/*
- * Kernel variables for tcp.
- */
-VNET_DECLARE(int, tcp_do_rfc1323);
-#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323)
-
-#endif /* _KERNEL */
-
+#if defined(_KERNEL) || defined(_WANT_TCPCB)
/* TCP segment queue entry */
struct tseg_qent {
LIST_ENTRY(tseg_qent) tqe_q;
@@ -83,90 +77,12 @@ struct sackhint {
uint64_t _pad[1]; /* TBD */
};
-struct tcptemp {
- u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
- struct tcphdr tt_t;
-};
-
-#define tcp6cb tcpcb /* for KAME src sync over BSD*'s */
-
-/*
- * TODO: We yet need to brave plowing in
- * to tcp_input() and the pru_usrreq() block.
- * Right now these go to the old standards which
- * are somewhat ok, but in the long term may
- * need to be changed. If we do tackle tcp_input()
- * then we need to get rid of the tcp_do_segment()
- * function below.
- */
-/* Flags for tcp functions */
-#define TCP_FUNC_BEING_REMOVED 0x01 /* Can no longer be referenced */
-struct tcpcb;
-struct inpcb;
-struct sockopt;
-struct socket;
-
-/*
- * If defining the optional tcp_timers, in the
- * tfb_tcp_timer_stop call you must use the
- * callout_async_drain() function with the
- * tcp_timer_discard callback. You should check
- * the return of callout_async_drain() and if 0
- * increment tt_draincnt. Since the timer sub-system
- * does not know your callbacks you must provide a
- * stop_all function that loops through and calls
- * tcp_timer_stop() with each of your defined timers.
- * Adding a tfb_tcp_handoff_ok function allows the socket
- * option to change stacks to query you even if the
- * connection is in a later stage. You return 0 to
- * say you can take over and run your stack, you return
- * non-zero (an error number) to say no you can't.
- * If the function is undefined you can only change
- * in the early states (before connect or listen).
- * tfb_tcp_fb_fini is changed to add a flag to tell
- * the old stack if the tcb is being destroyed or
- * not. A one in the flag means the TCB is being
- * destroyed, a zero indicates its transitioning to
- * another stack (via socket option).
- */
-struct tcp_function_block {
- char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
- int (*tfb_tcp_output)(struct tcpcb *);
- void (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *,
- struct socket *, struct tcpcb *,
- int, int, uint8_t,
- int);
- int (*tfb_tcp_ctloutput)(struct socket *so, struct sockopt *sopt,
- struct inpcb *inp, struct tcpcb *tp);
- /* Optional memory allocation/free routine */
- void (*tfb_tcp_fb_init)(struct tcpcb *);
- void (*tfb_tcp_fb_fini)(struct tcpcb *, int);
- /* Optional timers, must define all if you define one */
- int (*tfb_tcp_timer_stop_all)(struct tcpcb *);
- void (*tfb_tcp_timer_activate)(struct tcpcb *,
- uint32_t, u_int);
- int (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
- void (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
- void (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
- int (*tfb_tcp_handoff_ok)(struct tcpcb *);
- volatile uint32_t tfb_refcnt;
- uint32_t tfb_flags;
-};
-
-struct tcp_function {
- TAILQ_ENTRY(tcp_function) tf_next;
- struct tcp_function_block *tf_fb;
-};
-
-TAILQ_HEAD(tcp_funchead, tcp_function);
-
/*
* Tcp control block, one per tcp; fields:
* Organized for 16 byte cacheline efficiency.
*/
struct tcpcb {
struct tsegqe_head t_segq; /* segment reassembly queue */
- void *t_pspare[2]; /* new reassembly queue */
int t_segqlen; /* segment reassembly queue length */
int t_dupacks; /* consecutive dup acks recd */
@@ -197,12 +113,10 @@ struct tcpcb {
uint32_t snd_wnd; /* send window */
uint32_t snd_cwnd; /* congestion-controlled window */
- u_long snd_spare1; /* unused */
uint32_t snd_ssthresh; /* snd_cwnd size threshold for
* for slow start exponential to
* linear switch
*/
- u_long snd_spare2; /* unused */
tcp_seq snd_recover; /* for use in NewReno Fast Recovery */
u_int t_rcvtime; /* inactivity time */
@@ -210,9 +124,6 @@ struct tcpcb {
u_int t_rtttime; /* RTT measurement start time */
tcp_seq t_rtseq; /* sequence number being timed */
- u_int t_bw_spare1; /* unused */
- tcp_seq t_bw_spare2; /* unused */
-
int t_rxtcur; /* current retransmit value (ticks) */
u_int t_maxseg; /* maximum segment size */
u_int t_pmtud_saved_maxseg; /* pre-blackhole MSS */
@@ -276,33 +187,98 @@ struct tcpcb {
u_int t_tsomaxsegcount; /* TSO maximum segment count */
u_int t_tsomaxsegsize; /* TSO maximum segment size in bytes */
u_int t_flags2; /* More tcpcb flags storage */
-#if defined(_KERNEL) && defined(TCP_RFC7413)
- uint32_t t_ispare[6]; /* 5 UTO, 1 TBD */
- uint64_t t_tfo_cookie; /* TCP Fast Open cookie */
-#else
- uint32_t t_ispare[8]; /* 5 UTO, 3 TBD */
-#endif
struct tcp_function_block *t_fb;/* TCP function call block */
void *t_fb_ptr; /* Pointer to t_fb specific data */
-#if defined(_KERNEL) && defined(TCP_RFC7413)
+#ifdef TCP_RFC7413
+ uint64_t t_tfo_cookie; /* TCP Fast Open cookie */
unsigned int *t_tfo_pending; /* TCP Fast Open pending counter */
- void *t_pspare2[1]; /* 1 TCP_SIGNATURE */
-#else
- void *t_pspare2[2]; /* 1 TCP_SIGNATURE, 1 TBD */
#endif
-#if defined(_KERNEL) && defined(TCPPCAP)
+#ifdef TCPPCAP
struct mbufq t_inpkts; /* List of saved input packets. */
struct mbufq t_outpkts; /* List of saved output packets. */
-#ifdef _LP64
- uint64_t _pad[0]; /* all used! */
-#else
- uint64_t _pad[2]; /* 2 are available */
-#endif /* _LP64 */
-#else
- uint64_t _pad[6];
-#endif /* defined(_KERNEL) && defined(TCPPCAP) */
+#endif
+};
+#endif /* _KERNEL || _WANT_TCPCB */
+
+#ifdef _KERNEL
+/*
+ * Kernel variables for tcp.
+ */
+VNET_DECLARE(int, tcp_do_rfc1323);
+#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323)
+
+struct tcptemp {
+ u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
+ struct tcphdr tt_t;
};
+/*
+ * TODO: We yet need to brave plowing in
+ * to tcp_input() and the pru_usrreq() block.
+ * Right now these go to the old standards which
+ * are somewhat ok, but in the long term may
+ * need to be changed. If we do tackle tcp_input()
+ * then we need to get rid of the tcp_do_segment()
+ * function below.
+ */
+/* Flags for tcp functions */
+#define TCP_FUNC_BEING_REMOVED 0x01 /* Can no longer be referenced */
+
+/*
+ * If defining the optional tcp_timers, in the
+ * tfb_tcp_timer_stop call you must use the
+ * callout_async_drain() function with the
+ * tcp_timer_discard callback. You should check
+ * the return of callout_async_drain() and if 0
+ * increment tt_draincnt. Since the timer sub-system
+ * does not know your callbacks you must provide a
+ * stop_all function that loops through and calls
+ * tcp_timer_stop() with each of your defined timers.
+ * Adding a tfb_tcp_handoff_ok function allows the socket
+ * option to change stacks to query you even if the
+ * connection is in a later stage. You return 0 to
+ * say you can take over and run your stack, you return
+ * non-zero (an error number) to say no you can't.
+ * If the function is undefined you can only change
+ * in the early states (before connect or listen).
+ * tfb_tcp_fb_fini is changed to add a flag to tell
+ * the old stack if the tcb is being destroyed or
+ * not. A one in the flag means the TCB is being
+ * destroyed, a zero indicates its transitioning to
+ * another stack (via socket option).
+ */
+struct tcp_function_block {
+ char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
+ int (*tfb_tcp_output)(struct tcpcb *);
+ void (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *,
+ struct socket *, struct tcpcb *,
+ int, int, uint8_t,
+ int);
+ int (*tfb_tcp_ctloutput)(struct socket *so, struct sockopt *sopt,
+ struct inpcb *inp, struct tcpcb *tp);
+ /* Optional memory allocation/free routine */
+ void (*tfb_tcp_fb_init)(struct tcpcb *);
+ void (*tfb_tcp_fb_fini)(struct tcpcb *, int);
+ /* Optional timers, must define all if you define one */
+ int (*tfb_tcp_timer_stop_all)(struct tcpcb *);
+ void (*tfb_tcp_timer_activate)(struct tcpcb *,
+ uint32_t, u_int);
+ int (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
+ void (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
+ void (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
+ int (*tfb_tcp_handoff_ok)(struct tcpcb *);
+ volatile uint32_t tfb_refcnt;
+ uint32_t tfb_flags;
+};
+
+struct tcp_function {
+ TAILQ_ENTRY(tcp_function) tf_next;
+ struct tcp_function_block *tf_fb;
+};
+
+TAILQ_HEAD(tcp_funchead, tcp_function);
+#endif /* _KERNEL */
+
/*
* Flags and utility macros for the t_flags field.
*/
@@ -656,26 +632,41 @@ struct tcp_hhook_data {
/*
* TCB structure exported to user-land via sysctl(3).
+ *
+ * Fields prefixed with "xt_" are unique to the export structure, and fields
+ * with "t_" or other prefixes match corresponding fields of 'struct tcpcb'.
+ *
+ * Legend:
+ * (s) - used by userland utilities in src
+ * (p) - used by utilities in ports
+ * (3) - is known to be used by third party software not in ports
+ * (n) - no known usage
+ *
* Evil hack: declare only if in_pcb.h and sys/socketvar.h have been
* included. Not all of our clients do.
*/
#if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_)
-struct xtcp_timer {
- int tt_rexmt; /* retransmit timer */
- int tt_persist; /* retransmit persistence */
- int tt_keep; /* keepalive */
- int tt_2msl; /* 2*msl TIME_WAIT timer */
- int tt_delack; /* delayed ACK timer */
- int t_rcvtime; /* Time since last packet received */
-};
-struct xtcpcb {
- size_t xt_len;
- struct inpcb xt_inp;
- struct tcpcb xt_tp;
- struct xsocket xt_socket;
- struct xtcp_timer xt_timer;
- u_quad_t xt_alignment_hack;
-};
+struct xtcpcb {
+ size_t xt_len; /* length of this structure */
+ struct xinpcb xt_inp;
+ char xt_stack[TCP_FUNCTION_NAME_LEN_MAX]; /* (n) */
+ int64_t spare64[8];
+ int32_t t_state; /* (s,p) */
+ uint32_t t_flags; /* (s,p) */
+ int32_t t_sndzerowin; /* (s) */
+ int32_t t_sndrexmitpack; /* (s) */
+ int32_t t_rcvoopack; /* (s) */
+ int32_t t_rcvtime; /* (s) */
+ int32_t tt_rexmt; /* (s) */
+ int32_t tt_persist; /* (s) */
+ int32_t tt_keep; /* (s) */
+ int32_t tt_2msl; /* (s) */
+ int32_t tt_delack; /* (s) */
+ int32_t spare32[32];
+} __aligned(8);
+#ifdef _KERNEL
+void tcp_inptoxtp(const struct inpcb *, struct xtcpcb *);
+#endif
#endif
/*
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 8245603c3350..eaeb0b03152d 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -905,13 +905,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
- bzero(&xi, sizeof(xi));
- xi.xi_len = sizeof xi;
- /* XXX should avoid extra copy */
- bcopy(inp, &xi.xi_inp, sizeof *inp);
- if (inp->inp_socket)
- sotoxsocket(inp->inp_socket, &xi.xi_socket);
- xi.xi_inp.inp_gencnt = inp->inp_gencnt;
+ in_pcbtoxinpcb(inp, &xi);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xi, sizeof xi);
} else
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 3298e75b8bf5..524ea46618c8 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1200025 /* Master, propagated to newvers */
+#define __FreeBSD_version 1200026 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index 2b05ef2f80d9..40256ada49e1 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -91,7 +91,7 @@ static int udp_done, tcp_done, sdp_done;
#endif /* INET6 */
static int
-pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused)
+pcblist_sysctl(int proto, const char *name, char **bufp)
{
const char *mibvar;
char *buf;
@@ -181,120 +181,6 @@ sotoxsocket(struct socket *so, struct xsocket *xso)
return (0);
}
-static int
-pcblist_kvm(u_long off, char **bufp, int istcp)
-{
- struct inpcbinfo pcbinfo;
- struct inpcbhead listhead;
- struct inpcb *inp;
- struct xinpcb xi;
- struct xinpgen xig;
- struct xtcpcb xt;
- struct socket so;
- struct xsocket *xso;
- char *buf, *p;
- size_t len;
-
- if (off == 0)
- return (0);
- kread(off, &pcbinfo, sizeof(pcbinfo));
- if (istcp)
- len = 2 * sizeof(xig) +
- (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) *
- sizeof(struct xtcpcb);
- else
- len = 2 * sizeof(xig) +
- (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) *
- sizeof(struct xinpcb);
- if ((buf = malloc(len)) == NULL) {
- xo_warnx("malloc %lu bytes", (u_long)len);
- return (0);
- }
- p = buf;
-
-#define COPYOUT(obj, size) do { \
- if (len < (size)) { \
- xo_warnx("buffer size exceeded"); \
- goto fail; \
- } \
- bcopy((obj), p, (size)); \
- len -= (size); \
- p += (size); \
-} while (0)
-
-#define KREAD(off, buf, len) do { \
- if (kread((uintptr_t)(off), (buf), (len)) != 0) \
- goto fail; \
-} while (0)
-
- /* Write out header. */
- xig.xig_len = sizeof xig;
- xig.xig_count = pcbinfo.ipi_count;
- xig.xig_gen = pcbinfo.ipi_gencnt;
- xig.xig_sogen = 0;
- COPYOUT(&xig, sizeof xig);
-
- /* Walk the PCB list. */
- xt.xt_len = sizeof xt;
- xi.xi_len = sizeof xi;
- if (istcp)
- xso = &xt.xt_socket;
- else
- xso = &xi.xi_socket;
- KREAD(pcbinfo.ipi_listhead, &listhead, sizeof(listhead));
- LIST_FOREACH(inp, &listhead, inp_list) {
- if (istcp) {
- KREAD(inp, &xt.xt_inp, sizeof(*inp));
- inp = &xt.xt_inp;
- } else {
- KREAD(inp, &xi.xi_inp, sizeof(*inp));
- inp = &xi.xi_inp;
- }
-
- if (inp->inp_gencnt > pcbinfo.ipi_gencnt)
- continue;
-
- if (istcp) {
- if (inp->inp_ppcb == NULL)
- bzero(&xt.xt_tp, sizeof xt.xt_tp);
- else if (inp->inp_flags & INP_TIMEWAIT) {
- bzero(&xt.xt_tp, sizeof xt.xt_tp);
- xt.xt_tp.t_state = TCPS_TIME_WAIT;
- } else
- KREAD(inp->inp_ppcb, &xt.xt_tp,
- sizeof xt.xt_tp);
- }
- if (inp->inp_socket) {
- KREAD(inp->inp_socket, &so, sizeof(so));
- if (sotoxsocket(&so, xso) != 0)
- goto fail;
- } else {
- bzero(xso, sizeof(*xso));
- if (istcp)
- xso->xso_protocol = IPPROTO_TCP;
- }
- if (istcp)
- COPYOUT(&xt, sizeof xt);
- else
- COPYOUT(&xi, sizeof xi);
- }
-
- /* Reread the pcbinfo and write out the footer. */
- kread(off, &pcbinfo, sizeof(pcbinfo));
- xig.xig_count = pcbinfo.ipi_count;
- xig.xig_gen = pcbinfo.ipi_gencnt;
- COPYOUT(&xig, sizeof xig);
-
- *bufp = buf;
- return (1);
-
-fail:
- free(buf);
- return (0);
-#undef COPYOUT
-#undef KREAD
-}
-
/*
* Print a summary of connections related to an Internet
* protocol. For TCP, also give state of connection.
@@ -304,15 +190,14 @@ fail:
void
protopr(u_long off, const char *name, int af1, int proto)
{
- int istcp;
static int first = 1;
+ int istcp;
char *buf;
const char *vchar;
- struct tcpcb *tp = NULL;
- struct inpcb *inp;
+ struct xtcpcb *tp;
+ struct xinpcb *inp;
struct xinpgen *xig, *oxig;
struct xsocket *so;
- struct xtcp_timer *timer;
istcp = 0;
switch (proto) {
@@ -341,28 +226,21 @@ protopr(u_long off, const char *name, int af1, int proto)
#endif
break;
}
- if (live) {
- if (!pcblist_sysctl(proto, name, &buf, istcp))
- return;
- } else {
- if (!pcblist_kvm(off, &buf, istcp))
- return;
- }
+
+ if (!pcblist_sysctl(proto, name, &buf))
+ return;
oxig = xig = (struct xinpgen *)buf;
for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
xig->xig_len > sizeof(struct xinpgen);
xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
if (istcp) {
- timer = &((struct xtcpcb *)xig)->xt_timer;
- tp = &((struct xtcpcb *)xig)->xt_tp;
- inp = &((struct xtcpcb *)xig)->xt_inp;
- so = &((struct xtcpcb *)xig)->xt_socket;
+ tp = (struct xtcpcb *)xig;
+ inp = &tp->xt_inp;
} else {
- inp = &((struct xinpcb *)xig)->xi_inp;
- so = &((struct xinpcb *)xig)->xi_socket;
- timer = NULL;
+ inp = (struct xinpcb *)xig;
}
+ so = &inp->xi_socket;
/* Ignore sockets for protocols other than the desired one. */
if (so->xso_protocol != proto)
@@ -574,25 +452,25 @@ protopr(u_long off, const char *name, int af1, int proto)
so->so_rcv.sb_lowat, so->so_snd.sb_lowat,
so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt,
so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax);
- if (timer != NULL)
+ if (istcp)
xo_emit(" {:retransmit-timer/%4d.%02d} "
"{:persist-timer/%4d.%02d} "
"{:keepalive-timer/%4d.%02d} "
"{:msl2-timer/%4d.%02d} "
"{:delay-ack-timer/%4d.%02d} "
"{:inactivity-timer/%4d.%02d}",
- timer->tt_rexmt / 1000,
- (timer->tt_rexmt % 1000) / 10,
- timer->tt_persist / 1000,
- (timer->tt_persist % 1000) / 10,
- timer->tt_keep / 1000,
- (timer->tt_keep % 1000) / 10,
- timer->tt_2msl / 1000,
- (timer->tt_2msl % 1000) / 10,
- timer->tt_delack / 1000,
- (timer->tt_delack % 1000) / 10,
- timer->t_rcvtime / 1000,
- (timer->t_rcvtime % 1000) / 10);
+ tp->tt_rexmt / 1000,
+ (tp->tt_rexmt % 1000) / 10,
+ tp->tt_persist / 1000,
+ (tp->tt_persist % 1000) / 10,
+ tp->tt_keep / 1000,
+ (tp->tt_keep % 1000) / 10,
+ tp->tt_2msl / 1000,
+ (tp->tt_2msl % 1000) / 10,
+ tp->tt_delack / 1000,
+ (tp->tt_delack % 1000) / 10,
+ tp->t_rcvtime / 1000,
+ (tp->t_rcvtime % 1000) / 10);
}
if (istcp && !Lflag && !xflag && !Tflag && !Rflag) {
if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index dea195c387b1..97add95457a8 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -562,7 +562,6 @@ gather_inet(int proto)
struct xinpgen *xig, *exig;
struct xinpcb *xip;
struct xtcpcb *xtp;
- struct inpcb *inp;
struct xsocket *so;
struct sock *sock;
struct addr *laddr, *faddr;
@@ -625,54 +624,52 @@ gather_inet(int proto)
xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
if (xig >= exig)
break;
- xip = (struct xinpcb *)xig;
- xtp = (struct xtcpcb *)xig;
switch (proto) {
case IPPROTO_TCP:
+ xtp = (struct xtcpcb *)xig;
+ xip = &xtp->xt_inp;
if (xtp->xt_len != sizeof(*xtp)) {
warnx("struct xtcpcb size mismatch");
goto out;
}
- inp = &xtp->xt_inp;
- so = &xtp->xt_socket;
- protoname = xtp->xt_tp.t_flags & TF_TOE ? "toe" : "tcp";
+ protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
break;
case IPPROTO_UDP:
case IPPROTO_DIVERT:
+ xip = (struct xinpcb *)xig;
if (xip->xi_len != sizeof(*xip)) {
warnx("struct xinpcb size mismatch");
goto out;
}
- inp = &xip->xi_inp;
- so = &xip->xi_socket;
break;
default:
errx(1, "protocol %d not supported", proto);
}
- if ((inp->inp_vflag & vflag) == 0)
+ so = &xip->xi_socket;
+ if ((xip->inp_vflag & vflag) == 0)
continue;
- if (inp->inp_vflag & INP_IPV4) {
- if ((inp->inp_fport == 0 && !opt_l) ||
- (inp->inp_fport != 0 && !opt_c))
+ if (xip->inp_vflag & INP_IPV4) {
+ if ((xip->inp_fport == 0 && !opt_l) ||
+ (xip->inp_fport != 0 && !opt_c))
continue;
#define __IN_IS_ADDR_LOOPBACK(pina) \
((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
if (opt_L &&
- (__IN_IS_ADDR_LOOPBACK(&inp->inp_faddr) ||
- __IN_IS_ADDR_LOOPBACK(&inp->inp_laddr)))
+ (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
+ __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
continue;
#undef __IN_IS_ADDR_LOOPBACK
- } else if (inp->inp_vflag & INP_IPV6) {
- if ((inp->inp_fport == 0 && !opt_l) ||
- (inp->inp_fport != 0 && !opt_c))
+ } else if (xip->inp_vflag & INP_IPV6) {
+ if ((xip->inp_fport == 0 && !opt_l) ||
+ (xip->inp_fport != 0 && !opt_c))
continue;
if (opt_L &&
- (IN6_IS_ADDR_LOOPBACK(&inp->in6p_faddr) ||
- IN6_IS_ADDR_LOOPBACK(&inp->in6p_laddr)))
+ (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
+ IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
continue;
} else {
if (opt_v)
- warnx("invalid vflag 0x%x", inp->inp_vflag);
+ warnx("invalid vflag 0x%x", xip->inp_vflag);
continue;
}
if ((sock = calloc(1, sizeof(*sock))) == NULL)
@@ -683,26 +680,26 @@ gather_inet(int proto)
err(1, "malloc()");
sock->socket = so->xso_so;
sock->proto = proto;
- if (inp->inp_vflag & INP_IPV4) {
+ if (xip->inp_vflag & INP_IPV4) {
sock->family = AF_INET;
sockaddr(&laddr->address, sock->family,
- &inp->inp_laddr, inp->inp_lport);
+ &xip->inp_laddr, xip->inp_lport);
sockaddr(&faddr->address, sock->family,
- &inp->inp_faddr, inp->inp_fport);
- } else if (inp->inp_vflag & INP_IPV6) {
+ &xip->inp_faddr, xip->inp_fport);
+ } else if (xip->inp_vflag & INP_IPV6) {
sock->family = AF_INET6;
sockaddr(&laddr->address, sock->family,
- &inp->in6p_laddr, inp->inp_lport);
+ &xip->in6p_laddr, xip->inp_lport);
sockaddr(&faddr->address, sock->family,
- &inp->in6p_faddr, inp->inp_fport);
+ &xip->in6p_faddr, xip->inp_fport);
}
laddr->next = NULL;
faddr->next = NULL;
sock->laddr = laddr;
sock->faddr = faddr;
- sock->vflag = inp->inp_vflag;
+ sock->vflag = xip->inp_vflag;
if (proto == IPPROTO_TCP)
- sock->state = xtp->xt_tp.t_state;
+ sock->state = xtp->t_state;
sock->protoname = protoname;
hash = (int)((uintptr_t)sock->socket % HASHSIZE);
sock->next = sockhash[hash];
diff --git a/usr.bin/systat/extern.h b/usr.bin/systat/extern.h
index 1e214df3d08d..5d92f88f4b66 100644
--- a/usr.bin/systat/extern.h
+++ b/usr.bin/systat/extern.h
@@ -56,7 +56,7 @@ extern int protos;
extern int verbose;
extern unsigned int delay;
-struct inpcb;
+struct in_conninfo;
extern struct device_selection *dev_select;
extern long generation;
@@ -67,8 +67,8 @@ extern long select_generation;
extern struct nlist namelist[];
-int checkhost(struct inpcb *);
-int checkport(struct inpcb *);
+int checkhost(struct in_conninfo *);
+int checkport(struct in_conninfo *);
void closeicmp(WINDOW *);
void closeicmp6(WINDOW *);
void closeifstat(WINDOW *);
diff --git a/usr.bin/systat/netcmds.c b/usr.bin/systat/netcmds.c
index 084496804479..f8ff64a35c99 100644
--- a/usr.bin/systat/netcmds.c
+++ b/usr.bin/systat/netcmds.c
@@ -224,13 +224,13 @@ selectport(long port, int onoff)
}
int
-checkport(struct inpcb *inp)
+checkport(struct in_conninfo *inc)
{
struct pitem *p;
if (ports)
for (p = ports; p < ports+nports; p++)
- if (p->port == inp->inp_lport || p->port == inp->inp_fport)
+ if (p->port == inc->inc_lport || p->port == inc->inc_fport)
return (p->onoff);
return (1);
}
@@ -281,14 +281,14 @@ selecthost(struct in_addr *in, int onoff)
}
int
-checkhost(struct inpcb *inp)
+checkhost(struct in_conninfo *inc)
{
struct hitem *p;
if (hosts)
for (p = hosts; p < hosts+nhosts; p++)
- if (p->addr.s_addr == inp->inp_laddr.s_addr ||
- p->addr.s_addr == inp->inp_faddr.s_addr)
+ if (p->addr.s_addr == inc->inc_laddr.s_addr ||
+ p->addr.s_addr == inc->inc_faddr.s_addr)
return (p->onoff);
return (1);
}
diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c
index 0ac2244b25b2..5ab367a0a878 100644
--- a/usr.bin/systat/netstat.c
+++ b/usr.bin/systat/netstat.c
@@ -52,6 +52,7 @@ static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93";
#ifdef INET6
#include <netinet/ip6.h>
#endif
+#define _WANT_INPCB
#include <netinet/in_pcb.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp_var.h>
@@ -62,6 +63,7 @@ static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93";
#define TCPSTATES
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_timer.h>
+#define _WANT_TCPCB
#include <netinet/tcp_var.h>
#include <netinet/tcp_debug.h>
#include <netinet/udp.h>
@@ -76,9 +78,9 @@ static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93";
#include "systat.h"
#include "extern.h"
-static struct netinfo *enter(struct inpcb *, int, const char *);
+static struct netinfo *enter(struct in_conninfo *, uint8_t, int, const char *);
static void enter_kvm(struct inpcb *, struct socket *, int, const char *);
-static void enter_sysctl(struct inpcb *, struct xsocket *, int, const char *);
+static void enter_sysctl(struct xinpcb *, struct xsocket *, int, const char *);
static void fetchnetstat_kvm(void);
static void fetchnetstat_sysctl(void);
static char *inetname(struct sockaddr *);
@@ -212,9 +214,9 @@ again:
}
#endif
}
- if (nhosts && !checkhost(&inpcb))
+ if (nhosts && !checkhost(&inpcb.inp_inc))
continue;
- if (nports && !checkport(&inpcb))
+ if (nports && !checkport(&inpcb.inp_inc))
continue;
if (istcp) {
if (inpcb.inp_flags & INP_TIMEWAIT) {
@@ -245,7 +247,6 @@ fetchnetstat_sysctl(void)
int idx;
struct xinpgen *inpg;
char *cur, *end;
- struct inpcb *inpcb;
struct xinpcb *xip = NULL;
struct xtcpcb *xtp = NULL;
int plen;
@@ -291,37 +292,36 @@ fetchnetstat_sysctl(void)
while (cur + plen <= end) {
if (idx == 0) { /* TCP */
xtp = (struct xtcpcb *)cur;
- inpcb = &xtp->xt_inp;
+ xip = &xtp->xt_inp;
} else {
xip = (struct xinpcb *)cur;
- inpcb = &xip->xi_inp;
}
cur += plen;
if (!aflag) {
- if (inpcb->inp_vflag & INP_IPV4) {
- if (inet_lnaof(inpcb->inp_laddr) ==
+ if (xip->inp_vflag & INP_IPV4) {
+ if (inet_lnaof(xip->inp_laddr) ==
INADDR_ANY)
continue;
}
#ifdef INET6
- else if (inpcb->inp_vflag & INP_IPV6) {
- if (memcmp(&inpcb->in6p_laddr,
+ else if (xip->inp_vflag & INP_IPV6) {
+ if (memcmp(&xip->in6p_laddr,
&in6addr_any, sizeof(in6addr_any))
== 0)
continue;
}
#endif
}
- if (nhosts && !checkhost(inpcb))
+ if (nhosts && !checkhost(&xip->inp_inc))
continue;
- if (nports && !checkport(inpcb))
+ if (nports && !checkport(&xip->inp_inc))
continue;
- if (idx == 0) /* TCP */
- enter_sysctl(inpcb, &xtp->xt_socket,
- xtp->xt_tp.t_state, "tcp");
- else /* UDP */
- enter_sysctl(inpcb, &xip->xi_socket, 0, "udp");
+ if (idx == 0)
+ enter_sysctl(xip, &xip->xi_socket,
+ xtp->t_state, "tcp");
+ else
+ enter_sysctl(xip, &xip->xi_socket, 0, "udp");
}
free(inpg);
}
@@ -332,25 +332,26 @@ enter_kvm(struct inpcb *inp, struct socket *so, int state, const char *proto)
{
struct netinfo *p;
- if ((p = enter(inp, state, proto)) != NULL) {
+ if ((p = enter(&inp->inp_inc, inp->inp_vflag, state, proto)) != NULL) {
p->ni_rcvcc = so->so_rcv.sb_ccc;
p->ni_sndcc = so->so_snd.sb_ccc;
}
}
static void
-enter_sysctl(struct inpcb *inp, struct xsocket *so, int state, const char *proto)
+enter_sysctl(struct xinpcb *xip, struct xsocket *so, int state,
+ const char *proto)
{
struct netinfo *p;
- if ((p = enter(inp, state, proto)) != NULL) {
+ if ((p = enter(&xip->inp_inc, xip->inp_vflag, state, proto)) != NULL) {
p->ni_rcvcc = so->so_rcv.sb_cc;
p->ni_sndcc = so->so_snd.sb_cc;
}
}
static struct netinfo *
-enter(struct inpcb *inp, int state, const char *proto)
+enter(struct in_conninfo *inc, uint8_t vflag, int state, const char *proto)
{
struct netinfo *p;
struct sockaddr_storage lsa, fsa;
@@ -361,32 +362,32 @@ enter(struct inpcb *inp, int state, const char *proto)
memset(&lsa, 0, sizeof(lsa));
memset(&fsa, 0, sizeof(fsa));
- if (inp->inp_vflag & INP_IPV4) {
+ if (vflag & INP_IPV4) {
sa4 = (struct sockaddr_in *)&lsa;
- sa4->sin_addr = inp->inp_laddr;
- sa4->sin_port = inp->inp_lport;
+ sa4->sin_addr = inc->inc_laddr;
+ sa4->sin_port = inc->inc_lport;
sa4->sin_family = AF_INET;
sa4->sin_len = sizeof(struct sockaddr_in);
sa4 = (struct sockaddr_in *)&fsa;
- sa4->sin_addr = inp->inp_faddr;
- sa4->sin_port = inp->inp_fport;
+ sa4->sin_addr = inc->inc_faddr;
+ sa4->sin_port = inc->inc_fport;
sa4->sin_family = AF_INET;
sa4->sin_len = sizeof(struct sockaddr_in);
}
#ifdef INET6
- else if (inp->inp_vflag & INP_IPV6) {
+ else if (vflag & INP_IPV6) {
sa6 = (struct sockaddr_in6 *)&lsa;
- memcpy(&sa6->sin6_addr, &inp->in6p_laddr,
+ memcpy(&sa6->sin6_addr, &inc->inc6_laddr,
sizeof(struct in6_addr));
- sa6->sin6_port = inp->inp_lport;
+ sa6->sin6_port = inc->inc_lport;
sa6->sin6_family = AF_INET6;
sa6->sin6_len = sizeof(struct sockaddr_in6);
sa6 = (struct sockaddr_in6 *)&fsa;
- memcpy(&sa6->sin6_addr, &inp->in6p_faddr,
+ memcpy(&sa6->sin6_addr, &inc->inc6_faddr,
sizeof(struct in6_addr));
- sa6->sin6_port = inp->inp_fport;
+ sa6->sin6_port = inc->inc_fport;
sa6->sin6_family = AF_INET6;
sa6->sin6_len = sizeof(struct sockaddr_in6);
}
diff --git a/usr.sbin/tcpdrop/tcpdrop.c b/usr.sbin/tcpdrop/tcpdrop.c
index ef3f6bddf3d1..03667e4d8101 100644
--- a/usr.sbin/tcpdrop/tcpdrop.c
+++ b/usr.sbin/tcpdrop/tcpdrop.c
@@ -205,9 +205,8 @@ static bool
tcpdropall(void)
{
struct xinpgen *head, *xinp;
- struct xtcpcb *xpcb;
- struct tcpcb *tp;
- struct inpcb *inp;
+ struct xtcpcb *xtp;
+ struct xinpcb *xip;
bool ok;
ok = true;
@@ -219,9 +218,8 @@ tcpdropall(void)
for (xinp = XINP_NEXT(head); xinp->xig_len > sizeof *xinp;
xinp = XINP_NEXT(xinp)) {
- xpcb = (struct xtcpcb *)xinp;
- tp = &xpcb->xt_tp;
- inp = &xpcb->xt_inp;
+ xtp = (struct xtcpcb *)xinp;
+ xip = &xtp->xt_inp;
/*
* XXX
@@ -229,14 +227,14 @@ tcpdropall(void)
*/
/* Ignore PCBs which were freed during copyout. */
- if (inp->inp_gencnt > head->xig_gen)
+ if (xip->inp_gencnt > head->xig_gen)
continue;
/* Skip listening sockets. */
- if (tp->t_state == TCPS_LISTEN)
+ if (xtp->t_state == TCPS_LISTEN)
continue;
- if (!tcpdropconn(&inp->inp_inc))
+ if (!tcpdropconn(&xip->inp_inc))
ok = false;
}
free(head);
diff --git a/usr.sbin/trpt/trpt.c b/usr.sbin/trpt/trpt.c
index fd6edca23190..09e2422219a1 100644
--- a/usr.sbin/trpt/trpt.c
+++ b/usr.sbin/trpt/trpt.c
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_seq.h>
#define TCPTIMERS
#include <netinet/tcp_timer.h>
+#define _WANT_TCPCB
#include <netinet/tcp_var.h>
#include <netinet/tcpip.h>
#define TANAMES