2 * Copyright (c) 2004 Jeffrey M. Hsu. All rights reserved.
3 * Copyright (c) 2004 The DragonFly Project. All rights reserved.
5 * This code is derived from software contributed to The DragonFly Project
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of The DragonFly Project nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific, prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
36 * The Regents of the University of California. All rights reserved.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
67 * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.64.2.18 2003/01/24 05:11:34 sam Exp $
68 * $DragonFly: src/sys/netinet/udp_usrreq.c,v 1.42 2007/04/22 01:13:14 dillon Exp $
71 #include "opt_ipsec.h"
72 #include "opt_inet6.h"
74 #include <sys/param.h>
75 #include <sys/systm.h>
76 #include <sys/kernel.h>
77 #include <sys/malloc.h>
79 #include <sys/domain.h>
81 #include <sys/protosw.h>
82 #include <sys/socket.h>
83 #include <sys/socketvar.h>
84 #include <sys/sysctl.h>
85 #include <sys/syslog.h>
86 #include <sys/thread2.h>
87 #include <sys/in_cksum.h>
89 #include <machine/stdarg.h>
91 #include <vm/vm_zone.h>
94 #include <net/route.h>
96 #include <netinet/in.h>
97 #include <netinet/in_systm.h>
98 #include <netinet/ip.h>
100 #include <netinet/ip6.h>
102 #include <netinet/in_pcb.h>
103 #include <netinet/in_var.h>
104 #include <netinet/ip_var.h>
106 #include <netinet6/ip6_var.h>
108 #include <netinet/ip_icmp.h>
109 #include <netinet/icmp_var.h>
110 #include <netinet/udp.h>
111 #include <netinet/udp_var.h>
114 #include <netproto/ipsec/ipsec.h>
118 #include <netinet6/ipsec.h>
122 * UDP protocol implementation.
123 * Per RFC 768, August, 1980.
126 static int udpcksum
= 1;
128 static int udpcksum
= 0; /* XXX */
130 SYSCTL_INT(_net_inet_udp
, UDPCTL_CHECKSUM
, checksum
, CTLFLAG_RW
,
134 SYSCTL_INT(_net_inet_udp
, OID_AUTO
, log_in_vain
, CTLFLAG_RW
,
135 &log_in_vain
, 0, "Log all incoming UDP packets");
137 static int blackhole
= 0;
138 SYSCTL_INT(_net_inet_udp
, OID_AUTO
, blackhole
, CTLFLAG_RW
,
139 &blackhole
, 0, "Do not send port unreachables for refused connects");
141 static int strict_mcast_mship
= 1;
142 SYSCTL_INT(_net_inet_udp
, OID_AUTO
, strict_mcast_mship
, CTLFLAG_RW
,
143 &strict_mcast_mship
, 0, "Only send multicast to member sockets");
145 struct inpcbinfo udbinfo
;
148 #define UDBHASHSIZE 16
151 struct udpstat udpstat
; /* from udp_var.h */
152 SYSCTL_STRUCT(_net_inet_udp
, UDPCTL_STATS
, stats
, CTLFLAG_RW
,
153 &udpstat
, udpstat
, "UDP statistics (struct udpstat, netinet/udp_var.h)");
155 static struct sockaddr_in udp_in
= { sizeof udp_in
, AF_INET
};
158 struct sockaddr_in6 uin6_sin
;
159 u_char uin6_init_done
: 1;
161 { sizeof udp_in6
.uin6_sin
, AF_INET6
},
165 struct ip6_hdr uip6_ip6
;
166 u_char uip6_init_done
: 1;
170 static void udp_append (struct inpcb
*last
, struct ip
*ip
,
171 struct mbuf
*n
, int off
);
173 static void ip_2_ip6_hdr (struct ip6_hdr
*ip6
, struct ip
*ip
);
176 static int udp_detach (struct socket
*so
);
177 static int udp_output (struct inpcb
*, struct mbuf
*, struct sockaddr
*,
178 struct mbuf
*, struct thread
*);
183 in_pcbinfo_init(&udbinfo
);
184 udbinfo
.hashbase
= hashinit(UDBHASHSIZE
, M_PCB
, &udbinfo
.hashmask
);
185 udbinfo
.porthashbase
= hashinit(UDBHASHSIZE
, M_PCB
,
186 &udbinfo
.porthashmask
);
187 udbinfo
.wildcardhashbase
= hashinit(UDBHASHSIZE
, M_PCB
,
188 &udbinfo
.wildcardhashmask
);
189 udbinfo
.ipi_zone
= zinit("udpcb", sizeof(struct inpcb
), maxsockets
,
195 * Check multicast packets to make sure they are only sent to sockets with
196 * multicast memberships for the packet's destination address and arrival
197 * interface. Multicast packets to multicast-unaware sockets are also
200 * Returns 0 if the packet is acceptable, -1 if it is not.
203 check_multicast_membership(struct ip
*ip
, struct inpcb
*inp
, struct mbuf
*m
)
206 struct ip_moptions
*mopt
;
208 if (strict_mcast_mship
== 0 ||
209 !IN_MULTICAST(ntohl(ip
->ip_dst
.s_addr
))) {
212 mopt
= inp
->inp_moptions
;
215 for (mshipno
= 0; mshipno
<= mopt
->imo_num_memberships
; ++mshipno
) {
216 struct in_multi
*maddr
= mopt
->imo_membership
[mshipno
];
218 if (ip
->ip_dst
.s_addr
== maddr
->inm_addr
.s_addr
&&
219 m
->m_pkthdr
.rcvif
== maddr
->inm_ifp
) {
227 udp_input(struct mbuf
*m
, ...)
233 struct mbuf
*opts
= NULL
;
236 struct sockaddr
*append_sa
;
240 off
= __va_arg(ap
, int);
241 proto
= __va_arg(ap
, int);
245 udpstat
.udps_ipackets
++;
248 * Strip IP options, if any; should skip this,
249 * make available to user, and use on returned packets,
250 * but we don't yet have a way to check the checksum
251 * with options still present.
253 if (iphlen
> sizeof(struct ip
)) {
255 iphlen
= sizeof(struct ip
);
259 * IP and UDP headers are together in first mbuf.
260 * Already checked and pulled up in ip_demux().
262 KASSERT(m
->m_len
>= iphlen
+ sizeof(struct udphdr
),
263 ("UDP header not in one mbuf"));
265 ip
= mtod(m
, struct ip
*);
266 uh
= (struct udphdr
*)((caddr_t
)ip
+ iphlen
);
268 /* destination port of 0 is illegal, based on RFC768. */
269 if (uh
->uh_dport
== 0)
273 * Make mbuf data length reflect UDP length.
274 * If not enough data to reflect UDP length, drop.
276 len
= ntohs((u_short
)uh
->uh_ulen
);
277 if (ip
->ip_len
!= len
) {
278 if (len
> ip
->ip_len
|| len
< sizeof(struct udphdr
)) {
279 udpstat
.udps_badlen
++;
282 m_adj(m
, len
- ip
->ip_len
);
283 /* ip->ip_len = len; */
286 * Save a copy of the IP header in case we want restore it
287 * for sending an ICMP error message in response.
292 * Checksum extended UDP header and data.
295 if (m
->m_pkthdr
.csum_flags
& CSUM_DATA_VALID
) {
296 if (m
->m_pkthdr
.csum_flags
& CSUM_PSEUDO_HDR
)
297 uh
->uh_sum
= m
->m_pkthdr
.csum_data
;
299 uh
->uh_sum
= in_pseudo(ip
->ip_src
.s_addr
,
300 ip
->ip_dst
.s_addr
, htonl((u_short
)len
+
301 m
->m_pkthdr
.csum_data
+ IPPROTO_UDP
));
302 uh
->uh_sum
^= 0xffff;
306 bcopy(((struct ipovly
*)ip
)->ih_x1
, b
, 9);
307 bzero(((struct ipovly
*)ip
)->ih_x1
, 9);
308 ((struct ipovly
*)ip
)->ih_len
= uh
->uh_ulen
;
309 uh
->uh_sum
= in_cksum(m
, len
+ sizeof(struct ip
));
310 bcopy(b
, ((struct ipovly
*)ip
)->ih_x1
, 9);
313 udpstat
.udps_badsum
++;
318 udpstat
.udps_nosum
++;
320 if (IN_MULTICAST(ntohl(ip
->ip_dst
.s_addr
)) ||
321 in_broadcast(ip
->ip_dst
, m
->m_pkthdr
.rcvif
)) {
325 * Deliver a multicast or broadcast datagram to *all* sockets
326 * for which the local and remote addresses and ports match
327 * those of the incoming datagram. This allows more than
328 * one process to receive multi/broadcasts on the same port.
329 * (This really ought to be done for unicast datagrams as
330 * well, but that would cause problems with existing
331 * applications that open both address-specific sockets and
332 * a wildcard socket listening to the same port -- they would
333 * end up receiving duplicates of every unicast datagram.
334 * Those applications open the multiple sockets to overcome an
335 * inadequacy of the UDP socket interface, but for backwards
336 * compatibility we avoid the problem here rather than
337 * fixing the interface. Maybe 4.5BSD will remedy this?)
341 * Construct sockaddr format source address.
343 udp_in
.sin_port
= uh
->uh_sport
;
344 udp_in
.sin_addr
= ip
->ip_src
;
346 * Locate pcb(s) for datagram.
347 * (Algorithm copied from raw_intr().)
351 udp_in6
.uin6_init_done
= udp_ip6
.uip6_init_done
= 0;
353 LIST_FOREACH(inp
, &udbinfo
.pcblisthead
, inp_list
) {
354 if (inp
->inp_flags
& INP_PLACEMARKER
)
357 if (!(inp
->inp_vflag
& INP_IPV4
))
360 if (inp
->inp_lport
!= uh
->uh_dport
)
362 if (inp
->inp_laddr
.s_addr
!= INADDR_ANY
) {
363 if (inp
->inp_laddr
.s_addr
!=
367 if (inp
->inp_faddr
.s_addr
!= INADDR_ANY
) {
368 if (inp
->inp_faddr
.s_addr
!=
370 inp
->inp_fport
!= uh
->uh_sport
)
374 if (check_multicast_membership(ip
, inp
, m
) < 0)
381 /* check AH/ESP integrity. */
382 if (ipsec4_in_reject_so(m
, last
->inp_socket
))
383 ipsecstat
.in_polvio
++;
384 /* do not inject data to pcb */
388 /* check AH/ESP integrity. */
389 if (ipsec4_in_reject(m
, last
))
392 #endif /*FAST_IPSEC*/
393 if ((n
= m_copypacket(m
, MB_DONTWAIT
)) != NULL
)
394 udp_append(last
, ip
, n
,
396 sizeof(struct udphdr
));
400 * Don't look for additional matches if this one does
401 * not have either the SO_REUSEPORT or SO_REUSEADDR
402 * socket options set. This heuristic avoids searching
403 * through all pcbs in the common case of a non-shared
404 * port. It * assumes that an application will never
405 * clear these options after setting them.
407 if (!(last
->inp_socket
->so_options
&
408 (SO_REUSEPORT
| SO_REUSEADDR
)))
414 * No matching pcb found; discard datagram.
415 * (No need to send an ICMP Port Unreachable
416 * for a broadcast or multicast datgram.)
418 udpstat
.udps_noportbcast
++;
422 /* check AH/ESP integrity. */
423 if (ipsec4_in_reject_so(m
, last
->inp_socket
)) {
424 ipsecstat
.in_polvio
++;
429 /* check AH/ESP integrity. */
430 if (ipsec4_in_reject(m
, last
))
432 #endif /*FAST_IPSEC*/
433 udp_append(last
, ip
, m
, iphlen
+ sizeof(struct udphdr
));
437 * Locate pcb for datagram.
439 inp
= in_pcblookup_hash(&udbinfo
, ip
->ip_src
, uh
->uh_sport
,
440 ip
->ip_dst
, uh
->uh_dport
, 1, m
->m_pkthdr
.rcvif
);
443 char buf
[sizeof "aaa.bbb.ccc.ddd"];
445 strcpy(buf
, inet_ntoa(ip
->ip_dst
));
447 "Connection attempt to UDP %s:%d from %s:%d\n",
448 buf
, ntohs(uh
->uh_dport
), inet_ntoa(ip
->ip_src
),
449 ntohs(uh
->uh_sport
));
451 udpstat
.udps_noport
++;
452 if (m
->m_flags
& (M_BCAST
| M_MCAST
)) {
453 udpstat
.udps_noportbcast
++;
459 if (badport_bandlim(BANDLIM_ICMP_UNREACH
) < 0)
463 ip
->ip_len
+= iphlen
;
464 icmp_error(m
, ICMP_UNREACH
, ICMP_UNREACH_PORT
, 0, 0);
468 if (ipsec4_in_reject_so(m
, inp
->inp_socket
)) {
469 ipsecstat
.in_polvio
++;
474 if (ipsec4_in_reject(m
, inp
))
476 #endif /*FAST_IPSEC*/
478 * Check the minimum TTL for socket.
480 if (ip
->ip_ttl
< inp
->inp_ip_minttl
)
484 * Construct sockaddr format source address.
485 * Stuff source address and datagram in user buffer.
487 udp_in
.sin_port
= uh
->uh_sport
;
488 udp_in
.sin_addr
= ip
->ip_src
;
489 if ((inp
->inp_flags
& INP_CONTROLOPTS
) ||
490 (inp
->inp_socket
->so_options
& SO_TIMESTAMP
)) {
492 if (inp
->inp_vflag
& INP_IPV6
) {
495 ip_2_ip6_hdr(&udp_ip6
.uip6_ip6
, ip
);
496 savedflags
= inp
->inp_flags
;
497 inp
->inp_flags
&= ~INP_UNMAPPABLEOPTS
;
498 ip6_savecontrol(inp
, &opts
, &udp_ip6
.uip6_ip6
, m
);
499 inp
->inp_flags
= savedflags
;
502 ip_savecontrol(inp
, &opts
, ip
, m
);
504 m_adj(m
, iphlen
+ sizeof(struct udphdr
));
506 if (inp
->inp_vflag
& INP_IPV6
) {
507 in6_sin_2_v4mapsin6(&udp_in
, &udp_in6
.uin6_sin
);
508 append_sa
= (struct sockaddr
*)&udp_in6
;
511 append_sa
= (struct sockaddr
*)&udp_in
;
512 if (ssb_appendaddr(&inp
->inp_socket
->so_rcv
, append_sa
, m
, opts
) == 0) {
513 udpstat
.udps_fullsock
++;
516 sorwakeup(inp
->inp_socket
);
527 ip_2_ip6_hdr(struct ip6_hdr
*ip6
, struct ip
*ip
)
529 bzero(ip6
, sizeof *ip6
);
531 ip6
->ip6_vfc
= IPV6_VERSION
;
532 ip6
->ip6_plen
= ip
->ip_len
;
533 ip6
->ip6_nxt
= ip
->ip_p
;
534 ip6
->ip6_hlim
= ip
->ip_ttl
;
535 ip6
->ip6_src
.s6_addr32
[2] = ip6
->ip6_dst
.s6_addr32
[2] =
537 ip6
->ip6_src
.s6_addr32
[3] = ip
->ip_src
.s_addr
;
538 ip6
->ip6_dst
.s6_addr32
[3] = ip
->ip_dst
.s_addr
;
543 * subroutine of udp_input(), mainly for source code readability.
544 * caller must properly init udp_ip6 and udp_in6 beforehand.
547 udp_append(struct inpcb
*last
, struct ip
*ip
, struct mbuf
*n
, int off
)
549 struct sockaddr
*append_sa
;
550 struct mbuf
*opts
= NULL
;
552 if (last
->inp_flags
& INP_CONTROLOPTS
||
553 last
->inp_socket
->so_options
& SO_TIMESTAMP
) {
555 if (last
->inp_vflag
& INP_IPV6
) {
558 if (udp_ip6
.uip6_init_done
== 0) {
559 ip_2_ip6_hdr(&udp_ip6
.uip6_ip6
, ip
);
560 udp_ip6
.uip6_init_done
= 1;
562 savedflags
= last
->inp_flags
;
563 last
->inp_flags
&= ~INP_UNMAPPABLEOPTS
;
564 ip6_savecontrol(last
, &opts
, &udp_ip6
.uip6_ip6
, n
);
565 last
->inp_flags
= savedflags
;
568 ip_savecontrol(last
, &opts
, ip
, n
);
571 if (last
->inp_vflag
& INP_IPV6
) {
572 if (udp_in6
.uin6_init_done
== 0) {
573 in6_sin_2_v4mapsin6(&udp_in
, &udp_in6
.uin6_sin
);
574 udp_in6
.uin6_init_done
= 1;
576 append_sa
= (struct sockaddr
*)&udp_in6
.uin6_sin
;
579 append_sa
= (struct sockaddr
*)&udp_in
;
581 if (ssb_appendaddr(&last
->inp_socket
->so_rcv
, append_sa
, n
, opts
) == 0) {
585 udpstat
.udps_fullsock
++;
587 sorwakeup(last
->inp_socket
);
591 * Notify a udp user of an asynchronous error;
592 * just wake up so that he can collect error status.
595 udp_notify(struct inpcb
*inp
, int error
)
597 inp
->inp_socket
->so_error
= error
;
598 sorwakeup(inp
->inp_socket
);
599 sowwakeup(inp
->inp_socket
);
603 udp_ctlinput(int cmd
, struct sockaddr
*sa
, void *vip
)
607 void (*notify
) (struct inpcb
*, int) = udp_notify
;
608 struct in_addr faddr
;
611 faddr
= ((struct sockaddr_in
*)sa
)->sin_addr
;
612 if (sa
->sa_family
!= AF_INET
|| faddr
.s_addr
== INADDR_ANY
)
615 if (PRC_IS_REDIRECT(cmd
)) {
617 notify
= in_rtchange
;
618 } else if (cmd
== PRC_HOSTDEAD
)
620 else if ((unsigned)cmd
>= PRC_NCMDS
|| inetctlerrmap
[cmd
] == 0)
624 uh
= (struct udphdr
*)((caddr_t
)ip
+ (ip
->ip_hl
<< 2));
625 inp
= in_pcblookup_hash(&udbinfo
, faddr
, uh
->uh_dport
,
626 ip
->ip_src
, uh
->uh_sport
, 0, NULL
);
627 if (inp
!= NULL
&& inp
->inp_socket
!= NULL
)
628 (*notify
)(inp
, inetctlerrmap
[cmd
]);
631 in_pcbnotifyall(&udbinfo
.pcblisthead
, faddr
, inetctlerrmap
[cmd
],
635 SYSCTL_PROC(_net_inet_udp
, UDPCTL_PCBLIST
, pcblist
, CTLFLAG_RD
, &udbinfo
, 0,
636 in_pcblist_global
, "S,xinpcb", "List of active UDP sockets");
639 udp_getcred(SYSCTL_HANDLER_ARGS
)
641 struct sockaddr_in addrs
[2];
645 error
= suser(req
->td
);
648 error
= SYSCTL_IN(req
, addrs
, sizeof addrs
);
652 inp
= in_pcblookup_hash(&udbinfo
, addrs
[1].sin_addr
, addrs
[1].sin_port
,
653 addrs
[0].sin_addr
, addrs
[0].sin_port
, 1, NULL
);
654 if (inp
== NULL
|| inp
->inp_socket
== NULL
) {
658 error
= SYSCTL_OUT(req
, inp
->inp_socket
->so_cred
, sizeof(struct ucred
));
664 SYSCTL_PROC(_net_inet_udp
, OID_AUTO
, getcred
, CTLTYPE_OPAQUE
|CTLFLAG_RW
,
665 0, 0, udp_getcred
, "S,ucred", "Get the ucred of a UDP connection");
668 udp_output(struct inpcb
*inp
, struct mbuf
*m
, struct sockaddr
*dstaddr
,
669 struct mbuf
*control
, struct thread
*td
)
672 int len
= m
->m_pkthdr
.len
;
673 struct sockaddr_in
*sin
; /* really is initialized before use */
676 if (len
+ sizeof(struct udpiphdr
) > IP_MAXPACKET
) {
681 if (inp
->inp_lport
== 0) { /* unbound socket */
682 error
= in_pcbbind(inp
, (struct sockaddr
*)NULL
, td
);
685 in_pcbinswildcardhash(inp
);
688 if (dstaddr
!= NULL
) { /* destination address specified */
689 if (inp
->inp_faddr
.s_addr
!= INADDR_ANY
) {
690 /* already connected */
694 sin
= (struct sockaddr_in
*)dstaddr
;
695 if (!prison_remote_ip(td
, (struct sockaddr
*)&sin
)) {
696 error
= EAFNOSUPPORT
; /* IPv6 only jail */
700 if (inp
->inp_faddr
.s_addr
== INADDR_ANY
) {
701 /* no destination specified and not already connected */
709 * Calculate data length and get a mbuf
710 * for UDP and IP headers.
712 M_PREPEND(m
, sizeof(struct udpiphdr
), MB_DONTWAIT
);
719 * Fill in mbuf with extended UDP header
720 * and addresses and length put into network format.
722 ui
= mtod(m
, struct udpiphdr
*);
723 bzero(ui
->ui_x1
, sizeof ui
->ui_x1
); /* XXX still needed? */
724 ui
->ui_pr
= IPPROTO_UDP
;
727 * Set destination address.
729 if (dstaddr
!= NULL
) { /* use specified destination */
730 ui
->ui_dst
= sin
->sin_addr
;
731 ui
->ui_dport
= sin
->sin_port
;
732 } else { /* use connected destination */
733 ui
->ui_dst
= inp
->inp_faddr
;
734 ui
->ui_dport
= inp
->inp_fport
;
738 * Set source address.
740 if (inp
->inp_laddr
.s_addr
== INADDR_ANY
) {
741 struct sockaddr_in
*if_sin
;
743 if (dstaddr
== NULL
) {
745 * connect() had (or should have) failed because
746 * the interface had no IP address, but the
747 * application proceeded to call send() anyways.
753 /* Look up outgoing interface. */
754 if ((error
= in_pcbladdr(inp
, dstaddr
, &if_sin
, td
)))
756 ui
->ui_src
= if_sin
->sin_addr
; /* use address of interface */
758 ui
->ui_src
= inp
->inp_laddr
; /* use non-null bound address */
760 ui
->ui_sport
= inp
->inp_lport
;
761 KASSERT(inp
->inp_lport
!= 0, ("inp lport should have been bound"));
763 ui
->ui_ulen
= htons((u_short
)len
+ sizeof(struct udphdr
));
766 * Set up checksum and output datagram.
769 ui
->ui_sum
= in_pseudo(ui
->ui_src
.s_addr
, ui
->ui_dst
.s_addr
,
770 htons((u_short
)len
+ sizeof(struct udphdr
) + IPPROTO_UDP
));
771 m
->m_pkthdr
.csum_flags
= CSUM_UDP
;
772 m
->m_pkthdr
.csum_data
= offsetof(struct udphdr
, uh_sum
);
776 ((struct ip
*)ui
)->ip_len
= sizeof(struct udpiphdr
) + len
;
777 ((struct ip
*)ui
)->ip_ttl
= inp
->inp_ip_ttl
; /* XXX */
778 ((struct ip
*)ui
)->ip_tos
= inp
->inp_ip_tos
; /* XXX */
779 udpstat
.udps_opackets
++;
781 error
= ip_output(m
, inp
->inp_options
, &inp
->inp_route
,
782 (inp
->inp_socket
->so_options
& (SO_DONTROUTE
| SO_BROADCAST
)),
783 inp
->inp_moptions
, inp
);
792 u_long udp_sendspace
= 9216; /* really max datagram size */
793 /* 40 1K datagrams */
794 SYSCTL_INT(_net_inet_udp
, UDPCTL_MAXDGRAM
, maxdgram
, CTLFLAG_RW
,
795 &udp_sendspace
, 0, "Maximum outgoing UDP datagram size");
797 u_long udp_recvspace
= 40 * (1024 +
799 sizeof(struct sockaddr_in6
)
801 sizeof(struct sockaddr_in
)
804 SYSCTL_INT(_net_inet_udp
, UDPCTL_RECVSPACE
, recvspace
, CTLFLAG_RW
,
805 &udp_recvspace
, 0, "Maximum incoming UDP datagram size");
808 udp_abort(struct socket
*so
)
814 return EINVAL
; /* ??? possible? panic instead? */
815 soisdisconnected(so
);
823 udp_attach(struct socket
*so
, int proto
, struct pru_attach_info
*ai
)
832 error
= soreserve(so
, udp_sendspace
, udp_recvspace
, ai
->sb_rlimit
);
836 error
= in_pcballoc(so
, &udbinfo
);
841 inp
= (struct inpcb
*)so
->so_pcb
;
842 inp
->inp_vflag
|= INP_IPV4
;
843 inp
->inp_ip_ttl
= ip_defttl
;
848 udp_bind(struct socket
*so
, struct sockaddr
*nam
, struct thread
*td
)
850 struct sockaddr_in
*sin
= (struct sockaddr_in
*)nam
;
858 error
= in_pcbbind(inp
, nam
, td
);
861 if (sin
->sin_addr
.s_addr
!= INADDR_ANY
)
862 inp
->inp_flags
|= INP_WASBOUND_NOTANY
;
863 in_pcbinswildcardhash(inp
);
869 udp_connect(struct socket
*so
, struct sockaddr
*nam
, struct thread
*td
)
877 if (inp
->inp_faddr
.s_addr
!= INADDR_ANY
)
881 if (td
->td_proc
&& td
->td_proc
->p_ucred
->cr_prison
!= NULL
&&
882 inp
->inp_laddr
.s_addr
== INADDR_ANY
) {
883 error
= in_pcbbind(inp
, NULL
, td
);
886 if (!prison_remote_ip(td
, nam
))
887 return(EAFNOSUPPORT
); /* IPv6 only jail */
888 if (inp
->inp_flags
& INP_WILDCARD
)
889 in_pcbremwildcardhash(inp
);
890 error
= in_pcbconnect(inp
, nam
, td
);
895 else if (error
== EAFNOSUPPORT
) { /* connection dissolved */
897 * Follow traditional BSD behavior and retain
898 * the local port binding. But, fix the old misbehavior
899 * of overwriting any previously bound local address.
901 if (!(inp
->inp_flags
& INP_WASBOUND_NOTANY
))
902 inp
->inp_laddr
.s_addr
= INADDR_ANY
;
903 in_pcbinswildcardhash(inp
);
909 udp_detach(struct socket
*so
)
923 udp_disconnect(struct socket
*so
)
930 if (inp
->inp_faddr
.s_addr
== INADDR_ANY
)
934 in_pcbdisconnect(inp
);
936 so
->so_state
&= ~SS_ISCONNECTED
; /* XXX */
941 udp_send(struct socket
*so
, int flags
, struct mbuf
*m
, struct sockaddr
*addr
,
942 struct mbuf
*control
, struct thread
*td
)
951 return udp_output(inp
, m
, addr
, control
, td
);
955 udp_shutdown(struct socket
*so
)
966 struct pr_usrreqs udp_usrreqs
= {
967 .pru_abort
= udp_abort
,
968 .pru_accept
= pru_accept_notsupp
,
969 .pru_attach
= udp_attach
,
970 .pru_bind
= udp_bind
,
971 .pru_connect
= udp_connect
,
972 .pru_connect2
= pru_connect2_notsupp
,
973 .pru_control
= in_control
,
974 .pru_detach
= udp_detach
,
975 .pru_disconnect
= udp_disconnect
,
976 .pru_listen
= pru_listen_notsupp
,
977 .pru_peeraddr
= in_setpeeraddr
,
978 .pru_rcvd
= pru_rcvd_notsupp
,
979 .pru_rcvoob
= pru_rcvoob_notsupp
,
980 .pru_send
= udp_send
,
981 .pru_sense
= pru_sense_null
,
982 .pru_shutdown
= udp_shutdown
,
983 .pru_sockaddr
= in_setsockaddr
,
984 .pru_sosend
= sosendudp
,
985 .pru_soreceive
= soreceive
,