udp_usrreq.c (79bb84fb15da2ab013512575aa8dae0c4c39f029) udp_usrreq.c (79288c112cc4b7f2f9acccbe904d45fe5d1baf7a)
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
3 * The Regents of the University of California.
4 * Copyright (c) 2008 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 21 unchanged lines hidden (view full) ---

30 *
31 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD$");
36
37#include "opt_ipfw.h"
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
3 * The Regents of the University of California.
4 * Copyright (c) 2008 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 21 unchanged lines hidden (view full) ---

30 *
31 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD$");
36
37#include "opt_ipfw.h"
38#include "opt_inet.h"
38#include "opt_inet6.h"
39#include "opt_ipsec.h"
40
41#include <sys/param.h>
42#include <sys/domain.h>
43#include <sys/eventhandler.h>
44#include <sys/jail.h>
45#include <sys/kernel.h>

--- 92 unchanged lines hidden (view full) ---

138#define UDBHASHSIZE 128
139#endif
140
141VNET_DEFINE(struct udpstat, udpstat); /* from udp_var.h */
142SYSCTL_VNET_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW,
143 &VNET_NAME(udpstat), udpstat,
144 "UDP statistics (struct udpstat, netinet/udp_var.h)");
145
39#include "opt_inet6.h"
40#include "opt_ipsec.h"
41
42#include <sys/param.h>
43#include <sys/domain.h>
44#include <sys/eventhandler.h>
45#include <sys/jail.h>
46#include <sys/kernel.h>

--- 92 unchanged lines hidden (view full) ---

139#define UDBHASHSIZE 128
140#endif
141
142VNET_DEFINE(struct udpstat, udpstat); /* from udp_var.h */
143SYSCTL_VNET_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW,
144 &VNET_NAME(udpstat), udpstat,
145 "UDP statistics (struct udpstat, netinet/udp_var.h)");
146
147#ifdef INET
146static void udp_detach(struct socket *so);
147static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
148 struct mbuf *, struct thread *);
148static void udp_detach(struct socket *so);
149static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
150 struct mbuf *, struct thread *);
151#endif
152
149#ifdef IPSEC
150#ifdef IPSEC_NAT_T
151#define UF_ESPINUDP_ALL (UF_ESPINUDP_NON_IKE|UF_ESPINUDP)
152#ifdef INET
153static struct mbuf *udp4_espdecap(struct inpcb *, struct mbuf *, int);
154#endif
155#endif /* IPSEC_NAT_T */
156#endif /* IPSEC */

--- 67 unchanged lines hidden (view full) ---

224udp_destroy(void)
225{
226
227 in_pcbinfo_destroy(&V_udbinfo);
228 uma_zdestroy(V_udpcb_zone);
229}
230#endif
231
153#ifdef IPSEC
154#ifdef IPSEC_NAT_T
155#define UF_ESPINUDP_ALL (UF_ESPINUDP_NON_IKE|UF_ESPINUDP)
156#ifdef INET
157static struct mbuf *udp4_espdecap(struct inpcb *, struct mbuf *, int);
158#endif
159#endif /* IPSEC_NAT_T */
160#endif /* IPSEC */

--- 67 unchanged lines hidden (view full) ---

228udp_destroy(void)
229{
230
231 in_pcbinfo_destroy(&V_udbinfo);
232 uma_zdestroy(V_udpcb_zone);
233}
234#endif
235
236#ifdef INET
232/*
233 * Subroutine of udp_input(), which appends the provided mbuf chain to the
234 * passed pcb/socket. The caller must provide a sockaddr_in via udp_in that
235 * contains the source address. If the socket ends up being an IPv6 socket,
236 * udp_append() will convert to a sockaddr_in6 before passing the address
237 * into the socket code.
238 */
239static void

--- 27 unchanged lines hidden (view full) ---

