summaryrefslogtreecommitdiffstats
path: root/cpukit/libnetworking/netinet
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2003-01-03 18:09:57 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2003-01-03 18:09:57 +0000
commit36799d4063c2e6e74d5d5a520aabac199913227a (patch)
tree676ad75ffd851ab3bd5c01beb39c0c0b0c348490 /cpukit/libnetworking/netinet
parent2003-01-03 Victor V. Vengerov <vvv@oktet.ru> (diff)
downloadrtems-36799d4063c2e6e74d5d5a520aabac199913227a.tar.bz2
2002-11-26 Chris Johns <cjohns@cybertec.com.au>
* Makefile.am: Added sys/linker_set.h * kern/Makefile.am: Added kern_mib.c and kern_sysctl.c. * kern/uipc_socket.c: OID changed from KERN_SOMAXCONN to KIPC_SOMAXCONN. * kern/uipc_socket2.c: OID changed from KERN_MAXSOCKBUF to KIPC_MAXSOCKBUF. * net/if_ethersubr.c: FreeBSD 2.2.2 does not have a _net_link node while 5.0 does. * net/if_ppp.c: Removed the TEXT_SET define as these macros are now implemented. * net/rtsock.c: Enable sysctl support plus fix the bug with the lastest FreeBSD sysctl header file. * netinet/icmp_var.h: FreeBSD 2.2.2 does not have a _net_inet_icmp node while 5.0 does. * netinet/if_ether.c: FreeBSD 2.2.2 does not have a _net_link_ether node while 5.0 does. * netinet/igmp_var.h: FreeBSD 2.2.2 does not have a _net_inet_igmp node while 5.0 does. * netinet/in_pcb.c: Fixed the arguments to the sysctl call. Add inp_gencnt and ipi_count. These are used when listing connections. * netinet/in_pcb.h: Added counters to aid the listing of connections. * netinet/in_var.h: Provide the _net_inet_ip and _net_inet_raw nodes. * netinet/ip_fw.c: Disable the firewall sysctl calls. * netinet/tcp_subr.c: Merge tcp_pcblist from the lastest FreeBSD source. * netinet/tcp_var.h: Add structures needed by net-snmp to list connections. * netinet/udp_usrreq.c: Merged udp_pcblist from the lastest FreeBSD source. * netinet/udp_var.h: Added the sysctl id UDPCTL_PCBLIST. Used by net-snmp. * rtems_glue.c: Call sysctl_register_all when initialising the network stack to register all the sysctl calls. These are in the special sections and required an updated linker script. * rtems/rtems_syscall.c: Add the sysctl call. * sys/kernel.h: Use the lastest FreeBSD method of handling sysctl structures. This now held in the sys/linker_set.h file. * sys/queue.h: This is from the lastest FreeBSD code with the circular code merged back in as it is not used in the lastest FreeBSD kernel. * sys/sysctl.h: The lastest sysctl. This was needed to use with the new linker set method. The FreeBSD 2.2.2 version has asm hacks. The lastest version of the FreeBSD does not have these hacks. It uses gcc attribute directives.
Diffstat (limited to 'cpukit/libnetworking/netinet')
-rw-r--r--cpukit/libnetworking/netinet/icmp_var.h1
-rw-r--r--cpukit/libnetworking/netinet/if_ether.c1
-rw-r--r--cpukit/libnetworking/netinet/igmp_var.h3
-rw-r--r--cpukit/libnetworking/netinet/in_pcb.c9
-rw-r--r--cpukit/libnetworking/netinet/in_pcb.h33
-rw-r--r--cpukit/libnetworking/netinet/in_var.h6
-rw-r--r--cpukit/libnetworking/netinet/ip_fw.c5
-rw-r--r--cpukit/libnetworking/netinet/tcp_subr.c124
-rw-r--r--cpukit/libnetworking/netinet/tcp_var.h24
-rw-r--r--cpukit/libnetworking/netinet/udp_usrreq.c118
-rw-r--r--cpukit/libnetworking/netinet/udp_var.h5
11 files changed, 324 insertions, 5 deletions
diff --git a/cpukit/libnetworking/netinet/icmp_var.h b/cpukit/libnetworking/netinet/icmp_var.h
index 7657f31acf..e091ca2c61 100644
--- a/cpukit/libnetworking/netinet/icmp_var.h
+++ b/cpukit/libnetworking/netinet/icmp_var.h
@@ -72,6 +72,7 @@ struct icmpstat {
}
#ifdef KERNEL
+SYSCTL_DECL(_net_inet_icmp);
extern struct icmpstat icmpstat;
#endif
diff --git a/cpukit/libnetworking/netinet/if_ether.c b/cpukit/libnetworking/netinet/if_ether.c
index 985ce6e7d9..c4b85aa38e 100644
--- a/cpukit/libnetworking/netinet/if_ether.c
+++ b/cpukit/libnetworking/netinet/if_ether.c
@@ -62,6 +62,7 @@
#define SIN(s) ((struct sockaddr_in *)s)
#define SDL(s) ((struct sockaddr_dl *)s)
+SYSCTL_DECL(_net_link_ether);
SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
/* timer values */
diff --git a/cpukit/libnetworking/netinet/igmp_var.h b/cpukit/libnetworking/netinet/igmp_var.h
index f408bf2bc1..9618dbd50c 100644
--- a/cpukit/libnetworking/netinet/igmp_var.h
+++ b/cpukit/libnetworking/netinet/igmp_var.h
@@ -93,6 +93,9 @@ void igmp_joingroup __P((struct in_multi *));
void igmp_leavegroup __P((struct in_multi *));
void igmp_fasttimo __P((void));
void igmp_slowtimo __P((void));
+
+SYSCTL_DECL(_net_inet_igmp);
+
#endif
/*
diff --git a/cpukit/libnetworking/netinet/in_pcb.c b/cpukit/libnetworking/netinet/in_pcb.c
index 116f70eebf..312594dae2 100644
--- a/cpukit/libnetworking/netinet/in_pcb.c
+++ b/cpukit/libnetworking/netinet/in_pcb.c
@@ -79,9 +79,8 @@ static int ipport_hilastauto = IPPORT_HILASTAUTO; /* 44999 */
if ((var) < (min)) { (var) = (min); } \
else if ((var) > (max)) { (var) = (max); }
-#if 0
static int
-sysctl_net_ipport_check SYSCTL_HANDLER_ARGS
+sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
{
int error = sysctl_handle_int(oidp,
oidp->oid_arg1, oidp->oid_arg2, req);
@@ -95,7 +94,6 @@ sysctl_net_ipport_check SYSCTL_HANDLER_ARGS
}
return error;
}
-#endif
#undef RANGECHK
@@ -126,10 +124,12 @@ in_pcballoc(so, pcbinfo)
if (inp == NULL)
return (ENOBUFS);
bzero((caddr_t)inp, sizeof(*inp));
+ inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
inp->inp_pcbinfo = pcbinfo;
inp->inp_socket = so;
s = splnet();
LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list);
+ pcbinfo->ipi_count++;
in_pcbinshash(inp);
splx(s);
so->so_pcb = (caddr_t)inp;
@@ -445,8 +445,10 @@ in_pcbdetach(inp)
struct inpcb *inp;
{
struct socket *so = inp->inp_socket;
+ struct inpcbinfo *ipi = inp->inp_pcbinfo;
int s;
+ inp->inp_gencnt = ++ipi->ipi_gencnt;
so->so_pcb = 0;
sofree(so);
if (inp->inp_options)
@@ -753,5 +755,6 @@ in_pcbrehash(inp)
inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)];
LIST_INSERT_HEAD(head, inp, inp_hash);
+ inp->inp_pcbinfo->ipi_count--;
splx(s);
}
diff --git a/cpukit/libnetworking/netinet/in_pcb.h b/cpukit/libnetworking/netinet/in_pcb.h
index 9390cfda6c..df1eeead89 100644
--- a/cpukit/libnetworking/netinet/in_pcb.h
+++ b/cpukit/libnetworking/netinet/in_pcb.h
@@ -48,6 +48,8 @@
*/
LIST_HEAD(inpcbhead, inpcb);
+typedef u_int64_t inp_gen_t;
+
struct inpcb {
LIST_ENTRY(inpcb) inp_list; /* list for all PCBs of this proto */
LIST_ENTRY(inpcb) inp_hash; /* hash list */
@@ -66,11 +68,40 @@ struct inpcb {
u_char inp_ip_p; /* protocol proto */
u_char pad[1]; /* alignment */
struct ip_moptions *inp_moptions; /* IP multicast options */
+ inp_gen_t inp_gencnt; /* generation count of this instance */
#if 0 /* Someday, perhaps... */
struct ip inp_ip; /* header prototype; should have more */
#endif
};
+/*
+ * Interface exported to userland by various protocols which use
+ * inpcbs. Hack alert -- only define if struct xsocket is in scope.
+ *
+ * ccj - 20 Nov 2002
+ * Double hack alert. This is taken from the pre 5.0 sources and
+ * merged into RTEMS. This allows the TCPCTL_PCBLIST code in
+ * net-snmp to work.
+ */
+#ifdef _SYS_SOCKETVAR_H_
+typedef u_int64_t so_gen_t; /* should be in sys/sockvar.h */
+
+struct xinpcb {
+ size_t xi_len; /* length of this structure */
+ struct inpcb xi_inp;
+/* struct xsocket xi_socket; ccj removed */
+ u_int64_t xi_alignment_hack;
+};
+
+
+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 */
+};
+#endif /* _SYS_SOCKETVAR_H_ */
+
struct inpcbinfo {
struct inpcbhead *listhead;
struct inpcbhead *hashbase;
@@ -78,6 +109,8 @@ struct inpcbinfo {
unsigned short lastport;
unsigned short lastlow;
unsigned short lasthi;
+ u_int ipi_count; /* number of pcbs in this list */
+ u_int64_t ipi_gencnt; /* current generation count */
};
#define INP_PCBHASH(faddr, lport, fport, mask) \
diff --git a/cpukit/libnetworking/netinet/in_var.h b/cpukit/libnetworking/netinet/in_var.h
index e7a54d5e85..b64448d2fb 100644
--- a/cpukit/libnetworking/netinet/in_var.h
+++ b/cpukit/libnetworking/netinet/in_var.h
@@ -161,6 +161,12 @@ struct in_multi {
};
#ifdef KERNEL
+
+#ifdef SYSCTL_DECL
+SYSCTL_DECL(_net_inet_ip);
+SYSCTL_DECL(_net_inet_raw);
+#endif
+
/*
* Structure used by macros below to remember position when stepping through
* all of the in_multi records.
diff --git a/cpukit/libnetworking/netinet/ip_fw.c b/cpukit/libnetworking/netinet/ip_fw.c
index aeb09b0bbe..4bad293e7d 100644
--- a/cpukit/libnetworking/netinet/ip_fw.c
+++ b/cpukit/libnetworking/netinet/ip_fw.c
@@ -60,12 +60,17 @@ static int fw_verbose_limit = 0;
LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain;
+/*
+ * ccj - No current need for firewall so have provided the MIB.
+ */
+#if 0
#ifdef SYSCTL_NODE
SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, debug, CTLFLAG_RW, &fw_debug, 0, "");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose, CTLFLAG_RW, &fw_verbose, 0, "");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW, &fw_verbose_limit, 0, "");
#endif
+#endif
#define dprintf(a) if (!fw_debug); else printf a
diff --git a/cpukit/libnetworking/netinet/tcp_subr.c b/cpukit/libnetworking/netinet/tcp_subr.c
index 9e7e57611d..7f97e20eed 100644
--- a/cpukit/libnetworking/netinet/tcp_subr.c
+++ b/cpukit/libnetworking/netinet/tcp_subr.c
@@ -457,6 +457,130 @@ tcp_notify(inp, error)
sowwakeup(so);
}
+#ifdef __rtems__
+#define INP_INFO_RLOCK
+#define INP_INFO_RUNLOCK
+#define INP_LOCK
+#define INP_UNLOCK
+#endif
+
+static int
+tcp_pcblist(SYSCTL_HANDLER_ARGS)
+{
+ int error, i, n, s;
+ struct inpcb *inp, **inp_list;
+ inp_gen_t gencnt;
+ struct xinpgen xig;
+
+ /*
+ * The process of preparing the TCB list is too time-consuming and
+ * resource-intensive to repeat twice on every request.
+ */
+ if (req->oldptr == 0) {
+ n = tcbinfo.ipi_count;
+ req->oldidx = 2 * (sizeof xig)
+ + (n + n/8) * sizeof(struct xtcpcb);
+ return 0;
+ }
+
+ if (req->newptr != 0)
+ return EPERM;
+
+ /*
+ * OK, now we're committed to doing something.
+ */
+ s = splnet();
+ INP_INFO_RLOCK(&tcbinfo);
+ gencnt = tcbinfo.ipi_gencnt;
+ n = tcbinfo.ipi_count;
+ INP_INFO_RUNLOCK(&tcbinfo);
+ splx(s);
+
+ sysctl_wire_old_buffer(req, 2 * (sizeof xig)
+ + n * sizeof(struct xtcpcb));
+
+ xig.xig_len = sizeof xig;
+ xig.xig_count = n;
+ xig.xig_gen = gencnt;
+/* xig.xig_sogen = so_gencnt; remove by ccj */
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ if (error)
+ return error;
+
+ /* ccj add exit if the count is 0 */
+ if (!n)
+ return error;
+
+ inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
+ if (inp_list == 0)
+ return ENOMEM;
+
+ s = splnet();
+ INP_INFO_RLOCK(&tcbinfo);
+ for (inp = LIST_FIRST(tcbinfo.listhead), i = 0; inp && i < n;
+ inp = LIST_NEXT(inp, inp_list)) {
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt)
+#if 0
+ &&
+ cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0)
+#endif
+ inp_list[i++] = inp;
+ INP_UNLOCK(inp);
+ }
+ INP_INFO_RUNLOCK(&tcbinfo);
+ splx(s);
+ n = i;
+
+ error = 0;
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt) {
+ struct xtcpcb xt;
+ caddr_t inp_ppcb;
+ 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)
+ bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
+ else
+ bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
+#if 0
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xt.xt_socket);
+#endif
+ error = SYSCTL_OUT(req, &xt, sizeof xt);
+ }
+ INP_UNLOCK(inp);
+ }
+ if (!error) {
+ /*
+ * Give the user an updated idea of our state.
+ * If the generation differs from what we told
+ * her before, she knows that something happened
+ * while we were processing this request, and it
+ * might be necessary to retry.
+ */
+ s = splnet();
+ INP_INFO_RLOCK(&tcbinfo);
+ xig.xig_gen = tcbinfo.ipi_gencnt;
+#if 0
+ xig.xig_sogen = so_gencnt;
+#endif
+ xig.xig_count = tcbinfo.ipi_count;
+ INP_INFO_RUNLOCK(&tcbinfo);
+ splx(s);
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ }
+ free(inp_list, M_TEMP);
+ return error;
+}
+
+SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0,
+ tcp_pcblist, "S,xtcpcb", "List of active TCP connections");
+
void
tcp_ctlinput(cmd, sa, vip)
int cmd;
diff --git a/cpukit/libnetworking/netinet/tcp_var.h b/cpukit/libnetworking/netinet/tcp_var.h
index 113ec9a6ff..fdd3a17ccd 100644
--- a/cpukit/libnetworking/netinet/tcp_var.h
+++ b/cpukit/libnetworking/netinet/tcp_var.h
@@ -307,6 +307,23 @@ struct tcpstat {
};
/*
+ * TCB structure exported to user-land via sysctl(3).
+ * 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 xtcpcb {
+ size_t xt_len;
+ struct inpcb xt_inp;
+ struct tcpcb xt_tp;
+#if 0
+ struct xsocket xt_socket;
+ u_quad_t xt_alignment_hack;
+#endif
+};
+#endif
+
+/*
* Names for TCP sysctl objects
*/
#define TCPCTL_DO_RFC1323 1 /* use RFC-1323 extensions */
@@ -319,7 +336,8 @@ struct tcpstat {
#define TCPCTL_SENDSPACE 8 /* send buffer space */
#define TCPCTL_RECVSPACE 9 /* receive buffer space */
#define TCPCTL_KEEPINIT 10 /* receive buffer space */
-#define TCPCTL_MAXID 11
+#define TCPCTL_PCBLIST 11 /* list of all outstanding PCBs */
+#define TCPCTL_MAXID 12
#define TCPCTL_NAMES { \
{ 0, 0 }, \
@@ -336,6 +354,10 @@ struct tcpstat {
}
#ifdef KERNEL
+#ifdef SYSCTL_DECL
+SYSCTL_DECL(_net_inet_tcp);
+#endif
+
extern struct inpcbhead tcb; /* head of queue of active tcpcb's */
extern struct inpcbinfo tcbinfo;
extern struct tcpstat tcpstat; /* tcp statistics */
diff --git a/cpukit/libnetworking/netinet/udp_usrreq.c b/cpukit/libnetworking/netinet/udp_usrreq.c
index 16c5fce2df..8e28bddc25 100644
--- a/cpukit/libnetworking/netinet/udp_usrreq.c
+++ b/cpukit/libnetworking/netinet/udp_usrreq.c
@@ -455,6 +455,124 @@ release:
return (error);
}
+#ifdef __rtems__
+#define INP_INFO_RLOCK
+#define INP_INFO_RUNLOCK
+#define INP_LOCK
+#define INP_UNLOCK
+#endif
+
+static int
+udp_pcblist(SYSCTL_HANDLER_ARGS)
+{
+ int error, i, n, s;
+ struct inpcb *inp, **inp_list;
+ inp_gen_t gencnt;
+ struct xinpgen xig;
+
+ /*
+ * The process of preparing the TCB list is too time-consuming and
+ * resource-intensive to repeat twice on every request.
+ */
+ if (req->oldptr == 0) {
+ n = udbinfo.ipi_count;
+ req->oldidx = 2 * (sizeof xig)
+ + (n + n/8) * sizeof(struct xinpcb);
+ return 0;
+ }
+
+ if (req->newptr != 0)
+ return EPERM;
+
+ /*
+ * OK, now we're committed to doing something.
+ */
+ s = splnet();
+ gencnt = udbinfo.ipi_gencnt;
+ n = udbinfo.ipi_count;
+ splx(s);
+
+ sysctl_wire_old_buffer(req, 2 * (sizeof xig)
+ + n * sizeof(struct xinpcb));
+
+ xig.xig_len = sizeof xig;
+ xig.xig_count = n;
+ xig.xig_gen = gencnt;
+#if 0
+ xig.xig_sogen = so_gencnt;
+#endif
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ if (error)
+ return error;
+
+ /* ccj add the exit if count is 0 */
+ if (!n)
+ return error;
+
+ inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
+ if (inp_list == 0)
+ return ENOMEM;
+
+ s = splnet();
+ INP_INFO_RLOCK(&udbinfo);
+ for (inp = LIST_FIRST(udbinfo.listhead), i = 0; inp && i < n;
+ inp = LIST_NEXT(inp, inp_list)) {
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt)
+#if 0
+ &&
+ cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0)
+#endif
+ inp_list[i++] = inp;
+ INP_UNLOCK(inp);
+ }
+ INP_INFO_RUNLOCK(&udbinfo);
+ splx(s);
+ n = i;
+
+ error = 0;
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ INP_LOCK(inp);
+ if (inp->inp_gencnt <= gencnt) {
+ struct xinpcb xi;
+ xi.xi_len = sizeof xi;
+ /* XXX should avoid extra copy */
+ bcopy(inp, &xi.xi_inp, sizeof *inp);
+#if 0
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xi.xi_socket);
+#endif
+ error = SYSCTL_OUT(req, &xi, sizeof xi);
+ }
+ INP_UNLOCK(inp);
+ }
+ if (!error) {
+ /*
+ * Give the user an updated idea of our state.
+ * If the generation differs from what we told
+ * her before, she knows that something happened
+ * while we were processing this request, and it
+ * might be necessary to retry.
+ */
+ s = splnet();
+ INP_INFO_RLOCK(&udbinfo);
+ xig.xig_gen = udbinfo.ipi_gencnt;
+#if 0
+ xig.xig_sogen = so_gencnt;
+#endif
+ xig.xig_count = udbinfo.ipi_count;
+ INP_INFO_RUNLOCK(&udbinfo);
+ splx(s);
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ }
+ free(inp_list, M_TEMP);
+ return error;
+}
+
+SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0,
+ udp_pcblist, "S,xinpcb", "List of active UDP sockets");
+
static u_long udp_sendspace = 9216; /* really max datagram size */
/* 40 1K datagrams */
SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW,
diff --git a/cpukit/libnetworking/netinet/udp_var.h b/cpukit/libnetworking/netinet/udp_var.h
index 90785b53de..b010e56348 100644
--- a/cpukit/libnetworking/netinet/udp_var.h
+++ b/cpukit/libnetworking/netinet/udp_var.h
@@ -78,7 +78,8 @@ struct udpstat {
#define UDPCTL_STATS 2 /* statistics (read-only) */
#define UDPCTL_MAXDGRAM 3 /* max datagram size */
#define UDPCTL_RECVSPACE 4 /* default receive buffer space */
-#define UDPCTL_MAXID 5
+#define UDPCTL_PCBLIST 5 /* list of PCBs for UDP sockets */
+#define UDPCTL_MAXID 6
#define UDPCTL_NAMES { \
{ 0, 0 }, \
@@ -89,6 +90,8 @@ struct udpstat {
}
#ifdef KERNEL
+SYSCTL_DECL(_net_inet_udp);
+
extern struct inpcbhead udb;
extern struct inpcbinfo udbinfo;
extern struct udpstat udpstat;