1 /*
2 * Copyright (c) 2000-2021 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 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
30 * The Regents of the University of California. All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
61 */
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
66 #include <sys/malloc.h>
67 #include <sys/mbuf.h>
68 #include <sys/domain.h>
69 #include <sys/protosw.h>
70 #include <sys/socket.h>
71 #include <sys/socketvar.h>
72 #include <sys/sysctl.h>
73 #include <sys/syslog.h>
74 #include <sys/mcache.h>
75 #include <net/ntstat.h>
76
77 #include <kern/zalloc.h>
78 #include <mach/boolean.h>
79
80 #include <net/if.h>
81 #include <net/if_types.h>
82 #include <net/route.h>
83 #include <net/dlil.h>
84 #include <net/net_api_stats.h>
85
86 #include <netinet/in.h>
87 #include <netinet/in_systm.h>
88 #include <netinet/in_tclass.h>
89 #include <netinet/ip.h>
90 #include <netinet/ip6.h>
91 #include <netinet/in_pcb.h>
92 #include <netinet/in_var.h>
93 #include <netinet/ip_var.h>
94 #include <netinet6/in6_pcb.h>
95 #include <netinet6/ip6_var.h>
96 #include <netinet6/udp6_var.h>
97 #include <netinet/ip_icmp.h>
98 #include <netinet/icmp_var.h>
99 #include <netinet/udp.h>
100 #include <netinet/udp_var.h>
101 #include <sys/kdebug.h>
102
103 #if IPSEC
104 #include <netinet6/ipsec.h>
105 #include <netinet6/esp.h>
106 #include <netkey/key.h>
107 extern int ipsec_bypass;
108 extern int esp_udp_encap_port;
109 #endif /* IPSEC */
110
111 #if NECP
112 #include <net/necp.h>
113 #endif /* NECP */
114
115 #if FLOW_DIVERT
116 #include <netinet/flow_divert.h>
117 #endif /* FLOW_DIVERT */
118
119 #if CONTENT_FILTER
120 #include <net/content_filter.h>
121 #endif /* CONTENT_FILTER */
122
123 #if SKYWALK
124 #include <skywalk/core/skywalk_var.h>
125 #endif /* SKYWALK */
126
127 #define DBG_LAYER_IN_BEG NETDBG_CODE(DBG_NETUDP, 0)
128 #define DBG_LAYER_IN_END NETDBG_CODE(DBG_NETUDP, 2)
129 #define DBG_LAYER_OUT_BEG NETDBG_CODE(DBG_NETUDP, 1)
130 #define DBG_LAYER_OUT_END NETDBG_CODE(DBG_NETUDP, 3)
131 #define DBG_FNC_UDP_INPUT NETDBG_CODE(DBG_NETUDP, (5 << 8))
132 #define DBG_FNC_UDP_OUTPUT NETDBG_CODE(DBG_NETUDP, (6 << 8) | 1)
133
134 /*
135 * UDP protocol implementation.
136 * Per RFC 768, August, 1980.
137 */
138 #ifndef COMPAT_42
139 static int udpcksum = 1;
140 #else
141 static int udpcksum = 0; /* XXX */
142 #endif
143 SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum,
144 CTLFLAG_RW | CTLFLAG_LOCKED, &udpcksum, 0, "");
145
146 int udp_log_in_vain = 0;
147 SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW | CTLFLAG_LOCKED,
148 &udp_log_in_vain, 0, "Log all incoming UDP packets");
149
150 static int blackhole = 0;
151 SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW | CTLFLAG_LOCKED,
152 &blackhole, 0, "Do not send port unreachables for refused connects");
153
154 static KALLOC_TYPE_DEFINE(inpcbzone, struct inpcb, NET_KT_DEFAULT);
155
156 struct inpcbhead udb; /* from udp_var.h */
157 #define udb6 udb /* for KAME src sync over BSD*'s */
158 struct inpcbinfo udbinfo;
159
160 #ifndef UDBHASHSIZE
161 #define UDBHASHSIZE 16
162 #endif
163
164 /* Garbage collection performed during most recent udp_gc() run */
165 static boolean_t udp_gc_done = FALSE;
166
167 #define log_in_vain_log(a) { log a; }
168
169 static int udp_getstat SYSCTL_HANDLER_ARGS;
170 struct udpstat udpstat; /* from udp_var.h */
171 SYSCTL_PROC(_net_inet_udp, UDPCTL_STATS, stats,
172 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
173 0, 0, udp_getstat, "S,udpstat",
174 "UDP statistics (struct udpstat, netinet/udp_var.h)");
175
176 SYSCTL_INT(_net_inet_udp, OID_AUTO, pcbcount,
177 CTLFLAG_RD | CTLFLAG_LOCKED, &udbinfo.ipi_count, 0,
178 "Number of active PCBs");
179
180 __private_extern__ int udp_use_randomport = 1;
181 SYSCTL_INT(_net_inet_udp, OID_AUTO, randomize_ports,
182 CTLFLAG_RW | CTLFLAG_LOCKED, &udp_use_randomport, 0,
183 "Randomize UDP port numbers");
184
185 struct udp_in6 {
186 struct sockaddr_in6 uin6_sin;
187 u_char uin6_init_done : 1;
188 };
189 struct udp_ip6 {
190 struct ip6_hdr uip6_ip6;
191 u_char uip6_init_done : 1;
192 };
193
194 int udp_abort(struct socket *);
195 int udp_attach(struct socket *, int, struct proc *);
196 int udp_bind(struct socket *, struct sockaddr *, struct proc *);
197 int udp_connect(struct socket *, struct sockaddr *, struct proc *);
198 int udp_connectx(struct socket *, struct sockaddr *,
199 struct sockaddr *, struct proc *, uint32_t, sae_associd_t,
200 sae_connid_t *, uint32_t, void *, uint32_t, struct uio *, user_ssize_t *);
201 int udp_detach(struct socket *);
202 int udp_disconnect(struct socket *);
203 int udp_disconnectx(struct socket *, sae_associd_t, sae_connid_t);
204 int udp_send(struct socket *, int, struct mbuf *, struct sockaddr *,
205 struct mbuf *, struct proc *);
206 static void udp_append(struct inpcb *, struct ip *, struct mbuf *, int,
207 struct sockaddr_in *, struct udp_in6 *, struct udp_ip6 *, struct ifnet *);
208 static int udp_input_checksum(struct mbuf *, struct udphdr *, int, int);
209 int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
210 struct mbuf *, struct proc *);
211 static void ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip);
212 static void udp_gc(struct inpcbinfo *);
213 static int udp_defunct(struct socket *);
214
215 struct pr_usrreqs udp_usrreqs = {
216 .pru_abort = udp_abort,
217 .pru_attach = udp_attach,
218 .pru_bind = udp_bind,
219 .pru_connect = udp_connect,
220 .pru_connectx = udp_connectx,
221 .pru_control = in_control,
222 .pru_detach = udp_detach,
223 .pru_disconnect = udp_disconnect,
224 .pru_disconnectx = udp_disconnectx,
225 .pru_peeraddr = in_getpeeraddr,
226 .pru_send = udp_send,
227 .pru_shutdown = udp_shutdown,
228 .pru_sockaddr = in_getsockaddr,
229 .pru_sosend = sosend,
230 .pru_soreceive = soreceive,
231 .pru_soreceive_list = soreceive_list,
232 .pru_defunct = udp_defunct,
233 };
234
235 void
udp_init(struct protosw * pp,struct domain * dp)236 udp_init(struct protosw *pp, struct domain *dp)
237 {
238 #pragma unused(dp)
239 static int udp_initialized = 0;
240 struct inpcbinfo *pcbinfo;
241
242 VERIFY((pp->pr_flags & (PR_INITIALIZED | PR_ATTACHED)) == PR_ATTACHED);
243
244 if (udp_initialized) {
245 return;
246 }
247 udp_initialized = 1;
248 uint32_t pool_size = (nmbclusters << MCLSHIFT) >> MBSHIFT;
249 if (pool_size >= 96) {
250 /* Improves 10GbE UDP performance. */
251 udp_recvspace = 786896;
252 }
253 LIST_INIT(&udb);
254 udbinfo.ipi_listhead = &udb;
255 udbinfo.ipi_hashbase = hashinit(UDBHASHSIZE, M_PCB,
256 &udbinfo.ipi_hashmask);
257 udbinfo.ipi_porthashbase = hashinit(UDBHASHSIZE, M_PCB,
258 &udbinfo.ipi_porthashmask);
259 udbinfo.ipi_zone = inpcbzone;
260
261 pcbinfo = &udbinfo;
262 /*
263 * allocate lock group and attribute for udp pcb mutexes
264 */
265 pcbinfo->ipi_lock_grp = lck_grp_alloc_init("udppcb",
266 LCK_GRP_ATTR_NULL);
267 lck_attr_setdefault(&pcbinfo->ipi_lock_attr);
268 lck_rw_init(&pcbinfo->ipi_lock, pcbinfo->ipi_lock_grp,
269 &pcbinfo->ipi_lock_attr);
270
271 udbinfo.ipi_gc = udp_gc;
272 in_pcbinfo_attach(&udbinfo);
273 }
274
275 void
udp_input(struct mbuf * m,int iphlen)276 udp_input(struct mbuf *m, int iphlen)
277 {
278 struct ip *ip;
279 struct udphdr *uh;
280 struct inpcb *inp;
281 struct mbuf *opts = NULL;
282 int len, isbroadcast;
283 struct ip save_ip;
284 struct sockaddr *append_sa;
285 struct inpcbinfo *pcbinfo = &udbinfo;
286 struct sockaddr_in udp_in;
287 struct ip_moptions *imo = NULL;
288 int foundmembership = 0, ret = 0;
289 struct udp_in6 udp_in6;
290 struct udp_ip6 udp_ip6;
291 struct ifnet *ifp = m->m_pkthdr.rcvif;
292 boolean_t cell = IFNET_IS_CELLULAR(ifp);
293 boolean_t wifi = (!cell && IFNET_IS_WIFI(ifp));
294 boolean_t wired = (!wifi && IFNET_IS_WIRED(ifp));
295 u_int16_t pf_tag = 0;
296 boolean_t is_wake_pkt = false;
297
298 bzero(&udp_in, sizeof(udp_in));
299 udp_in.sin_len = sizeof(struct sockaddr_in);
300 udp_in.sin_family = AF_INET;
301 bzero(&udp_in6, sizeof(udp_in6));
302 udp_in6.uin6_sin.sin6_len = sizeof(struct sockaddr_in6);
303 udp_in6.uin6_sin.sin6_family = AF_INET6;
304
305 if (m->m_flags & M_PKTHDR) {
306 pf_tag = m_pftag(m)->pftag_tag;
307 if (m->m_pkthdr.pkt_flags & PKTF_WAKE_PKT) {
308 is_wake_pkt = true;
309 }
310 }
311
312 udpstat.udps_ipackets++;
313
314 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_START, 0, 0, 0, 0, 0);
315
316 /* Expect 32-bit aligned data pointer on strict-align platforms */
317 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
318
319 m_add_crumb(m, PKT_CRUMB_UDP_INPUT);
320
321 /*
322 * Strip IP options, if any; should skip this,
323 * make available to user, and use on returned packets,
324 * but we don't yet have a way to check the checksum
325 * with options still present.
326 */
327 if (iphlen > sizeof(struct ip)) {
328 ip_stripoptions(m);
329 iphlen = sizeof(struct ip);
330 }
331
332 /*
333 * Get IP and UDP header together in first mbuf.
334 */
335 ip = mtod(m, struct ip *);
336 if (m->m_len < iphlen + sizeof(struct udphdr)) {
337 m = m_pullup(m, iphlen + sizeof(struct udphdr));
338 if (m == NULL) {
339 udpstat.udps_hdrops++;
340 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END,
341 0, 0, 0, 0, 0);
342 return;
343 }
344 ip = mtod(m, struct ip *);
345 }
346 uh = (struct udphdr *)(void *)((caddr_t)ip + iphlen);
347
348 /* destination port of 0 is illegal, based on RFC768. */
349 if (uh->uh_dport == 0) {
350 IF_UDP_STATINC(ifp, port0);
351 goto bad;
352 }
353
354 KERNEL_DEBUG(DBG_LAYER_IN_BEG, uh->uh_dport, uh->uh_sport,
355 ip->ip_src.s_addr, ip->ip_dst.s_addr, uh->uh_ulen);
356
357 /*
358 * Make mbuf data length reflect UDP length.
359 * If not enough data to reflect UDP length, drop.
360 */
361 len = ntohs((u_short)uh->uh_ulen);
362 if (ip->ip_len != len) {
363 if (len > ip->ip_len || len < sizeof(struct udphdr)) {
364 udpstat.udps_badlen++;
365 IF_UDP_STATINC(ifp, badlength);
366 goto bad;
367 }
368 m_adj(m, len - ip->ip_len);
369 /* ip->ip_len = len; */
370 }
371 /*
372 * Save a copy of the IP header in case we want restore it
373 * for sending an ICMP error message in response.
374 */
375 save_ip = *ip;
376
377 /*
378 * Checksum extended UDP header and data.
379 */
380 if (udp_input_checksum(m, uh, iphlen, len)) {
381 goto bad;
382 }
383
384 isbroadcast = in_broadcast(ip->ip_dst, ifp);
385
386 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || isbroadcast) {
387 int reuse_sock = 0, mcast_delivered = 0;
388
389 lck_rw_lock_shared(&pcbinfo->ipi_lock);
390 /*
391 * Deliver a multicast or broadcast datagram to *all* sockets
392 * for which the local and remote addresses and ports match
393 * those of the incoming datagram. This allows more than
394 * one process to receive multi/broadcasts on the same port.
395 * (This really ought to be done for unicast datagrams as
396 * well, but that would cause problems with existing
397 * applications that open both address-specific sockets and
398 * a wildcard socket listening to the same port -- they would
399 * end up receiving duplicates of every unicast datagram.
400 * Those applications open the multiple sockets to overcome an
401 * inadequacy of the UDP socket interface, but for backwards
402 * compatibility we avoid the problem here rather than
403 * fixing the interface. Maybe 4.5BSD will remedy this?)
404 */
405
406 /*
407 * Construct sockaddr format source address.
408 */
409 udp_in.sin_port = uh->uh_sport;
410 udp_in.sin_addr = ip->ip_src;
411 /*
412 * Locate pcb(s) for datagram.
413 * (Algorithm copied from raw_intr().)
414 */
415 udp_in6.uin6_init_done = udp_ip6.uip6_init_done = 0;
416 LIST_FOREACH(inp, &udb, inp_list) {
417 #if IPSEC
418 int skipit;
419 #endif /* IPSEC */
420
421 if (inp->inp_socket == NULL) {
422 continue;
423 }
424 if (inp != sotoinpcb(inp->inp_socket)) {
425 panic("%s: bad so back ptr inp=%p",
426 __func__, inp);
427 /* NOTREACHED */
428 }
429 if ((inp->inp_vflag & INP_IPV4) == 0) {
430 continue;
431 }
432 if (inp_restricted_recv(inp, ifp)) {
433 continue;
434 }
435
436 if ((inp->inp_moptions == NULL) &&
437 (ntohl(ip->ip_dst.s_addr) !=
438 INADDR_ALLHOSTS_GROUP) && (isbroadcast == 0)) {
439 continue;
440 }
441 /*
442 * Skip unbound sockets before taking the lock on the socket as
443 * the test with the destination port in the header will fail
444 */
445 if (inp->inp_lport == 0) {
446 continue;
447 }
448
449 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) ==
450 WNT_STOPUSING) {
451 continue;
452 }
453
454 udp_lock(inp->inp_socket, 1, 0);
455
456 if (in_pcb_checkstate(inp, WNT_RELEASE, 1) ==
457 WNT_STOPUSING) {
458 udp_unlock(inp->inp_socket, 1, 0);
459 continue;
460 }
461
462 if (inp->inp_lport != uh->uh_dport) {
463 udp_unlock(inp->inp_socket, 1, 0);
464 continue;
465 }
466 if (inp->inp_laddr.s_addr != INADDR_ANY) {
467 if (inp->inp_laddr.s_addr !=
468 ip->ip_dst.s_addr) {
469 udp_unlock(inp->inp_socket, 1, 0);
470 continue;
471 }
472 }
473 if (inp->inp_faddr.s_addr != INADDR_ANY) {
474 if (inp->inp_faddr.s_addr !=
475 ip->ip_src.s_addr ||
476 inp->inp_fport != uh->uh_sport) {
477 udp_unlock(inp->inp_socket, 1, 0);
478 continue;
479 }
480 }
481
482 if (isbroadcast == 0 && (ntohl(ip->ip_dst.s_addr) !=
483 INADDR_ALLHOSTS_GROUP)) {
484 struct sockaddr_in group;
485 int blocked;
486
487 if ((imo = inp->inp_moptions) == NULL) {
488 udp_unlock(inp->inp_socket, 1, 0);
489 continue;
490 }
491 IMO_LOCK(imo);
492
493 bzero(&group, sizeof(struct sockaddr_in));
494 group.sin_len = sizeof(struct sockaddr_in);
495 group.sin_family = AF_INET;
496 group.sin_addr = ip->ip_dst;
497
498 blocked = imo_multi_filter(imo, ifp,
499 &group, &udp_in);
500 if (blocked == MCAST_PASS) {
501 foundmembership = 1;
502 }
503
504 IMO_UNLOCK(imo);
505 if (!foundmembership) {
506 udp_unlock(inp->inp_socket, 1, 0);
507 if (blocked == MCAST_NOTSMEMBER ||
508 blocked == MCAST_MUTED) {
509 udpstat.udps_filtermcast++;
510 }
511 continue;
512 }
513 foundmembership = 0;
514 }
515
516 reuse_sock = (inp->inp_socket->so_options &
517 (SO_REUSEPORT | SO_REUSEADDR));
518
519 #if NECP
520 skipit = 0;
521 if (!necp_socket_is_allowed_to_send_recv_v4(inp,
522 uh->uh_dport, uh->uh_sport, &ip->ip_dst,
523 &ip->ip_src, ifp, pf_tag, NULL, NULL, NULL, NULL)) {
524 /* do not inject data to pcb */
525 skipit = 1;
526 }
527 if (skipit == 0)
528 #endif /* NECP */
529 {
530 struct mbuf *n = NULL;
531
532 if (reuse_sock) {
533 n = m_copy(m, 0, M_COPYALL);
534 }
535 udp_append(inp, ip, m,
536 iphlen + sizeof(struct udphdr),
537 &udp_in, &udp_in6, &udp_ip6, ifp);
538 mcast_delivered++;
539
540 m = n;
541 }
542 if (is_wake_pkt) {
543 soevent(inp->inp_socket, SO_FILT_HINT_LOCKED | SO_FILT_HINT_WAKE_PKT);
544 }
545
546 udp_unlock(inp->inp_socket, 1, 0);
547
548
549 /*
550 * Don't look for additional matches if this one does
551 * not have either the SO_REUSEPORT or SO_REUSEADDR
552 * socket options set. This heuristic avoids searching
553 * through all pcbs in the common case of a non-shared
554 * port. It assumes that an application will never
555 * clear these options after setting them.
556 */
557 if (reuse_sock == 0 || m == NULL) {
558 break;
559 }
560
561 /*
562 * Expect 32-bit aligned data pointer on strict-align
563 * platforms.
564 */
565 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
566 /*
567 * Recompute IP and UDP header pointers for new mbuf
568 */
569 ip = mtod(m, struct ip *);
570 uh = (struct udphdr *)(void *)((caddr_t)ip + iphlen);
571 }
572 lck_rw_done(&pcbinfo->ipi_lock);
573
574 if (mcast_delivered == 0) {
575 /*
576 * No matching pcb found; discard datagram.
577 * (No need to send an ICMP Port Unreachable
578 * for a broadcast or multicast datgram.)
579 */
580 udpstat.udps_noportbcast++;
581 IF_UDP_STATINC(ifp, port_unreach);
582 goto bad;
583 }
584
585 /* free the extra copy of mbuf or skipped by IPsec */
586 if (m != NULL) {
587 m_freem(m);
588 }
589 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END, 0, 0, 0, 0, 0);
590 return;
591 }
592
593 #if IPSEC
594 /*
595 * UDP to port 4500 with a payload where the first four bytes are
596 * not zero is a UDP encapsulated IPsec packet. Packets where
597 * the payload is one byte and that byte is 0xFF are NAT keepalive
598 * packets. Decapsulate the ESP packet and carry on with IPsec input
599 * or discard the NAT keep-alive.
600 */
601 if (ipsec_bypass == 0 && (esp_udp_encap_port & 0xFFFF) != 0 &&
602 (uh->uh_dport == ntohs((u_short)esp_udp_encap_port) ||
603 uh->uh_sport == ntohs((u_short)esp_udp_encap_port))) {
604 /*
605 * Check if ESP or keepalive:
606 * 1. If the destination port of the incoming packet is 4500.
607 * 2. If the source port of the incoming packet is 4500,
608 * then check the SADB to match IP address and port.
609 */
610 bool check_esp = true;
611 if (uh->uh_dport != ntohs((u_short)esp_udp_encap_port)) {
612 check_esp = key_checksa_present(AF_INET, (caddr_t)&ip->ip_dst,
613 (caddr_t)&ip->ip_src, uh->uh_dport,
614 uh->uh_sport, IFSCOPE_NONE, IFSCOPE_NONE);
615 }
616
617 if (check_esp) {
618 int payload_len = len - sizeof(struct udphdr) > 4 ? 4 :
619 len - sizeof(struct udphdr);
620
621 if (m->m_len < iphlen + sizeof(struct udphdr) + payload_len) {
622 if ((m = m_pullup(m, iphlen + sizeof(struct udphdr) +
623 payload_len)) == NULL) {
624 udpstat.udps_hdrops++;
625 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END,
626 0, 0, 0, 0, 0);
627 return;
628 }
629 /*
630 * Expect 32-bit aligned data pointer on strict-align
631 * platforms.
632 */
633 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
634
635 ip = mtod(m, struct ip *);
636 uh = (struct udphdr *)(void *)((caddr_t)ip + iphlen);
637 }
638 /* Check for NAT keepalive packet */
639 if (payload_len == 1 && *(u_int8_t *)
640 ((caddr_t)uh + sizeof(struct udphdr)) == 0xFF) {
641 m_freem(m);
642 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END,
643 0, 0, 0, 0, 0);
644 return;
645 } else if (payload_len == 4 && *(u_int32_t *)(void *)
646 ((caddr_t)uh + sizeof(struct udphdr)) != 0) {
647 /* UDP encapsulated IPsec packet to pass through NAT */
648 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END,
649 0, 0, 0, 0, 0);
650 /* preserve the udp header */
651 esp4_input(m, iphlen + sizeof(struct udphdr));
652 return;
653 }
654 }
655 }
656 #endif /* IPSEC */
657
658 /*
659 * Locate pcb for datagram.
660 */
661 inp = in_pcblookup_hash(&udbinfo, ip->ip_src, uh->uh_sport,
662 ip->ip_dst, uh->uh_dport, 1, ifp);
663 if (inp == NULL) {
664 IF_UDP_STATINC(ifp, port_unreach);
665
666 if (udp_log_in_vain) {
667 char buf[MAX_IPv4_STR_LEN];
668 char buf2[MAX_IPv4_STR_LEN];
669
670 /* check src and dst address */
671 if (udp_log_in_vain < 3) {
672 log(LOG_INFO, "Connection attempt to "
673 "UDP %s:%d from %s:%d\n", inet_ntop(AF_INET,
674 &ip->ip_dst, buf, sizeof(buf)),
675 ntohs(uh->uh_dport), inet_ntop(AF_INET,
676 &ip->ip_src, buf2, sizeof(buf2)),
677 ntohs(uh->uh_sport));
678 } else if (!(m->m_flags & (M_BCAST | M_MCAST)) &&
679 ip->ip_dst.s_addr != ip->ip_src.s_addr) {
680 log_in_vain_log((LOG_INFO,
681 "Stealth Mode connection attempt to "
682 "UDP %s:%d from %s:%d\n", inet_ntop(AF_INET,
683 &ip->ip_dst, buf, sizeof(buf)),
684 ntohs(uh->uh_dport), inet_ntop(AF_INET,
685 &ip->ip_src, buf2, sizeof(buf2)),
686 ntohs(uh->uh_sport)))
687 }
688 }
689 udpstat.udps_noport++;
690 if (m->m_flags & (M_BCAST | M_MCAST)) {
691 udpstat.udps_noportbcast++;
692 goto bad;
693 }
694 if (blackhole) {
695 if (ifp && ifp->if_type != IFT_LOOP) {
696 goto bad;
697 }
698 }
699 *ip = save_ip;
700 ip->ip_len += iphlen;
701 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
702 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END, 0, 0, 0, 0, 0);
703 return;
704 }
705 udp_lock(inp->inp_socket, 1, 0);
706
707 if (in_pcb_checkstate(inp, WNT_RELEASE, 1) == WNT_STOPUSING) {
708 udp_unlock(inp->inp_socket, 1, 0);
709 IF_UDP_STATINC(ifp, cleanup);
710 goto bad;
711 }
712 #if NECP
713 if (!necp_socket_is_allowed_to_send_recv_v4(inp, uh->uh_dport,
714 uh->uh_sport, &ip->ip_dst, &ip->ip_src, ifp, pf_tag, NULL, NULL, NULL, NULL)) {
715 udp_unlock(inp->inp_socket, 1, 0);
716 IF_UDP_STATINC(ifp, badipsec);
717 goto bad;
718 }
719 #endif /* NECP */
720
721 /*
722 * Construct sockaddr format source address.
723 * Stuff source address and datagram in user buffer.
724 */
725 udp_in.sin_port = uh->uh_sport;
726 udp_in.sin_addr = ip->ip_src;
727 if ((inp->inp_flags & INP_CONTROLOPTS) != 0 ||
728 SOFLOW_ENABLED(inp->inp_socket) ||
729 SO_RECV_CONTROL_OPTS(inp->inp_socket)) {
730 if (inp->inp_vflag & INP_IPV6 || inp->inp_vflag & INP_V4MAPPEDV6) {
731 int savedflags;
732
733 ip_2_ip6_hdr(&udp_ip6.uip6_ip6, ip);
734 savedflags = inp->inp_flags;
735 inp->inp_flags &= ~INP_UNMAPPABLEOPTS;
736 ret = ip6_savecontrol(inp, m, &opts);
737 inp->inp_flags = savedflags;
738 } else {
739 ret = ip_savecontrol(inp, &opts, ip, m);
740 }
741 if (ret != 0) {
742 udp_unlock(inp->inp_socket, 1, 0);
743 goto bad;
744 }
745 }
746 m_adj(m, iphlen + sizeof(struct udphdr));
747
748 KERNEL_DEBUG(DBG_LAYER_IN_END, uh->uh_dport, uh->uh_sport,
749 save_ip.ip_src.s_addr, save_ip.ip_dst.s_addr, uh->uh_ulen);
750
751 if (inp->inp_vflag & INP_IPV6) {
752 in6_sin_2_v4mapsin6(&udp_in, &udp_in6.uin6_sin);
753 append_sa = (struct sockaddr *)&udp_in6.uin6_sin;
754 } else {
755 append_sa = (struct sockaddr *)&udp_in;
756 }
757 if (nstat_collect) {
758 INP_ADD_STAT(inp, cell, wifi, wired, rxpackets, 1);
759 INP_ADD_STAT(inp, cell, wifi, wired, rxbytes, m->m_pkthdr.len);
760 inp_set_activity_bitmap(inp);
761 }
762 so_recv_data_stat(inp->inp_socket, m, 0);
763 if (sbappendaddr(&inp->inp_socket->so_rcv, append_sa,
764 m, opts, NULL) == 0) {
765 udpstat.udps_fullsock++;
766 } else {
767 sorwakeup(inp->inp_socket);
768 }
769 if (is_wake_pkt) {
770 soevent(inp->inp_socket, SO_FILT_HINT_LOCKED | SO_FILT_HINT_WAKE_PKT);
771 }
772 udp_unlock(inp->inp_socket, 1, 0);
773 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END, 0, 0, 0, 0, 0);
774 return;
775 bad:
776 m_freem(m);
777 if (opts) {
778 m_freem(opts);
779 }
780 KERNEL_DEBUG(DBG_FNC_UDP_INPUT | DBG_FUNC_END, 0, 0, 0, 0, 0);
781 }
782
783 static void
ip_2_ip6_hdr(struct ip6_hdr * ip6,struct ip * ip)784 ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip)
785 {
786 bzero(ip6, sizeof(*ip6));
787
788 ip6->ip6_vfc = IPV6_VERSION;
789 ip6->ip6_plen = ip->ip_len;
790 ip6->ip6_nxt = ip->ip_p;
791 ip6->ip6_hlim = ip->ip_ttl;
792 if (ip->ip_src.s_addr) {
793 ip6->ip6_src.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
794 ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr;
795 }
796 if (ip->ip_dst.s_addr) {
797 ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
798 ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr;
799 }
800 }
801
802 /*
803 * subroutine of udp_input(), mainly for source code readability.
804 */
805 static void
udp_append(struct inpcb * last,struct ip * ip,struct mbuf * n,int off,struct sockaddr_in * pudp_in,struct udp_in6 * pudp_in6,struct udp_ip6 * pudp_ip6,struct ifnet * ifp)806 udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n, int off,
807 struct sockaddr_in *pudp_in, struct udp_in6 *pudp_in6,
808 struct udp_ip6 *pudp_ip6, struct ifnet *ifp)
809 {
810 struct sockaddr *append_sa;
811 struct mbuf *opts = 0;
812 boolean_t cell = IFNET_IS_CELLULAR(ifp);
813 boolean_t wifi = (!cell && IFNET_IS_WIFI(ifp));
814 boolean_t wired = (!wifi && IFNET_IS_WIRED(ifp));
815 int ret = 0;
816
817 if ((last->inp_flags & INP_CONTROLOPTS) != 0 ||
818 SOFLOW_ENABLED(last->inp_socket) ||
819 SO_RECV_CONTROL_OPTS(last->inp_socket)) {
820 if (last->inp_vflag & INP_IPV6 || last->inp_vflag & INP_V4MAPPEDV6) {
821 int savedflags;
822
823 if (pudp_ip6->uip6_init_done == 0) {
824 ip_2_ip6_hdr(&pudp_ip6->uip6_ip6, ip);
825 pudp_ip6->uip6_init_done = 1;
826 }
827 savedflags = last->inp_flags;
828 last->inp_flags &= ~INP_UNMAPPABLEOPTS;
829 ret = ip6_savecontrol(last, n, &opts);
830 if (ret != 0) {
831 last->inp_flags = savedflags;
832 goto error;
833 }
834 last->inp_flags = savedflags;
835 } else {
836 ret = ip_savecontrol(last, &opts, ip, n);
837 if (ret != 0) {
838 goto error;
839 }
840 }
841 }
842 if (last->inp_vflag & INP_IPV6) {
843 if (pudp_in6->uin6_init_done == 0) {
844 in6_sin_2_v4mapsin6(pudp_in, &pudp_in6->uin6_sin);
845 pudp_in6->uin6_init_done = 1;
846 }
847 append_sa = (struct sockaddr *)&pudp_in6->uin6_sin;
848 } else {
849 append_sa = (struct sockaddr *)pudp_in;
850 }
851 if (nstat_collect) {
852 INP_ADD_STAT(last, cell, wifi, wired, rxpackets, 1);
853 INP_ADD_STAT(last, cell, wifi, wired, rxbytes,
854 n->m_pkthdr.len);
855 inp_set_activity_bitmap(last);
856 }
857 so_recv_data_stat(last->inp_socket, n, 0);
858 m_adj(n, off);
859 if (sbappendaddr(&last->inp_socket->so_rcv, append_sa,
860 n, opts, NULL) == 0) {
861 udpstat.udps_fullsock++;
862 } else {
863 sorwakeup(last->inp_socket);
864 }
865 return;
866 error:
867 m_freem(n);
868 m_freem(opts);
869 }
870
871 /*
872 * Notify a udp user of an asynchronous error;
873 * just wake up so that he can collect error status.
874 */
875 void
udp_notify(struct inpcb * inp,int errno)876 udp_notify(struct inpcb *inp, int errno)
877 {
878 inp->inp_socket->so_error = (u_short)errno;
879 sorwakeup(inp->inp_socket);
880 sowwakeup(inp->inp_socket);
881 }
882
883 void
udp_ctlinput(int cmd,struct sockaddr * sa,void * vip,__unused struct ifnet * ifp)884 udp_ctlinput(int cmd, struct sockaddr *sa, void *vip, __unused struct ifnet * ifp)
885 {
886 struct ipctlparam *ctl_param = vip;
887 struct ip *ip = NULL;
888 struct mbuf *m = NULL;
889 void (*notify)(struct inpcb *, int) = udp_notify;
890 struct in_addr faddr;
891 struct inpcb *inp = NULL;
892 struct icmp *icp = NULL;
893 size_t off;
894
895 if (ctl_param != NULL) {
896 ip = ctl_param->ipc_icmp_ip;
897 icp = ctl_param->ipc_icmp;
898 m = ctl_param->ipc_m;
899 off = ctl_param->ipc_off;
900 } else {
901 ip = NULL;
902 icp = NULL;
903 m = NULL;
904 off = 0;
905 }
906
907 faddr = ((struct sockaddr_in *)(void *)sa)->sin_addr;
908 if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) {
909 return;
910 }
911
912 if (PRC_IS_REDIRECT(cmd)) {
913 ip = 0;
914 notify = in_rtchange;
915 } else if (cmd == PRC_HOSTDEAD) {
916 ip = 0;
917 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
918 return;
919 }
920 if (ip) {
921 struct udphdr uh;
922
923 /* Check if we can safely get the ports from the UDP header */
924 if (m == NULL ||
925 (m->m_len < off + sizeof(uh))) {
926 /* Insufficient length */
927 return;
928 }
929
930 bcopy(m->m_data + off, &uh, sizeof(uh));
931 inp = in_pcblookup_hash(&udbinfo, faddr, uh.uh_dport,
932 ip->ip_src, uh.uh_sport, 0, NULL);
933
934 if (inp != NULL && inp->inp_socket != NULL) {
935 udp_lock(inp->inp_socket, 1, 0);
936 if (in_pcb_checkstate(inp, WNT_RELEASE, 1) ==
937 WNT_STOPUSING) {
938 udp_unlock(inp->inp_socket, 1, 0);
939 return;
940 }
941 if (cmd == PRC_MSGSIZE && !uuid_is_null(inp->necp_client_uuid)) {
942 uuid_t null_uuid;
943 uuid_clear(null_uuid);
944 necp_update_flow_protoctl_event(null_uuid, inp->necp_client_uuid,
945 PRC_MSGSIZE, ntohs(icp->icmp_nextmtu), 0);
946 /*
947 * Avoid calling udp_notify() to set so_error
948 * when using Network.framework since the notification
949 * of PRC_MSGSIZE has been delivered through NECP.
950 */
951 } else {
952 (*notify)(inp, inetctlerrmap[cmd]);
953 }
954 udp_unlock(inp->inp_socket, 1, 0);
955 }
956 #if SKYWALK
957 else {
958 union sockaddr_in_4_6 sock_laddr;
959 struct protoctl_ev_val prctl_ev_val;
960 bzero(&prctl_ev_val, sizeof(prctl_ev_val));
961 bzero(&sock_laddr, sizeof(sock_laddr));
962
963 if (cmd == PRC_MSGSIZE) {
964 prctl_ev_val.val = ntohs(icp->icmp_nextmtu);
965 }
966
967 sock_laddr.sin.sin_family = AF_INET;
968 sock_laddr.sin.sin_len = sizeof(sock_laddr.sin);
969 sock_laddr.sin.sin_addr = ip->ip_src;
970
971 protoctl_event_enqueue_nwk_wq_entry(ifp,
972 (struct sockaddr *)&sock_laddr, sa,
973 uh.uh_sport, uh.uh_dport, IPPROTO_UDP,
974 cmd, &prctl_ev_val);
975 }
976 #endif /* SKYWALK */
977 } else {
978 in_pcbnotifyall(&udbinfo, faddr, inetctlerrmap[cmd], notify);
979 }
980 }
981
982 int
udp_ctloutput(struct socket * so,struct sockopt * sopt)983 udp_ctloutput(struct socket *so, struct sockopt *sopt)
984 {
985 int error = 0, optval = 0;
986 struct inpcb *inp;
987
988 /* Allow <SOL_SOCKET,SO_FLUSH> at this level */
989 if (sopt->sopt_level != IPPROTO_UDP &&
990 !(sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_FLUSH)) {
991 if (SOCK_CHECK_DOM(so, PF_INET6)) {
992 error = ip6_ctloutput(so, sopt);
993 } else {
994 error = ip_ctloutput(so, sopt);
995 }
996 return error;
997 }
998
999 inp = sotoinpcb(so);
1000
1001 switch (sopt->sopt_dir) {
1002 case SOPT_SET:
1003 switch (sopt->sopt_name) {
1004 case UDP_NOCKSUM:
1005 /* This option is settable only for UDP over IPv4 */
1006 if (!(inp->inp_vflag & INP_IPV4)) {
1007 error = EINVAL;
1008 break;
1009 }
1010
1011 if ((error = sooptcopyin(sopt, &optval, sizeof(optval),
1012 sizeof(optval))) != 0) {
1013 break;
1014 }
1015
1016 if (optval != 0) {
1017 inp->inp_flags |= INP_UDP_NOCKSUM;
1018 } else {
1019 inp->inp_flags &= ~INP_UDP_NOCKSUM;
1020 }
1021 break;
1022 case UDP_KEEPALIVE_OFFLOAD:
1023 {
1024 struct udp_keepalive_offload ka;
1025 /*
1026 * If the socket is not connected, the stack will
1027 * not know the destination address to put in the
1028 * keepalive datagram. Return an error now instead
1029 * of failing later.
1030 */
1031 if (!(so->so_state & SS_ISCONNECTED)) {
1032 error = EINVAL;
1033 break;
1034 }
1035 if (sopt->sopt_valsize != sizeof(ka)) {
1036 error = EINVAL;
1037 break;
1038 }
1039 if ((error = sooptcopyin(sopt, &ka, sizeof(ka),
1040 sizeof(ka))) != 0) {
1041 break;
1042 }
1043
1044 /* application should specify the type */
1045 if (ka.ka_type == 0) {
1046 return EINVAL;
1047 }
1048
1049 if (ka.ka_interval == 0) {
1050 /*
1051 * if interval is 0, disable the offload
1052 * mechanism
1053 */
1054 if (inp->inp_keepalive_data != NULL) {
1055 kfree_data(inp->inp_keepalive_data,
1056 inp->inp_keepalive_datalen);
1057 }
1058 inp->inp_keepalive_data = NULL;
1059 inp->inp_keepalive_datalen = 0;
1060 inp->inp_keepalive_interval = 0;
1061 inp->inp_keepalive_type = 0;
1062 inp->inp_flags2 &= ~INP2_KEEPALIVE_OFFLOAD;
1063 } else {
1064 if (inp->inp_keepalive_data != NULL) {
1065 kfree_data(inp->inp_keepalive_data,
1066 inp->inp_keepalive_datalen);
1067 inp->inp_keepalive_data = NULL;
1068 }
1069
1070 inp->inp_keepalive_datalen = (uint8_t)min(
1071 ka.ka_data_len,
1072 UDP_KEEPALIVE_OFFLOAD_DATA_SIZE);
1073 if (inp->inp_keepalive_datalen > 0) {
1074 inp->inp_keepalive_data = (u_int8_t *)kalloc_data(
1075 inp->inp_keepalive_datalen, Z_WAITOK);
1076 if (inp->inp_keepalive_data == NULL) {
1077 inp->inp_keepalive_datalen = 0;
1078 error = ENOMEM;
1079 break;
1080 }
1081 bcopy(ka.ka_data,
1082 inp->inp_keepalive_data,
1083 inp->inp_keepalive_datalen);
1084 } else {
1085 inp->inp_keepalive_datalen = 0;
1086 }
1087 inp->inp_keepalive_interval = (uint8_t)
1088 min(UDP_KEEPALIVE_INTERVAL_MAX_SECONDS,
1089 ka.ka_interval);
1090 inp->inp_keepalive_type = ka.ka_type;
1091 inp->inp_flags2 |= INP2_KEEPALIVE_OFFLOAD;
1092 }
1093 break;
1094 }
1095 case SO_FLUSH:
1096 if ((error = sooptcopyin(sopt, &optval, sizeof(optval),
1097 sizeof(optval))) != 0) {
1098 break;
1099 }
1100
1101 error = inp_flush(inp, optval);
1102 break;
1103
1104 default:
1105 error = ENOPROTOOPT;
1106 break;
1107 }
1108 break;
1109
1110 case SOPT_GET:
1111 switch (sopt->sopt_name) {
1112 case UDP_NOCKSUM:
1113 optval = inp->inp_flags & INP_UDP_NOCKSUM;
1114 break;
1115
1116 default:
1117 error = ENOPROTOOPT;
1118 break;
1119 }
1120 if (error == 0) {
1121 error = sooptcopyout(sopt, &optval, sizeof(optval));
1122 }
1123 break;
1124 }
1125 return error;
1126 }
1127
1128 static int
1129 udp_pcblist SYSCTL_HANDLER_ARGS
1130 {
1131 #pragma unused(oidp, arg1, arg2)
1132 int error, i, n, sz;
1133 struct inpcb *inp, **inp_list;
1134 inp_gen_t gencnt;
1135 struct xinpgen xig;
1136
1137 /*
1138 * The process of preparing the TCB list is too time-consuming and
1139 * resource-intensive to repeat twice on every request.
1140 */
1141 lck_rw_lock_exclusive(&udbinfo.ipi_lock);
1142 if (req->oldptr == USER_ADDR_NULL) {
1143 n = udbinfo.ipi_count;
1144 req->oldidx = 2 * (sizeof(xig))
1145 + (n + n / 8) * sizeof(struct xinpcb);
1146 lck_rw_done(&udbinfo.ipi_lock);
1147 return 0;
1148 }
1149
1150 if (req->newptr != USER_ADDR_NULL) {
1151 lck_rw_done(&udbinfo.ipi_lock);
1152 return EPERM;
1153 }
1154
1155 /*
1156 * OK, now we're committed to doing something.
1157 */
1158 gencnt = udbinfo.ipi_gencnt;
1159 sz = n = udbinfo.ipi_count;
1160
1161 bzero(&xig, sizeof(xig));
1162 xig.xig_len = sizeof(xig);
1163 xig.xig_count = n;
1164 xig.xig_gen = gencnt;
1165 xig.xig_sogen = so_gencnt;
1166 error = SYSCTL_OUT(req, &xig, sizeof(xig));
1167 if (error) {
1168 lck_rw_done(&udbinfo.ipi_lock);
1169 return error;
1170 }
1171 /*
1172 * We are done if there is no pcb
1173 */
1174 if (n == 0) {
1175 lck_rw_done(&udbinfo.ipi_lock);
1176 return 0;
1177 }
1178
1179 inp_list = kalloc_type(struct inpcb *, n, Z_WAITOK);
1180 if (inp_list == NULL) {
1181 lck_rw_done(&udbinfo.ipi_lock);
1182 return ENOMEM;
1183 }
1184
1185 for (inp = LIST_FIRST(udbinfo.ipi_listhead), i = 0; inp && i < n;
1186 inp = LIST_NEXT(inp, inp_list)) {
1187 if (inp->inp_gencnt <= gencnt &&
1188 inp->inp_state != INPCB_STATE_DEAD) {
1189 inp_list[i++] = inp;
1190 }
1191 }
1192 n = i;
1193
1194 error = 0;
1195 for (i = 0; i < n; i++) {
1196 struct xinpcb xi;
1197
1198 inp = inp_list[i];
1199
1200 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) == WNT_STOPUSING) {
1201 continue;
1202 }
1203 udp_lock(inp->inp_socket, 1, 0);
1204 if (in_pcb_checkstate(inp, WNT_RELEASE, 1) == WNT_STOPUSING) {
1205 udp_unlock(inp->inp_socket, 1, 0);
1206 continue;
1207 }
1208 if (inp->inp_gencnt > gencnt) {
1209 udp_unlock(inp->inp_socket, 1, 0);
1210 continue;
1211 }
1212
1213 bzero(&xi, sizeof(xi));
1214 xi.xi_len = sizeof(xi);
1215 /* XXX should avoid extra copy */
1216 inpcb_to_compat(inp, &xi.xi_inp);
1217 if (inp->inp_socket) {
1218 sotoxsocket(inp->inp_socket, &xi.xi_socket);
1219 }
1220
1221 udp_unlock(inp->inp_socket, 1, 0);
1222
1223 error = SYSCTL_OUT(req, &xi, sizeof(xi));
1224 }
1225 if (!error) {
1226 /*
1227 * Give the user an updated idea of our state.
1228 * If the generation differs from what we told
1229 * her before, she knows that something happened
1230 * while we were processing this request, and it
1231 * might be necessary to retry.
1232 */
1233 bzero(&xig, sizeof(xig));
1234 xig.xig_len = sizeof(xig);
1235 xig.xig_gen = udbinfo.ipi_gencnt;
1236 xig.xig_sogen = so_gencnt;
1237 xig.xig_count = udbinfo.ipi_count;
1238 error = SYSCTL_OUT(req, &xig, sizeof(xig));
1239 }
1240
1241 lck_rw_done(&udbinfo.ipi_lock);
1242 kfree_type(struct inpcb *, sz, inp_list);
1243 return error;
1244 }
1245
1246 SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist,
1247 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, udp_pcblist,
1248 "S,xinpcb", "List of active UDP sockets");
1249
1250 #if XNU_TARGET_OS_OSX
1251
1252 static int
1253 udp_pcblist64 SYSCTL_HANDLER_ARGS
1254 {
1255 #pragma unused(oidp, arg1, arg2)
1256 int error, i, n, sz;
1257 struct inpcb *inp, **inp_list;
1258 inp_gen_t gencnt;
1259 struct xinpgen xig;
1260
1261 /*
1262 * The process of preparing the TCB list is too time-consuming and
1263 * resource-intensive to repeat twice on every request.
1264 */
1265 lck_rw_lock_shared(&udbinfo.ipi_lock);
1266 if (req->oldptr == USER_ADDR_NULL) {
1267 n = udbinfo.ipi_count;
1268 req->oldidx =
1269 2 * (sizeof(xig)) + (n + n / 8) * sizeof(struct xinpcb64);
1270 lck_rw_done(&udbinfo.ipi_lock);
1271 return 0;
1272 }
1273
1274 if (req->newptr != USER_ADDR_NULL) {
1275 lck_rw_done(&udbinfo.ipi_lock);
1276 return EPERM;
1277 }
1278
1279 /*
1280 * OK, now we're committed to doing something.
1281 */
1282 gencnt = udbinfo.ipi_gencnt;
1283 sz = n = udbinfo.ipi_count;
1284
1285 bzero(&xig, sizeof(xig));
1286 xig.xig_len = sizeof(xig);
1287 xig.xig_count = n;
1288 xig.xig_gen = gencnt;
1289 xig.xig_sogen = so_gencnt;
1290 error = SYSCTL_OUT(req, &xig, sizeof(xig));
1291 if (error) {
1292 lck_rw_done(&udbinfo.ipi_lock);
1293 return error;
1294 }
1295 /*
1296 * We are done if there is no pcb
1297 */
1298 if (n == 0) {
1299 lck_rw_done(&udbinfo.ipi_lock);
1300 return 0;
1301 }
1302
1303 inp_list = kalloc_type(struct inpcb *, n, Z_WAITOK);
1304 if (inp_list == NULL) {
1305 lck_rw_done(&udbinfo.ipi_lock);
1306 return ENOMEM;
1307 }
1308
1309 for (inp = LIST_FIRST(udbinfo.ipi_listhead), i = 0; inp && i < n;
1310 inp = LIST_NEXT(inp, inp_list)) {
1311 if (inp->inp_gencnt <= gencnt &&
1312 inp->inp_state != INPCB_STATE_DEAD) {
1313 inp_list[i++] = inp;
1314 }
1315 }
1316 n = i;
1317
1318 error = 0;
1319 for (i = 0; i < n; i++) {
1320 struct xinpcb64 xi;
1321
1322 inp = inp_list[i];
1323
1324 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) == WNT_STOPUSING) {
1325 continue;
1326 }
1327 udp_lock(inp->inp_socket, 1, 0);
1328 if (in_pcb_checkstate(inp, WNT_RELEASE, 1) == WNT_STOPUSING) {
1329 udp_unlock(inp->inp_socket, 1, 0);
1330 continue;
1331 }
1332 if (inp->inp_gencnt > gencnt) {
1333 udp_unlock(inp->inp_socket, 1, 0);
1334 continue;
1335 }
1336
1337 bzero(&xi, sizeof(xi));
1338 xi.xi_len = sizeof(xi);
1339 inpcb_to_xinpcb64(inp, &xi);
1340 if (inp->inp_socket) {
1341 sotoxsocket64(inp->inp_socket, &xi.xi_socket);
1342 }
1343
1344 udp_unlock(inp->inp_socket, 1, 0);
1345
1346 error = SYSCTL_OUT(req, &xi, sizeof(xi));
1347 }
1348 if (!error) {
1349 /*
1350 * Give the user an updated idea of our state.
1351 * If the generation differs from what we told
1352 * her before, she knows that something happened
1353 * while we were processing this request, and it
1354 * might be necessary to retry.
1355 */
1356 bzero(&xig, sizeof(xig));
1357 xig.xig_len = sizeof(xig);
1358 xig.xig_gen = udbinfo.ipi_gencnt;
1359 xig.xig_sogen = so_gencnt;
1360 xig.xig_count = udbinfo.ipi_count;
1361 error = SYSCTL_OUT(req, &xig, sizeof(xig));
1362 }
1363
1364 lck_rw_done(&udbinfo.ipi_lock);
1365 kfree_type(struct inpcb *, sz, inp_list);
1366 return error;
1367 }
1368
1369 SYSCTL_PROC(_net_inet_udp, OID_AUTO, pcblist64,
1370 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, udp_pcblist64,
1371 "S,xinpcb64", "List of active UDP sockets");
1372
1373 #endif /* XNU_TARGET_OS_OSX */
1374
1375 static int
1376 udp_pcblist_n SYSCTL_HANDLER_ARGS
1377 {
1378 #pragma unused(oidp, arg1, arg2)
1379 return get_pcblist_n(IPPROTO_UDP, req, &udbinfo);
1380 }
1381
1382 SYSCTL_PROC(_net_inet_udp, OID_AUTO, pcblist_n,
1383 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, udp_pcblist_n,
1384 "S,xinpcb_n", "List of active UDP sockets");
1385
1386 __private_extern__ void
udp_get_ports_used(ifnet_t ifp,int protocol,uint32_t flags,bitstr_t * bitfield)1387 udp_get_ports_used(ifnet_t ifp, int protocol, uint32_t flags,
1388 bitstr_t *bitfield)
1389 {
1390 inpcb_get_ports_used(ifp, protocol, flags, bitfield,
1391 &udbinfo);
1392 }
1393
1394 __private_extern__ uint32_t
udp_count_opportunistic(unsigned int ifindex,u_int32_t flags)1395 udp_count_opportunistic(unsigned int ifindex, u_int32_t flags)
1396 {
1397 return inpcb_count_opportunistic(ifindex, &udbinfo, flags);
1398 }
1399
1400 __private_extern__ uint32_t
udp_find_anypcb_byaddr(struct ifaddr * ifa)1401 udp_find_anypcb_byaddr(struct ifaddr *ifa)
1402 {
1403 #if SKYWALK
1404 if (netns_is_enabled()) {
1405 return netns_find_anyres_byaddr(ifa, IPPROTO_UDP);
1406 } else
1407 #endif /* SKYWALK */
1408 return inpcb_find_anypcb_byaddr(ifa, &udbinfo);
1409 }
1410
1411 static int
udp_check_pktinfo(struct mbuf * control,struct ifnet ** outif,struct in_addr * laddr)1412 udp_check_pktinfo(struct mbuf *control, struct ifnet **outif,
1413 struct in_addr *laddr)
1414 {
1415 struct cmsghdr *cm = 0;
1416 struct in_pktinfo *pktinfo;
1417 struct ifnet *ifp;
1418
1419 if (outif != NULL) {
1420 *outif = NULL;
1421 }
1422
1423 /*
1424 * XXX: Currently, we assume all the optional information is stored
1425 * in a single mbuf.
1426 */
1427 if (control->m_next) {
1428 return EINVAL;
1429 }
1430
1431 if (control->m_len < CMSG_LEN(0)) {
1432 return EINVAL;
1433 }
1434
1435 for (cm = M_FIRST_CMSGHDR(control);
1436 is_cmsg_valid(control, cm);
1437 cm = M_NXT_CMSGHDR(control, cm)) {
1438 if (cm->cmsg_level != IPPROTO_IP ||
1439 cm->cmsg_type != IP_PKTINFO) {
1440 continue;
1441 }
1442
1443 if (cm->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo))) {
1444 return EINVAL;
1445 }
1446
1447 pktinfo = (struct in_pktinfo *)(void *)CMSG_DATA(cm);
1448
1449 /* Check for a valid ifindex in pktinfo */
1450 ifnet_head_lock_shared();
1451
1452 if (pktinfo->ipi_ifindex > if_index) {
1453 ifnet_head_done();
1454 return ENXIO;
1455 }
1456
1457 /*
1458 * If ipi_ifindex is specified it takes precedence
1459 * over ipi_spec_dst.
1460 */
1461 if (pktinfo->ipi_ifindex) {
1462 ifp = ifindex2ifnet[pktinfo->ipi_ifindex];
1463 if (ifp == NULL) {
1464 ifnet_head_done();
1465 return ENXIO;
1466 }
1467 if (outif != NULL) {
1468 ifnet_reference(ifp);
1469 *outif = ifp;
1470 }
1471 ifnet_head_done();
1472 laddr->s_addr = INADDR_ANY;
1473 break;
1474 }
1475
1476 ifnet_head_done();
1477
1478 /*
1479 * Use the provided ipi_spec_dst address for temp
1480 * source address.
1481 */
1482 *laddr = pktinfo->ipi_spec_dst;
1483 break;
1484 }
1485 return 0;
1486 }
1487
1488 int
udp_output(struct inpcb * inp,struct mbuf * m,struct sockaddr * addr,struct mbuf * control,struct proc * p)1489 udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
1490 struct mbuf *control, struct proc *p)
1491 {
1492 struct udpiphdr *ui;
1493 int len = m->m_pkthdr.len;
1494 struct sockaddr_in *sin;
1495 struct in_addr origladdr, laddr, faddr, pi_laddr;
1496 u_short lport, fport;
1497 int error = 0, udp_dodisconnect = 0, pktinfo = 0;
1498 struct socket *so = inp->inp_socket;
1499 int soopts = 0;
1500 struct mbuf *inpopts;
1501 struct ip_moptions *mopts;
1502 struct route ro;
1503 struct ip_out_args ipoa;
1504 bool sndinprog_cnt_used = false;
1505 #if CONTENT_FILTER
1506 struct m_tag *cfil_tag = NULL;
1507 bool cfil_faddr_use = false;
1508 uint32_t cfil_so_state_change_cnt = 0;
1509 uint32_t cfil_so_options = 0;
1510 struct sockaddr *cfil_faddr = NULL;
1511 #endif
1512 bool check_qos_marking_again = (so->so_flags1 & SOF1_QOSMARKING_POLICY_OVERRIDE) ? FALSE : TRUE;
1513
1514 bzero(&ipoa, sizeof(ipoa));
1515 ipoa.ipoa_boundif = IFSCOPE_NONE;
1516 ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
1517
1518 struct ifnet *outif = NULL;
1519 struct flowadv *adv = &ipoa.ipoa_flowadv;
1520 int sotc = SO_TC_UNSPEC;
1521 int netsvctype = _NET_SERVICE_TYPE_UNSPEC;
1522 struct ifnet *origoutifp = NULL;
1523 int flowadv = 0;
1524 int tos = IPTOS_UNSPEC;
1525
1526 /* Enable flow advisory only when connected */
1527 flowadv = (so->so_state & SS_ISCONNECTED) ? 1 : 0;
1528 pi_laddr.s_addr = INADDR_ANY;
1529
1530 KERNEL_DEBUG(DBG_FNC_UDP_OUTPUT | DBG_FUNC_START, 0, 0, 0, 0, 0);
1531
1532 socket_lock_assert_owned(so);
1533
1534 #if CONTENT_FILTER
1535 /*
1536 * If socket is subject to UDP Content Filter and no addr is passed in,
1537 * retrieve CFIL saved state from mbuf and use it if necessary.
1538 */
1539 if (CFIL_DGRAM_FILTERED(so) && !addr) {
1540 cfil_tag = cfil_dgram_get_socket_state(m, &cfil_so_state_change_cnt, &cfil_so_options, &cfil_faddr, NULL);
1541 if (cfil_tag) {
1542 sin = (struct sockaddr_in *)(void *)cfil_faddr;
1543 if (inp && inp->inp_faddr.s_addr == INADDR_ANY) {
1544 /*
1545 * Socket is unconnected, simply use the saved faddr as 'addr' to go through
1546 * the connect/disconnect logic.
1547 */
1548 addr = (struct sockaddr *)cfil_faddr;
1549 } else if ((so->so_state_change_cnt != cfil_so_state_change_cnt) &&
1550 (inp->inp_fport != sin->sin_port ||
1551 inp->inp_faddr.s_addr != sin->sin_addr.s_addr)) {
1552 /*
1553 * Socket is connected but socket state and dest addr/port changed.
1554 * We need to use the saved faddr info.
1555 */
1556 cfil_faddr_use = true;
1557 }
1558 }
1559 }
1560 #endif
1561
1562 if (control != NULL) {
1563 tos = so_tos_from_control(control);
1564 sotc = so_tc_from_control(control, &netsvctype);
1565 VERIFY(outif == NULL);
1566 error = udp_check_pktinfo(control, &outif, &pi_laddr);
1567 m_freem(control);
1568 control = NULL;
1569 if (error) {
1570 goto release;
1571 }
1572 if (outif != NULL) {
1573 pktinfo++;
1574 ipoa.ipoa_boundif = outif->if_index;
1575 }
1576 }
1577 if (sotc == SO_TC_UNSPEC) {
1578 sotc = so->so_traffic_class;
1579 netsvctype = so->so_netsvctype;
1580 }
1581
1582 KERNEL_DEBUG(DBG_LAYER_OUT_BEG, inp->inp_fport, inp->inp_lport,
1583 inp->inp_laddr.s_addr, inp->inp_faddr.s_addr,
1584 (htons((u_short)len + sizeof(struct udphdr))));
1585
1586 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) {
1587 error = EMSGSIZE;
1588 goto release;
1589 }
1590
1591 if (flowadv && INP_WAIT_FOR_IF_FEEDBACK(inp)) {
1592 /*
1593 * The socket is flow-controlled, drop the packets
1594 * until the inp is not flow controlled
1595 */
1596 error = ENOBUFS;
1597 goto release;
1598 }
1599 /*
1600 * If socket was bound to an ifindex, tell ip_output about it.
1601 * If the ancillary IP_PKTINFO option contains an interface index,
1602 * it takes precedence over the one specified by IP_BOUND_IF.
1603 */
1604 if (ipoa.ipoa_boundif == IFSCOPE_NONE &&
1605 (inp->inp_flags & INP_BOUND_IF)) {
1606 VERIFY(inp->inp_boundifp != NULL);
1607 ifnet_reference(inp->inp_boundifp); /* for this routine */
1608 if (outif != NULL) {
1609 ifnet_release(outif);
1610 }
1611 outif = inp->inp_boundifp;
1612 ipoa.ipoa_boundif = outif->if_index;
1613 }
1614 if (INP_NO_CELLULAR(inp)) {
1615 ipoa.ipoa_flags |= IPOAF_NO_CELLULAR;
1616 }
1617 if (INP_NO_EXPENSIVE(inp)) {
1618 ipoa.ipoa_flags |= IPOAF_NO_EXPENSIVE;
1619 }
1620 if (INP_NO_CONSTRAINED(inp)) {
1621 ipoa.ipoa_flags |= IPOAF_NO_CONSTRAINED;
1622 }
1623 if (INP_AWDL_UNRESTRICTED(inp)) {
1624 ipoa.ipoa_flags |= IPOAF_AWDL_UNRESTRICTED;
1625 }
1626 if (INP_MANAGEMENT_ALLOWED(inp)) {
1627 ipoa.ipoa_flags |= IPOAF_MANAGEMENT_ALLOWED;
1628 }
1629 ipoa.ipoa_sotc = sotc;
1630 ipoa.ipoa_netsvctype = netsvctype;
1631 soopts |= IP_OUTARGS;
1632
1633 /*
1634 * If there was a routing change, discard cached route and check
1635 * that we have a valid source address. Reacquire a new source
1636 * address if INADDR_ANY was specified.
1637 *
1638 * If we are using cfil saved state, go through this cache cleanup
1639 * so that we can get a new route.
1640 */
1641 if (ROUTE_UNUSABLE(&inp->inp_route)
1642 #if CONTENT_FILTER
1643 || cfil_faddr_use
1644 #endif
1645 ) {
1646 struct in_ifaddr *ia = NULL;
1647
1648 ROUTE_RELEASE(&inp->inp_route);
1649
1650 /* src address is gone? */
1651 if (inp->inp_laddr.s_addr != INADDR_ANY &&
1652 (ia = ifa_foraddr(inp->inp_laddr.s_addr)) == NULL) {
1653 if (!(inp->inp_flags & INP_INADDR_ANY) ||
1654 (so->so_state & SS_ISCONNECTED)) {
1655 /*
1656 * Rdar://5448998
1657 * If the source address is gone, return an
1658 * error if:
1659 * - the source was specified
1660 * - the socket was already connected
1661 */
1662 soevent(so, (SO_FILT_HINT_LOCKED |
1663 SO_FILT_HINT_NOSRCADDR));
1664 error = EADDRNOTAVAIL;
1665 goto release;
1666 } else {
1667 /* new src will be set later */
1668 inp->inp_laddr.s_addr = INADDR_ANY;
1669 inp->inp_last_outifp = NULL;
1670 #if SKYWALK
1671 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
1672 netns_set_ifnet(&inp->inp_netns_token, NULL);
1673 }
1674 #endif /* SKYWALK */
1675 }
1676 }
1677 if (ia != NULL) {
1678 IFA_REMREF(&ia->ia_ifa);
1679 }
1680 }
1681
1682 /*
1683 * IP_PKTINFO option check. If a temporary scope or src address
1684 * is provided, use it for this packet only and make sure we forget
1685 * it after sending this datagram.
1686 */
1687 if (pi_laddr.s_addr != INADDR_ANY ||
1688 (ipoa.ipoa_boundif != IFSCOPE_NONE && pktinfo)) {
1689 /* temp src address for this datagram only */
1690 laddr = pi_laddr;
1691 origladdr.s_addr = INADDR_ANY;
1692 /* we don't want to keep the laddr or route */
1693 udp_dodisconnect = 1;
1694 /* remember we don't care about src addr */
1695 inp->inp_flags |= INP_INADDR_ANY;
1696 } else {
1697 origladdr = laddr = inp->inp_laddr;
1698 }
1699
1700 origoutifp = inp->inp_last_outifp;
1701 faddr = inp->inp_faddr;
1702 lport = inp->inp_lport;
1703 fport = inp->inp_fport;
1704
1705 #if CONTENT_FILTER
1706 if (cfil_faddr_use) {
1707 faddr = ((struct sockaddr_in *)(void *)cfil_faddr)->sin_addr;
1708 fport = ((struct sockaddr_in *)(void *)cfil_faddr)->sin_port;
1709 }
1710 #endif
1711 inp->inp_sndinprog_cnt++;
1712 sndinprog_cnt_used = true;
1713
1714 if (addr) {
1715 sin = (struct sockaddr_in *)(void *)addr;
1716 if (faddr.s_addr != INADDR_ANY) {
1717 error = EISCONN;
1718 goto release;
1719 }
1720 if (lport == 0) {
1721 /*
1722 * In case we don't have a local port set, go through
1723 * the full connect. We don't have a local port yet
1724 * (i.e., we can't be looked up), so it's not an issue
1725 * if the input runs at the same time we do this.
1726 */
1727 /* if we have a source address specified, use that */
1728 if (pi_laddr.s_addr != INADDR_ANY) {
1729 inp->inp_laddr = pi_laddr;
1730 }
1731 /*
1732 * If a scope is specified, use it. Scope from
1733 * IP_PKTINFO takes precendence over the the scope
1734 * set via INP_BOUND_IF.
1735 */
1736 error = in_pcbconnect(inp, addr, p, ipoa.ipoa_boundif,
1737 &outif);
1738 if (error) {
1739 goto release;
1740 }
1741
1742 laddr = inp->inp_laddr;
1743 lport = inp->inp_lport;
1744 faddr = inp->inp_faddr;
1745 fport = inp->inp_fport;
1746 udp_dodisconnect = 1;
1747
1748 /* synch up in case in_pcbladdr() overrides */
1749 if (outif != NULL && ipoa.ipoa_boundif != IFSCOPE_NONE) {
1750 ipoa.ipoa_boundif = outif->if_index;
1751 }
1752 } else {
1753 /*
1754 * Fast path case
1755 *
1756 * We have a full address and a local port; use those
1757 * info to build the packet without changing the pcb
1758 * and interfering with the input path. See 3851370.
1759 *
1760 * Scope from IP_PKTINFO takes precendence over the
1761 * the scope set via INP_BOUND_IF.
1762 */
1763 if (laddr.s_addr == INADDR_ANY) {
1764 if ((error = in_pcbladdr(inp, addr, &laddr,
1765 ipoa.ipoa_boundif, &outif, 0)) != 0) {
1766 goto release;
1767 }
1768 /*
1769 * from pcbconnect: remember we don't
1770 * care about src addr.
1771 */
1772 inp->inp_flags |= INP_INADDR_ANY;
1773
1774 /* synch up in case in_pcbladdr() overrides */
1775 if (outif != NULL &&
1776 ipoa.ipoa_boundif != IFSCOPE_NONE) {
1777 ipoa.ipoa_boundif = outif->if_index;
1778 }
1779 }
1780
1781 faddr = sin->sin_addr;
1782 fport = sin->sin_port;
1783 }
1784 } else {
1785 if (faddr.s_addr == INADDR_ANY) {
1786 error = ENOTCONN;
1787 goto release;
1788 }
1789 }
1790
1791 if (inp->inp_flowhash == 0) {
1792 inp_calc_flowhash(inp);
1793 ASSERT(inp->inp_flowhash != 0);
1794 }
1795
1796 if (fport == htons(53) && !(so->so_flags1 & SOF1_DNS_COUNTED)) {
1797 so->so_flags1 |= SOF1_DNS_COUNTED;
1798 INC_ATOMIC_INT64_LIM(net_api_stats.nas_socket_inet_dgram_dns);
1799 }
1800
1801 /*
1802 * Calculate data length and get a mbuf
1803 * for UDP and IP headers.
1804 */
1805 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT, 1);
1806 if (m == 0) {
1807 error = ENOBUFS;
1808 goto abort;
1809 }
1810
1811 /*
1812 * Fill in mbuf with extended UDP header
1813 * and addresses and length put into network format.
1814 */
1815 ui = mtod(m, struct udpiphdr *);
1816 bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */
1817 ui->ui_pr = IPPROTO_UDP;
1818 ui->ui_src = laddr;
1819 ui->ui_dst = faddr;
1820 ui->ui_sport = lport;
1821 ui->ui_dport = fport;
1822 ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr));
1823
1824 /*
1825 * Set the Don't Fragment bit in the IP header.
1826 */
1827 if (inp->inp_flags2 & INP2_DONTFRAG) {
1828 struct ip *ip;
1829
1830 ip = (struct ip *)&ui->ui_i;
1831 ip->ip_off |= IP_DF;
1832 }
1833
1834 /*
1835 * Set up checksum to pseudo header checksum and output datagram.
1836 *
1837 * Treat flows to be CLAT46'd as IPv6 flow and compute checksum
1838 * no matter what, as IPv6 mandates checksum for UDP.
1839 *
1840 * Here we only compute the one's complement sum of the pseudo header.
1841 * The payload computation and final complement is delayed to much later
1842 * in IP processing to decide if remaining computation needs to be done
1843 * through offload.
1844 *
1845 * That is communicated by setting CSUM_UDP in csum_flags.
1846 * The offset of checksum from the start of ULP header is communicated
1847 * through csum_data.
1848 *
1849 * Note since this already contains the pseudo checksum header, any
1850 * later operation at IP layer that modify the values used here must
1851 * update the checksum as well (for example NAT etc).
1852 */
1853 if ((inp->inp_flags2 & INP2_CLAT46_FLOW) ||
1854 (udpcksum && !(inp->inp_flags & INP_UDP_NOCKSUM))) {
1855 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, ui->ui_dst.s_addr,
1856 htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP));
1857 m->m_pkthdr.csum_flags = (CSUM_UDP | CSUM_ZERO_INVERT);
1858 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
1859 } else {
1860 ui->ui_sum = 0;
1861 }
1862 ((struct ip *)ui)->ip_len = (uint16_t)(sizeof(struct udpiphdr) + len);
1863 ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl; /* XXX */
1864 if (tos != IPTOS_UNSPEC) {
1865 ((struct ip *)ui)->ip_tos = (uint8_t)(tos & IPTOS_MASK);
1866 } else {
1867 ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */
1868 }
1869 udpstat.udps_opackets++;
1870
1871 KERNEL_DEBUG(DBG_LAYER_OUT_END, ui->ui_dport, ui->ui_sport,
1872 ui->ui_src.s_addr, ui->ui_dst.s_addr, ui->ui_ulen);
1873
1874 #if NECP
1875 {
1876 necp_kernel_policy_id policy_id;
1877 necp_kernel_policy_id skip_policy_id;
1878 u_int32_t route_rule_id;
1879 u_int32_t pass_flags;
1880
1881 /*
1882 * We need a route to perform NECP route rule checks
1883 */
1884 if (net_qos_policy_restricted != 0 &&
1885 ROUTE_UNUSABLE(&inp->inp_route)) {
1886 struct sockaddr_in to;
1887 struct sockaddr_in from;
1888
1889 ROUTE_RELEASE(&inp->inp_route);
1890
1891 bzero(&from, sizeof(struct sockaddr_in));
1892 from.sin_family = AF_INET;
1893 from.sin_len = sizeof(struct sockaddr_in);
1894 from.sin_addr = laddr;
1895
1896 bzero(&to, sizeof(struct sockaddr_in));
1897 to.sin_family = AF_INET;
1898 to.sin_len = sizeof(struct sockaddr_in);
1899 to.sin_addr = faddr;
1900
1901 inp->inp_route.ro_dst.sa_family = AF_INET;
1902 inp->inp_route.ro_dst.sa_len = sizeof(struct sockaddr_in);
1903 ((struct sockaddr_in *)(void *)&inp->inp_route.ro_dst)->sin_addr =
1904 faddr;
1905
1906 rtalloc_scoped(&inp->inp_route, ipoa.ipoa_boundif);
1907
1908 inp_update_necp_policy(inp, (struct sockaddr *)&from,
1909 (struct sockaddr *)&to, ipoa.ipoa_boundif);
1910 inp->inp_policyresult.results.qos_marking_gencount = 0;
1911 }
1912
1913 if (!necp_socket_is_allowed_to_send_recv_v4(inp, lport, fport,
1914 &laddr, &faddr, NULL, 0, &policy_id, &route_rule_id, &skip_policy_id, &pass_flags)) {
1915 error = EHOSTUNREACH;
1916 goto abort;
1917 }
1918
1919 necp_mark_packet_from_socket(m, inp, policy_id, route_rule_id, skip_policy_id, pass_flags);
1920
1921 if (net_qos_policy_restricted != 0) {
1922 necp_socket_update_qos_marking(inp, inp->inp_route.ro_rt, route_rule_id);
1923 }
1924 }
1925 #endif /* NECP */
1926 if ((so->so_flags1 & SOF1_QOSMARKING_ALLOWED)) {
1927 ipoa.ipoa_flags |= IPOAF_QOSMARKING_ALLOWED;
1928 }
1929 if (check_qos_marking_again) {
1930 ipoa.ipoa_flags |= IPOAF_REDO_QOSMARKING_POLICY;
1931 }
1932 ipoa.qos_marking_gencount = inp->inp_policyresult.results.qos_marking_gencount;
1933
1934 #if IPSEC
1935 if (inp->inp_sp != NULL && ipsec_setsocket(m, inp->inp_socket) != 0) {
1936 error = ENOBUFS;
1937 goto abort;
1938 }
1939 #endif /* IPSEC */
1940
1941 inpopts = inp->inp_options;
1942 #if CONTENT_FILTER
1943 if (cfil_tag && (inp->inp_socket->so_options != cfil_so_options)) {
1944 soopts |= (cfil_so_options & (SO_DONTROUTE | SO_BROADCAST));
1945 } else
1946 #endif
1947 soopts |= (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST));
1948
1949 mopts = inp->inp_moptions;
1950 if (mopts != NULL) {
1951 IMO_LOCK(mopts);
1952 IMO_ADDREF_LOCKED(mopts);
1953 if (IN_MULTICAST(ntohl(ui->ui_dst.s_addr)) &&
1954 mopts->imo_multicast_ifp != NULL) {
1955 /* no reference needed */
1956 inp->inp_last_outifp = mopts->imo_multicast_ifp;
1957 #if SKYWALK
1958 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
1959 netns_set_ifnet(&inp->inp_netns_token,
1960 inp->inp_last_outifp);
1961 }
1962 #endif /* SKYWALK */
1963 }
1964 IMO_UNLOCK(mopts);
1965 }
1966
1967 /* Copy the cached route and take an extra reference */
1968 inp_route_copyout(inp, &ro);
1969
1970 set_packet_service_class(m, so, sotc, 0);
1971 m->m_pkthdr.pkt_flowsrc = FLOWSRC_INPCB;
1972 m->m_pkthdr.pkt_flowid = inp->inp_flowhash;
1973 m->m_pkthdr.pkt_proto = IPPROTO_UDP;
1974 m->m_pkthdr.pkt_flags |= (PKTF_FLOW_ID | PKTF_FLOW_LOCALSRC);
1975 if (flowadv) {
1976 m->m_pkthdr.pkt_flags |= PKTF_FLOW_ADV;
1977 }
1978 m->m_pkthdr.tx_udp_pid = so->last_pid;
1979 if (so->so_flags & SOF_DELEGATED) {
1980 m->m_pkthdr.tx_udp_e_pid = so->e_pid;
1981 } else {
1982 m->m_pkthdr.tx_udp_e_pid = 0;
1983 }
1984 #if (DEBUG || DEVELOPMENT)
1985 if (so->so_flags & SOF_MARK_WAKE_PKT) {
1986 so->so_flags &= ~SOF_MARK_WAKE_PKT;
1987 m->m_pkthdr.pkt_flags |= PKTF_WAKE_PKT;
1988 }
1989 #endif /* (DEBUG || DEVELOPMENT) */
1990
1991 m_add_crumb(m, PKT_CRUMB_UDP_OUTPUT);
1992
1993 if (ipoa.ipoa_boundif != IFSCOPE_NONE) {
1994 ipoa.ipoa_flags |= IPOAF_BOUND_IF;
1995 }
1996
1997 if (laddr.s_addr != INADDR_ANY) {
1998 ipoa.ipoa_flags |= IPOAF_BOUND_SRCADDR;
1999 }
2000
2001 socket_unlock(so, 0);
2002 error = ip_output(m, inpopts, &ro, soopts, mopts, &ipoa);
2003 m = NULL;
2004 socket_lock(so, 0);
2005 if (mopts != NULL) {
2006 IMO_REMREF(mopts);
2007 }
2008
2009 if (check_qos_marking_again) {
2010 inp->inp_policyresult.results.qos_marking_gencount = ipoa.qos_marking_gencount;
2011
2012 if (ipoa.ipoa_flags & IPOAF_QOSMARKING_ALLOWED) {
2013 inp->inp_socket->so_flags1 |= SOF1_QOSMARKING_ALLOWED;
2014 } else {
2015 inp->inp_socket->so_flags1 &= ~SOF1_QOSMARKING_ALLOWED;
2016 }
2017 }
2018
2019 if (error == 0 && nstat_collect) {
2020 boolean_t cell, wifi, wired;
2021
2022 if (ro.ro_rt != NULL) {
2023 cell = IFNET_IS_CELLULAR(ro.ro_rt->rt_ifp);
2024 wifi = (!cell && IFNET_IS_WIFI(ro.ro_rt->rt_ifp));
2025 wired = (!wifi && IFNET_IS_WIRED(ro.ro_rt->rt_ifp));
2026 } else {
2027 cell = wifi = wired = FALSE;
2028 }
2029 INP_ADD_STAT(inp, cell, wifi, wired, txpackets, 1);
2030 INP_ADD_STAT(inp, cell, wifi, wired, txbytes, len);
2031 inp_set_activity_bitmap(inp);
2032 }
2033
2034 if (flowadv && (adv->code == FADV_FLOW_CONTROLLED ||
2035 adv->code == FADV_SUSPENDED)) {
2036 /*
2037 * return a hint to the application that
2038 * the packet has been dropped
2039 */
2040 error = ENOBUFS;
2041 inp_set_fc_state(inp, adv->code);
2042 }
2043
2044 /* Synchronize PCB cached route */
2045 inp_route_copyin(inp, &ro);
2046
2047 abort:
2048 if (udp_dodisconnect) {
2049 /* Always discard the cached route for unconnected socket */
2050 ROUTE_RELEASE(&inp->inp_route);
2051 in_pcbdisconnect(inp);
2052 inp->inp_laddr = origladdr; /* XXX rehash? */
2053 /* no reference needed */
2054 inp->inp_last_outifp = origoutifp;
2055 #if SKYWALK
2056 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
2057 netns_set_ifnet(&inp->inp_netns_token,
2058 inp->inp_last_outifp);
2059 }
2060 #endif /* SKYWALK */
2061 } else if (inp->inp_route.ro_rt != NULL) {
2062 struct rtentry *rt = inp->inp_route.ro_rt;
2063 struct ifnet *outifp;
2064
2065 if (rt->rt_flags & (RTF_MULTICAST | RTF_BROADCAST)) {
2066 rt = NULL; /* unusable */
2067 }
2068 #if CONTENT_FILTER
2069 /*
2070 * Discard temporary route for cfil case
2071 */
2072 if (cfil_faddr_use) {
2073 rt = NULL; /* unusable */
2074 }
2075 #endif
2076
2077 /*
2078 * Always discard if it is a multicast or broadcast route.
2079 */
2080 if (rt == NULL) {
2081 ROUTE_RELEASE(&inp->inp_route);
2082 }
2083
2084 /*
2085 * If the destination route is unicast, update outifp with
2086 * that of the route interface used by IP.
2087 */
2088 if (rt != NULL &&
2089 (outifp = rt->rt_ifp) != inp->inp_last_outifp) {
2090 inp->inp_last_outifp = outifp; /* no reference needed */
2091 #if SKYWALK
2092 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
2093 netns_set_ifnet(&inp->inp_netns_token,
2094 inp->inp_last_outifp);
2095 }
2096 #endif /* SKYWALK */
2097
2098 so->so_pktheadroom = (uint16_t)P2ROUNDUP(
2099 sizeof(struct udphdr) +
2100 sizeof(struct ip) +
2101 ifnet_hdrlen(outifp) +
2102 ifnet_mbuf_packetpreamblelen(outifp),
2103 sizeof(u_int32_t));
2104 }
2105 } else {
2106 ROUTE_RELEASE(&inp->inp_route);
2107 }
2108
2109 /*
2110 * If output interface was cellular/expensive, and this socket is
2111 * denied access to it, generate an event.
2112 */
2113 if (error != 0 && (ipoa.ipoa_flags & IPOAF_R_IFDENIED) &&
2114 (INP_NO_CELLULAR(inp) || INP_NO_EXPENSIVE(inp) || INP_NO_CONSTRAINED(inp))) {
2115 soevent(so, (SO_FILT_HINT_LOCKED | SO_FILT_HINT_IFDENIED));
2116 }
2117
2118 release:
2119 KERNEL_DEBUG(DBG_FNC_UDP_OUTPUT | DBG_FUNC_END, error, 0, 0, 0, 0);
2120
2121 if (m != NULL) {
2122 m_freem(m);
2123 }
2124
2125 if (outif != NULL) {
2126 ifnet_release(outif);
2127 }
2128
2129 #if CONTENT_FILTER
2130 if (cfil_tag) {
2131 m_tag_free(cfil_tag);
2132 }
2133 #endif
2134 if (sndinprog_cnt_used) {
2135 VERIFY(inp->inp_sndinprog_cnt > 0);
2136 if (--inp->inp_sndinprog_cnt == 0) {
2137 inp->inp_flags &= ~(INP_FC_FEEDBACK);
2138 if (inp->inp_sndingprog_waiters > 0) {
2139 wakeup(&inp->inp_sndinprog_cnt);
2140 }
2141 }
2142 sndinprog_cnt_used = false;
2143 }
2144
2145 return error;
2146 }
2147
2148 u_int32_t udp_sendspace = 9216; /* really max datagram size */
2149 /* 187 1K datagrams (approx 192 KB) */
2150 u_int32_t udp_recvspace = 187 * (1024 + sizeof(struct sockaddr_in6));
2151
2152 /* Check that the values of udp send and recv space do not exceed sb_max */
2153 static int
sysctl_udp_sospace(struct sysctl_oid * oidp,void * arg1,int arg2,struct sysctl_req * req)2154 sysctl_udp_sospace(struct sysctl_oid *oidp, void *arg1, int arg2,
2155 struct sysctl_req *req)
2156 {
2157 #pragma unused(arg1, arg2)
2158 u_int32_t new_value = 0, *space_p = NULL;
2159 int changed = 0, error = 0;
2160 u_quad_t sb_effective_max = (sb_max / (MSIZE + MCLBYTES)) * MCLBYTES;
2161
2162 switch (oidp->oid_number) {
2163 case UDPCTL_RECVSPACE:
2164 space_p = &udp_recvspace;
2165 break;
2166 case UDPCTL_MAXDGRAM:
2167 space_p = &udp_sendspace;
2168 break;
2169 default:
2170 return EINVAL;
2171 }
2172 error = sysctl_io_number(req, *space_p, sizeof(u_int32_t),
2173 &new_value, &changed);
2174 if (changed) {
2175 if (new_value > 0 && new_value <= sb_effective_max) {
2176 *space_p = new_value;
2177 } else {
2178 error = ERANGE;
2179 }
2180 }
2181 return error;
2182 }
2183
2184 SYSCTL_PROC(_net_inet_udp, UDPCTL_RECVSPACE, recvspace,
2185 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, &udp_recvspace, 0,
2186 &sysctl_udp_sospace, "IU", "Maximum incoming UDP datagram size");
2187
2188 SYSCTL_PROC(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram,
2189 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, &udp_sendspace, 0,
2190 &sysctl_udp_sospace, "IU", "Maximum outgoing UDP datagram size");
2191
2192 int
udp_abort(struct socket * so)2193 udp_abort(struct socket *so)
2194 {
2195 struct inpcb *inp;
2196
2197 inp = sotoinpcb(so);
2198 if (inp == NULL) {
2199 panic("%s: so=%p null inp", __func__, so);
2200 /* NOTREACHED */
2201 }
2202 soisdisconnected(so);
2203 in_pcbdetach(inp);
2204 return 0;
2205 }
2206
2207 int
udp_attach(struct socket * so,int proto,struct proc * p)2208 udp_attach(struct socket *so, int proto, struct proc *p)
2209 {
2210 #pragma unused(proto)
2211 struct inpcb *inp;
2212 int error;
2213
2214 error = soreserve(so, udp_sendspace, udp_recvspace);
2215 if (error != 0) {
2216 return error;
2217 }
2218 inp = sotoinpcb(so);
2219 if (inp != NULL) {
2220 panic("%s so=%p inp=%p", __func__, so, inp);
2221 /* NOTREACHED */
2222 }
2223 error = in_pcballoc(so, &udbinfo, p);
2224 if (error != 0) {
2225 return error;
2226 }
2227 inp = (struct inpcb *)so->so_pcb;
2228 inp->inp_vflag |= INP_IPV4;
2229 inp->inp_ip_ttl = (uint8_t)ip_defttl;
2230 if (nstat_collect) {
2231 nstat_udp_new_pcb(inp);
2232 }
2233 return 0;
2234 }
2235
2236 int
udp_bind(struct socket * so,struct sockaddr * nam,struct proc * p)2237 udp_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
2238 {
2239 struct inpcb *inp;
2240 int error;
2241
2242 if (nam->sa_family != 0 && nam->sa_family != AF_INET &&
2243 nam->sa_family != AF_INET6) {
2244 return EAFNOSUPPORT;
2245 }
2246
2247 inp = sotoinpcb(so);
2248 if (inp == NULL) {
2249 return EINVAL;
2250 }
2251 error = in_pcbbind(inp, nam, p);
2252
2253 #if NECP
2254 /* Update NECP client with bind result if not in middle of connect */
2255 if (error == 0 &&
2256 (inp->inp_flags2 & INP2_CONNECT_IN_PROGRESS) &&
2257 !uuid_is_null(inp->necp_client_uuid)) {
2258 socket_unlock(so, 0);
2259 necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
2260 socket_lock(so, 0);
2261 }
2262 #endif /* NECP */
2263
2264 return error;
2265 }
2266
2267 int
udp_connect(struct socket * so,struct sockaddr * nam,struct proc * p)2268 udp_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
2269 {
2270 struct inpcb *inp;
2271 int error;
2272
2273 inp = sotoinpcb(so);
2274 if (inp == NULL) {
2275 return EINVAL;
2276 }
2277 if (inp->inp_faddr.s_addr != INADDR_ANY) {
2278 return EISCONN;
2279 }
2280
2281 if (!(so->so_flags1 & SOF1_CONNECT_COUNTED)) {
2282 so->so_flags1 |= SOF1_CONNECT_COUNTED;
2283 INC_ATOMIC_INT64_LIM(net_api_stats.nas_socket_inet_dgram_connected);
2284 }
2285
2286 #if NECP
2287 #if FLOW_DIVERT
2288 if (necp_socket_should_use_flow_divert(inp)) {
2289 error = flow_divert_pcb_init(so);
2290 if (error == 0) {
2291 error = flow_divert_connect_out(so, nam, p);
2292 }
2293 return error;
2294 }
2295 #endif /* FLOW_DIVERT */
2296 #endif /* NECP */
2297
2298 error = in_pcbconnect(inp, nam, p, IFSCOPE_NONE, NULL);
2299 if (error == 0) {
2300 #if NECP
2301 /* Update NECP client with connected five-tuple */
2302 if (!uuid_is_null(inp->necp_client_uuid)) {
2303 socket_unlock(so, 0);
2304 necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
2305 socket_lock(so, 0);
2306 }
2307 #endif /* NECP */
2308
2309 soisconnected(so);
2310 if (inp->inp_flowhash == 0) {
2311 inp_calc_flowhash(inp);
2312 ASSERT(inp->inp_flowhash != 0);
2313 }
2314 }
2315 return error;
2316 }
2317
2318 int
udp_connectx_common(struct socket * so,int af,struct sockaddr * src,struct sockaddr * dst,struct proc * p,uint32_t ifscope,sae_associd_t aid,sae_connid_t * pcid,uint32_t flags,void * arg,uint32_t arglen,struct uio * uio,user_ssize_t * bytes_written)2319 udp_connectx_common(struct socket *so, int af, struct sockaddr *src, struct sockaddr *dst,
2320 struct proc *p, uint32_t ifscope, sae_associd_t aid, sae_connid_t *pcid,
2321 uint32_t flags, void *arg, uint32_t arglen,
2322 struct uio *uio, user_ssize_t *bytes_written)
2323 {
2324 #pragma unused(aid, flags, arg, arglen)
2325 struct inpcb *inp = sotoinpcb(so);
2326 int error = 0;
2327 user_ssize_t datalen = 0;
2328
2329 if (inp == NULL) {
2330 return EINVAL;
2331 }
2332
2333 VERIFY(dst != NULL);
2334
2335 ASSERT(!(inp->inp_flags2 & INP2_CONNECT_IN_PROGRESS));
2336 inp->inp_flags2 |= INP2_CONNECT_IN_PROGRESS;
2337
2338 #if NECP
2339 inp_update_necp_policy(inp, src, dst, ifscope);
2340 #endif /* NECP */
2341
2342 /* bind socket to the specified interface, if requested */
2343 if (ifscope != IFSCOPE_NONE &&
2344 (error = inp_bindif(inp, ifscope, NULL)) != 0) {
2345 goto done;
2346 }
2347
2348 /* if source address and/or port is specified, bind to it */
2349 if (src != NULL) {
2350 error = sobindlock(so, src, 0); /* already locked */
2351 if (error != 0) {
2352 goto done;
2353 }
2354 }
2355
2356 switch (af) {
2357 case AF_INET:
2358 error = udp_connect(so, dst, p);
2359 break;
2360 case AF_INET6:
2361 error = udp6_connect(so, dst, p);
2362 break;
2363 default:
2364 VERIFY(0);
2365 /* NOTREACHED */
2366 }
2367
2368 if (error != 0) {
2369 goto done;
2370 }
2371
2372 /*
2373 * If there is data, copy it. DATA_IDEMPOTENT is ignored.
2374 * CONNECT_RESUME_ON_READ_WRITE is ignored.
2375 */
2376 if (uio != NULL) {
2377 socket_unlock(so, 0);
2378
2379 VERIFY(bytes_written != NULL);
2380
2381 datalen = uio_resid(uio);
2382 error = so->so_proto->pr_usrreqs->pru_sosend(so, NULL,
2383 (uio_t)uio, NULL, NULL, 0);
2384 socket_lock(so, 0);
2385
2386 /* If error returned is EMSGSIZE, for example, disconnect */
2387 if (error == 0 || error == EWOULDBLOCK) {
2388 *bytes_written = datalen - uio_resid(uio);
2389 } else {
2390 (void) so->so_proto->pr_usrreqs->pru_disconnectx(so,
2391 SAE_ASSOCID_ANY, SAE_CONNID_ANY);
2392 }
2393 /*
2394 * mask the EWOULDBLOCK error so that the caller
2395 * knows that atleast the connect was successful.
2396 */
2397 if (error == EWOULDBLOCK) {
2398 error = 0;
2399 }
2400 }
2401
2402 if (error == 0 && pcid != NULL) {
2403 *pcid = 1; /* there is only 1 connection for UDP */
2404 }
2405 done:
2406 inp->inp_flags2 &= ~INP2_CONNECT_IN_PROGRESS;
2407 return error;
2408 }
2409
2410 int
udp_connectx(struct socket * so,struct sockaddr * src,struct sockaddr * dst,struct proc * p,uint32_t ifscope,sae_associd_t aid,sae_connid_t * pcid,uint32_t flags,void * arg,uint32_t arglen,struct uio * uio,user_ssize_t * bytes_written)2411 udp_connectx(struct socket *so, struct sockaddr *src,
2412 struct sockaddr *dst, struct proc *p, uint32_t ifscope,
2413 sae_associd_t aid, sae_connid_t *pcid, uint32_t flags, void *arg,
2414 uint32_t arglen, struct uio *uio, user_ssize_t *bytes_written)
2415 {
2416 return udp_connectx_common(so, AF_INET, src, dst,
2417 p, ifscope, aid, pcid, flags, arg, arglen, uio, bytes_written);
2418 }
2419
2420 int
udp_detach(struct socket * so)2421 udp_detach(struct socket *so)
2422 {
2423 struct inpcb *inp;
2424
2425 inp = sotoinpcb(so);
2426 if (inp == NULL) {
2427 panic("%s: so=%p null inp", __func__, so);
2428 /* NOTREACHED */
2429 }
2430
2431 /*
2432 * If this is a socket that does not want to wakeup the device
2433 * for it's traffic, the application might be waiting for
2434 * close to complete before going to sleep. Send a notification
2435 * for this kind of sockets
2436 */
2437 if (so->so_options & SO_NOWAKEFROMSLEEP) {
2438 socket_post_kev_msg_closed(so);
2439 }
2440
2441 in_pcbdetach(inp);
2442 inp->inp_state = INPCB_STATE_DEAD;
2443 return 0;
2444 }
2445
2446 int
udp_disconnect(struct socket * so)2447 udp_disconnect(struct socket *so)
2448 {
2449 struct inpcb *inp;
2450
2451 inp = sotoinpcb(so);
2452 if (inp == NULL) {
2453 return EINVAL;
2454 }
2455 if (inp->inp_faddr.s_addr == INADDR_ANY) {
2456 return ENOTCONN;
2457 }
2458
2459 in_pcbdisconnect(inp);
2460
2461 /* reset flow controlled state, just in case */
2462 inp_reset_fc_state(inp);
2463
2464 inp->inp_laddr.s_addr = INADDR_ANY;
2465 so->so_state &= ~SS_ISCONNECTED; /* XXX */
2466 inp->inp_last_outifp = NULL;
2467 #if SKYWALK
2468 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
2469 netns_set_ifnet(&inp->inp_netns_token, NULL);
2470 }
2471 #endif /* SKYWALK */
2472
2473 return 0;
2474 }
2475
2476 int
udp_disconnectx(struct socket * so,sae_associd_t aid,sae_connid_t cid)2477 udp_disconnectx(struct socket *so, sae_associd_t aid, sae_connid_t cid)
2478 {
2479 #pragma unused(cid)
2480 if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL) {
2481 return EINVAL;
2482 }
2483
2484 return udp_disconnect(so);
2485 }
2486
2487 int
udp_send(struct socket * so,int flags,struct mbuf * m,struct sockaddr * addr,struct mbuf * control,struct proc * p)2488 udp_send(struct socket *so, int flags, struct mbuf *m,
2489 struct sockaddr *addr, struct mbuf *control, struct proc *p)
2490 {
2491 #ifndef FLOW_DIVERT
2492 #pragma unused(flags)
2493 #endif /* !(FLOW_DIVERT) */
2494 struct inpcb *inp;
2495 int error;
2496
2497 inp = sotoinpcb(so);
2498 if (inp == NULL) {
2499 if (m != NULL) {
2500 m_freem(m);
2501 }
2502 if (control != NULL) {
2503 m_freem(control);
2504 }
2505 return EINVAL;
2506 }
2507
2508 #if NECP
2509 #if FLOW_DIVERT
2510 if (necp_socket_should_use_flow_divert(inp)) {
2511 /* Implicit connect */
2512 return flow_divert_implicit_data_out(so, flags, m, addr,
2513 control, p);
2514 }
2515 #endif /* FLOW_DIVERT */
2516 #endif /* NECP */
2517
2518 #if SKYWALK
2519 sk_protect_t protect = sk_async_transmit_protect();
2520 #endif /* SKYWALK */
2521 error = udp_output(inp, m, addr, control, p);
2522 #if SKYWALK
2523 sk_async_transmit_unprotect(protect);
2524 #endif /* SKYWALK */
2525
2526 return error;
2527 }
2528
2529 int
udp_shutdown(struct socket * so)2530 udp_shutdown(struct socket *so)
2531 {
2532 struct inpcb *inp;
2533
2534 inp = sotoinpcb(so);
2535 if (inp == NULL) {
2536 return EINVAL;
2537 }
2538 socantsendmore(so);
2539 return 0;
2540 }
2541
2542 int
udp_lock(struct socket * so,int refcount,void * debug)2543 udp_lock(struct socket *so, int refcount, void *debug)
2544 {
2545 void *lr_saved;
2546
2547 if (debug == NULL) {
2548 lr_saved = __builtin_return_address(0);
2549 } else {
2550 lr_saved = debug;
2551 }
2552
2553 if (so->so_pcb != NULL) {
2554 LCK_MTX_ASSERT(&((struct inpcb *)so->so_pcb)->inpcb_mtx,
2555 LCK_MTX_ASSERT_NOTOWNED);
2556 lck_mtx_lock(&((struct inpcb *)so->so_pcb)->inpcb_mtx);
2557 } else {
2558 panic("%s: so=%p NO PCB! lr=%p lrh= %s", __func__,
2559 so, lr_saved, solockhistory_nr(so));
2560 /* NOTREACHED */
2561 }
2562 if (refcount) {
2563 so->so_usecount++;
2564 }
2565
2566 so->lock_lr[so->next_lock_lr] = lr_saved;
2567 so->next_lock_lr = (so->next_lock_lr + 1) % SO_LCKDBG_MAX;
2568 return 0;
2569 }
2570
2571 int
udp_unlock(struct socket * so,int refcount,void * debug)2572 udp_unlock(struct socket *so, int refcount, void *debug)
2573 {
2574 void *lr_saved;
2575
2576 if (debug == NULL) {
2577 lr_saved = __builtin_return_address(0);
2578 } else {
2579 lr_saved = debug;
2580 }
2581
2582 if (refcount) {
2583 VERIFY(so->so_usecount > 0);
2584 so->so_usecount--;
2585 }
2586 if (so->so_pcb == NULL) {
2587 panic("%s: so=%p NO PCB! lr=%p lrh= %s", __func__,
2588 so, lr_saved, solockhistory_nr(so));
2589 /* NOTREACHED */
2590 } else {
2591 LCK_MTX_ASSERT(&((struct inpcb *)so->so_pcb)->inpcb_mtx,
2592 LCK_MTX_ASSERT_OWNED);
2593 so->unlock_lr[so->next_unlock_lr] = lr_saved;
2594 so->next_unlock_lr = (so->next_unlock_lr + 1) % SO_LCKDBG_MAX;
2595 lck_mtx_unlock(&((struct inpcb *)so->so_pcb)->inpcb_mtx);
2596 }
2597 return 0;
2598 }
2599
2600 lck_mtx_t *
udp_getlock(struct socket * so,int flags)2601 udp_getlock(struct socket *so, int flags)
2602 {
2603 #pragma unused(flags)
2604 struct inpcb *inp = sotoinpcb(so);
2605
2606 if (so->so_pcb == NULL) {
2607 panic("%s: so=%p NULL so_pcb lrh= %s", __func__,
2608 so, solockhistory_nr(so));
2609 /* NOTREACHED */
2610 }
2611 return &inp->inpcb_mtx;
2612 }
2613
2614 /*
2615 * UDP garbage collector callback (inpcb_timer_func_t).
2616 *
2617 * Returns > 0 to keep timer active.
2618 */
2619 static void
udp_gc(struct inpcbinfo * ipi)2620 udp_gc(struct inpcbinfo *ipi)
2621 {
2622 struct inpcb *inp, *inpnxt;
2623 struct socket *so;
2624
2625 if (lck_rw_try_lock_exclusive(&ipi->ipi_lock) == FALSE) {
2626 if (udp_gc_done == TRUE) {
2627 udp_gc_done = FALSE;
2628 /* couldn't get the lock, must lock next time */
2629 atomic_add_32(&ipi->ipi_gc_req.intimer_fast, 1);
2630 return;
2631 }
2632 lck_rw_lock_exclusive(&ipi->ipi_lock);
2633 }
2634
2635 udp_gc_done = TRUE;
2636
2637 for (inp = udb.lh_first; inp != NULL; inp = inpnxt) {
2638 inpnxt = inp->inp_list.le_next;
2639
2640 /*
2641 * Skip unless it's STOPUSING; garbage collector will
2642 * be triggered by in_pcb_checkstate() upon setting
2643 * wantcnt to that value. If the PCB is already dead,
2644 * keep gc active to anticipate wantcnt changing.
2645 */
2646 if (inp->inp_wantcnt != WNT_STOPUSING) {
2647 continue;
2648 }
2649
2650 /*
2651 * Skip if busy, no hurry for cleanup. Keep gc active
2652 * and try the lock again during next round.
2653 */
2654 if (!socket_try_lock(inp->inp_socket)) {
2655 atomic_add_32(&ipi->ipi_gc_req.intimer_fast, 1);
2656 continue;
2657 }
2658
2659 /*
2660 * Keep gc active unless usecount is 0.
2661 */
2662 so = inp->inp_socket;
2663 if (so->so_usecount == 0) {
2664 if (inp->inp_state != INPCB_STATE_DEAD) {
2665 if (SOCK_CHECK_DOM(so, PF_INET6)) {
2666 in6_pcbdetach(inp);
2667 } else {
2668 in_pcbdetach(inp);
2669 }
2670 }
2671 in_pcbdispose(inp);
2672 } else {
2673 socket_unlock(so, 0);
2674 atomic_add_32(&ipi->ipi_gc_req.intimer_fast, 1);
2675 }
2676 }
2677 lck_rw_done(&ipi->ipi_lock);
2678 }
2679
2680 static int
2681 udp_getstat SYSCTL_HANDLER_ARGS
2682 {
2683 #pragma unused(oidp, arg1, arg2)
2684 if (req->oldptr == USER_ADDR_NULL) {
2685 req->oldlen = (size_t)sizeof(struct udpstat);
2686 }
2687
2688 return SYSCTL_OUT(req, &udpstat, MIN(sizeof(udpstat), req->oldlen));
2689 }
2690
2691 void
udp_in_cksum_stats(u_int32_t len)2692 udp_in_cksum_stats(u_int32_t len)
2693 {
2694 udpstat.udps_rcv_swcsum++;
2695 udpstat.udps_rcv_swcsum_bytes += len;
2696 }
2697
2698 void
udp_out_cksum_stats(u_int32_t len)2699 udp_out_cksum_stats(u_int32_t len)
2700 {
2701 udpstat.udps_snd_swcsum++;
2702 udpstat.udps_snd_swcsum_bytes += len;
2703 }
2704
2705 void
udp_in6_cksum_stats(u_int32_t len)2706 udp_in6_cksum_stats(u_int32_t len)
2707 {
2708 udpstat.udps_rcv6_swcsum++;
2709 udpstat.udps_rcv6_swcsum_bytes += len;
2710 }
2711
2712 void
udp_out6_cksum_stats(u_int32_t len)2713 udp_out6_cksum_stats(u_int32_t len)
2714 {
2715 udpstat.udps_snd6_swcsum++;
2716 udpstat.udps_snd6_swcsum_bytes += len;
2717 }
2718
2719 /*
2720 * Checksum extended UDP header and data.
2721 */
2722 static int
udp_input_checksum(struct mbuf * m,struct udphdr * uh,int off,int ulen)2723 udp_input_checksum(struct mbuf *m, struct udphdr *uh, int off, int ulen)
2724 {
2725 struct ifnet *ifp = m->m_pkthdr.rcvif;
2726 struct ip *ip = mtod(m, struct ip *);
2727 struct ipovly *ipov = (struct ipovly *)ip;
2728
2729 if (uh->uh_sum == 0) {
2730 udpstat.udps_nosum++;
2731 return 0;
2732 }
2733
2734 /* ip_stripoptions() must have been called before we get here */
2735 ASSERT((ip->ip_hl << 2) == sizeof(*ip));
2736
2737 if ((hwcksum_rx || (ifp->if_flags & IFF_LOOPBACK) ||
2738 (m->m_pkthdr.pkt_flags & PKTF_LOOP)) &&
2739 (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)) {
2740 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
2741 uh->uh_sum = m->m_pkthdr.csum_rx_val;
2742 } else {
2743 uint32_t sum = m->m_pkthdr.csum_rx_val;
2744 uint32_t start = m->m_pkthdr.csum_rx_start;
2745 int32_t trailer = (m_pktlen(m) - (off + ulen));
2746
2747 /*
2748 * Perform 1's complement adjustment of octets
2749 * that got included/excluded in the hardware-
2750 * calculated checksum value. Ignore cases
2751 * where the value already includes the entire
2752 * IP header span, as the sum for those octets
2753 * would already be 0 by the time we get here;
2754 * IP has already performed its header checksum
2755 * checks. If we do need to adjust, restore
2756 * the original fields in the IP header when
2757 * computing the adjustment value. Also take
2758 * care of any trailing bytes and subtract out
2759 * their partial sum.
2760 */
2761 ASSERT(trailer >= 0);
2762 if ((m->m_pkthdr.csum_flags & CSUM_PARTIAL) &&
2763 ((start != 0 && start != off) || trailer != 0)) {
2764 uint32_t swbytes = (uint32_t)trailer;
2765
2766 if (start < off) {
2767 ip->ip_len += sizeof(*ip);
2768 #if BYTE_ORDER != BIG_ENDIAN
2769 HTONS(ip->ip_len);
2770 HTONS(ip->ip_off);
2771 #endif /* BYTE_ORDER != BIG_ENDIAN */
2772 }
2773 /* callee folds in sum */
2774 sum = m_adj_sum16(m, start, off, ulen, sum);
2775 if (off > start) {
2776 swbytes += (off - start);
2777 } else {
2778 swbytes += (start - off);
2779 }
2780
2781 if (start < off) {
2782 #if BYTE_ORDER != BIG_ENDIAN
2783 NTOHS(ip->ip_off);
2784 NTOHS(ip->ip_len);
2785 #endif /* BYTE_ORDER != BIG_ENDIAN */
2786 ip->ip_len -= sizeof(*ip);
2787 }
2788
2789 if (swbytes != 0) {
2790 udp_in_cksum_stats(swbytes);
2791 }
2792 if (trailer != 0) {
2793 m_adj(m, -trailer);
2794 }
2795 }
2796
2797 /* callee folds in sum */
2798 uh->uh_sum = in_pseudo(ip->ip_src.s_addr,
2799 ip->ip_dst.s_addr, sum + htonl(ulen + IPPROTO_UDP));
2800 }
2801 uh->uh_sum ^= 0xffff;
2802 } else {
2803 uint16_t ip_sum;
2804 char b[9];
2805
2806 bcopy(ipov->ih_x1, b, sizeof(ipov->ih_x1));
2807 bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
2808 ip_sum = ipov->ih_len;
2809 ipov->ih_len = uh->uh_ulen;
2810 uh->uh_sum = in_cksum(m, ulen + sizeof(struct ip));
2811 bcopy(b, ipov->ih_x1, sizeof(ipov->ih_x1));
2812 ipov->ih_len = ip_sum;
2813
2814 udp_in_cksum_stats(ulen);
2815 }
2816
2817 if (uh->uh_sum != 0) {
2818 udpstat.udps_badsum++;
2819 IF_UDP_STATINC(ifp, badchksum);
2820 return -1;
2821 }
2822
2823 return 0;
2824 }
2825
2826 void
udp_fill_keepalive_offload_frames(ifnet_t ifp,struct ifnet_keepalive_offload_frame * frames_array,u_int32_t frames_array_count,size_t frame_data_offset,u_int32_t * used_frames_count)2827 udp_fill_keepalive_offload_frames(ifnet_t ifp,
2828 struct ifnet_keepalive_offload_frame *frames_array,
2829 u_int32_t frames_array_count, size_t frame_data_offset,
2830 u_int32_t *used_frames_count)
2831 {
2832 struct inpcb *inp;
2833 inp_gen_t gencnt;
2834 u_int32_t frame_index = *used_frames_count;
2835
2836 if (ifp == NULL || frames_array == NULL ||
2837 frames_array_count == 0 ||
2838 frame_index >= frames_array_count ||
2839 frame_data_offset >= IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE) {
2840 return;
2841 }
2842
2843 lck_rw_lock_shared(&udbinfo.ipi_lock);
2844 gencnt = udbinfo.ipi_gencnt;
2845 LIST_FOREACH(inp, udbinfo.ipi_listhead, inp_list) {
2846 struct socket *so;
2847 u_int8_t *data;
2848 struct ifnet_keepalive_offload_frame *frame;
2849 struct mbuf *m = NULL;
2850
2851 if (frame_index >= frames_array_count) {
2852 break;
2853 }
2854
2855 if (inp->inp_gencnt > gencnt ||
2856 inp->inp_state == INPCB_STATE_DEAD) {
2857 continue;
2858 }
2859
2860 if ((so = inp->inp_socket) == NULL ||
2861 (so->so_state & SS_DEFUNCT)) {
2862 continue;
2863 }
2864 /*
2865 * check for keepalive offload flag without socket
2866 * lock to avoid a deadlock
2867 */
2868 if (!(inp->inp_flags2 & INP2_KEEPALIVE_OFFLOAD)) {
2869 continue;
2870 }
2871
2872 udp_lock(so, 1, 0);
2873 if (!(inp->inp_vflag & (INP_IPV4 | INP_IPV6))) {
2874 udp_unlock(so, 1, 0);
2875 continue;
2876 }
2877 if ((inp->inp_vflag & INP_IPV4) &&
2878 (inp->inp_laddr.s_addr == INADDR_ANY ||
2879 inp->inp_faddr.s_addr == INADDR_ANY)) {
2880 udp_unlock(so, 1, 0);
2881 continue;
2882 }
2883 if ((inp->inp_vflag & INP_IPV6) &&
2884 (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) ||
2885 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))) {
2886 udp_unlock(so, 1, 0);
2887 continue;
2888 }
2889 if (inp->inp_lport == 0 || inp->inp_fport == 0) {
2890 udp_unlock(so, 1, 0);
2891 continue;
2892 }
2893 if (inp->inp_last_outifp == NULL ||
2894 inp->inp_last_outifp->if_index != ifp->if_index) {
2895 udp_unlock(so, 1, 0);
2896 continue;
2897 }
2898 if ((inp->inp_vflag & INP_IPV4)) {
2899 if ((frame_data_offset + sizeof(struct udpiphdr) +
2900 inp->inp_keepalive_datalen) >
2901 IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE) {
2902 udp_unlock(so, 1, 0);
2903 continue;
2904 }
2905 if ((sizeof(struct udpiphdr) +
2906 inp->inp_keepalive_datalen) > _MHLEN) {
2907 udp_unlock(so, 1, 0);
2908 continue;
2909 }
2910 } else {
2911 if ((frame_data_offset + sizeof(struct ip6_hdr) +
2912 sizeof(struct udphdr) +
2913 inp->inp_keepalive_datalen) >
2914 IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE) {
2915 udp_unlock(so, 1, 0);
2916 continue;
2917 }
2918 if ((sizeof(struct ip6_hdr) + sizeof(struct udphdr) +
2919 inp->inp_keepalive_datalen) > _MHLEN) {
2920 udp_unlock(so, 1, 0);
2921 continue;
2922 }
2923 }
2924 MGETHDR(m, M_WAIT, MT_HEADER);
2925 if (m == NULL) {
2926 udp_unlock(so, 1, 0);
2927 continue;
2928 }
2929 /*
2930 * This inp has all the information that is needed to
2931 * generate an offload frame.
2932 */
2933 if (inp->inp_vflag & INP_IPV4) {
2934 struct ip *ip;
2935 struct udphdr *udp;
2936
2937 frame = &frames_array[frame_index];
2938 frame->length = (uint8_t)(frame_data_offset +
2939 sizeof(struct udpiphdr) +
2940 inp->inp_keepalive_datalen);
2941 frame->ether_type =
2942 IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV4;
2943 frame->interval = inp->inp_keepalive_interval;
2944 switch (inp->inp_keepalive_type) {
2945 case UDP_KEEPALIVE_OFFLOAD_TYPE_AIRPLAY:
2946 frame->type =
2947 IFNET_KEEPALIVE_OFFLOAD_FRAME_AIRPLAY;
2948 break;
2949 default:
2950 break;
2951 }
2952 data = mtod(m, u_int8_t *);
2953 bzero(data, sizeof(struct udpiphdr));
2954 ip = (__typeof__(ip))(void *)data;
2955 udp = (__typeof__(udp))(void *) (data +
2956 sizeof(struct ip));
2957 m->m_len = sizeof(struct udpiphdr);
2958 data = data + sizeof(struct udpiphdr);
2959 if (inp->inp_keepalive_datalen > 0 &&
2960 inp->inp_keepalive_data != NULL) {
2961 bcopy(inp->inp_keepalive_data, data,
2962 inp->inp_keepalive_datalen);
2963 m->m_len += inp->inp_keepalive_datalen;
2964 }
2965 m->m_pkthdr.len = m->m_len;
2966
2967 ip->ip_v = IPVERSION;
2968 ip->ip_hl = (sizeof(struct ip) >> 2);
2969 ip->ip_p = IPPROTO_UDP;
2970 ip->ip_len = htons(sizeof(struct udpiphdr) +
2971 (u_short)inp->inp_keepalive_datalen);
2972 ip->ip_ttl = inp->inp_ip_ttl;
2973 ip->ip_tos |= (inp->inp_ip_tos & ~IPTOS_ECN_MASK);
2974 ip->ip_src = inp->inp_laddr;
2975 ip->ip_dst = inp->inp_faddr;
2976 ip->ip_sum = in_cksum_hdr_opt(ip);
2977
2978 udp->uh_sport = inp->inp_lport;
2979 udp->uh_dport = inp->inp_fport;
2980 udp->uh_ulen = htons(sizeof(struct udphdr) +
2981 (u_short)inp->inp_keepalive_datalen);
2982
2983 if (!(inp->inp_flags & INP_UDP_NOCKSUM)) {
2984 udp->uh_sum = in_pseudo(ip->ip_src.s_addr,
2985 ip->ip_dst.s_addr,
2986 htons(sizeof(struct udphdr) +
2987 (u_short)inp->inp_keepalive_datalen +
2988 IPPROTO_UDP));
2989 m->m_pkthdr.csum_flags =
2990 (CSUM_UDP | CSUM_ZERO_INVERT);
2991 m->m_pkthdr.csum_data = offsetof(struct udphdr,
2992 uh_sum);
2993 }
2994 m->m_pkthdr.pkt_proto = IPPROTO_UDP;
2995 in_delayed_cksum(m);
2996 bcopy(m->m_data, frame->data + frame_data_offset,
2997 m->m_len);
2998 } else {
2999 struct ip6_hdr *ip6;
3000 struct udphdr *udp6;
3001
3002 VERIFY(inp->inp_vflag & INP_IPV6);
3003 frame = &frames_array[frame_index];
3004 frame->length = (uint8_t)(frame_data_offset +
3005 sizeof(struct ip6_hdr) +
3006 sizeof(struct udphdr) +
3007 inp->inp_keepalive_datalen);
3008 frame->ether_type =
3009 IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV6;
3010 frame->interval = inp->inp_keepalive_interval;
3011 switch (inp->inp_keepalive_type) {
3012 case UDP_KEEPALIVE_OFFLOAD_TYPE_AIRPLAY:
3013 frame->type =
3014 IFNET_KEEPALIVE_OFFLOAD_FRAME_AIRPLAY;
3015 break;
3016 default:
3017 break;
3018 }
3019 data = mtod(m, u_int8_t *);
3020 bzero(data, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
3021 ip6 = (__typeof__(ip6))(void *)data;
3022 udp6 = (__typeof__(udp6))(void *)(data +
3023 sizeof(struct ip6_hdr));
3024 m->m_len = sizeof(struct ip6_hdr) +
3025 sizeof(struct udphdr);
3026 data = data + (sizeof(struct ip6_hdr) +
3027 sizeof(struct udphdr));
3028 if (inp->inp_keepalive_datalen > 0 &&
3029 inp->inp_keepalive_data != NULL) {
3030 bcopy(inp->inp_keepalive_data, data,
3031 inp->inp_keepalive_datalen);
3032 m->m_len += inp->inp_keepalive_datalen;
3033 }
3034 m->m_pkthdr.len = m->m_len;
3035 ip6->ip6_flow = inp->inp_flow & IPV6_FLOWINFO_MASK;
3036 ip6->ip6_flow = ip6->ip6_flow & ~IPV6_FLOW_ECN_MASK;
3037 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
3038 ip6->ip6_vfc |= IPV6_VERSION;
3039 ip6->ip6_nxt = IPPROTO_UDP;
3040 ip6->ip6_hlim = (uint8_t)ip6_defhlim;
3041 ip6->ip6_plen = htons(sizeof(struct udphdr) +
3042 (u_short)inp->inp_keepalive_datalen);
3043 ip6->ip6_src = inp->in6p_laddr;
3044 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
3045 ip6->ip6_src.s6_addr16[1] = 0;
3046 }
3047
3048 ip6->ip6_dst = inp->in6p_faddr;
3049 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
3050 ip6->ip6_dst.s6_addr16[1] = 0;
3051 }
3052
3053 udp6->uh_sport = inp->in6p_lport;
3054 udp6->uh_dport = inp->in6p_fport;
3055 udp6->uh_ulen = htons(sizeof(struct udphdr) +
3056 (u_short)inp->inp_keepalive_datalen);
3057 if (!(inp->inp_flags & INP_UDP_NOCKSUM)) {
3058 udp6->uh_sum = in6_pseudo(&ip6->ip6_src,
3059 &ip6->ip6_dst,
3060 htonl(sizeof(struct udphdr) +
3061 (u_short)inp->inp_keepalive_datalen +
3062 IPPROTO_UDP));
3063 m->m_pkthdr.csum_flags =
3064 (CSUM_UDPIPV6 | CSUM_ZERO_INVERT);
3065 m->m_pkthdr.csum_data = offsetof(struct udphdr,
3066 uh_sum);
3067 }
3068 m->m_pkthdr.pkt_proto = IPPROTO_UDP;
3069 in6_delayed_cksum(m);
3070 bcopy(m->m_data, frame->data + frame_data_offset,
3071 m->m_len);
3072 }
3073 if (m != NULL) {
3074 m_freem(m);
3075 m = NULL;
3076 }
3077 frame_index++;
3078 udp_unlock(so, 1, 0);
3079 }
3080 lck_rw_done(&udbinfo.ipi_lock);
3081 *used_frames_count = frame_index;
3082 }
3083
3084 int
udp_defunct(struct socket * so)3085 udp_defunct(struct socket *so)
3086 {
3087 struct ip_moptions *imo;
3088 struct inpcb *inp;
3089
3090 inp = sotoinpcb(so);
3091 if (inp == NULL) {
3092 return EINVAL;
3093 }
3094
3095 imo = inp->inp_moptions;
3096 if (imo != NULL) {
3097 struct proc *p = current_proc();
3098
3099 SODEFUNCTLOG("%s[%d, %s]: defuncting so 0x%llu drop multicast memberships",
3100 __func__, proc_pid(p), proc_best_name(p),
3101 so->so_gencnt);
3102
3103 inp->inp_moptions = NULL;
3104
3105 IMO_REMREF(imo);
3106 }
3107
3108 return 0;
3109 }
3110