]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/udp6_usrreq.c
xnu-6153.41.3.tar.gz
[apple/xnu.git] / bsd / netinet6 / udp6_usrreq.c
1 /*
2 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 /* $FreeBSD: src/sys/netinet6/udp6_usrreq.c,v 1.6.2.6 2001/07/29 19:32:40 ume Exp $ */
30 /* $KAME: udp6_usrreq.c,v 1.27 2001/05/21 05:45:10 jinmei Exp $ */
31
32 /*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61 /*
62 * Copyright (c) 1982, 1986, 1989, 1993
63 * The Regents of the University of California. All rights reserved.
64 *
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
67 * are met:
68 * 1. Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in the
72 * documentation and/or other materials provided with the distribution.
73 * 3. All advertising materials mentioning features or use of this software
74 * must display the following acknowledgement:
75 * This product includes software developed by the University of
76 * California, Berkeley and its contributors.
77 * 4. Neither the name of the University nor the names of its contributors
78 * may be used to endorse or promote products derived from this software
79 * without specific prior written permission.
80 *
81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * SUCH DAMAGE.
92 *
93 * @(#)udp_var.h 8.1 (Berkeley) 6/10/93
94 */
95 #include <sys/kernel.h>
96 #include <sys/malloc.h>
97 #include <sys/mbuf.h>
98 #include <sys/param.h>
99 #include <sys/protosw.h>
100 #include <sys/socket.h>
101 #include <sys/socketvar.h>
102 #include <sys/sysctl.h>
103 #include <sys/errno.h>
104 #include <sys/stat.h>
105 #include <sys/systm.h>
106 #include <sys/syslog.h>
107 #include <sys/proc.h>
108 #include <sys/kauth.h>
109
110 #include <net/if.h>
111 #include <net/route.h>
112 #include <net/if_types.h>
113 #include <net/ntstat.h>
114 #include <net/dlil.h>
115 #include <net/net_api_stats.h>
116
117 #include <netinet/in.h>
118 #include <netinet/in_systm.h>
119 #include <netinet/ip.h>
120 #include <netinet/in_pcb.h>
121 #include <netinet/in_var.h>
122 #include <netinet/ip_var.h>
123 #include <netinet/udp.h>
124 #include <netinet/udp_var.h>
125 #include <netinet/ip6.h>
126 #include <netinet6/ip6_var.h>
127 #include <netinet6/in6_pcb.h>
128 #include <netinet/icmp6.h>
129 #include <netinet6/udp6_var.h>
130 #include <netinet6/ip6protosw.h>
131
132 #if IPSEC
133 #include <netinet6/ipsec.h>
134 #include <netinet6/ipsec6.h>
135 #include <netinet6/esp6.h>
136 #include <netkey/key.h>
137 extern int ipsec_bypass;
138 extern int esp_udp_encap_port;
139 #endif /* IPSEC */
140
141 #if NECP
142 #include <net/necp.h>
143 #endif /* NECP */
144
145 #if FLOW_DIVERT
146 #include <netinet/flow_divert.h>
147 #endif /* FLOW_DIVERT */
148
149 #if CONTENT_FILTER
150 #include <net/content_filter.h>
151 #endif /* CONTENT_FILTER */
152
153 /*
154 * UDP protocol inplementation.
155 * Per RFC 768, August, 1980.
156 */
157
158 static int udp6_abort(struct socket *);
159 static int udp6_attach(struct socket *, int, struct proc *);
160 static int udp6_bind(struct socket *, struct sockaddr *, struct proc *);
161 static int udp6_connectx(struct socket *, struct sockaddr *,
162 struct sockaddr *, struct proc *, uint32_t, sae_associd_t,
163 sae_connid_t *, uint32_t, void *, uint32_t, struct uio *, user_ssize_t *);
164 static int udp6_detach(struct socket *);
165 static int udp6_disconnect(struct socket *);
166 static int udp6_disconnectx(struct socket *, sae_associd_t, sae_connid_t);
167 static int udp6_send(struct socket *, int, struct mbuf *, struct sockaddr *,
168 struct mbuf *, struct proc *);
169 static void udp6_append(struct inpcb *, struct ip6_hdr *,
170 struct sockaddr_in6 *, struct mbuf *, int, struct ifnet *);
171 static int udp6_input_checksum(struct mbuf *, struct udphdr *, int, int);
172
173 struct pr_usrreqs udp6_usrreqs = {
174 .pru_abort = udp6_abort,
175 .pru_attach = udp6_attach,
176 .pru_bind = udp6_bind,
177 .pru_connect = udp6_connect,
178 .pru_connectx = udp6_connectx,
179 .pru_control = in6_control,
180 .pru_detach = udp6_detach,
181 .pru_disconnect = udp6_disconnect,
182 .pru_disconnectx = udp6_disconnectx,
183 .pru_peeraddr = in6_mapped_peeraddr,
184 .pru_send = udp6_send,
185 .pru_shutdown = udp_shutdown,
186 .pru_sockaddr = in6_mapped_sockaddr,
187 .pru_sosend = sosend,
188 .pru_soreceive = soreceive,
189 .pru_soreceive_list = soreceive_list,
190 };
191
192 /*
193 * subroutine of udp6_input(), mainly for source code readability.
194 */
195 static void
196 udp6_append(struct inpcb *last, struct ip6_hdr *ip6,
197 struct sockaddr_in6 *udp_in6, struct mbuf *n, int off, struct ifnet *ifp)
198 {
199 #pragma unused(ip6)
200 struct mbuf *opts = NULL;
201 int ret = 0;
202 boolean_t cell = IFNET_IS_CELLULAR(ifp);
203 boolean_t wifi = (!cell && IFNET_IS_WIFI(ifp));
204 boolean_t wired = (!wifi && IFNET_IS_WIRED(ifp));
205
206 #if CONFIG_MACF_NET
207 if (mac_inpcb_check_deliver(last, n, AF_INET6, SOCK_DGRAM) != 0) {
208 m_freem(n);
209 return;
210 }
211 #endif /* CONFIG_MACF_NET */
212 if ((last->in6p_flags & INP_CONTROLOPTS) != 0 ||
213 (last->in6p_socket->so_options & SO_TIMESTAMP) != 0 ||
214 (last->in6p_socket->so_options & SO_TIMESTAMP_MONOTONIC) != 0 ||
215 (last->in6p_socket->so_options & SO_TIMESTAMP_CONTINUOUS) != 0) {
216 ret = ip6_savecontrol(last, n, &opts);
217 if (ret != 0) {
218 m_freem(n);
219 m_freem(opts);
220 return;
221 }
222 }
223 m_adj(n, off);
224 if (nstat_collect) {
225 INP_ADD_STAT(last, cell, wifi, wired, rxpackets, 1);
226 INP_ADD_STAT(last, cell, wifi, wired, rxbytes, n->m_pkthdr.len);
227 inp_set_activity_bitmap(last);
228 }
229 so_recv_data_stat(last->in6p_socket, n, 0);
230 if (sbappendaddr(&last->in6p_socket->so_rcv,
231 (struct sockaddr *)udp_in6, n, opts, NULL) == 0) {
232 udpstat.udps_fullsock++;
233 } else {
234 sorwakeup(last->in6p_socket);
235 }
236 }
237
238 int
239 udp6_input(struct mbuf **mp, int *offp, int proto)
240 {
241 #pragma unused(proto)
242 struct mbuf *m = *mp;
243 struct ifnet *ifp;
244 struct ip6_hdr *ip6;
245 struct udphdr *uh;
246 struct inpcb *in6p;
247 struct mbuf *opts = NULL;
248 int off = *offp;
249 int plen, ulen, ret = 0;
250 boolean_t cell, wifi, wired;
251 struct sockaddr_in6 udp_in6;
252 struct inpcbinfo *pcbinfo = &udbinfo;
253 struct sockaddr_in6 fromsa;
254
255 IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), return IPPROTO_DONE);
256
257 /* Expect 32-bit aligned data pointer on strict-align platforms */
258 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
259
260 ifp = m->m_pkthdr.rcvif;
261 ip6 = mtod(m, struct ip6_hdr *);
262 cell = IFNET_IS_CELLULAR(ifp);
263 wifi = (!cell && IFNET_IS_WIFI(ifp));
264 wired = (!wifi && IFNET_IS_WIRED(ifp));
265
266 udpstat.udps_ipackets++;
267
268 plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
269 uh = (struct udphdr *)(void *)((caddr_t)ip6 + off);
270 ulen = ntohs((u_short)uh->uh_ulen);
271
272 if (plen != ulen) {
273 udpstat.udps_badlen++;
274 IF_UDP_STATINC(ifp, badlength);
275 goto bad;
276 }
277
278 /* destination port of 0 is illegal, based on RFC768. */
279 if (uh->uh_dport == 0) {
280 IF_UDP_STATINC(ifp, port0);
281 goto bad;
282 }
283
284 /*
285 * Checksum extended UDP header and data.
286 */
287 if (udp6_input_checksum(m, uh, off, ulen)) {
288 goto bad;
289 }
290
291 /*
292 * Construct sockaddr format source address.
293 */
294 init_sin6(&fromsa, m);
295 fromsa.sin6_port = uh->uh_sport;
296
297 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
298 int reuse_sock = 0, mcast_delivered = 0;
299 struct ip6_moptions *imo;
300
301 /*
302 * Deliver a multicast datagram to all sockets
303 * for which the local and remote addresses and ports match
304 * those of the incoming datagram. This allows more than
305 * one process to receive multicasts on the same port.
306 * (This really ought to be done for unicast datagrams as
307 * well, but that would cause problems with existing
308 * applications that open both address-specific sockets and
309 * a wildcard socket listening to the same port -- they would
310 * end up receiving duplicates of every unicast datagram.
311 * Those applications open the multiple sockets to overcome an
312 * inadequacy of the UDP socket interface, but for backwards
313 * compatibility we avoid the problem here rather than
314 * fixing the interface. Maybe 4.5BSD will remedy this?)
315 */
316
317 /*
318 * In a case that laddr should be set to the link-local
319 * address (this happens in RIPng), the multicast address
320 * specified in the received packet does not match with
321 * laddr. To cure this situation, the matching is relaxed
322 * if the receiving interface is the same as one specified
323 * in the socket and if the destination multicast address
324 * matches one of the multicast groups specified in the socket.
325 */
326
327 /*
328 * Construct sockaddr format source address.
329 */
330 init_sin6(&udp_in6, m); /* general init */
331 udp_in6.sin6_port = uh->uh_sport;
332 /*
333 * KAME note: usually we drop udphdr from mbuf here.
334 * We need udphdr for IPsec processing so we do that later.
335 */
336
337 /*
338 * Locate pcb(s) for datagram.
339 * (Algorithm copied from raw_intr().)
340 */
341 lck_rw_lock_shared(pcbinfo->ipi_lock);
342
343 LIST_FOREACH(in6p, &udb, inp_list) {
344 #if IPSEC
345 int skipit;
346 #endif /* IPSEC */
347
348 if ((in6p->inp_vflag & INP_IPV6) == 0) {
349 continue;
350 }
351
352 if (inp_restricted_recv(in6p, ifp)) {
353 continue;
354 }
355
356 if (in_pcb_checkstate(in6p, WNT_ACQUIRE, 0) ==
357 WNT_STOPUSING) {
358 continue;
359 }
360
361 udp_lock(in6p->in6p_socket, 1, 0);
362
363 if (in_pcb_checkstate(in6p, WNT_RELEASE, 1) ==
364 WNT_STOPUSING) {
365 udp_unlock(in6p->in6p_socket, 1, 0);
366 continue;
367 }
368 if (in6p->in6p_lport != uh->uh_dport) {
369 udp_unlock(in6p->in6p_socket, 1, 0);
370 continue;
371 }
372
373 /*
374 * Handle socket delivery policy for any-source
375 * and source-specific multicast. [RFC3678]
376 */
377 imo = in6p->in6p_moptions;
378 if (imo && IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
379 struct sockaddr_in6 mcaddr;
380 int blocked;
381
382 IM6O_LOCK(imo);
383 bzero(&mcaddr, sizeof(struct sockaddr_in6));
384 mcaddr.sin6_len = sizeof(struct sockaddr_in6);
385 mcaddr.sin6_family = AF_INET6;
386 mcaddr.sin6_addr = ip6->ip6_dst;
387
388 blocked = im6o_mc_filter(imo, ifp,
389 &mcaddr, &fromsa);
390 IM6O_UNLOCK(imo);
391 if (blocked != MCAST_PASS) {
392 udp_unlock(in6p->in6p_socket, 1, 0);
393 if (blocked == MCAST_NOTSMEMBER ||
394 blocked == MCAST_MUTED) {
395 udpstat.udps_filtermcast++;
396 }
397 continue;
398 }
399 }
400 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
401 (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr,
402 &ip6->ip6_src) ||
403 in6p->in6p_fport != uh->uh_sport)) {
404 udp_unlock(in6p->in6p_socket, 1, 0);
405 continue;
406 }
407
408 reuse_sock = in6p->inp_socket->so_options &
409 (SO_REUSEPORT | SO_REUSEADDR);
410
411 #if NECP
412 skipit = 0;
413 if (!necp_socket_is_allowed_to_send_recv_v6(in6p,
414 uh->uh_dport, uh->uh_sport, &ip6->ip6_dst,
415 &ip6->ip6_src, ifp, NULL, NULL, NULL)) {
416 /* do not inject data to pcb */
417 skipit = 1;
418 }
419 if (skipit == 0)
420 #endif /* NECP */
421 {
422 struct mbuf *n = NULL;
423 /*
424 * KAME NOTE: do not
425 * m_copy(m, offset, ...) below.
426 * sbappendaddr() expects M_PKTHDR,
427 * and m_copy() will copy M_PKTHDR
428 * only if offset is 0.
429 */
430 if (reuse_sock) {
431 n = m_copy(m, 0, M_COPYALL);
432 }
433 udp6_append(in6p, ip6, &udp_in6, m,
434 off + sizeof(struct udphdr), ifp);
435 mcast_delivered++;
436 m = n;
437 }
438 udp_unlock(in6p->in6p_socket, 1, 0);
439
440 /*
441 * Don't look for additional matches if this one does
442 * not have either the SO_REUSEPORT or SO_REUSEADDR
443 * socket options set. This heuristic avoids searching
444 * through all pcbs in the common case of a non-shared
445 * port. It assumes that an application will never
446 * clear these options after setting them.
447 */
448 if (reuse_sock == 0 || m == NULL) {
449 break;
450 }
451
452 /*
453 * Expect 32-bit aligned data pointer on strict-align
454 * platforms.
455 */
456 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
457
458 /*
459 * Recompute IP and UDP header pointers for new mbuf
460 */
461 ip6 = mtod(m, struct ip6_hdr *);
462 uh = (struct udphdr *)(void *)((caddr_t)ip6 + off);
463 }
464 lck_rw_done(pcbinfo->ipi_lock);
465
466 if (mcast_delivered == 0) {
467 /*
468 * No matching pcb found; discard datagram.
469 * (No need to send an ICMP Port Unreachable
470 * for a broadcast or multicast datgram.)
471 */
472 udpstat.udps_noport++;
473 udpstat.udps_noportmcast++;
474 IF_UDP_STATINC(ifp, port_unreach);
475 goto bad;
476 }
477
478 /* free the extra copy of mbuf or skipped by NECP */
479 if (m != NULL) {
480 m_freem(m);
481 }
482 return IPPROTO_DONE;
483 }
484
485 #if IPSEC
486 /*
487 * UDP to port 4500 with a payload where the first four bytes are
488 * not zero is a UDP encapsulated IPsec packet. Packets where
489 * the payload is one byte and that byte is 0xFF are NAT keepalive
490 * packets. Decapsulate the ESP packet and carry on with IPsec input
491 * or discard the NAT keep-alive.
492 */
493 if (ipsec_bypass == 0 && (esp_udp_encap_port & 0xFFFF) != 0 &&
494 (uh->uh_dport == ntohs((u_short)esp_udp_encap_port) ||
495 uh->uh_sport == ntohs((u_short)esp_udp_encap_port))) {
496 /*
497 * Check if ESP or keepalive:
498 * 1. If the destination port of the incoming packet is 4500.
499 * 2. If the source port of the incoming packet is 4500,
500 * then check the SADB to match IP address and port.
501 */
502 bool check_esp = true;
503 if (uh->uh_dport != ntohs((u_short)esp_udp_encap_port)) {
504 check_esp = key_checksa_present(AF_INET6, (caddr_t)&ip6->ip6_dst,
505 (caddr_t)&ip6->ip6_src, uh->uh_dport,
506 uh->uh_sport);
507 }
508
509 if (check_esp) {
510 int payload_len = ulen - sizeof(struct udphdr) > 4 ? 4 :
511 ulen - sizeof(struct udphdr);
512
513 if (m->m_len < off + sizeof(struct udphdr) + payload_len) {
514 if ((m = m_pullup(m, off + sizeof(struct udphdr) +
515 payload_len)) == NULL) {
516 udpstat.udps_hdrops++;
517 goto bad;
518 }
519 /*
520 * Expect 32-bit aligned data pointer on strict-align
521 * platforms.
522 */
523 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
524
525 ip6 = mtod(m, struct ip6_hdr *);
526 uh = (struct udphdr *)(void *)((caddr_t)ip6 + off);
527 }
528 /* Check for NAT keepalive packet */
529 if (payload_len == 1 && *(u_int8_t*)
530 ((caddr_t)uh + sizeof(struct udphdr)) == 0xFF) {
531 goto bad;
532 } else if (payload_len == 4 && *(u_int32_t*)(void *)
533 ((caddr_t)uh + sizeof(struct udphdr)) != 0) {
534 /* UDP encapsulated IPsec packet to pass through NAT */
535 /* preserve the udp header */
536 *offp = off + sizeof(struct udphdr);
537 return esp6_input(mp, offp, IPPROTO_UDP);
538 }
539 }
540 }
541 #endif /* IPSEC */
542
543 /*
544 * Locate pcb for datagram.
545 */
546 in6p = in6_pcblookup_hash(&udbinfo, &ip6->ip6_src, uh->uh_sport,
547 &ip6->ip6_dst, uh->uh_dport, 1, m->m_pkthdr.rcvif);
548 if (in6p == NULL) {
549 IF_UDP_STATINC(ifp, port_unreach);
550
551 if (udp_log_in_vain) {
552 char buf[INET6_ADDRSTRLEN];
553
554 strlcpy(buf, ip6_sprintf(&ip6->ip6_dst), sizeof(buf));
555 if (udp_log_in_vain < 3) {
556 log(LOG_INFO, "Connection attempt to UDP "
557 "%s:%d from %s:%d\n", buf,
558 ntohs(uh->uh_dport),
559 ip6_sprintf(&ip6->ip6_src),
560 ntohs(uh->uh_sport));
561 } else if (!(m->m_flags & (M_BCAST | M_MCAST)) &&
562 !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &ip6->ip6_src)) {
563 log(LOG_INFO, "Connection attempt "
564 "to UDP %s:%d from %s:%d\n", buf,
565 ntohs(uh->uh_dport),
566 ip6_sprintf(&ip6->ip6_src),
567 ntohs(uh->uh_sport));
568 }
569 }
570 udpstat.udps_noport++;
571 if (m->m_flags & M_MCAST) {
572 printf("UDP6: M_MCAST is set in a unicast packet.\n");
573 udpstat.udps_noportmcast++;
574 IF_UDP_STATINC(ifp, badmcast);
575 goto bad;
576 }
577 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
578 return IPPROTO_DONE;
579 }
580 #if NECP
581 if (!necp_socket_is_allowed_to_send_recv_v6(in6p, uh->uh_dport,
582 uh->uh_sport, &ip6->ip6_dst, &ip6->ip6_src, ifp, NULL, NULL, NULL)) {
583 in_pcb_checkstate(in6p, WNT_RELEASE, 0);
584 IF_UDP_STATINC(ifp, badipsec);
585 goto bad;
586 }
587 #endif /* NECP */
588
589 /*
590 * Construct sockaddr format source address.
591 * Stuff source address and datagram in user buffer.
592 */
593 udp_lock(in6p->in6p_socket, 1, 0);
594
595 if (in_pcb_checkstate(in6p, WNT_RELEASE, 1) == WNT_STOPUSING) {
596 udp_unlock(in6p->in6p_socket, 1, 0);
597 IF_UDP_STATINC(ifp, cleanup);
598 goto bad;
599 }
600
601 init_sin6(&udp_in6, m); /* general init */
602 udp_in6.sin6_port = uh->uh_sport;
603 if ((in6p->in6p_flags & INP_CONTROLOPTS) != 0 ||
604 (in6p->in6p_socket->so_options & SO_TIMESTAMP) != 0 ||
605 (in6p->in6p_socket->so_options & SO_TIMESTAMP_MONOTONIC) != 0 ||
606 (in6p->in6p_socket->so_options & SO_TIMESTAMP_CONTINUOUS) != 0) {
607 ret = ip6_savecontrol(in6p, m, &opts);
608 if (ret != 0) {
609 udp_unlock(in6p->in6p_socket, 1, 0);
610 goto bad;
611 }
612 }
613 m_adj(m, off + sizeof(struct udphdr));
614 if (nstat_collect) {
615 INP_ADD_STAT(in6p, cell, wifi, wired, rxpackets, 1);
616 INP_ADD_STAT(in6p, cell, wifi, wired, rxbytes, m->m_pkthdr.len);
617 inp_set_activity_bitmap(in6p);
618 }
619 so_recv_data_stat(in6p->in6p_socket, m, 0);
620 if (sbappendaddr(&in6p->in6p_socket->so_rcv,
621 (struct sockaddr *)&udp_in6, m, opts, NULL) == 0) {
622 m = NULL;
623 opts = NULL;
624 udpstat.udps_fullsock++;
625 udp_unlock(in6p->in6p_socket, 1, 0);
626 goto bad;
627 }
628 sorwakeup(in6p->in6p_socket);
629 udp_unlock(in6p->in6p_socket, 1, 0);
630 return IPPROTO_DONE;
631 bad:
632 if (m != NULL) {
633 m_freem(m);
634 }
635 if (opts != NULL) {
636 m_freem(opts);
637 }
638 return IPPROTO_DONE;
639 }
640
641 void
642 udp6_ctlinput(int cmd, struct sockaddr *sa, void *d, __unused struct ifnet *ifp)
643 {
644 struct udphdr uh;
645 struct ip6_hdr *ip6;
646 struct mbuf *m;
647 int off = 0;
648 struct ip6ctlparam *ip6cp = NULL;
649 struct icmp6_hdr *icmp6 = NULL;
650 const struct sockaddr_in6 *sa6_src = NULL;
651 void (*notify)(struct inpcb *, int) = udp_notify;
652 struct udp_portonly {
653 u_int16_t uh_sport;
654 u_int16_t uh_dport;
655 } *uhp;
656
657 if (sa->sa_family != AF_INET6 ||
658 sa->sa_len != sizeof(struct sockaddr_in6)) {
659 return;
660 }
661
662 if ((unsigned)cmd >= PRC_NCMDS) {
663 return;
664 }
665 if (PRC_IS_REDIRECT(cmd)) {
666 notify = in6_rtchange;
667 d = NULL;
668 } else if (cmd == PRC_HOSTDEAD) {
669 d = NULL;
670 } else if (inet6ctlerrmap[cmd] == 0) {
671 return;
672 }
673
674 /* if the parameter is from icmp6, decode it. */
675 if (d != NULL) {
676 ip6cp = (struct ip6ctlparam *)d;
677 icmp6 = ip6cp->ip6c_icmp6;
678 m = ip6cp->ip6c_m;
679 ip6 = ip6cp->ip6c_ip6;
680 off = ip6cp->ip6c_off;
681 sa6_src = ip6cp->ip6c_src;
682 } else {
683 m = NULL;
684 ip6 = NULL;
685 sa6_src = &sa6_any;
686 }
687
688 if (ip6 != NULL) {
689 /*
690 * XXX: We assume that when IPV6 is non NULL,
691 * M and OFF are valid.
692 */
693 /* check if we can safely examine src and dst ports */
694 if (m->m_pkthdr.len < off + sizeof(*uhp)) {
695 return;
696 }
697
698 bzero(&uh, sizeof(uh));
699 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
700
701 (void) in6_pcbnotify(&udbinfo, sa, uh.uh_dport,
702 (struct sockaddr*)ip6cp->ip6c_src, uh.uh_sport,
703 cmd, NULL, notify);
704 }
705 /*
706 * XXX The else condition here was broken for a long time.
707 * Fixing it made us deliver notification correctly but broke
708 * some frameworks that didn't handle it well.
709 * For now we have removed it and will revisit it later.
710 */
711 }
712
713 static int
714 udp6_abort(struct socket *so)
715 {
716 struct inpcb *inp;
717
718 inp = sotoinpcb(so);
719 if (inp == NULL) {
720 panic("%s: so=%p null inp\n", __func__, so);
721 /* NOTREACHED */
722 }
723 soisdisconnected(so);
724 in6_pcbdetach(inp);
725 return 0;
726 }
727
728 static int
729 udp6_attach(struct socket *so, int proto, struct proc *p)
730 {
731 #pragma unused(proto)
732 struct inpcb *inp;
733 int error;
734
735 inp = sotoinpcb(so);
736 if (inp != NULL) {
737 return EINVAL;
738 }
739
740 error = in_pcballoc(so, &udbinfo, p);
741 if (error) {
742 return error;
743 }
744
745 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
746 error = soreserve(so, udp_sendspace, udp_recvspace);
747 if (error) {
748 return error;
749 }
750 }
751 inp = (struct inpcb *)so->so_pcb;
752 inp->inp_vflag |= INP_IPV6;
753 if (ip6_mapped_addr_on) {
754 inp->inp_vflag |= INP_IPV4;
755 }
756 inp->in6p_hops = -1; /* use kernel default */
757 inp->in6p_cksum = -1; /* just to be sure */
758 /*
759 * XXX: ugly!!
760 * IPv4 TTL initialization is necessary for an IPv6 socket as well,
761 * because the socket may be bound to an IPv6 wildcard address,
762 * which may match an IPv4-mapped IPv6 address.
763 */
764 inp->inp_ip_ttl = ip_defttl;
765 if (nstat_collect) {
766 nstat_udp_new_pcb(inp);
767 }
768 return 0;
769 }
770
771 static int
772 udp6_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
773 {
774 struct inpcb *inp;
775 int error;
776
777 inp = sotoinpcb(so);
778 if (inp == NULL) {
779 return EINVAL;
780 }
781
782 inp->inp_vflag &= ~INP_IPV4;
783 inp->inp_vflag |= INP_IPV6;
784 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
785 struct sockaddr_in6 *sin6_p;
786
787 sin6_p = (struct sockaddr_in6 *)(void *)nam;
788
789 if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) {
790 inp->inp_vflag |= INP_IPV4;
791 } else if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
792 struct sockaddr_in sin;
793
794 in6_sin6_2_sin(&sin, sin6_p);
795 inp->inp_vflag |= INP_IPV4;
796 inp->inp_vflag &= ~INP_IPV6;
797 error = in_pcbbind(inp, (struct sockaddr *)&sin, p);
798 return error;
799 }
800 }
801
802 error = in6_pcbbind(inp, nam, p);
803 return error;
804 }
805
806 int
807 udp6_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
808 {
809 struct inpcb *inp;
810 int error;
811 #if defined(NECP) && defined(FLOW_DIVERT)
812 int should_use_flow_divert = 0;
813 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
814
815 inp = sotoinpcb(so);
816 if (inp == NULL) {
817 return EINVAL;
818 }
819
820 #if defined(NECP) && defined(FLOW_DIVERT)
821 should_use_flow_divert = necp_socket_should_use_flow_divert(inp);
822 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
823
824 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
825 struct sockaddr_in6 *sin6_p;
826
827 sin6_p = (struct sockaddr_in6 *)(void *)nam;
828 if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
829 struct sockaddr_in sin;
830
831 if (inp->inp_faddr.s_addr != INADDR_ANY) {
832 return EISCONN;
833 }
834
835 if (!(so->so_flags1 & SOF1_CONNECT_COUNTED)) {
836 so->so_flags1 |= SOF1_CONNECT_COUNTED;
837 INC_ATOMIC_INT64_LIM(net_api_stats.nas_socket_inet_dgram_connected);
838 }
839
840 in6_sin6_2_sin(&sin, sin6_p);
841 #if defined(NECP) && defined(FLOW_DIVERT)
842 if (should_use_flow_divert) {
843 goto do_flow_divert;
844 }
845 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
846 error = in_pcbconnect(inp, (struct sockaddr *)&sin,
847 p, IFSCOPE_NONE, NULL);
848 if (error == 0) {
849 #if NECP
850 /* Update NECP client with connected five-tuple */
851 if (!uuid_is_null(inp->necp_client_uuid)) {
852 socket_unlock(so, 0);
853 necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
854 socket_lock(so, 0);
855 }
856 #endif /* NECP */
857 inp->inp_vflag |= INP_IPV4;
858 inp->inp_vflag &= ~INP_IPV6;
859 soisconnected(so);
860 }
861 return error;
862 }
863 }
864
865 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
866 return EISCONN;
867 }
868
869 if (!(so->so_flags1 & SOF1_CONNECT_COUNTED)) {
870 so->so_flags1 |= SOF1_CONNECT_COUNTED;
871 INC_ATOMIC_INT64_LIM(net_api_stats.nas_socket_inet6_dgram_connected);
872 }
873
874 #if defined(NECP) && defined(FLOW_DIVERT)
875 do_flow_divert:
876 if (should_use_flow_divert) {
877 uint32_t fd_ctl_unit = necp_socket_get_flow_divert_control_unit(inp);
878 if (fd_ctl_unit > 0) {
879 error = flow_divert_pcb_init(so, fd_ctl_unit);
880 if (error == 0) {
881 error = flow_divert_connect_out(so, nam, p);
882 }
883 } else {
884 error = ENETDOWN;
885 }
886 return error;
887 }
888 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
889
890 error = in6_pcbconnect(inp, nam, p);
891 if (error == 0) {
892 /* should be non mapped addr */
893 if (ip6_mapped_addr_on ||
894 (inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
895 inp->inp_vflag &= ~INP_IPV4;
896 inp->inp_vflag |= INP_IPV6;
897 }
898 #if NECP
899 /* Update NECP client with connected five-tuple */
900 if (!uuid_is_null(inp->necp_client_uuid)) {
901 socket_unlock(so, 0);
902 necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
903 socket_lock(so, 0);
904 }
905 #endif /* NECP */
906 soisconnected(so);
907 if (inp->inp_flowhash == 0) {
908 inp->inp_flowhash = inp_calc_flowhash(inp);
909 }
910 /* update flowinfo - RFC 6437 */
911 if (inp->inp_flow == 0 &&
912 inp->in6p_flags & IN6P_AUTOFLOWLABEL) {
913 inp->inp_flow &= ~IPV6_FLOWLABEL_MASK;
914 inp->inp_flow |=
915 (htonl(inp->inp_flowhash) & IPV6_FLOWLABEL_MASK);
916 }
917 }
918 return error;
919 }
920
921 static int
922 udp6_connectx(struct socket *so, struct sockaddr *src,
923 struct sockaddr *dst, struct proc *p, uint32_t ifscope,
924 sae_associd_t aid, sae_connid_t *pcid, uint32_t flags, void *arg,
925 uint32_t arglen, struct uio *uio, user_ssize_t *bytes_written)
926 {
927 return udp_connectx_common(so, AF_INET6, src, dst,
928 p, ifscope, aid, pcid, flags, arg, arglen, uio, bytes_written);
929 }
930
931 static int
932 udp6_detach(struct socket *so)
933 {
934 struct inpcb *inp;
935
936 inp = sotoinpcb(so);
937 if (inp == NULL) {
938 return EINVAL;
939 }
940 in6_pcbdetach(inp);
941 return 0;
942 }
943
944 static int
945 udp6_disconnect(struct socket *so)
946 {
947 struct inpcb *inp;
948
949 inp = sotoinpcb(so);
950 if (inp == NULL
951 #if NECP
952 || (necp_socket_should_use_flow_divert(inp))
953 #endif /* NECP */
954 ) {
955 return inp == NULL ? EINVAL : EPROTOTYPE;
956 }
957
958 if (inp->inp_vflag & INP_IPV4) {
959 struct pr_usrreqs *pru;
960
961 pru = ip_protox[IPPROTO_UDP]->pr_usrreqs;
962 return (*pru->pru_disconnect)(so);
963 }
964
965 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
966 return ENOTCONN;
967 }
968
969 in6_pcbdisconnect(inp);
970
971 /* reset flow-controlled state, just in case */
972 inp_reset_fc_state(inp);
973
974 inp->in6p_laddr = in6addr_any;
975 inp->in6p_last_outifp = NULL;
976
977 so->so_state &= ~SS_ISCONNECTED; /* XXX */
978 return 0;
979 }
980
981 static int
982 udp6_disconnectx(struct socket *so, sae_associd_t aid, sae_connid_t cid)
983 {
984 #pragma unused(cid)
985 if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL) {
986 return EINVAL;
987 }
988
989 return udp6_disconnect(so);
990 }
991
992 static int
993 udp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
994 struct mbuf *control, struct proc *p)
995 {
996 struct inpcb *inp;
997 int error = 0;
998 #if defined(NECP) && defined(FLOW_DIVERT)
999 int should_use_flow_divert = 0;
1000 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
1001 #if CONTENT_FILTER
1002 struct m_tag *cfil_tag = NULL;
1003 struct sockaddr *cfil_faddr = NULL;
1004 #endif
1005
1006 inp = sotoinpcb(so);
1007 if (inp == NULL) {
1008 error = EINVAL;
1009 goto bad;
1010 }
1011
1012 #if CONTENT_FILTER
1013 //If socket is subject to UDP Content Filter and unconnected, get addr from tag.
1014 if (so->so_cfil_db && !addr && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1015 cfil_tag = cfil_udp_get_socket_state(m, NULL, NULL, &cfil_faddr);
1016 if (cfil_tag) {
1017 addr = (struct sockaddr *)cfil_faddr;
1018 }
1019 }
1020 #endif
1021
1022 #if defined(NECP) && defined(FLOW_DIVERT)
1023 should_use_flow_divert = necp_socket_should_use_flow_divert(inp);
1024 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
1025
1026 if (addr != NULL) {
1027 if (addr->sa_len != sizeof(struct sockaddr_in6)) {
1028 error = EINVAL;
1029 goto bad;
1030 }
1031 if (addr->sa_family != AF_INET6) {
1032 error = EAFNOSUPPORT;
1033 goto bad;
1034 }
1035 }
1036
1037 if (ip6_mapped_addr_on || (inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
1038 int hasv4addr;
1039 struct sockaddr_in6 *sin6 = NULL;
1040
1041 if (addr == NULL) {
1042 hasv4addr = (inp->inp_vflag & INP_IPV4);
1043 } else {
1044 sin6 = (struct sockaddr_in6 *)(void *)addr;
1045 hasv4addr =
1046 IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ? 1 : 0;
1047 }
1048 if (hasv4addr) {
1049 struct pr_usrreqs *pru;
1050
1051 if (sin6 != NULL) {
1052 in6_sin6_2_sin_in_sock(addr);
1053 }
1054 #if defined(NECP) && defined(FLOW_DIVERT)
1055 if (should_use_flow_divert) {
1056 goto do_flow_divert;
1057 }
1058 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
1059 pru = ip_protox[IPPROTO_UDP]->pr_usrreqs;
1060 error = ((*pru->pru_send)(so, flags, m, addr,
1061 control, p));
1062 #if CONTENT_FILTER
1063 if (cfil_tag) {
1064 m_tag_free(cfil_tag);
1065 }
1066 #endif
1067 /* addr will just be freed in sendit(). */
1068 return error;
1069 }
1070 }
1071
1072 #if defined(NECP) && defined(FLOW_DIVERT)
1073 do_flow_divert:
1074 if (should_use_flow_divert) {
1075 /* Implicit connect */
1076 error = flow_divert_implicit_data_out(so, flags, m, addr, control, p);
1077 #if CONTENT_FILTER
1078 if (cfil_tag) {
1079 m_tag_free(cfil_tag);
1080 }
1081 #endif
1082 return error;
1083 }
1084 #endif /* defined(NECP) && defined(FLOW_DIVERT) */
1085
1086 error = udp6_output(inp, m, addr, control, p);
1087 #if CONTENT_FILTER
1088 if (cfil_tag) {
1089 m_tag_free(cfil_tag);
1090 }
1091 #endif
1092 return error;
1093
1094 bad:
1095 VERIFY(error != 0);
1096
1097 if (m != NULL) {
1098 m_freem(m);
1099 }
1100 if (control != NULL) {
1101 m_freem(control);
1102 }
1103 #if CONTENT_FILTER
1104 if (cfil_tag) {
1105 m_tag_free(cfil_tag);
1106 }
1107 #endif
1108 return error;
1109 }
1110
1111 /*
1112 * Checksum extended UDP header and data.
1113 */
1114 static int
1115 udp6_input_checksum(struct mbuf *m, struct udphdr *uh, int off, int ulen)
1116 {
1117 struct ifnet *ifp = m->m_pkthdr.rcvif;
1118 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1119
1120 if (!(m->m_pkthdr.csum_flags & CSUM_DATA_VALID) &&
1121 uh->uh_sum == 0) {
1122 /* UDP/IPv6 checksum is mandatory (RFC2460) */
1123
1124 /*
1125 * If checksum was already validated, ignore this check.
1126 * This is necessary for transport-mode ESP, which may be
1127 * getting UDP payloads without checksums when the network
1128 * has a NAT64.
1129 */
1130 udpstat.udps_nosum++;
1131 goto badsum;
1132 }
1133
1134 if ((hwcksum_rx || (ifp->if_flags & IFF_LOOPBACK) ||
1135 (m->m_pkthdr.pkt_flags & PKTF_LOOP)) &&
1136 (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)) {
1137 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
1138 uh->uh_sum = m->m_pkthdr.csum_rx_val;
1139 } else {
1140 uint32_t sum = m->m_pkthdr.csum_rx_val;
1141 uint32_t start = m->m_pkthdr.csum_rx_start;
1142 int32_t trailer = (m_pktlen(m) - (off + ulen));
1143
1144 /*
1145 * Perform 1's complement adjustment of octets
1146 * that got included/excluded in the hardware-
1147 * calculated checksum value. Also take care
1148 * of any trailing bytes and subtract out
1149 * their partial sum.
1150 */
1151 ASSERT(trailer >= 0);
1152 if ((m->m_pkthdr.csum_flags & CSUM_PARTIAL) &&
1153 (start != off || trailer != 0)) {
1154 uint32_t swbytes = (uint32_t)trailer;
1155 uint16_t s = 0, d = 0;
1156
1157 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
1158 s = ip6->ip6_src.s6_addr16[1];
1159 ip6->ip6_src.s6_addr16[1] = 0;
1160 }
1161 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
1162 d = ip6->ip6_dst.s6_addr16[1];
1163 ip6->ip6_dst.s6_addr16[1] = 0;
1164 }
1165
1166 /* callee folds in sum */
1167 sum = m_adj_sum16(m, start, off, ulen, sum);
1168 if (off > start) {
1169 swbytes += (off - start);
1170 } else {
1171 swbytes += (start - off);
1172 }
1173
1174 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
1175 ip6->ip6_src.s6_addr16[1] = s;
1176 }
1177 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
1178 ip6->ip6_dst.s6_addr16[1] = d;
1179 }
1180
1181 if (swbytes != 0) {
1182 udp_in_cksum_stats(swbytes);
1183 }
1184 if (trailer != 0) {
1185 m_adj(m, -trailer);
1186 }
1187 }
1188
1189 uh->uh_sum = in6_pseudo(&ip6->ip6_src, &ip6->ip6_dst,
1190 sum + htonl(ulen + IPPROTO_UDP));
1191 }
1192 uh->uh_sum ^= 0xffff;
1193 } else {
1194 udp_in6_cksum_stats(ulen);
1195 uh->uh_sum = in6_cksum(m, IPPROTO_UDP, off, ulen);
1196 }
1197
1198 if (uh->uh_sum != 0) {
1199 badsum:
1200 udpstat.udps_badsum++;
1201 IF_UDP_STATINC(ifp, badchksum);
1202 return -1;
1203 }
1204
1205 return 0;
1206 }