267#ifdef IPSEC
268 /* Check AH/ESP integrity. */
269 if (ipsec4_in_reject(n, inp)) {
270 m_freem(n);
271 V_ipsec4stat.in_polvio++;
272 return;
273 }
274#ifdef IPSEC_NAT_T
237/*
238 * Subroutine of udp_input(), which appends the provided mbuf chain to the
239 * passed pcb/socket. The caller must provide a sockaddr_in via udp_in that
240 * contains the source address. If the socket ends up being an IPv6 socket,
241 * udp_append() will convert to a sockaddr_in6 before passing the address
242 * into the socket code.
243 */
244static void

--- 27 unchanged lines hidden (view full) ---

272#ifdef IPSEC
273 /* Check AH/ESP integrity. */
274 if (ipsec4_in_reject(n, inp)) {
275 m_freem(n);
276 V_ipsec4stat.in_polvio++;
277 return;
278 }
279#ifdef IPSEC_NAT_T
275#ifdef INET
276 up = intoudpcb(inp);
277 KASSERT(up != NULL, ("%s: udpcb NULL", __func__));
278 if (up->u_flags & UF_ESPINUDP_ALL) { /* IPSec UDP encaps. */
279 n = udp4_espdecap(inp, n, off);
280 if (n == NULL) /* Consumed. */
281 return;
282 }
280 up = intoudpcb(inp);
281 KASSERT(up != NULL, ("%s: udpcb NULL", __func__));
282 if (up->u_flags & UF_ESPINUDP_ALL) { /* IPSec UDP encaps. */
283 n = udp4_espdecap(inp, n, off);
284 if (n == NULL) /* Consumed. */
285 return;
286 }
283#endif /* INET */
284#endif /* IPSEC_NAT_T */
285#endif /* IPSEC */
286#ifdef MAC
287 if (mac_inpcb_check_deliver(inp, n) != 0) {
288 m_freem(n);
289 return;
290 }
287#endif /* IPSEC_NAT_T */
288#endif /* IPSEC */
289#ifdef MAC
290 if (mac_inpcb_check_deliver(inp, n) != 0) {
291 m_freem(n);
292 return;
293 }
291#endif
294#endif /* MAC */
292 if (inp->inp_flags & INP_CONTROLOPTS ||
293 inp->inp_socket->so_options & (SO_TIMESTAMP | SO_BINTIME)) {
294#ifdef INET6
295 if (inp->inp_vflag & INP_IPV6)
296 (void)ip6_savecontrol_v4(inp, n, &opts, NULL);
297 else
295 if (inp->inp_flags & INP_CONTROLOPTS ||
296 inp->inp_socket->so_options & (SO_TIMESTAMP | SO_BINTIME)) {
297#ifdef INET6
298 if (inp->inp_vflag & INP_IPV6)
299 (void)ip6_savecontrol_v4(inp, n, &opts, NULL);
300 else
298#endif
301#endif /* INET6 */
299 ip_savecontrol(inp, &opts, ip, n);
300 }
301#ifdef INET6
302 if (inp->inp_vflag & INP_IPV6) {
303 bzero(&udp_in6, sizeof(udp_in6));
304 udp_in6.sin6_len = sizeof(udp_in6);
305 udp_in6.sin6_family = AF_INET6;
306 in6_sin_2_v4mapsin6(udp_in, &udp_in6);
307 append_sa = (struct sockaddr *)&udp_in6;
308 } else
302 ip_savecontrol(inp, &opts, ip, n);
303 }
304#ifdef INET6
305 if (inp->inp_vflag & INP_IPV6) {
306 bzero(&udp_in6, sizeof(udp_in6));
307 udp_in6.sin6_len = sizeof(udp_in6);
308 udp_in6.sin6_family = AF_INET6;
309 in6_sin_2_v4mapsin6(udp_in, &udp_in6);
310 append_sa = (struct sockaddr *)&udp_in6;
311 } else
309#endif
312#endif /* INET6 */
310 append_sa = (struct sockaddr *)udp_in;
311 m_adj(n, off);
312
313 so = inp->inp_socket;
314 SOCKBUF_LOCK(&so->so_rcv);
315 if (sbappendaddr_locked(&so->so_rcv, append_sa, n, opts) == 0) {
316 SOCKBUF_UNLOCK(&so->so_rcv);
317 m_freem(n);

--- 275 unchanged lines hidden (view full) ---

593
594badheadlocked:
595 if (inp)
596 INP_RUNLOCK(inp);
597 INP_INFO_RUNLOCK(&V_udbinfo);
598badunlocked:
599 m_freem(m);
600}
313 append_sa = (struct sockaddr *)udp_in;
314 m_adj(n, off);
315
316 so = inp->inp_socket;
317 SOCKBUF_LOCK(&so->so_rcv);
318 if (sbappendaddr_locked(&so->so_rcv, append_sa, n, opts) == 0) {
319 SOCKBUF_UNLOCK(&so->so_rcv);
320 m_freem(n);

--- 275 unchanged lines hidden (view full) ---

596
597badheadlocked:
598 if (inp)
599 INP_RUNLOCK(inp);
600 INP_INFO_RUNLOCK(&V_udbinfo);
601badunlocked:
602 m_freem(m);
603}
604#endif /* INET */
601
602/*
603 * Notify a udp user of an asynchronous error; just wake up so that they can
604 * collect error status.
605 */
606struct inpcb *
607udp_notify(struct inpcb *inp, int errno)
608{

--- 7 unchanged lines hidden (view full) ---

616 INP_LOCK_ASSERT(inp);
617
618 inp->inp_socket->so_error = errno;
619 sorwakeup(inp->inp_socket);
620 sowwakeup(inp->inp_socket);
621 return (inp);
622}
623
605
606/*
607 * Notify a udp user of an asynchronous error; just wake up so that they can
608 * collect error status.
609 */
610struct inpcb *
611udp_notify(struct inpcb *inp, int errno)
612{

--- 7 unchanged lines hidden (view full) ---

620 INP_LOCK_ASSERT(inp);
621
622 inp->inp_socket->so_error = errno;
623 sorwakeup(inp->inp_socket);
624 sowwakeup(inp->inp_socket);
625 return (inp);
626}
627
628#ifdef INET
624void
625udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
626{
627 struct ip *ip = vip;
628 struct udphdr *uh;
629 struct in_addr faddr;
630 struct inpcb *inp;
631

--- 29 unchanged lines hidden (view full) ---

661 }
662 INP_RUNLOCK(inp);
663 }
664 INP_INFO_RUNLOCK(&V_udbinfo);
665 } else
666 in_pcbnotifyall(&V_udbinfo, faddr, inetctlerrmap[cmd],
667 udp_notify);
668}
629void
630udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
631{
632 struct ip *ip = vip;
633 struct udphdr *uh;
634 struct in_addr faddr;
635 struct inpcb *inp;
636

--- 29 unchanged lines hidden (view full) ---

666 }
667 INP_RUNLOCK(inp);
668 }
669 INP_INFO_RUNLOCK(&V_udbinfo);
670 } else
671 in_pcbnotifyall(&V_udbinfo, faddr, inetctlerrmap[cmd],
672 udp_notify);
673}
674#endif /* INET */
669
670static int
671udp_pcblist(SYSCTL_HANDLER_ARGS)
672{
673 int error, i, n;
674 struct inpcb *inp, **inp_list;
675 inp_gen_t gencnt;
676 struct xinpgen xig;

--- 96 unchanged lines hidden (view full) ---

773 free(inp_list, M_TEMP);
774 return (error);
775}
776
777SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist,
778 CTLTYPE_OPAQUE | CTLFLAG_RD, NULL, 0,
779 udp_pcblist, "S,xinpcb", "List of active UDP sockets");
780
675
676static int
677udp_pcblist(SYSCTL_HANDLER_ARGS)
678{
679 int error, i, n;
680 struct inpcb *inp, **inp_list;
681 inp_gen_t gencnt;
682 struct xinpgen xig;

--- 96 unchanged lines hidden (view full) ---

779 free(inp_list, M_TEMP);
780 return (error);
781}
782
783SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist,
784 CTLTYPE_OPAQUE | CTLFLAG_RD, NULL, 0,
785 udp_pcblist, "S,xinpcb", "List of active UDP sockets");
786
787#ifdef INET
781static int
782udp_getcred(SYSCTL_HANDLER_ARGS)
783{
784 struct xucred xuc;
785 struct sockaddr_in addrs[2];
786 struct inpcb *inp;
787 int error;
788

--- 23 unchanged lines hidden (view full) ---

812 if (error == 0)
813 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
814 return (error);
815}
816
817SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred,
818 CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0,
819 udp_getcred, "S,xucred", "Get the xucred of a UDP connection");
788static int
789udp_getcred(SYSCTL_HANDLER_ARGS)
790{
791 struct xucred xuc;
792 struct sockaddr_in addrs[2];
793 struct inpcb *inp;
794 int error;
795

--- 23 unchanged lines hidden (view full) ---

819 if (error == 0)
820 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
821 return (error);
822}
823
824SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred,
825 CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0,
826 udp_getcred, "S,xucred", "Get the xucred of a UDP connection");
827#endif /* INET */
820
821int
822udp_ctloutput(struct socket *so, struct sockopt *sopt)
823{
824 int error = 0, optval;
825 struct inpcb *inp;
826#ifdef IPSEC_NAT_T
827 struct udpcb *up;
828#endif
829
830 inp = sotoinpcb(so);
831 KASSERT(inp != NULL, ("%s: inp == NULL", __func__));
832 INP_WLOCK(inp);
833 if (sopt->sopt_level != IPPROTO_UDP) {
834#ifdef INET6
835 if (INP_CHECK_SOCKAF(so, AF_INET6)) {
836 INP_WUNLOCK(inp);
837 error = ip6_ctloutput(so, sopt);
828
829int
830udp_ctloutput(struct socket *so, struct sockopt *sopt)
831{
832 int error = 0, optval;
833 struct inpcb *inp;
834#ifdef IPSEC_NAT_T
835 struct udpcb *up;
836#endif
837
838 inp = sotoinpcb(so);
839 KASSERT(inp != NULL, ("%s: inp == NULL", __func__));
840 INP_WLOCK(inp);
841 if (sopt->sopt_level != IPPROTO_UDP) {
842#ifdef INET6
843 if (INP_CHECK_SOCKAF(so, AF_INET6)) {
844 INP_WUNLOCK(inp);
845 error = ip6_ctloutput(so, sopt);
838 } else {
846 }
839#endif
847#endif
848#if defined(INET) && defined(INET6)
849 else
850#endif
851#ifdef INET
852 {
840 INP_WUNLOCK(inp);
841 error = ip_ctloutput(so, sopt);
853 INP_WUNLOCK(inp);
854 error = ip_ctloutput(so, sopt);
842#ifdef INET6
843 }
844#endif
845 return (error);
846 }
847
848 switch (sopt->sopt_dir) {
849 case SOPT_SET:
850 switch (sopt->sopt_name) {

--- 55 unchanged lines hidden (view full) ---

906 error = ENOPROTOOPT;
907 break;
908 }
909 break;
910 }
911 return (error);
912}
913
855 }
856#endif
857 return (error);
858 }
859
860 switch (sopt->sopt_dir) {
861 case SOPT_SET:
862 switch (sopt->sopt_name) {

--- 55 unchanged lines hidden (view full) ---

918 error = ENOPROTOOPT;
919 break;
920 }
921 break;
922 }
923 return (error);
924}
925
926#ifdef INET
914static int
915udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
916 struct mbuf *control, struct thread *td)
917{
918 struct udpiphdr *ui;
919 int len = m->m_pkthdr.len;
920 struct in_addr faddr, laddr;
921 struct cmsghdr *cm;

--- 296 unchanged lines hidden (view full) ---

1218 } else
1219 INP_RUNLOCK(inp);
1220 m_freem(m);
1221 return (error);
1222}
1223
1224
1225#if defined(IPSEC) && defined(IPSEC_NAT_T)
927static int
928udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
929 struct mbuf *control, struct thread *td)
930{
931 struct udpiphdr *ui;
932 int len = m->m_pkthdr.len;
933 struct in_addr faddr, laddr;
934 struct cmsghdr *cm;

--- 296 unchanged lines hidden (view full) ---

1231 } else
1232 INP_RUNLOCK(inp);
1233 m_freem(m);
1234 return (error);
1235}
1236
1237
1238#if defined(IPSEC) && defined(IPSEC_NAT_T)
1226#ifdef INET
1227/*
1228 * Potentially decap ESP in UDP frame. Check for an ESP header
1229 * and optional marker; if present, strip the UDP header and
1230 * push the result through IPSec.
1231 *
1232 * Returns mbuf to be processed (potentially re-allocated) or
1233 * NULL if consumed and/or processed.
1234 */

