Hi!

  This change is known to break a ton of ports. More than 100 if
counting depends. I'm sorry for that and I already started to fix
them.

Please send all new breakages to me.

On Tue, Mar 21, 2017 at 06:39:49AM +0000, Gleb Smirnoff wrote:
T> Author: glebius
T> Date: Tue Mar 21 06:39:49 2017
T> New Revision: 315662
T> URL: https://svnweb.freebsd.org/changeset/base/315662
T> 
T> Log:
T>   Hide struct inpcb, struct tcpcb from the userland.
T>   
T>   This is a painful change, but it is needed.  On the one hand, we avoid
T>   modifying them, and this slows down some ideas, on the other hand we still
T>   eventually modify them and tools like netstat(1) never work on next 
version of
T>   FreeBSD.  We maintain a ton of spares in them, and we already got some 
ifdef
T>   hell at the end of tcpcb.
T>   
T>   Details:
T>   - Hide struct inpcb, struct tcpcb under _KERNEL || _WANT_FOO.
T>   - Make struct xinpcb, struct xtcpcb pure API structures, not including
T>     kernel structures inpcb and tcpcb inside.  Export into these structures
T>     the fields from inpcb and tcpcb that are known to be used, and put there
T>     a ton of spare space.
T>   - Make kernel and userland utilities compilable after these changes.
T>   - Bump __FreeBSD_version.
T>   
T>   Reviewed by:       rrs, gnn
T>   Differential Revision:     D10018
T> 
T> Modified:
T>   head/contrib/bsnmp/snmp_mibII/mibII_tcp.c
T>   head/contrib/bsnmp/snmp_mibII/mibII_udp.c
T>   head/contrib/ipfilter/ipsend/sock.c
T>   head/lib/libprocstat/libprocstat.c
T>   head/sys/netinet/in_pcb.c
T>   head/sys/netinet/in_pcb.h
T>   head/sys/netinet/ip_divert.c
T>   head/sys/netinet/raw_ip.c
T>   head/sys/netinet/tcp_subr.c
T>   head/sys/netinet/tcp_syncache.c
T>   head/sys/netinet/tcp_timer.c
T>   head/sys/netinet/tcp_timer.h
T>   head/sys/netinet/tcp_var.h
T>   head/sys/netinet/udp_usrreq.c
T>   head/sys/sys/param.h
T>   head/usr.bin/netstat/inet.c
T>   head/usr.bin/sockstat/sockstat.c
T>   head/usr.bin/systat/extern.h
T>   head/usr.bin/systat/netcmds.c
T>   head/usr.bin/systat/netstat.c
T>   head/usr.sbin/tcpdrop/tcpdrop.c
T>   head/usr.sbin/trpt/trpt.c
T> 
T> Modified: head/contrib/bsnmp/snmp_mibII/mibII_tcp.c
T> 
==============================================================================
T> --- head/contrib/bsnmp/snmp_mibII/mibII_tcp.c        Tue Mar 21 05:15:10 
2017        (r315661)
T> +++ head/contrib/bsnmp/snmp_mibII/mibII_tcp.c        Tue Mar 21 06:39:49 
2017        (r315662)
T> @@ -310,7 +310,7 @@ op_tcpconn(struct snmp_context *ctx __un
T>      switch (value->var.subs[sub - 1]) {
T>  
T>        case LEAF_tcpConnState:
T> -            switch (tcpoids[i].tp->xt_tp.t_state) {
T> +            switch (tcpoids[i].tp->t_state) {
T>  
T>                case TCPS_CLOSED:
T>                      value->v.integer = 1;
T> 
T> Modified: head/contrib/bsnmp/snmp_mibII/mibII_udp.c
T> 
==============================================================================
T> --- head/contrib/bsnmp/snmp_mibII/mibII_udp.c        Tue Mar 21 05:15:10 
2017        (r315661)
T> +++ head/contrib/bsnmp/snmp_mibII/mibII_udp.c        Tue Mar 21 06:39:49 
2017        (r315662)
T> @@ -105,8 +105,8 @@ fetch_udp(void)
T>           ptr->xig_len > sizeof(struct xinpgen);
T>               ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
T>              inp = (struct xinpcb *)ptr;
T> -            if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen ||
T> -                (inp->xi_inp.inp_vflag & INP_IPV4) == 0)
T> +            if (inp->inp_gencnt > xinpgen->xig_gen ||
T> +                (inp->inp_vflag & INP_IPV4) == 0)
T>                      continue;
T>  
T>              udp_total++;
T> @@ -128,17 +128,17 @@ fetch_udp(void)
T>           ptr->xig_len > sizeof(struct xinpgen);
T>               ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
T>              inp = (struct xinpcb *)ptr;
T> -            if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen ||
T> -                (inp->xi_inp.inp_vflag & INP_IPV4) == 0)
T> +            if (inp->inp_gencnt > xinpgen->xig_gen ||
T> +                (inp->inp_vflag & INP_IPV4) == 0)
T>                      continue;
T>              oid->inp = inp;
T>              oid->index.len = 5;
T> -            inaddr = ntohl(inp->xi_inp.inp_laddr.s_addr);
T> +            inaddr = ntohl(inp->inp_laddr.s_addr);
T>              oid->index.subs[0] = (inaddr >> 24) & 0xff;
T>              oid->index.subs[1] = (inaddr >> 16) & 0xff;
T>              oid->index.subs[2] = (inaddr >>  8) & 0xff;
T>              oid->index.subs[3] = (inaddr >>  0) & 0xff;
T> -            oid->index.subs[4] = ntohs(inp->xi_inp.inp_lport);
T> +            oid->index.subs[4] = ntohs(inp->inp_lport);
T>              oid++;
T>      }
T>  
T> 
T> Modified: head/contrib/ipfilter/ipsend/sock.c
T> 
==============================================================================
T> --- head/contrib/ipfilter/ipsend/sock.c      Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/contrib/ipfilter/ipsend/sock.c      Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -78,8 +78,10 @@ typedef int     boolean_t;
T>  # include <net/route.h>
T>  #endif
T>  #include <netinet/ip_var.h>
T> +#define     _WANT_INPCB
T>  #include <netinet/in_pcb.h>
T>  #include <netinet/tcp_timer.h>
T> +#define     _WANT_TCPCB
T>  #include <netinet/tcp_var.h>
T>  #include <stdio.h>
T>  #include <unistd.h>
T> 
T> Modified: head/lib/libprocstat/libprocstat.c
T> 
==============================================================================
T> --- head/lib/libprocstat/libprocstat.c       Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/lib/libprocstat/libprocstat.c       Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
T>  #include <netinet/in.h>
T>  #include <netinet/in_systm.h>
T>  #include <netinet/ip.h>
T> +#define     _WANT_INPCB
T>  #include <netinet/in_pcb.h>
T>  
T>  #include <assert.h>
T> 
T> Modified: head/sys/netinet/in_pcb.c
T> 
==============================================================================
T> --- head/sys/netinet/in_pcb.c        Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/in_pcb.c        Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -2434,6 +2434,41 @@ so_sototcpcb(struct socket *so)
T>      return (sototcpcb(so));
T>  }
T>  
T> +/*
T> + * Create an external-format (``xinpcb'') structure using the information in
T> + * the kernel-format in_pcb structure pointed to by inp.  This is done to
T> + * reduce the spew of irrelevant information over this interface, to isolate
T> + * user code from changes in the kernel structure, and potentially to 
provide
T> + * information-hiding if we decide that some of this information should be
T> + * hidden from users.
T> + */
T> +void
T> +in_pcbtoxinpcb(const struct inpcb *inp, struct xinpcb *xi)
T> +{
T> +
T> +    xi->xi_len = sizeof(struct xinpcb);
T> +    if (inp->inp_socket)
T> +            sotoxsocket(inp->inp_socket, &xi->xi_socket);
T> +    else
T> +            bzero(&xi->xi_socket, sizeof(struct xsocket));
T> +    bcopy(&inp->inp_inc, &xi->inp_inc, sizeof(struct in_conninfo));
T> +    xi->inp_gencnt = inp->inp_gencnt;
T> +    xi->inp_ppcb = inp->inp_ppcb;
T> +    xi->inp_flow = inp->inp_flow;
T> +    xi->inp_flowid = inp->inp_flowid;
T> +    xi->inp_flowtype = inp->inp_flowtype;
T> +    xi->inp_flags = inp->inp_flags;
T> +    xi->inp_flags2 = inp->inp_flags2;
T> +    xi->inp_rss_listen_bucket = inp->inp_rss_listen_bucket;
T> +    xi->in6p_cksum = inp->in6p_cksum;
T> +    xi->in6p_hops = inp->in6p_hops;
T> +    xi->inp_ip_tos = inp->inp_ip_tos;
T> +    xi->inp_vflag = inp->inp_vflag;
T> +    xi->inp_ip_ttl = inp->inp_ip_ttl;
T> +    xi->inp_ip_p = inp->inp_ip_p;
T> +    xi->inp_ip_minttl = inp->inp_ip_minttl;
T> +}
T> +
T>  #ifdef DDB
T>  static void
T>  db_print_indent(int indent)
T> 
T> Modified: head/sys/netinet/in_pcb.h
T> 
==============================================================================
T> --- head/sys/netinet/in_pcb.h        Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/in_pcb.h        Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -53,7 +53,6 @@
T>  
T>  #define     in6pcb          inpcb   /* for KAME src sync over BSD*'s */
T>  #define     in6p_sp         inp_sp  /* for KAME src sync over BSD*'s */
T> -struct inpcbpolicy;
T>  
T>  /*
T>   * struct inpcb is the common protocol control block structure used in most
T> @@ -65,7 +64,7 @@ struct inpcbpolicy;
T>   */
T>  LIST_HEAD(inpcbhead, inpcb);
T>  LIST_HEAD(inpcbporthead, inpcbport);
T> -typedef     u_quad_t        inp_gen_t;
T> +typedef     uint64_t        inp_gen_t;
T>  
T>  /*
T>   * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
T> @@ -130,9 +129,8 @@ struct in_conninfo {
T>  #define     inc6_laddr      inc_ie.ie6_laddr
T>  #define     inc6_zoneid     inc_ie.ie6_zoneid
T>  
T> -struct      icmp6_filter;
T> -
T> -/*-
T> +#if defined(_KERNEL) || defined(_WANT_INPCB)
T> +/*
T>   * struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 
and
T>   * IPv6 sockets.  In the case of TCP and UDP, further per-connection state 
is
T>   * hung off of inp_ppcb most of the time.  Almost all fields of struct inpcb
T> @@ -181,6 +179,8 @@ struct   icmp6_filter;
T>   * read-lock usage during modification, this model can be applied to other
T>   * protocols (especially SCTP).
T>   */
T> +struct icmp6_filter;
T> +struct inpcbpolicy;
T>  struct m_snd_tag;
T>  struct inpcb {
T>      LIST_ENTRY(inpcb) inp_hash;     /* (h/i) hash list */
T> @@ -204,10 +204,8 @@ struct inpcb {
T>      uint32_t inp_flowid;            /* (x) flow id / queue id */
T>      u_int   inp_refcount;           /* (i) refcount */
T>      struct m_snd_tag *inp_snd_tag;  /* (i) send tag for outgoing mbufs */
T> -    void    *inp_pspare[4];         /* (x) general use */
T>      uint32_t inp_flowtype;          /* (x) M_HASHTYPE value */
T>      uint32_t inp_rss_listen_bucket; /* (x) overridden RSS listen bucket */
T> -    u_int   inp_ispare[4];          /* (x) user cookie / general use */
T>  
T>      /* Local and foreign ports, local and foreign addr. */
T>      struct  in_conninfo inp_inc;    /* (i) list for PCB's local port */
T> @@ -218,23 +216,23 @@ struct inpcb {
T>  
T>      /* Protocol-dependent part; options. */
T>      struct {
T> -            u_char  inp4_ip_tos;            /* (i) type of service proto */
T> -            struct  mbuf *inp4_options;     /* (i) IP options */
T> -            struct  ip_moptions *inp4_moptions; /* (i) IP mcast options */
T> -    } inp_depend4;
T> +            u_char  inp_ip_tos;             /* (i) type of service proto */
T> +            struct mbuf             *inp_options;   /* (i) IP options */
T> +            struct ip_moptions      *inp_moptions;  /* (i) mcast options */
T> +    };
T>      struct {
T>              /* (i) IP options */
T> -            struct  mbuf *inp6_options;
T> +            struct mbuf             *in6p_options;
T>              /* (i) IP6 options for outgoing packets */
T> -            struct  ip6_pktopts *inp6_outputopts;
T> +            struct ip6_pktopts      *in6p_outputopts;
T>              /* (i) IP multicast options */
T> -            struct  ip6_moptions *inp6_moptions;
T> +            struct ip6_moptions     *in6p_moptions;
T>              /* (i) ICMPv6 code type filter */
T> -            struct  icmp6_filter *inp6_icmp6filt;
T> +            struct icmp6_filter     *in6p_icmp6filt;
T>              /* (i) IPV6_CHECKSUM setsockopt */
T> -            int     inp6_cksum;
T> -            short   inp6_hops;
T> -    } inp_depend6;
T> +            int     in6p_cksum;
T> +            short   in6p_hops;
T> +    };
T>      LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */
T>      struct  inpcbport *inp_phd;     /* (i/h) head of this list */
T>  #define inp_zero_size offsetof(struct inpcb, inp_gencnt)
T> @@ -249,24 +247,17 @@ struct inpcb {
T>  #define inp_route inp_rtu.inpu_route
T>  #define inp_route6 inp_rtu.inpu_route6
T>  };
T> +#endif      /* _KERNEL */
T> +
T>  #define     inp_fport       inp_inc.inc_fport
T>  #define     inp_lport       inp_inc.inc_lport
T>  #define     inp_faddr       inp_inc.inc_faddr
T>  #define     inp_laddr       inp_inc.inc_laddr
T> -#define     inp_ip_tos      inp_depend4.inp4_ip_tos
T> -#define     inp_options     inp_depend4.inp4_options
T> -#define     inp_moptions    inp_depend4.inp4_moptions
T>  
T>  #define     in6p_faddr      inp_inc.inc6_faddr
T>  #define     in6p_laddr      inp_inc.inc6_laddr
T>  #define     in6p_zoneid     inp_inc.inc6_zoneid
T> -#define     in6p_hops       inp_depend6.inp6_hops   /* default hop limit */
T>  #define     in6p_flowinfo   inp_flow
T> -#define     in6p_options    inp_depend6.inp6_options
T> -#define     in6p_outputopts inp_depend6.inp6_outputopts
T> -#define     in6p_moptions   inp_depend6.inp6_moptions
T> -#define     in6p_icmp6filt  inp_depend6.inp6_icmp6filt
T> -#define     in6p_cksum      inp_depend6.inp6_cksum
T>  
T>  #define     inp_vnet        inp_pcbinfo->ipi_vnet
T>  
T> @@ -280,21 +271,53 @@ struct inpcb {
T>  /*
T>   * Interface exported to userland by various protocols which use inpcbs.  
Hack
T>   * alert -- only define if struct xsocket is in scope.
T> + * Fields prefixed with "xi_" are unique to this structure, and the rest
T> + * match fields in the struct inpcb, to ease coding and porting.
T> + *
T> + * Legend:
T> + * (s) - used by userland utilities in src
T> + * (p) - used by utilities in ports
T> + * (3) - is known to be used by third party software not in ports
T> + * (n) - no known usage
T>   */
T>  #ifdef _SYS_SOCKETVAR_H_
T> -struct      xinpcb {
T> -    size_t  xi_len;         /* length of this structure */
T> -    struct  inpcb xi_inp;
T> -    struct  xsocket xi_socket;
T> -    u_quad_t        xi_alignment_hack;
T> -};
T> -
T> -struct      xinpgen {
T> -    size_t  xig_len;        /* length of this structure */
T> -    u_int   xig_count;      /* number of PCBs at this time */
T> -    inp_gen_t xig_gen;      /* generation count at this time */
T> -    so_gen_t xig_sogen;     /* socket generation count at this time */
T> +struct xinpcb {
T> +    size_t          xi_len;         /* length of this structure */
T> +    struct xsocket  xi_socket;              /* (s,p) */
T> +    struct in_conninfo inp_inc;             /* (s,p) */
T> +    uint64_t        inp_gencnt;             /* (s,p) */
T> +    union {
T> +            void    *inp_ppcb;              /* (s) netstat(1) */
T> +            int64_t ph_ppcb;
T> +    };
T> +    int64_t         inp_spare64[4];
T> +    uint32_t        inp_flow;               /* (s) */
T> +    uint32_t        inp_flowid;             /* (s) */
T> +    uint32_t        inp_flowtype;           /* (s) */
T> +    int32_t         inp_flags;              /* (s,p) */
T> +    int32_t         inp_flags2;             /* (s) */
T> +    int32_t         inp_rss_listen_bucket;  /* (n) */
T> +    int32_t         in6p_cksum;             /* (n) */
T> +    int32_t         inp_spare32[4];
T> +    uint16_t        in6p_hops;              /* (n) */
T> +    uint8_t         inp_ip_tos;             /* (n) */
T> +    int8_t          pad8;
T> +    uint8_t         inp_vflag;              /* (s,p) */
T> +    uint8_t         inp_ip_ttl;             /* (n) */
T> +    uint8_t         inp_ip_p;               /* (n) */
T> +    uint8_t         inp_ip_minttl;          /* (n) */
T> +    int8_t          inp_spare8[4];
T> +} __aligned(8);
T> +
T> +struct xinpgen {
T> +    size_t          xig_len;        /* length of this structure */
T> +    u_int           xig_count;      /* number of PCBs at this time */
T> +    inp_gen_t       xig_gen;        /* generation count at this time */
T> +    so_gen_t        xig_sogen;      /* socket generation count this time */
T>  };
T> +#ifdef      _KERNEL
T> +void        in_pcbtoxinpcb(const struct inpcb *, struct xinpcb *);
T> +#endif
T>  #endif /* _SYS_SOCKETVAR_H_ */
T>  
T>  struct inpcbport {
T> 
T> Modified: head/sys/netinet/ip_divert.c
T> 
==============================================================================
T> --- head/sys/netinet/ip_divert.c     Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/ip_divert.c     Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -691,12 +691,8 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
T>              INP_RLOCK(inp);
T>              if (inp->inp_gencnt <= gencnt) {
T>                      struct xinpcb xi;
T> -                    bzero(&xi, sizeof(xi));
T> -                    xi.xi_len = sizeof xi;
T> -                    /* XXX should avoid extra copy */
T> -                    bcopy(inp, &xi.xi_inp, sizeof *inp);
T> -                    if (inp->inp_socket)
T> -                            sotoxsocket(inp->inp_socket, &xi.xi_socket);
T> +
T> +                    in_pcbtoxinpcb(inp, &xi);
T>                      INP_RUNLOCK(inp);
T>                      error = SYSCTL_OUT(req, &xi, sizeof xi);
T>              } else
T> 
T> Modified: head/sys/netinet/raw_ip.c
T> 
==============================================================================
T> --- head/sys/netinet/raw_ip.c        Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/raw_ip.c        Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -1077,12 +1077,7 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
T>              if (inp->inp_gencnt <= gencnt) {
T>                      struct xinpcb xi;
T>  
T> -                    bzero(&xi, sizeof(xi));
T> -                    xi.xi_len = sizeof xi;
T> -                    /* XXX should avoid extra copy */
T> -                    bcopy(inp, &xi.xi_inp, sizeof *inp);
T> -                    if (inp->inp_socket)
T> -                            sotoxsocket(inp->inp_socket, &xi.xi_socket);
T> +                    in_pcbtoxinpcb(inp, &xi);
T>                      INP_RUNLOCK(inp);
T>                      error = SYSCTL_OUT(req, &xi, sizeof xi);
T>              } else
T> 
T> Modified: head/sys/netinet/tcp_subr.c
T> 
==============================================================================
T> --- head/sys/netinet/tcp_subr.c      Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/tcp_subr.c      Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -1773,30 +1773,8 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
T>              INP_RLOCK(inp);
T>              if (inp->inp_gencnt <= gencnt) {
T>                      struct xtcpcb xt;
T> -                    void *inp_ppcb;
T>  
T> -                    bzero(&xt, sizeof(xt));
T> -                    xt.xt_len = sizeof xt;
T> -                    /* XXX should avoid extra copy */
T> -                    bcopy(inp, &xt.xt_inp, sizeof *inp);
T> -                    inp_ppcb = inp->inp_ppcb;
T> -                    if (inp_ppcb == NULL)
T> -                            bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
T> -                    else if (inp->inp_flags & INP_TIMEWAIT) {
T> -                            bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
T> -                            xt.xt_tp.t_state = TCPS_TIME_WAIT;
T> -                    } else {
T> -                            bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
T> -                            if (xt.xt_tp.t_timers)
T> -                                    tcp_timer_to_xtimer(&xt.xt_tp, 
xt.xt_tp.t_timers, &xt.xt_timer);
T> -                    }
T> -                    if (inp->inp_socket != NULL)
T> -                            sotoxsocket(inp->inp_socket, &xt.xt_socket);
T> -                    else {
T> -                            bzero(&xt.xt_socket, sizeof xt.xt_socket);
T> -                            xt.xt_socket.xso_protocol = IPPROTO_TCP;
T> -                    }
T> -                    xt.xt_inp.inp_gencnt = inp->inp_gencnt;
T> +                    tcp_inptoxtp(inp, &xt);
T>                      INP_RUNLOCK(inp);
T>                      error = SYSCTL_OUT(req, &xt, sizeof xt);
T>              } else
T> @@ -2765,3 +2743,53 @@ tcp_state_change(struct tcpcb *tp, int n
T>      tp->t_state = newstate;
T>      TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate);
T>  }
T> +
T> +/*
T> + * Create an external-format (``xtcpcb'') structure using the information in
T> + * the kernel-format tcpcb structure pointed to by tp.  This is done to
T> + * reduce the spew of irrelevant information over this interface, to isolate
T> + * user code from changes in the kernel structure, and potentially to 
provide
T> + * information-hiding if we decide that some of this information should be
T> + * hidden from users.
T> + */
T> +void
T> +tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt)
T> +{
T> +    struct tcpcb *tp = intotcpcb(inp);
T> +    sbintime_t now;
T> +
T> +    if (inp->inp_flags & INP_TIMEWAIT) {
T> +            bzero(xt, sizeof(struct xtcpcb));
T> +            xt->t_state = TCPS_TIME_WAIT;
T> +    } else {
T> +            xt->t_state = tp->t_state;
T> +            xt->t_flags = tp->t_flags;
T> +            xt->t_sndzerowin = tp->t_sndzerowin;
T> +            xt->t_sndrexmitpack = tp->t_sndrexmitpack;
T> +            xt->t_rcvoopack = tp->t_rcvoopack;
T> +
T> +            now = getsbinuptime();
T> +#define     COPYTIMER(ttt)  do {                                            
\
T> +            if (callout_active(&tp->t_timers->ttt))                 \
T> +                    xt->ttt = (tp->t_timers->ttt.c_time - now) /    \
T> +                        SBT_1MS;                                    \
T> +            else                                                    \
T> +                    xt->ttt = 0;                                    \
T> +} while (0)
T> +            COPYTIMER(tt_delack);
T> +            COPYTIMER(tt_rexmt);
T> +            COPYTIMER(tt_persist);
T> +            COPYTIMER(tt_keep);
T> +            COPYTIMER(tt_2msl);
T> +#undef COPYTIMER
T> +            xt->t_rcvtime = 1000 * (ticks - tp->t_rcvtime) / hz;
T> +
T> +            bcopy(tp->t_fb->tfb_tcp_block_name, xt->xt_stack,
T> +                TCP_FUNCTION_NAME_LEN_MAX);
T> +    }
T> +
T> +    xt->xt_len = sizeof(struct xtcpcb);
T> +    in_pcbtoxinpcb(inp, &xt->xt_inp);
T> +    if (inp->inp_socket == NULL)
T> +            xt->xt_inp.xi_socket.xso_protocol = IPPROTO_TCP;
T> +}
T> 
T> Modified: head/sys/netinet/tcp_syncache.c
T> 
==============================================================================
T> --- head/sys/netinet/tcp_syncache.c  Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/tcp_syncache.c  Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -2217,13 +2217,13 @@ syncache_pcblist(struct sysctl_req *req,
T>                              xt.xt_inp.inp_vflag = INP_IPV6;
T>                      else
T>                              xt.xt_inp.inp_vflag = INP_IPV4;
T> -                    bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc, sizeof (struct 
in_conninfo));
T> -                    xt.xt_tp.t_inpcb = &xt.xt_inp;
T> -                    xt.xt_tp.t_state = TCPS_SYN_RECEIVED;
T> -                    xt.xt_socket.xso_protocol = IPPROTO_TCP;
T> -                    xt.xt_socket.xso_len = sizeof (struct xsocket);
T> -                    xt.xt_socket.so_type = SOCK_STREAM;
T> -                    xt.xt_socket.so_state = SS_ISCONNECTING;
T> +                    bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc,
T> +                        sizeof (struct in_conninfo));
T> +                    xt.t_state = TCPS_SYN_RECEIVED;
T> +                    xt.xt_inp.xi_socket.xso_protocol = IPPROTO_TCP;
T> +                    xt.xt_inp.xi_socket.xso_len = sizeof (struct xsocket);
T> +                    xt.xt_inp.xi_socket.so_type = SOCK_STREAM;
T> +                    xt.xt_inp.xi_socket.so_state = SS_ISCONNECTING;
T>                      error = SYSCTL_OUT(req, &xt, sizeof xt);
T>                      if (error) {
T>                              SCH_UNLOCK(sch);
T> 
T> Modified: head/sys/netinet/tcp_timer.c
T> 
==============================================================================
T> --- head/sys/netinet/tcp_timer.c     Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/tcp_timer.c     Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -1006,28 +1006,3 @@ tcp_timer_stop(struct tcpcb *tp, uint32_
T>              tp->t_timers->tt_draincnt++;
T>      }
T>  }
T> -
T> -#define     ticks_to_msecs(t)       (1000*(t) / hz)
T> -
T> -void
T> -tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
T> -    struct xtcp_timer *xtimer)
T> -{
T> -    sbintime_t now;
T> -
T> -    bzero(xtimer, sizeof(*xtimer));
T> -    if (timer == NULL)
T> -            return;
T> -    now = getsbinuptime();
T> -    if (callout_active(&timer->tt_delack))
T> -            xtimer->tt_delack = (timer->tt_delack.c_time - now) / SBT_1MS;
T> -    if (callout_active(&timer->tt_rexmt))
T> -            xtimer->tt_rexmt = (timer->tt_rexmt.c_time - now) / SBT_1MS;
T> -    if (callout_active(&timer->tt_persist))
T> -            xtimer->tt_persist = (timer->tt_persist.c_time - now) / SBT_1MS;
T> -    if (callout_active(&timer->tt_keep))
T> -            xtimer->tt_keep = (timer->tt_keep.c_time - now) / SBT_1MS;
T> -    if (callout_active(&timer->tt_2msl))
T> -            xtimer->tt_2msl = (timer->tt_2msl.c_time - now) / SBT_1MS;
T> -    xtimer->t_rcvtime = ticks_to_msecs(ticks - tp->t_rcvtime);
T> -}
T> 
T> Modified: head/sys/netinet/tcp_timer.h
T> 
==============================================================================
T> --- head/sys/netinet/tcp_timer.h     Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/tcp_timer.h     Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -210,8 +210,6 @@ void     tcp_timer_keep(void *xtp);
T>  void        tcp_timer_persist(void *xtp);
T>  void        tcp_timer_rexmt(void *xtp);
T>  void        tcp_timer_delack(void *xtp);
T> -void        tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
T> -    struct xtcp_timer *xtimer);
T>  
T>  #endif /* _KERNEL */
T>  
T> 
T> Modified: head/sys/netinet/tcp_var.h
T> 
==============================================================================
T> --- head/sys/netinet/tcp_var.h       Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/tcp_var.h       Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -39,15 +39,9 @@
T>  #ifdef _KERNEL
T>  #include <net/vnet.h>
T>  #include <sys/mbuf.h>
T> +#endif
T>  
T> -/*
T> - * Kernel variables for tcp.
T> - */
T> -VNET_DECLARE(int, tcp_do_rfc1323);
T> -#define     V_tcp_do_rfc1323        VNET(tcp_do_rfc1323)
T> -
T> -#endif /* _KERNEL */
T> -
T> +#if defined(_KERNEL) || defined(_WANT_TCPCB)
T>  /* TCP segment queue entry */
T>  struct tseg_qent {
T>      LIST_ENTRY(tseg_qent) tqe_q;
T> @@ -83,90 +77,12 @@ struct sackhint {
T>      uint64_t        _pad[1];        /* TBD */
T>  };
T>  
T> -struct tcptemp {
T> -    u_char  tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
T> -    struct  tcphdr tt_t;
T> -};
T> -
T> -#define tcp6cb              tcpcb  /* for KAME src sync over BSD*'s */
T> -
T> -/* 
T> - * TODO: We yet need to brave plowing in
T> - * to tcp_input() and the pru_usrreq() block.
T> - * Right now these go to the old standards which
T> - * are somewhat ok, but in the long term may
T> - * need to be changed. If we do tackle tcp_input()
T> - * then we need to get rid of the tcp_do_segment()
T> - * function below.
T> - */
T> -/* Flags for tcp functions */
T> -#define TCP_FUNC_BEING_REMOVED 0x01         /* Can no longer be referenced 
*/
T> -struct tcpcb;
T> -struct inpcb;
T> -struct sockopt;
T> -struct socket;
T> -
T> -/*
T> - * If defining the optional tcp_timers, in the
T> - * tfb_tcp_timer_stop call you must use the
T> - * callout_async_drain() function with the
T> - * tcp_timer_discard callback. You should check
T> - * the return of callout_async_drain() and if 0
T> - * increment tt_draincnt. Since the timer sub-system
T> - * does not know your callbacks you must provide a
T> - * stop_all function that loops through and calls
T> - * tcp_timer_stop() with each of your defined timers.
T> - * Adding a tfb_tcp_handoff_ok function allows the socket
T> - * option to change stacks to query you even if the
T> - * connection is in a later stage. You return 0 to
T> - * say you can take over and run your stack, you return
T> - * non-zero (an error number) to say no you can't.
T> - * If the function is undefined you can only change
T> - * in the early states (before connect or listen).
T> - * tfb_tcp_fb_fini is changed to add a flag to tell
T> - * the old stack if the tcb is being destroyed or
T> - * not. A one in the flag means the TCB is being
T> - * destroyed, a zero indicates its transitioning to
T> - * another stack (via socket option).
T> - */
T> -struct tcp_function_block {
T> -    char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
T> -    int     (*tfb_tcp_output)(struct tcpcb *);
T> -    void    (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *,
T> -                        struct socket *, struct tcpcb *,
T> -                        int, int, uint8_t,
T> -                        int);
T> -    int     (*tfb_tcp_ctloutput)(struct socket *so, struct sockopt *sopt,
T> -                        struct inpcb *inp, struct tcpcb *tp);
T> -    /* Optional memory allocation/free routine */
T> -    void    (*tfb_tcp_fb_init)(struct tcpcb *);
T> -    void    (*tfb_tcp_fb_fini)(struct tcpcb *, int);
T> -    /* Optional timers, must define all if you define one */
T> -    int     (*tfb_tcp_timer_stop_all)(struct tcpcb *);
T> -    void    (*tfb_tcp_timer_activate)(struct tcpcb *,
T> -                        uint32_t, u_int);
T> -    int     (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
T> -    void    (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
T> -    void    (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
T> -    int     (*tfb_tcp_handoff_ok)(struct tcpcb *);
T> -    volatile uint32_t tfb_refcnt;
T> -    uint32_t  tfb_flags;
T> -};
T> -
T> -struct tcp_function {
T> -    TAILQ_ENTRY(tcp_function) tf_next;
T> -    struct tcp_function_block *tf_fb;
T> -};
T> -
T> -TAILQ_HEAD(tcp_funchead, tcp_function);
T> -
T>  /*
T>   * Tcp control block, one per tcp; fields:
T>   * Organized for 16 byte cacheline efficiency.
T>   */
T>  struct tcpcb {
T>      struct  tsegqe_head t_segq;     /* segment reassembly queue */
T> -    void    *t_pspare[2];           /* new reassembly queue */
T>      int     t_segqlen;              /* segment reassembly queue length */
T>      int     t_dupacks;              /* consecutive dup acks recd */
T>  
T> @@ -197,12 +113,10 @@ struct tcpcb {
T>  
T>      uint32_t  snd_wnd;              /* send window */
T>      uint32_t  snd_cwnd;             /* congestion-controlled window */
T> -    u_long  snd_spare1;             /* unused */
T>      uint32_t  snd_ssthresh;         /* snd_cwnd size threshold for
T>                                       * for slow start exponential to
T>                                       * linear switch
T>                                       */
T> -    u_long  snd_spare2;             /* unused */
T>      tcp_seq snd_recover;            /* for use in NewReno Fast Recovery */
T>  
T>      u_int   t_rcvtime;              /* inactivity time */
T> @@ -210,9 +124,6 @@ struct tcpcb {
T>      u_int   t_rtttime;              /* RTT measurement start time */
T>      tcp_seq t_rtseq;                /* sequence number being timed */
T>  
T> -    u_int   t_bw_spare1;            /* unused */
T> -    tcp_seq t_bw_spare2;            /* unused */
T> -
T>      int     t_rxtcur;               /* current retransmit value (ticks) */
T>      u_int   t_maxseg;               /* maximum segment size */
T>      u_int   t_pmtud_saved_maxseg;   /* pre-blackhole MSS */
T> @@ -276,32 +187,97 @@ struct tcpcb {
T>      u_int   t_tsomaxsegcount;       /* TSO maximum segment count */
T>      u_int   t_tsomaxsegsize;        /* TSO maximum segment size in bytes */
T>      u_int   t_flags2;               /* More tcpcb flags storage */
T> -#if defined(_KERNEL) && defined(TCP_RFC7413)
T> -    uint32_t t_ispare[6];           /* 5 UTO, 1 TBD */
T> -    uint64_t t_tfo_cookie;          /* TCP Fast Open cookie */
T> -#else
T> -    uint32_t t_ispare[8];           /* 5 UTO, 3 TBD */
T> -#endif
T>      struct tcp_function_block *t_fb;/* TCP function call block */
T>      void    *t_fb_ptr;              /* Pointer to t_fb specific data */
T> -#if defined(_KERNEL) && defined(TCP_RFC7413)
T> +#ifdef TCP_RFC7413
T> +    uint64_t t_tfo_cookie;          /* TCP Fast Open cookie */
T>      unsigned int *t_tfo_pending;    /* TCP Fast Open pending counter */
T> -    void    *t_pspare2[1];          /* 1 TCP_SIGNATURE */
T> -#else
T> -    void    *t_pspare2[2];          /* 1 TCP_SIGNATURE, 1 TBD */
T>  #endif
T> -#if defined(_KERNEL) && defined(TCPPCAP)
T> +#ifdef TCPPCAP
T>      struct mbufq t_inpkts;          /* List of saved input packets. */
T>      struct mbufq t_outpkts;         /* List of saved output packets. */
T> -#ifdef _LP64
T> -    uint64_t _pad[0];               /* all used! */
T> -#else
T> -    uint64_t _pad[2];               /* 2 are available */
T> -#endif /* _LP64 */
T> -#else
T> -    uint64_t _pad[6];
T> -#endif /* defined(_KERNEL) && defined(TCPPCAP) */
T> +#endif
T>  };
T> +#endif      /* _KERNEL || _WANT_TCPCB */
T> +
T> +#ifdef _KERNEL
T> +/*
T> + * Kernel variables for tcp.
T> + */
T> +VNET_DECLARE(int, tcp_do_rfc1323);
T> +#define     V_tcp_do_rfc1323        VNET(tcp_do_rfc1323)
T> +
T> +struct tcptemp {
T> +    u_char  tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
T> +    struct  tcphdr tt_t;
T> +};
T> +
T> +/* 
T> + * TODO: We yet need to brave plowing in
T> + * to tcp_input() and the pru_usrreq() block.
T> + * Right now these go to the old standards which
T> + * are somewhat ok, but in the long term may
T> + * need to be changed. If we do tackle tcp_input()
T> + * then we need to get rid of the tcp_do_segment()
T> + * function below.
T> + */
T> +/* Flags for tcp functions */
T> +#define TCP_FUNC_BEING_REMOVED 0x01         /* Can no longer be referenced 
*/
T> +
T> +/*
T> + * If defining the optional tcp_timers, in the
T> + * tfb_tcp_timer_stop call you must use the
T> + * callout_async_drain() function with the
T> + * tcp_timer_discard callback. You should check
T> + * the return of callout_async_drain() and if 0
T> + * increment tt_draincnt. Since the timer sub-system
T> + * does not know your callbacks you must provide a
T> + * stop_all function that loops through and calls
T> + * tcp_timer_stop() with each of your defined timers.
T> + * Adding a tfb_tcp_handoff_ok function allows the socket
T> + * option to change stacks to query you even if the
T> + * connection is in a later stage. You return 0 to
T> + * say you can take over and run your stack, you return
T> + * non-zero (an error number) to say no you can't.
T> + * If the function is undefined you can only change
T> + * in the early states (before connect or listen).
T> + * tfb_tcp_fb_fini is changed to add a flag to tell
T> + * the old stack if the tcb is being destroyed or
T> + * not. A one in the flag means the TCB is being
T> + * destroyed, a zero indicates its transitioning to
T> + * another stack (via socket option).
T> + */
T> +struct tcp_function_block {
T> +    char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
T> +    int     (*tfb_tcp_output)(struct tcpcb *);
T> +    void    (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *,
T> +                        struct socket *, struct tcpcb *,
T> +                        int, int, uint8_t,
T> +                        int);
T> +    int     (*tfb_tcp_ctloutput)(struct socket *so, struct sockopt *sopt,
T> +                        struct inpcb *inp, struct tcpcb *tp);
T> +    /* Optional memory allocation/free routine */
T> +    void    (*tfb_tcp_fb_init)(struct tcpcb *);
T> +    void    (*tfb_tcp_fb_fini)(struct tcpcb *, int);
T> +    /* Optional timers, must define all if you define one */
T> +    int     (*tfb_tcp_timer_stop_all)(struct tcpcb *);
T> +    void    (*tfb_tcp_timer_activate)(struct tcpcb *,
T> +                        uint32_t, u_int);
T> +    int     (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
T> +    void    (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
T> +    void    (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
T> +    int     (*tfb_tcp_handoff_ok)(struct tcpcb *);
T> +    volatile uint32_t tfb_refcnt;
T> +    uint32_t  tfb_flags;
T> +};
T> +
T> +struct tcp_function {
T> +    TAILQ_ENTRY(tcp_function) tf_next;
T> +    struct tcp_function_block *tf_fb;
T> +};
T> +
T> +TAILQ_HEAD(tcp_funchead, tcp_function);
T> +#endif      /* _KERNEL */
T>  
T>  /*
T>   * Flags and utility macros for the t_flags field.
T> @@ -656,26 +632,41 @@ struct tcp_hhook_data {
T>  
T>  /*
T>   * TCB structure exported to user-land via sysctl(3).
T> + *
T> + * Fields prefixed with "xt_" are unique to the export structure, and fields
T> + * with "t_" or other prefixes match corresponding fields of 'struct tcpcb'.
T> + *
T> + * Legend:
T> + * (s) - used by userland utilities in src
T> + * (p) - used by utilities in ports
T> + * (3) - is known to be used by third party software not in ports
T> + * (n) - no known usage
T> + *
T>   * Evil hack: declare only if in_pcb.h and sys/socketvar.h have been
T>   * included.  Not all of our clients do.
T>   */
T>  #if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_)
T> -struct xtcp_timer {
T> -    int tt_rexmt;   /* retransmit timer */
T> -    int tt_persist; /* retransmit persistence */
T> -    int tt_keep;    /* keepalive */
T> -    int tt_2msl;    /* 2*msl TIME_WAIT timer */
T> -    int tt_delack;  /* delayed ACK timer */
T> -    int t_rcvtime;  /* Time since last packet received */
T> -};
T> -struct      xtcpcb {
T> -    size_t  xt_len;
T> -    struct  inpcb   xt_inp;
T> -    struct  tcpcb   xt_tp;
T> -    struct  xsocket xt_socket;
T> -    struct  xtcp_timer xt_timer;
T> -    u_quad_t        xt_alignment_hack;
T> -};
T> +struct xtcpcb {
T> +    size_t          xt_len;         /* length of this structure */
T> +    struct xinpcb   xt_inp;
T> +    char            xt_stack[TCP_FUNCTION_NAME_LEN_MAX];    /* (n) */
T> +    int64_t         spare64[8];
T> +    int32_t         t_state;                /* (s,p) */
T> +    uint32_t        t_flags;                /* (s,p) */
T> +    int32_t         t_sndzerowin;           /* (s) */
T> +    int32_t         t_sndrexmitpack;        /* (s) */
T> +    int32_t         t_rcvoopack;            /* (s) */
T> +    int32_t         t_rcvtime;              /* (s) */
T> +    int32_t         tt_rexmt;               /* (s) */
T> +    int32_t         tt_persist;             /* (s) */
T> +    int32_t         tt_keep;                /* (s) */
T> +    int32_t         tt_2msl;                /* (s) */
T> +    int32_t         tt_delack;              /* (s) */
T> +    int32_t         spare32[32];
T> +} __aligned(8);
T> +#ifdef _KERNEL
T> +void        tcp_inptoxtp(const struct inpcb *, struct xtcpcb *);
T> +#endif
T>  #endif
T>  
T>  /*
T> 
T> Modified: head/sys/netinet/udp_usrreq.c
T> 
==============================================================================
T> --- head/sys/netinet/udp_usrreq.c    Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/sys/netinet/udp_usrreq.c    Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -905,13 +905,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
T>              if (inp->inp_gencnt <= gencnt) {
T>                      struct xinpcb xi;
T>  
T> -                    bzero(&xi, sizeof(xi));
T> -                    xi.xi_len = sizeof xi;
T> -                    /* XXX should avoid extra copy */
T> -                    bcopy(inp, &xi.xi_inp, sizeof *inp);
T> -                    if (inp->inp_socket)
T> -                            sotoxsocket(inp->inp_socket, &xi.xi_socket);
T> -                    xi.xi_inp.inp_gencnt = inp->inp_gencnt;
T> +                    in_pcbtoxinpcb(inp, &xi);
T>                      INP_RUNLOCK(inp);
T>                      error = SYSCTL_OUT(req, &xi, sizeof xi);
T>              } else
T> 
T> Modified: head/sys/sys/param.h
T> 
==============================================================================
T> --- head/sys/sys/param.h     Tue Mar 21 05:15:10 2017        (r315661)
T> +++ head/sys/sys/param.h     Tue Mar 21 06:39:49 2017        (r315662)
T> @@ -58,7 +58,7 @@
T>   *          in the range 5 to 9.
T>   */
T>  #undef __FreeBSD_version
T> -#define __FreeBSD_version 1200025   /* Master, propagated to newvers */
T> +#define __FreeBSD_version 1200026   /* Master, propagated to newvers */
T>  
T>  /*
T>   * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
T> 
T> Modified: head/usr.bin/netstat/inet.c
T> 
==============================================================================
T> --- head/usr.bin/netstat/inet.c      Tue Mar 21 05:15:10 2017        
(r315661)
T> +++ head/usr.bin/netstat/inet.c      Tue Mar 21 06:39:49 2017        
(r315662)
T> @@ -91,7 +91,7 @@ static int udp_done, tcp_done, sdp_done;
T>  #endif /* INET6 */
T>  
T>  static int
T> -pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused)
T> +pcblist_sysctl(int proto, const char *name, char **bufp)
T>  {
T>      const char *mibvar;
T>      char *buf;
T> @@ -181,120 +181,6 @@ sotoxsocket(struct socket *so, struct xs
T>      return (0);
T>  }
T>  
T> -static int
T> -pcblist_kvm(u_long off, char **bufp, int istcp)
T> -{
T> -    struct inpcbinfo pcbinfo;
T> -    struct inpcbhead listhead;
T> -    struct inpcb *inp;
T> -    struct xinpcb xi;
T> -    struct xinpgen xig;
T> -    struct xtcpcb xt;
T> -    struct socket so;
T> -    struct xsocket *xso;
T> -    char *buf, *p;
T> -    size_t len;
T> -
T> -    if (off == 0)
T> -            return (0);
T> -    kread(off, &pcbinfo, sizeof(pcbinfo));
T> -    if (istcp)
T> -            len = 2 * sizeof(xig) +
T> -                (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) *
T> -                sizeof(struct xtcpcb);
T> -    else
T> -            len = 2 * sizeof(xig) +
T> -                (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) *
T> -                sizeof(struct xinpcb);
T> -    if ((buf = malloc(len)) == NULL) {
T> -            xo_warnx("malloc %lu bytes", (u_long)len);
T> -            return (0);
T> -    }
T> -    p = buf;
T> -
T> -#define     COPYOUT(obj, size) do {                                         
\
T> -    if (len < (size)) {                                             \
T> -            xo_warnx("buffer size exceeded");                       \
T> -            goto fail;                                              \
T> -    }                                                               \
T> -    bcopy((obj), p, (size));                                        \
T> -    len -= (size);                                                  \
T> -    p += (size);                                                    \
T> -} while (0)
T> -
T> -#define     KREAD(off, buf, len) do {                                       
\
T> -    if (kread((uintptr_t)(off), (buf), (len)) != 0)                 \
T> -            goto fail;                                              \
T> -} while (0)
T> -
T> -    /* Write out header. */
T> -    xig.xig_len = sizeof xig;
T> -    xig.xig_count = pcbinfo.ipi_count;
T> -    xig.xig_gen = pcbinfo.ipi_gencnt;
T> -    xig.xig_sogen = 0;
T> -    COPYOUT(&xig, sizeof xig);
T> -
T> -    /* Walk the PCB list. */
T> -    xt.xt_len = sizeof xt;
T> -    xi.xi_len = sizeof xi;
T> -    if (istcp)
T> -            xso = &xt.xt_socket;
T> -    else
T> -            xso = &xi.xi_socket;
T> -    KREAD(pcbinfo.ipi_listhead, &listhead, sizeof(listhead));
T> -    LIST_FOREACH(inp, &listhead, inp_list) {
T> -            if (istcp) {
T> -                    KREAD(inp, &xt.xt_inp, sizeof(*inp));
T> -                    inp = &xt.xt_inp;
T> -            } else {
T> -                    KREAD(inp, &xi.xi_inp, sizeof(*inp));
T> -                    inp = &xi.xi_inp;
T> -            }
T> -
T> -            if (inp->inp_gencnt > pcbinfo.ipi_gencnt)
T> -                    continue;
T> -
T> -            if (istcp) {
T> -                    if (inp->inp_ppcb == NULL)
T> -                            bzero(&xt.xt_tp, sizeof xt.xt_tp);
T> -                    else if (inp->inp_flags & INP_TIMEWAIT) {
T> -                            bzero(&xt.xt_tp, sizeof xt.xt_tp);
T> -                            xt.xt_tp.t_state = TCPS_TIME_WAIT;
T> -                    } else
T> -                            KREAD(inp->inp_ppcb, &xt.xt_tp,
T> -                                sizeof xt.xt_tp);
T> -            }
T> -            if (inp->inp_socket) {
T> -                    KREAD(inp->inp_socket, &so, sizeof(so));
T> -                    if (sotoxsocket(&so, xso) != 0)
T> -                            goto fail;
T> -            } else {
T> -                    bzero(xso, sizeof(*xso));
T> -                    if (istcp)
T> -                            xso->xso_protocol = IPPROTO_TCP;
T> -            }
T> -            if (istcp)
T> -                    COPYOUT(&xt, sizeof xt);
T> -            else
T> -                    COPYOUT(&xi, sizeof xi);
T> -    }
T> -
T> -    /* Reread the pcbinfo and write out the footer. */
T> -    kread(off, &pcbinfo, sizeof(pcbinfo));
T> -    xig.xig_count = pcbinfo.ipi_count;
T> -    xig.xig_gen = pcbinfo.ipi_gencnt;
T> -    COPYOUT(&xig, sizeof xig);
T> -
T> -    *bufp = buf;
T> -    return (1);
T> -
T> -fail:
T> -    free(buf);
T> -    return (0);
T> -#undef COPYOUT
T> -#undef KREAD
T> -}
T> -
T>  /*
T>   * Print a summary of connections related to an Internet
T>   * protocol.  For TCP, also give state of connection.
T> @@ -304,15 +190,14 @@ fail:
T>  void
T>  protopr(u_long off, const char *name, int af1, int proto)
T>  {
T> -    int istcp;
T>      static int first = 1;
T> +    int istcp;
T>      char *buf;
T>      const char *vchar;
T> -    struct tcpcb *tp = NULL;
T> -    struct inpcb *inp;
T> +    struct xtcpcb *tp;
T> +    struct xinpcb *inp;
T>      struct xinpgen *xig, *oxig;
T>      struct xsocket *so;
T> -    struct xtcp_timer *timer;
T>  
T>      istcp = 0;
T>      switch (proto) {
T> @@ -341,28 +226,21 @@ protopr(u_long off, const char *name, in
T>  #endif
T>              break;
T>      }
T> -    if (live) {
T> -            if (!pcblist_sysctl(proto, name, &buf, istcp))
T> -                    return;
T> -    } else {
T> -            if (!pcblist_kvm(off, &buf, istcp))
T> -                    return;
T> -    }
T> +
T> +    if (!pcblist_sysctl(proto, name, &buf))
T> +            return;
T>  
T>      oxig = xig = (struct xinpgen *)buf;
T>      for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
T>          xig->xig_len > sizeof(struct xinpgen);
T>          xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
T>              if (istcp) {
T> -                    timer = &((struct xtcpcb *)xig)->xt_timer;
T> -                    tp = &((struct xtcpcb *)xig)->xt_tp;
T> -                    inp = &((struct xtcpcb *)xig)->xt_inp;
T> -                    so = &((struct xtcpcb *)xig)->xt_socket;
T> +                    tp = (struct xtcpcb *)xig;
T> +                    inp = &tp->xt_inp;
T>              } else {
T> -                    inp = &((struct xinpcb *)xig)->xi_inp;
T> -                    so = &((struct xinpcb *)xig)->xi_socket;
T> -                    timer = NULL;
T> +                    inp = (struct xinpcb *)xig;
T>              }
T> +            so = &inp->xi_socket;
T>  
T> 
T> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
T> _______________________________________________
T> svn-src-all@freebsd.org mailing list
T> https://lists.freebsd.org/mailman/listinfo/svn-src-all
T> To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

-- 
Totus tuus, Glebius.
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to