--- 115 unchanged lines hidden (view full) ---

1350 * h/w cksum flags as they are no longer valid.
1351 */
1352 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)
1353 m->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
1354
1355 (void) ipsec4_common_input(m, iphlen, ip->ip_p);
1356 return (NULL); /* NB: consumed, bypass processing. */
1357}
1239/*
1240 * Potentially decap ESP in UDP frame. Check for an ESP header
1241 * and optional marker; if present, strip the UDP header and
1242 * push the result through IPSec.
1243 *
1244 * Returns mbuf to be processed (potentially re-allocated) or
1245 * NULL if consumed and/or processed.
1246 */

--- 115 unchanged lines hidden (view full) ---

1362 * h/w cksum flags as they are no longer valid.
1363 */
1364 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)
1365 m->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
1366
1367 (void) ipsec4_common_input(m, iphlen, ip->ip_p);
1368 return (NULL); /* NB: consumed, bypass processing. */
1369}
1358#endif /* INET */
1359#endif /* defined(IPSEC) && defined(IPSEC_NAT_T) */
1360
1361static void
1362udp_abort(struct socket *so)
1363{
1364 struct inpcb *inp;
1365
1366 inp = sotoinpcb(so);

--- 38 unchanged lines hidden (view full) ---

1405 INP_INFO_WUNLOCK(&V_udbinfo);
1406 return (error);
1407 }
1408
1409 INP_WUNLOCK(inp);
1410 INP_INFO_WUNLOCK(&V_udbinfo);
1411 return (0);
1412}
1370#endif /* defined(IPSEC) && defined(IPSEC_NAT_T) */
1371
1372static void
1373udp_abort(struct socket *so)
1374{
1375 struct inpcb *inp;
1376
1377 inp = sotoinpcb(so);

--- 38 unchanged lines hidden (view full) ---

1416 INP_INFO_WUNLOCK(&V_udbinfo);
1417 return (error);
1418 }
1419
1420 INP_WUNLOCK(inp);
1421 INP_INFO_WUNLOCK(&V_udbinfo);
1422 return (0);
1423}
1424#endif /* INET */
1413
1414int
1415udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f)
1416{
1417 struct inpcb *inp;
1418 struct udpcb *up;
1419
1420 KASSERT(so->so_type == SOCK_DGRAM,

--- 6 unchanged lines hidden (view full) ---

1427 INP_WUNLOCK(inp);
1428 return (EBUSY);
1429 }
1430 up->u_tun_func = f;
1431 INP_WUNLOCK(inp);
1432 return (0);
1433}
1434
1425
1426int
1427udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f)
1428{
1429 struct inpcb *inp;
1430 struct udpcb *up;
1431
1432 KASSERT(so->so_type == SOCK_DGRAM,

--- 6 unchanged lines hidden (view full) ---

1439 INP_WUNLOCK(inp);
1440 return (EBUSY);
1441 }
1442 up->u_tun_func = f;
1443 INP_WUNLOCK(inp);
1444 return (0);
1445}
1446
1447#ifdef INET
1435static int
1436udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
1437{
1438 struct inpcb *inp;
1439 int error;
1440
1441 inp = sotoinpcb(so);
1442 KASSERT(inp != NULL, ("udp_bind: inp == NULL"));

--- 105 unchanged lines hidden (view full) ---

1548 struct mbuf *control, struct thread *td)
1549{
1550 struct inpcb *inp;
1551
1552 inp = sotoinpcb(so);
1553 KASSERT(inp != NULL, ("udp_send: inp == NULL"));
1554 return (udp_output(inp, m, addr, control, td));
1555}
1448static int
1449udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
1450{
1451 struct inpcb *inp;
1452 int error;
1453
1454 inp = sotoinpcb(so);
1455 KASSERT(inp != NULL, ("udp_bind: inp == NULL"));

--- 105 unchanged lines hidden (view full) ---

1561 struct mbuf *control, struct thread *td)
1562{
1563 struct inpcb *inp;
1564
1565 inp = sotoinpcb(so);
1566 KASSERT(inp != NULL, ("udp_send: inp == NULL"));
1567 return (udp_output(inp, m, addr, control, td));
1568}
1569#endif /* INET */
1556
1557int
1558udp_shutdown(struct socket *so)
1559{
1560 struct inpcb *inp;
1561
1562 inp = sotoinpcb(so);
1563 KASSERT(inp != NULL, ("udp_shutdown: inp == NULL"));
1564 INP_WLOCK(inp);
1565 socantsendmore(so);
1566 INP_WUNLOCK(inp);
1567 return (0);
1568}
1569
1570
1571int
1572udp_shutdown(struct socket *so)
1573{
1574 struct inpcb *inp;
1575
1576 inp = sotoinpcb(so);
1577 KASSERT(inp != NULL, ("udp_shutdown: inp == NULL"));
1578 INP_WLOCK(inp);
1579 socantsendmore(so);
1580 INP_WUNLOCK(inp);
1581 return (0);
1582}
1583
1584#ifdef INET
1570struct pr_usrreqs udp_usrreqs = {
1571 .pru_abort = udp_abort,
1572 .pru_attach = udp_attach,
1573 .pru_bind = udp_bind,
1574 .pru_connect = udp_connect,
1575 .pru_control = in_control,
1576 .pru_detach = udp_detach,
1577 .pru_disconnect = udp_disconnect,
1578 .pru_peeraddr = in_getpeeraddr,
1579 .pru_send = udp_send,
1580 .pru_soreceive = soreceive_dgram,
1581 .pru_sosend = sosend_dgram,
1582 .pru_shutdown = udp_shutdown,
1583 .pru_sockaddr = in_getsockaddr,
1584 .pru_sosetlabel = in_pcbsosetlabel,
1585 .pru_close = udp_close,
1586};
1585struct pr_usrreqs udp_usrreqs = {
1586 .pru_abort = udp_abort,
1587 .pru_attach = udp_attach,
1588 .pru_bind = udp_bind,
1589 .pru_connect = udp_connect,
1590 .pru_control = in_control,
1591 .pru_detach = udp_detach,
1592 .pru_disconnect = udp_disconnect,
1593 .pru_peeraddr = in_getpeeraddr,
1594 .pru_send = udp_send,
1595 .pru_soreceive = soreceive_dgram,
1596 .pru_sosend = sosend_dgram,
1597 .pru_shutdown = udp_shutdown,
1598 .pru_sockaddr = in_getsockaddr,
1599 .pru_sosetlabel = in_pcbsosetlabel,
1600 .pru_close = udp_close,
1601};
1602#endif /* INET */