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.zov_kt_heap = 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 pktinfo++;
1573 if (outif != NULL) {
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 ipoa.ipoa_sotc = sotc;
1627 ipoa.ipoa_netsvctype = netsvctype;
1628 soopts |= IP_OUTARGS;
1629
1630 /*
1631 * If there was a routing change, discard cached route and check
1632 * that we have a valid source address. Reacquire a new source
1633 * address if INADDR_ANY was specified.
1634 *
1635 * If we are using cfil saved state, go through this cache cleanup
1636 * so that we can get a new route.
1637 */
1638 if (ROUTE_UNUSABLE(&inp->inp_route)
1639 #if CONTENT_FILTER
1640 || cfil_faddr_use
1641 #endif
1642 ) {
1643 struct in_ifaddr *ia = NULL;
1644
1645 ROUTE_RELEASE(&inp->inp_route);
1646
1647 /* src address is gone? */
1648 if (inp->inp_laddr.s_addr != INADDR_ANY &&
1649 (ia = ifa_foraddr(inp->inp_laddr.s_addr)) == NULL) {
1650 if (!(inp->inp_flags & INP_INADDR_ANY) ||
1651 (so->so_state & SS_ISCONNECTED)) {
1652 /*
1653 * Rdar://5448998
1654 * If the source address is gone, return an
1655 * error if:
1656 * - the source was specified
1657 * - the socket was already connected
1658 */
1659 soevent(so, (SO_FILT_HINT_LOCKED |
1660 SO_FILT_HINT_NOSRCADDR));
1661 error = EADDRNOTAVAIL;
1662 goto release;
1663 } else {
1664 /* new src will be set later */
1665 inp->inp_laddr.s_addr = INADDR_ANY;
1666 inp->inp_last_outifp = NULL;
1667 #if SKYWALK
1668 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
1669 netns_set_ifnet(&inp->inp_netns_token, NULL);
1670 }
1671 #endif /* SKYWALK */
1672 }
1673 }
1674 if (ia != NULL) {
1675 IFA_REMREF(&ia->ia_ifa);
1676 }
1677 }
1678
1679 /*
1680 * IP_PKTINFO option check. If a temporary scope or src address
1681 * is provided, use it for this packet only and make sure we forget
1682 * it after sending this datagram.
1683 */
1684 if (pi_laddr.s_addr != INADDR_ANY ||
1685 (ipoa.ipoa_boundif != IFSCOPE_NONE && pktinfo)) {
1686 /* temp src address for this datagram only */
1687 laddr = pi_laddr;
1688 origladdr.s_addr = INADDR_ANY;
1689 /* we don't want to keep the laddr or route */
1690 udp_dodisconnect = 1;
1691 /* remember we don't care about src addr */
1692 inp->inp_flags |= INP_INADDR_ANY;
1693 } else {
1694 origladdr = laddr = inp->inp_laddr;
1695 }
1696
1697 origoutifp = inp->inp_last_outifp;
1698 faddr = inp->inp_faddr;
1699 lport = inp->inp_lport;
1700 fport = inp->inp_fport;
1701
1702 #if CONTENT_FILTER
1703 if (cfil_faddr_use) {
1704 faddr = ((struct sockaddr_in *)(void *)cfil_faddr)->sin_addr;
1705 fport = ((struct sockaddr_in *)(void *)cfil_faddr)->sin_port;
1706 }
1707 #endif
1708 inp->inp_sndinprog_cnt++;
1709 sndinprog_cnt_used = true;
1710
1711 if (addr) {
1712 sin = (struct sockaddr_in *)(void *)addr;
1713 if (faddr.s_addr != INADDR_ANY) {
1714 error = EISCONN;
1715 goto release;
1716 }
1717 if (lport == 0) {
1718 /*
1719 * In case we don't have a local port set, go through
1720 * the full connect. We don't have a local port yet
1721 * (i.e., we can't be looked up), so it's not an issue
1722 * if the input runs at the same time we do this.
1723 */
1724 /* if we have a source address specified, use that */
1725 if (pi_laddr.s_addr != INADDR_ANY) {
1726 inp->inp_laddr = pi_laddr;
1727 }
1728 /*
1729 * If a scope is specified, use it. Scope from
1730 * IP_PKTINFO takes precendence over the the scope
1731 * set via INP_BOUND_IF.
1732 */
1733 error = in_pcbconnect(inp, addr, p, ipoa.ipoa_boundif,
1734 &outif);
1735 if (error) {
1736 goto release;
1737 }
1738
1739 laddr = inp->inp_laddr;
1740 lport = inp->inp_lport;
1741 faddr = inp->inp_faddr;
1742 fport = inp->inp_fport;
1743 udp_dodisconnect = 1;
1744
1745 /* synch up in case in_pcbladdr() overrides */
1746 if (outif != NULL && ipoa.ipoa_boundif != IFSCOPE_NONE) {
1747 ipoa.ipoa_boundif = outif->if_index;
1748 }
1749 } else {
1750 /*
1751 * Fast path case
1752 *
1753 * We have a full address and a local port; use those
1754 * info to build the packet without changing the pcb
1755 * and interfering with the input path. See 3851370.
1756 *
1757 * Scope from IP_PKTINFO takes precendence over the
1758 * the scope set via INP_BOUND_IF.
1759 */
1760 if (laddr.s_addr == INADDR_ANY) {
1761 if ((error = in_pcbladdr(inp, addr, &laddr,
1762 ipoa.ipoa_boundif, &outif, 0)) != 0) {
1763 goto release;
1764 }
1765 /*
1766 * from pcbconnect: remember we don't
1767 * care about src addr.
1768 */
1769 inp->inp_flags |= INP_INADDR_ANY;
1770
1771 /* synch up in case in_pcbladdr() overrides */
1772 if (outif != NULL &&
1773 ipoa.ipoa_boundif != IFSCOPE_NONE) {
1774 ipoa.ipoa_boundif = outif->if_index;
1775 }
1776 }
1777
1778 faddr = sin->sin_addr;
1779 fport = sin->sin_port;
1780 }
1781 } else {
1782 if (faddr.s_addr == INADDR_ANY) {
1783 error = ENOTCONN;
1784 goto release;
1785 }
1786 }
1787
1788 if (inp->inp_flowhash == 0) {
1789 inp_calc_flowhash(inp);
1790 ASSERT(inp->inp_flowhash != 0);
1791 }
1792
1793 if (fport == htons(53) && !(so->so_flags1 & SOF1_DNS_COUNTED)) {
1794 so->so_flags1 |= SOF1_DNS_COUNTED;
1795 INC_ATOMIC_INT64_LIM(net_api_stats.nas_socket_inet_dgram_dns);
1796 }
1797
1798 /*
1799 * Calculate data length and get a mbuf
1800 * for UDP and IP headers.
1801 */
1802 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT, 1);
1803 if (m == 0) {
1804 error = ENOBUFS;
1805 goto abort;
1806 }
1807
1808 /*
1809 * Fill in mbuf with extended UDP header
1810 * and addresses and length put into network format.
1811 */
1812 ui = mtod(m, struct udpiphdr *);
1813 bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */
1814 ui->ui_pr = IPPROTO_UDP;
1815 ui->ui_src = laddr;
1816 ui->ui_dst = faddr;
1817 ui->ui_sport = lport;
1818 ui->ui_dport = fport;
1819 ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr));
1820
1821 /*
1822 * Set the Don't Fragment bit in the IP header.
1823 */
1824 if (inp->inp_flags2 & INP2_DONTFRAG) {
1825 struct ip *ip;
1826
1827 ip = (struct ip *)&ui->ui_i;
1828 ip->ip_off |= IP_DF;
1829 }
1830
1831 /*
1832 * Set up checksum to pseudo header checksum and output datagram.
1833 *
1834 * Treat flows to be CLAT46'd as IPv6 flow and compute checksum
1835 * no matter what, as IPv6 mandates checksum for UDP.
1836 *
1837 * Here we only compute the one's complement sum of the pseudo header.
1838 * The payload computation and final complement is delayed to much later
1839 * in IP processing to decide if remaining computation needs to be done
1840 * through offload.
1841 *
1842 * That is communicated by setting CSUM_UDP in csum_flags.
1843 * The offset of checksum from the start of ULP header is communicated
1844 * through csum_data.
1845 *
1846 * Note since this already contains the pseudo checksum header, any
1847 * later operation at IP layer that modify the values used here must
1848 * update the checksum as well (for example NAT etc).
1849 */
1850 if ((inp->inp_flags2 & INP2_CLAT46_FLOW) ||
1851 (udpcksum && !(inp->inp_flags & INP_UDP_NOCKSUM))) {
1852 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, ui->ui_dst.s_addr,
1853 htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP));
1854 m->m_pkthdr.csum_flags = (CSUM_UDP | CSUM_ZERO_INVERT);
1855 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
1856 } else {
1857 ui->ui_sum = 0;
1858 }
1859 ((struct ip *)ui)->ip_len = (uint16_t)(sizeof(struct udpiphdr) + len);
1860 ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl; /* XXX */
1861 if (tos != IPTOS_UNSPEC) {
1862 ((struct ip *)ui)->ip_tos = (uint8_t)(tos & IPTOS_MASK);
1863 } else {
1864 ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */
1865 }
1866 udpstat.udps_opackets++;
1867
1868 KERNEL_DEBUG(DBG_LAYER_OUT_END, ui->ui_dport, ui->ui_sport,
1869 ui->ui_src.s_addr, ui->ui_dst.s_addr, ui->ui_ulen);
1870
1871 #if NECP
1872 {
1873 necp_kernel_policy_id policy_id;
1874 necp_kernel_policy_id skip_policy_id;
1875 u_int32_t route_rule_id;
1876 u_int32_t pass_flags;
1877
1878 /*
1879 * We need a route to perform NECP route rule checks
1880 */
1881 if (net_qos_policy_restricted != 0 &&
1882 ROUTE_UNUSABLE(&inp->inp_route)) {
1883 struct sockaddr_in to;
1884 struct sockaddr_in from;
1885
1886 ROUTE_RELEASE(&inp->inp_route);
1887
1888 bzero(&from, sizeof(struct sockaddr_in));
1889 from.sin_family = AF_INET;
1890 from.sin_len = sizeof(struct sockaddr_in);
1891 from.sin_addr = laddr;
1892
1893 bzero(&to, sizeof(struct sockaddr_in));
1894 to.sin_family = AF_INET;
1895 to.sin_len = sizeof(struct sockaddr_in);
1896 to.sin_addr = faddr;
1897
1898 inp->inp_route.ro_dst.sa_family = AF_INET;
1899 inp->inp_route.ro_dst.sa_len = sizeof(struct sockaddr_in);
1900 ((struct sockaddr_in *)(void *)&inp->inp_route.ro_dst)->sin_addr =
1901 faddr;
1902
1903 rtalloc_scoped(&inp->inp_route, ipoa.ipoa_boundif);
1904
1905 inp_update_necp_policy(inp, (struct sockaddr *)&from,
1906 (struct sockaddr *)&to, ipoa.ipoa_boundif);
1907 inp->inp_policyresult.results.qos_marking_gencount = 0;
1908 }
1909
1910 if (!necp_socket_is_allowed_to_send_recv_v4(inp, lport, fport,
1911 &laddr, &faddr, NULL, 0, &policy_id, &route_rule_id, &skip_policy_id, &pass_flags)) {
1912 error = EHOSTUNREACH;
1913 goto abort;
1914 }
1915
1916 necp_mark_packet_from_socket(m, inp, policy_id, route_rule_id, skip_policy_id, pass_flags);
1917
1918 if (net_qos_policy_restricted != 0) {
1919 necp_socket_update_qos_marking(inp, inp->inp_route.ro_rt, route_rule_id);
1920 }
1921 }
1922 #endif /* NECP */
1923 if ((so->so_flags1 & SOF1_QOSMARKING_ALLOWED)) {
1924 ipoa.ipoa_flags |= IPOAF_QOSMARKING_ALLOWED;
1925 }
1926 if (check_qos_marking_again) {
1927 ipoa.ipoa_flags |= IPOAF_REDO_QOSMARKING_POLICY;
1928 }
1929 ipoa.qos_marking_gencount = inp->inp_policyresult.results.qos_marking_gencount;
1930
1931 #if IPSEC
1932 if (inp->inp_sp != NULL && ipsec_setsocket(m, inp->inp_socket) != 0) {
1933 error = ENOBUFS;
1934 goto abort;
1935 }
1936 #endif /* IPSEC */
1937
1938 inpopts = inp->inp_options;
1939 #if CONTENT_FILTER
1940 if (cfil_tag && (inp->inp_socket->so_options != cfil_so_options)) {
1941 soopts |= (cfil_so_options & (SO_DONTROUTE | SO_BROADCAST));
1942 } else
1943 #endif
1944 soopts |= (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST));
1945
1946 mopts = inp->inp_moptions;
1947 if (mopts != NULL) {
1948 IMO_LOCK(mopts);
1949 IMO_ADDREF_LOCKED(mopts);
1950 if (IN_MULTICAST(ntohl(ui->ui_dst.s_addr)) &&
1951 mopts->imo_multicast_ifp != NULL) {
1952 /* no reference needed */
1953 inp->inp_last_outifp = mopts->imo_multicast_ifp;
1954 #if SKYWALK
1955 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
1956 netns_set_ifnet(&inp->inp_netns_token,
1957 inp->inp_last_outifp);
1958 }
1959 #endif /* SKYWALK */
1960 }
1961 IMO_UNLOCK(mopts);
1962 }
1963
1964 /* Copy the cached route and take an extra reference */
1965 inp_route_copyout(inp, &ro);
1966
1967 set_packet_service_class(m, so, sotc, 0);
1968 m->m_pkthdr.pkt_flowsrc = FLOWSRC_INPCB;
1969 m->m_pkthdr.pkt_flowid = inp->inp_flowhash;
1970 m->m_pkthdr.pkt_proto = IPPROTO_UDP;
1971 m->m_pkthdr.pkt_flags |= (PKTF_FLOW_ID | PKTF_FLOW_LOCALSRC);
1972 if (flowadv) {
1973 m->m_pkthdr.pkt_flags |= PKTF_FLOW_ADV;
1974 }
1975 m->m_pkthdr.tx_udp_pid = so->last_pid;
1976 if (so->so_flags & SOF_DELEGATED) {
1977 m->m_pkthdr.tx_udp_e_pid = so->e_pid;
1978 } else {
1979 m->m_pkthdr.tx_udp_e_pid = 0;
1980 }
1981 #if (DEBUG || DEVELOPMENT)
1982 if (so->so_flags & SOF_MARK_WAKE_PKT) {
1983 so->so_flags &= ~SOF_MARK_WAKE_PKT;
1984 m->m_pkthdr.pkt_flags |= PKTF_WAKE_PKT;
1985 }
1986 #endif /* (DEBUG || DEVELOPMENT) */
1987
1988 m_add_crumb(m, PKT_CRUMB_UDP_OUTPUT);
1989
1990 if (ipoa.ipoa_boundif != IFSCOPE_NONE) {
1991 ipoa.ipoa_flags |= IPOAF_BOUND_IF;
1992 }
1993
1994 if (laddr.s_addr != INADDR_ANY) {
1995 ipoa.ipoa_flags |= IPOAF_BOUND_SRCADDR;
1996 }
1997
1998 socket_unlock(so, 0);
1999 error = ip_output(m, inpopts, &ro, soopts, mopts, &ipoa);
2000 m = NULL;
2001 socket_lock(so, 0);
2002 if (mopts != NULL) {
2003 IMO_REMREF(mopts);
2004 }
2005
2006 if (check_qos_marking_again) {
2007 inp->inp_policyresult.results.qos_marking_gencount = ipoa.qos_marking_gencount;
2008
2009 if (ipoa.ipoa_flags & IPOAF_QOSMARKING_ALLOWED) {
2010 inp->inp_socket->so_flags1 |= SOF1_QOSMARKING_ALLOWED;
2011 } else {
2012 inp->inp_socket->so_flags1 &= ~SOF1_QOSMARKING_ALLOWED;
2013 }
2014 }
2015
2016 if (error == 0 && nstat_collect) {
2017 boolean_t cell, wifi, wired;
2018
2019 if (ro.ro_rt != NULL) {
2020 cell = IFNET_IS_CELLULAR(ro.ro_rt->rt_ifp);
2021 wifi = (!cell && IFNET_IS_WIFI(ro.ro_rt->rt_ifp));
2022 wired = (!wifi && IFNET_IS_WIRED(ro.ro_rt->rt_ifp));
2023 } else {
2024 cell = wifi = wired = FALSE;
2025 }
2026 INP_ADD_STAT(inp, cell, wifi, wired, txpackets, 1);
2027 INP_ADD_STAT(inp, cell, wifi, wired, txbytes, len);
2028 inp_set_activity_bitmap(inp);
2029 }
2030
2031 if (flowadv && (adv->code == FADV_FLOW_CONTROLLED ||
2032 adv->code == FADV_SUSPENDED)) {
2033 /*
2034 * return a hint to the application that
2035 * the packet has been dropped
2036 */
2037 error = ENOBUFS;
2038 inp_set_fc_state(inp, adv->code);
2039 }
2040
2041 /* Synchronize PCB cached route */
2042 inp_route_copyin(inp, &ro);
2043
2044 abort:
2045 if (udp_dodisconnect) {
2046 /* Always discard the cached route for unconnected socket */
2047 ROUTE_RELEASE(&inp->inp_route);
2048 in_pcbdisconnect(inp);
2049 inp->inp_laddr = origladdr; /* XXX rehash? */
2050 /* no reference needed */
2051 inp->inp_last_outifp = origoutifp;
2052 #if SKYWALK
2053 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
2054 netns_set_ifnet(&inp->inp_netns_token,
2055 inp->inp_last_outifp);
2056 }
2057 #endif /* SKYWALK */
2058 } else if (inp->inp_route.ro_rt != NULL) {
2059 struct rtentry *rt = inp->inp_route.ro_rt;
2060 struct ifnet *outifp;
2061
2062 if (rt->rt_flags & (RTF_MULTICAST | RTF_BROADCAST)) {
2063 rt = NULL; /* unusable */
2064 }
2065 #if CONTENT_FILTER
2066 /*
2067 * Discard temporary route for cfil case
2068 */
2069 if (cfil_faddr_use) {
2070 rt = NULL; /* unusable */
2071 }
2072 #endif
2073
2074 /*
2075 * Always discard if it is a multicast or broadcast route.
2076 */
2077 if (rt == NULL) {
2078 ROUTE_RELEASE(&inp->inp_route);
2079 }
2080
2081 /*
2082 * If the destination route is unicast, update outifp with
2083 * that of the route interface used by IP.
2084 */
2085 if (rt != NULL &&
2086 (outifp = rt->rt_ifp) != inp->inp_last_outifp) {
2087 inp->inp_last_outifp = outifp; /* no reference needed */
2088 #if SKYWALK
2089 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
2090 netns_set_ifnet(&inp->inp_netns_token,
2091 inp->inp_last_outifp);
2092 }
2093 #endif /* SKYWALK */
2094
2095 so->so_pktheadroom = (uint16_t)P2ROUNDUP(
2096 sizeof(struct udphdr) +
2097 sizeof(struct ip) +
2098 ifnet_hdrlen(outifp) +
2099 ifnet_mbuf_packetpreamblelen(outifp),
2100 sizeof(u_int32_t));
2101 }
2102 } else {
2103 ROUTE_RELEASE(&inp->inp_route);
2104 }
2105
2106 /*
2107 * If output interface was cellular/expensive, and this socket is
2108 * denied access to it, generate an event.
2109 */
2110 if (error != 0 && (ipoa.ipoa_flags & IPOAF_R_IFDENIED) &&
2111 (INP_NO_CELLULAR(inp) || INP_NO_EXPENSIVE(inp) || INP_NO_CONSTRAINED(inp))) {
2112 soevent(so, (SO_FILT_HINT_LOCKED | SO_FILT_HINT_IFDENIED));
2113 }
2114
2115 release:
2116 KERNEL_DEBUG(DBG_FNC_UDP_OUTPUT | DBG_FUNC_END, error, 0, 0, 0, 0);
2117
2118 if (m != NULL) {
2119 m_freem(m);
2120 }
2121
2122 if (outif != NULL) {
2123 ifnet_release(outif);
2124 }
2125
2126 #if CONTENT_FILTER
2127 if (cfil_tag) {
2128 m_tag_free(cfil_tag);
2129 }
2130 #endif
2131 if (sndinprog_cnt_used) {
2132 VERIFY(inp->inp_sndinprog_cnt > 0);
2133 if (--inp->inp_sndinprog_cnt == 0) {
2134 inp->inp_flags &= ~(INP_FC_FEEDBACK);
2135 if (inp->inp_sndingprog_waiters > 0) {
2136 wakeup(&inp->inp_sndinprog_cnt);
2137 }
2138 }
2139 sndinprog_cnt_used = false;
2140 }
2141
2142 return error;
2143 }
2144
2145 u_int32_t udp_sendspace = 9216; /* really max datagram size */
2146 /* 187 1K datagrams (approx 192 KB) */
2147 u_int32_t udp_recvspace = 187 * (1024 + sizeof(struct sockaddr_in6));
2148
2149 /* Check that the values of udp send and recv space do not exceed sb_max */
2150 static int
sysctl_udp_sospace(struct sysctl_oid * oidp,void * arg1,int arg2,struct sysctl_req * req)2151 sysctl_udp_sospace(struct sysctl_oid *oidp, void *arg1, int arg2,
2152 struct sysctl_req *req)
2153 {
2154 #pragma unused(arg1, arg2)
2155 u_int32_t new_value = 0, *space_p = NULL;
2156 int changed = 0, error = 0;
2157 u_quad_t sb_effective_max = (sb_max / (MSIZE + MCLBYTES)) * MCLBYTES;
2158
2159 switch (oidp->oid_number) {
2160 case UDPCTL_RECVSPACE:
2161 space_p = &udp_recvspace;
2162 break;
2163 case UDPCTL_MAXDGRAM:
2164 space_p = &udp_sendspace;
2165 break;
2166 default:
2167 return EINVAL;
2168 }
2169 error = sysctl_io_number(req, *space_p, sizeof(u_int32_t),
2170 &new_value, &changed);
2171 if (changed) {
2172 if (new_value > 0 && new_value <= sb_effective_max) {
2173 *space_p = new_value;
2174 } else {
2175 error = ERANGE;
2176 }
2177 }
2178 return error;
2179 }
2180
2181 SYSCTL_PROC(_net_inet_udp, UDPCTL_RECVSPACE, recvspace,
2182 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, &udp_recvspace, 0,
2183 &sysctl_udp_sospace, "IU", "Maximum incoming UDP datagram size");
2184
2185 SYSCTL_PROC(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram,
2186 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, &udp_sendspace, 0,
2187 &sysctl_udp_sospace, "IU", "Maximum outgoing UDP datagram size");
2188
2189 int
udp_abort(struct socket * so)2190 udp_abort(struct socket *so)
2191 {
2192 struct inpcb *inp;
2193
2194 inp = sotoinpcb(so);
2195 if (inp == NULL) {
2196 panic("%s: so=%p null inp", __func__, so);
2197 /* NOTREACHED */
2198 }
2199 soisdisconnected(so);
2200 in_pcbdetach(inp);
2201 return 0;
2202 }
2203
2204 int
udp_attach(struct socket * so,int proto,struct proc * p)2205 udp_attach(struct socket *so, int proto, struct proc *p)
2206 {
2207 #pragma unused(proto)
2208 struct inpcb *inp;
2209 int error;
2210
2211 error = soreserve(so, udp_sendspace, udp_recvspace);
2212 if (error != 0) {
2213 return error;
2214 }
2215 inp = sotoinpcb(so);
2216 if (inp != NULL) {
2217 panic("%s so=%p inp=%p", __func__, so, inp);
2218 /* NOTREACHED */
2219 }
2220 error = in_pcballoc(so, &udbinfo, p);
2221 if (error != 0) {
2222 return error;
2223 }
2224 inp = (struct inpcb *)so->so_pcb;
2225 inp->inp_vflag |= INP_IPV4;
2226 inp->inp_ip_ttl = (uint8_t)ip_defttl;
2227 if (nstat_collect) {
2228 nstat_udp_new_pcb(inp);
2229 }
2230 return 0;
2231 }
2232
2233 int
udp_bind(struct socket * so,struct sockaddr * nam,struct proc * p)2234 udp_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
2235 {
2236 struct inpcb *inp;
2237 int error;
2238
2239 if (nam->sa_family != 0 && nam->sa_family != AF_INET &&
2240 nam->sa_family != AF_INET6) {
2241 return EAFNOSUPPORT;
2242 }
2243
2244 inp = sotoinpcb(so);
2245 if (inp == NULL) {
2246 return EINVAL;
2247 }
2248 error = in_pcbbind(inp, nam, p);
2249
2250 #if NECP
2251 /* Update NECP client with bind result if not in middle of connect */
2252 if (error == 0 &&
2253 (inp->inp_flags2 & INP2_CONNECT_IN_PROGRESS) &&
2254 !uuid_is_null(inp->necp_client_uuid)) {
2255 socket_unlock(so, 0);
2256 necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
2257 socket_lock(so, 0);
2258 }
2259 #endif /* NECP */
2260
2261 return error;
2262 }
2263
2264 int
udp_connect(struct socket * so,struct sockaddr * nam,struct proc * p)2265 udp_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
2266 {
2267 struct inpcb *inp;
2268 int error;
2269
2270 inp = sotoinpcb(so);
2271 if (inp == NULL) {
2272 return EINVAL;
2273 }
2274 if (inp->inp_faddr.s_addr != INADDR_ANY) {
2275 return EISCONN;
2276 }
2277
2278 if (!(so->so_flags1 & SOF1_CONNECT_COUNTED)) {
2279 so->so_flags1 |= SOF1_CONNECT_COUNTED;
2280 INC_ATOMIC_INT64_LIM(net_api_stats.nas_socket_inet_dgram_connected);
2281 }
2282
2283 #if NECP
2284 #if FLOW_DIVERT
2285 if (necp_socket_should_use_flow_divert(inp)) {
2286 error = flow_divert_pcb_init(so);
2287 if (error == 0) {
2288 error = flow_divert_connect_out(so, nam, p);
2289 }
2290 return error;
2291 }
2292 #endif /* FLOW_DIVERT */
2293 #endif /* NECP */
2294
2295 error = in_pcbconnect(inp, nam, p, IFSCOPE_NONE, NULL);
2296 if (error == 0) {
2297 #if NECP
2298 /* Update NECP client with connected five-tuple */
2299 if (!uuid_is_null(inp->necp_client_uuid)) {
2300 socket_unlock(so, 0);
2301 necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
2302 socket_lock(so, 0);
2303 }
2304 #endif /* NECP */
2305
2306 soisconnected(so);
2307 if (inp->inp_flowhash == 0) {
2308 inp_calc_flowhash(inp);
2309 ASSERT(inp->inp_flowhash != 0);
2310 }
2311 }
2312 return error;
2313 }
2314
2315 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)2316 udp_connectx_common(struct socket *so, int af, struct sockaddr *src, struct sockaddr *dst,
2317 struct proc *p, uint32_t ifscope, sae_associd_t aid, sae_connid_t *pcid,
2318 uint32_t flags, void *arg, uint32_t arglen,
2319 struct uio *uio, user_ssize_t *bytes_written)
2320 {
2321 #pragma unused(aid, flags, arg, arglen)
2322 struct inpcb *inp = sotoinpcb(so);
2323 int error = 0;
2324 user_ssize_t datalen = 0;
2325
2326 if (inp == NULL) {
2327 return EINVAL;
2328 }
2329
2330 VERIFY(dst != NULL);
2331
2332 ASSERT(!(inp->inp_flags2 & INP2_CONNECT_IN_PROGRESS));
2333 inp->inp_flags2 |= INP2_CONNECT_IN_PROGRESS;
2334
2335 #if NECP
2336 inp_update_necp_policy(inp, src, dst, ifscope);
2337 #endif /* NECP */
2338
2339 /* bind socket to the specified interface, if requested */
2340 if (ifscope != IFSCOPE_NONE &&
2341 (error = inp_bindif(inp, ifscope, NULL)) != 0) {
2342 goto done;
2343 }
2344
2345 /* if source address and/or port is specified, bind to it */
2346 if (src != NULL) {
2347 error = sobindlock(so, src, 0); /* already locked */
2348 if (error != 0) {
2349 goto done;
2350 }
2351 }
2352
2353 switch (af) {
2354 case AF_INET:
2355 error = udp_connect(so, dst, p);
2356 break;
2357 case AF_INET6:
2358 error = udp6_connect(so, dst, p);
2359 break;
2360 default:
2361 VERIFY(0);
2362 /* NOTREACHED */
2363 }
2364
2365 if (error != 0) {
2366 goto done;
2367 }
2368
2369 /*
2370 * If there is data, copy it. DATA_IDEMPOTENT is ignored.
2371 * CONNECT_RESUME_ON_READ_WRITE is ignored.
2372 */
2373 if (uio != NULL) {
2374 socket_unlock(so, 0);
2375
2376 VERIFY(bytes_written != NULL);
2377
2378 datalen = uio_resid(uio);
2379 error = so->so_proto->pr_usrreqs->pru_sosend(so, NULL,
2380 (uio_t)uio, NULL, NULL, 0);
2381 socket_lock(so, 0);
2382
2383 /* If error returned is EMSGSIZE, for example, disconnect */
2384 if (error == 0 || error == EWOULDBLOCK) {
2385 *bytes_written = datalen - uio_resid(uio);
2386 } else {
2387 (void) so->so_proto->pr_usrreqs->pru_disconnectx(so,
2388 SAE_ASSOCID_ANY, SAE_CONNID_ANY);
2389 }
2390 /*
2391 * mask the EWOULDBLOCK error so that the caller
2392 * knows that atleast the connect was successful.
2393 */
2394 if (error == EWOULDBLOCK) {
2395 error = 0;
2396 }
2397 }
2398
2399 if (error == 0 && pcid != NULL) {
2400 *pcid = 1; /* there is only 1 connection for UDP */
2401 }
2402 done:
2403 inp->inp_flags2 &= ~INP2_CONNECT_IN_PROGRESS;
2404 return error;
2405 }
2406
2407 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)2408 udp_connectx(struct socket *so, struct sockaddr *src,
2409 struct sockaddr *dst, struct proc *p, uint32_t ifscope,
2410 sae_associd_t aid, sae_connid_t *pcid, uint32_t flags, void *arg,
2411 uint32_t arglen, struct uio *uio, user_ssize_t *bytes_written)
2412 {
2413 return udp_connectx_common(so, AF_INET, src, dst,
2414 p, ifscope, aid, pcid, flags, arg, arglen, uio, bytes_written);
2415 }
2416
2417 int
udp_detach(struct socket * so)2418 udp_detach(struct socket *so)
2419 {
2420 struct inpcb *inp;
2421
2422 inp = sotoinpcb(so);
2423 if (inp == NULL) {
2424 panic("%s: so=%p null inp", __func__, so);
2425 /* NOTREACHED */
2426 }
2427
2428 /*
2429 * If this is a socket that does not want to wakeup the device
2430 * for it's traffic, the application might be waiting for
2431 * close to complete before going to sleep. Send a notification
2432 * for this kind of sockets
2433 */
2434 if (so->so_options & SO_NOWAKEFROMSLEEP) {
2435 socket_post_kev_msg_closed(so);
2436 }
2437
2438 in_pcbdetach(inp);
2439 inp->inp_state = INPCB_STATE_DEAD;
2440 return 0;
2441 }
2442
2443 int
udp_disconnect(struct socket * so)2444 udp_disconnect(struct socket *so)
2445 {
2446 struct inpcb *inp;
2447
2448 inp = sotoinpcb(so);
2449 if (inp == NULL) {
2450 return EINVAL;
2451 }
2452 if (inp->inp_faddr.s_addr == INADDR_ANY) {
2453 return ENOTCONN;
2454 }
2455
2456 in_pcbdisconnect(inp);
2457
2458 /* reset flow controlled state, just in case */
2459 inp_reset_fc_state(inp);
2460
2461 inp->inp_laddr.s_addr = INADDR_ANY;
2462 so->so_state &= ~SS_ISCONNECTED; /* XXX */
2463 inp->inp_last_outifp = NULL;
2464 #if SKYWALK
2465 if (NETNS_TOKEN_VALID(&inp->inp_netns_token)) {
2466 netns_set_ifnet(&inp->inp_netns_token, NULL);
2467 }
2468 #endif /* SKYWALK */
2469
2470 return 0;
2471 }
2472
2473 int
udp_disconnectx(struct socket * so,sae_associd_t aid,sae_connid_t cid)2474 udp_disconnectx(struct socket *so, sae_associd_t aid, sae_connid_t cid)
2475 {
2476 #pragma unused(cid)
2477 if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL) {
2478 return EINVAL;
2479 }
2480
2481 return udp_disconnect(so);
2482 }
2483
2484 int
udp_send(struct socket * so,int flags,struct mbuf * m,struct sockaddr * addr,struct mbuf * control,struct proc * p)2485 udp_send(struct socket *so, int flags, struct mbuf *m,
2486 struct sockaddr *addr, struct mbuf *control, struct proc *p)
2487 {
2488 #ifndef FLOW_DIVERT
2489 #pragma unused(flags)
2490 #endif /* !(FLOW_DIVERT) */
2491 struct inpcb *inp;
2492 int error;
2493
2494 inp = sotoinpcb(so);
2495 if (inp == NULL) {
2496 if (m != NULL) {
2497 m_freem(m);
2498 }
2499 if (control != NULL) {
2500 m_freem(control);
2501 }
2502 return EINVAL;
2503 }
2504
2505 #if NECP
2506 #if FLOW_DIVERT
2507 if (necp_socket_should_use_flow_divert(inp)) {
2508 /* Implicit connect */
2509 return flow_divert_implicit_data_out(so, flags, m, addr,
2510 control, p);
2511 }
2512 #endif /* FLOW_DIVERT */
2513 #endif /* NECP */
2514
2515 #if SKYWALK
2516 sk_protect_t protect = sk_async_transmit_protect();
2517 #endif /* SKYWALK */
2518 error = udp_output(inp, m, addr, control, p);
2519 #if SKYWALK
2520 sk_async_transmit_unprotect(protect);
2521 #endif /* SKYWALK */
2522
2523 return error;
2524 }
2525
2526 int
udp_shutdown(struct socket * so)2527 udp_shutdown(struct socket *so)
2528 {
2529 struct inpcb *inp;
2530
2531 inp = sotoinpcb(so);
2532 if (inp == NULL) {
2533 return EINVAL;
2534 }
2535 socantsendmore(so);
2536 return 0;
2537 }
2538
2539 int
udp_lock(struct socket * so,int refcount,void * debug)2540 udp_lock(struct socket *so, int refcount, void *debug)
2541 {
2542 void *lr_saved;
2543
2544 if (debug == NULL) {
2545 lr_saved = __builtin_return_address(0);
2546 } else {
2547 lr_saved = debug;
2548 }
2549
2550 if (so->so_pcb != NULL) {
2551 LCK_MTX_ASSERT(&((struct inpcb *)so->so_pcb)->inpcb_mtx,
2552 LCK_MTX_ASSERT_NOTOWNED);
2553 lck_mtx_lock(&((struct inpcb *)so->so_pcb)->inpcb_mtx);
2554 } else {
2555 panic("%s: so=%p NO PCB! lr=%p lrh= %s", __func__,
2556 so, lr_saved, solockhistory_nr(so));
2557 /* NOTREACHED */
2558 }
2559 if (refcount) {
2560 so->so_usecount++;
2561 }
2562
2563 so->lock_lr[so->next_lock_lr] = lr_saved;
2564 so->next_lock_lr = (so->next_lock_lr + 1) % SO_LCKDBG_MAX;
2565 return 0;
2566 }
2567
2568 int
udp_unlock(struct socket * so,int refcount,void * debug)2569 udp_unlock(struct socket *so, int refcount, void *debug)
2570 {
2571 void *lr_saved;
2572
2573 if (debug == NULL) {
2574 lr_saved = __builtin_return_address(0);
2575 } else {
2576 lr_saved = debug;
2577 }
2578
2579 if (refcount) {
2580 VERIFY(so->so_usecount > 0);
2581 so->so_usecount--;
2582 }
2583 if (so->so_pcb == NULL) {
2584 panic("%s: so=%p NO PCB! lr=%p lrh= %s", __func__,
2585 so, lr_saved, solockhistory_nr(so));
2586 /* NOTREACHED */
2587 } else {
2588 LCK_MTX_ASSERT(&((struct inpcb *)so->so_pcb)->inpcb_mtx,
2589 LCK_MTX_ASSERT_OWNED);
2590 so->unlock_lr[so->next_unlock_lr] = lr_saved;
2591 so->next_unlock_lr = (so->next_unlock_lr + 1) % SO_LCKDBG_MAX;
2592 lck_mtx_unlock(&((struct inpcb *)so->so_pcb)->inpcb_mtx);
2593 }
2594 return 0;
2595 }
2596
2597 lck_mtx_t *
udp_getlock(struct socket * so,int flags)2598 udp_getlock(struct socket *so, int flags)
2599 {
2600 #pragma unused(flags)
2601 struct inpcb *inp = sotoinpcb(so);
2602
2603 if (so->so_pcb == NULL) {
2604 panic("%s: so=%p NULL so_pcb lrh= %s", __func__,
2605 so, solockhistory_nr(so));
2606 /* NOTREACHED */
2607 }
2608 return &inp->inpcb_mtx;
2609 }
2610
2611 /*
2612 * UDP garbage collector callback (inpcb_timer_func_t).
2613 *
2614 * Returns > 0 to keep timer active.
2615 */
2616 static void
udp_gc(struct inpcbinfo * ipi)2617 udp_gc(struct inpcbinfo *ipi)
2618 {
2619 struct inpcb *inp, *inpnxt;
2620 struct socket *so;
2621
2622 if (lck_rw_try_lock_exclusive(&ipi->ipi_lock) == FALSE) {
2623 if (udp_gc_done == TRUE) {
2624 udp_gc_done = FALSE;
2625 /* couldn't get the lock, must lock next time */
2626 atomic_add_32(&ipi->ipi_gc_req.intimer_fast, 1);
2627 return;
2628 }
2629 lck_rw_lock_exclusive(&ipi->ipi_lock);
2630 }
2631
2632 udp_gc_done = TRUE;
2633
2634 for (inp = udb.lh_first; inp != NULL; inp = inpnxt) {
2635 inpnxt = inp->inp_list.le_next;
2636
2637 /*
2638 * Skip unless it's STOPUSING; garbage collector will
2639 * be triggered by in_pcb_checkstate() upon setting
2640 * wantcnt to that value. If the PCB is already dead,
2641 * keep gc active to anticipate wantcnt changing.
2642 */
2643 if (inp->inp_wantcnt != WNT_STOPUSING) {
2644 continue;
2645 }
2646
2647 /*
2648 * Skip if busy, no hurry for cleanup. Keep gc active
2649 * and try the lock again during next round.
2650 */
2651 if (!socket_try_lock(inp->inp_socket)) {
2652 atomic_add_32(&ipi->ipi_gc_req.intimer_fast, 1);
2653 continue;
2654 }
2655
2656 /*
2657 * Keep gc active unless usecount is 0.
2658 */
2659 so = inp->inp_socket;
2660 if (so->so_usecount == 0) {
2661 if (inp->inp_state != INPCB_STATE_DEAD) {
2662 if (SOCK_CHECK_DOM(so, PF_INET6)) {
2663 in6_pcbdetach(inp);
2664 } else {
2665 in_pcbdetach(inp);
2666 }
2667 }
2668 in_pcbdispose(inp);
2669 } else {
2670 socket_unlock(so, 0);
2671 atomic_add_32(&ipi->ipi_gc_req.intimer_fast, 1);
2672 }
2673 }
2674 lck_rw_done(&ipi->ipi_lock);
2675 }
2676
2677 static int
2678 udp_getstat SYSCTL_HANDLER_ARGS
2679 {
2680 #pragma unused(oidp, arg1, arg2)
2681 if (req->oldptr == USER_ADDR_NULL) {
2682 req->oldlen = (size_t)sizeof(struct udpstat);
2683 }
2684
2685 return SYSCTL_OUT(req, &udpstat, MIN(sizeof(udpstat), req->oldlen));
2686 }
2687
2688 void
udp_in_cksum_stats(u_int32_t len)2689 udp_in_cksum_stats(u_int32_t len)
2690 {
2691 udpstat.udps_rcv_swcsum++;
2692 udpstat.udps_rcv_swcsum_bytes += len;
2693 }
2694
2695 void
udp_out_cksum_stats(u_int32_t len)2696 udp_out_cksum_stats(u_int32_t len)
2697 {
2698 udpstat.udps_snd_swcsum++;
2699 udpstat.udps_snd_swcsum_bytes += len;
2700 }
2701
2702 void
udp_in6_cksum_stats(u_int32_t len)2703 udp_in6_cksum_stats(u_int32_t len)
2704 {
2705 udpstat.udps_rcv6_swcsum++;
2706 udpstat.udps_rcv6_swcsum_bytes += len;
2707 }
2708
2709 void
udp_out6_cksum_stats(u_int32_t len)2710 udp_out6_cksum_stats(u_int32_t len)
2711 {
2712 udpstat.udps_snd6_swcsum++;
2713 udpstat.udps_snd6_swcsum_bytes += len;
2714 }
2715
2716 /*
2717 * Checksum extended UDP header and data.
2718 */
2719 static int
udp_input_checksum(struct mbuf * m,struct udphdr * uh,int off,int ulen)2720 udp_input_checksum(struct mbuf *m, struct udphdr *uh, int off, int ulen)
2721 {
2722 struct ifnet *ifp = m->m_pkthdr.rcvif;
2723 struct ip *ip = mtod(m, struct ip *);
2724 struct ipovly *ipov = (struct ipovly *)ip;
2725
2726 if (uh->uh_sum == 0) {
2727 udpstat.udps_nosum++;
2728 return 0;
2729 }
2730
2731 /* ip_stripoptions() must have been called before we get here */
2732 ASSERT((ip->ip_hl << 2) == sizeof(*ip));
2733
2734 if ((hwcksum_rx || (ifp->if_flags & IFF_LOOPBACK) ||
2735 (m->m_pkthdr.pkt_flags & PKTF_LOOP)) &&
2736 (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)) {
2737 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
2738 uh->uh_sum = m->m_pkthdr.csum_rx_val;
2739 } else {
2740 uint32_t sum = m->m_pkthdr.csum_rx_val;
2741 uint32_t start = m->m_pkthdr.csum_rx_start;
2742 int32_t trailer = (m_pktlen(m) - (off + ulen));
2743
2744 /*
2745 * Perform 1's complement adjustment of octets
2746 * that got included/excluded in the hardware-
2747 * calculated checksum value. Ignore cases
2748 * where the value already includes the entire
2749 * IP header span, as the sum for those octets
2750 * would already be 0 by the time we get here;
2751 * IP has already performed its header checksum
2752 * checks. If we do need to adjust, restore
2753 * the original fields in the IP header when
2754 * computing the adjustment value. Also take
2755 * care of any trailing bytes and subtract out
2756 * their partial sum.
2757 */
2758 ASSERT(trailer >= 0);
2759 if ((m->m_pkthdr.csum_flags & CSUM_PARTIAL) &&
2760 ((start != 0 && start != off) || trailer != 0)) {
2761 uint32_t swbytes = (uint32_t)trailer;
2762
2763 if (start < off) {
2764 ip->ip_len += sizeof(*ip);
2765 #if BYTE_ORDER != BIG_ENDIAN
2766 HTONS(ip->ip_len);
2767 HTONS(ip->ip_off);
2768 #endif /* BYTE_ORDER != BIG_ENDIAN */
2769 }
2770 /* callee folds in sum */
2771 sum = m_adj_sum16(m, start, off, ulen, sum);
2772 if (off > start) {
2773 swbytes += (off - start);
2774 } else {
2775 swbytes += (start - off);
2776 }
2777
2778 if (start < off) {
2779 #if BYTE_ORDER != BIG_ENDIAN
2780 NTOHS(ip->ip_off);
2781 NTOHS(ip->ip_len);
2782 #endif /* BYTE_ORDER != BIG_ENDIAN */
2783 ip->ip_len -= sizeof(*ip);
2784 }
2785
2786 if (swbytes != 0) {
2787 udp_in_cksum_stats(swbytes);
2788 }
2789 if (trailer != 0) {
2790 m_adj(m, -trailer);
2791 }
2792 }
2793
2794 /* callee folds in sum */
2795 uh->uh_sum = in_pseudo(ip->ip_src.s_addr,
2796 ip->ip_dst.s_addr, sum + htonl(ulen + IPPROTO_UDP));
2797 }
2798 uh->uh_sum ^= 0xffff;
2799 } else {
2800 uint16_t ip_sum;
2801 char b[9];
2802
2803 bcopy(ipov->ih_x1, b, sizeof(ipov->ih_x1));
2804 bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
2805 ip_sum = ipov->ih_len;
2806 ipov->ih_len = uh->uh_ulen;
2807 uh->uh_sum = in_cksum(m, ulen + sizeof(struct ip));
2808 bcopy(b, ipov->ih_x1, sizeof(ipov->ih_x1));
2809 ipov->ih_len = ip_sum;
2810
2811 udp_in_cksum_stats(ulen);
2812 }
2813
2814 if (uh->uh_sum != 0) {
2815 udpstat.udps_badsum++;
2816 IF_UDP_STATINC(ifp, badchksum);
2817 return -1;
2818 }
2819
2820 return 0;
2821 }
2822
2823 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)2824 udp_fill_keepalive_offload_frames(ifnet_t ifp,
2825 struct ifnet_keepalive_offload_frame *frames_array,
2826 u_int32_t frames_array_count, size_t frame_data_offset,
2827 u_int32_t *used_frames_count)
2828 {
2829 struct inpcb *inp;
2830 inp_gen_t gencnt;
2831 u_int32_t frame_index = *used_frames_count;
2832
2833 if (ifp == NULL || frames_array == NULL ||
2834 frames_array_count == 0 ||
2835 frame_index >= frames_array_count ||
2836 frame_data_offset >= IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE) {
2837 return;
2838 }
2839
2840 lck_rw_lock_shared(&udbinfo.ipi_lock);
2841 gencnt = udbinfo.ipi_gencnt;
2842 LIST_FOREACH(inp, udbinfo.ipi_listhead, inp_list) {
2843 struct socket *so;
2844 u_int8_t *data;
2845 struct ifnet_keepalive_offload_frame *frame;
2846 struct mbuf *m = NULL;
2847
2848 if (frame_index >= frames_array_count) {
2849 break;
2850 }
2851
2852 if (inp->inp_gencnt > gencnt ||
2853 inp->inp_state == INPCB_STATE_DEAD) {
2854 continue;
2855 }
2856
2857 if ((so = inp->inp_socket) == NULL ||
2858 (so->so_state & SS_DEFUNCT)) {
2859 continue;
2860 }
2861 /*
2862 * check for keepalive offload flag without socket
2863 * lock to avoid a deadlock
2864 */
2865 if (!(inp->inp_flags2 & INP2_KEEPALIVE_OFFLOAD)) {
2866 continue;
2867 }
2868
2869 udp_lock(so, 1, 0);
2870 if (!(inp->inp_vflag & (INP_IPV4 | INP_IPV6))) {
2871 udp_unlock(so, 1, 0);
2872 continue;
2873 }
2874 if ((inp->inp_vflag & INP_IPV4) &&
2875 (inp->inp_laddr.s_addr == INADDR_ANY ||
2876 inp->inp_faddr.s_addr == INADDR_ANY)) {
2877 udp_unlock(so, 1, 0);
2878 continue;
2879 }
2880 if ((inp->inp_vflag & INP_IPV6) &&
2881 (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) ||
2882 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))) {
2883 udp_unlock(so, 1, 0);
2884 continue;
2885 }
2886 if (inp->inp_lport == 0 || inp->inp_fport == 0) {
2887 udp_unlock(so, 1, 0);
2888 continue;
2889 }
2890 if (inp->inp_last_outifp == NULL ||
2891 inp->inp_last_outifp->if_index != ifp->if_index) {
2892 udp_unlock(so, 1, 0);
2893 continue;
2894 }
2895 if ((inp->inp_vflag & INP_IPV4)) {
2896 if ((frame_data_offset + sizeof(struct udpiphdr) +
2897 inp->inp_keepalive_datalen) >
2898 IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE) {
2899 udp_unlock(so, 1, 0);
2900 continue;
2901 }
2902 if ((sizeof(struct udpiphdr) +
2903 inp->inp_keepalive_datalen) > _MHLEN) {
2904 udp_unlock(so, 1, 0);
2905 continue;
2906 }
2907 } else {
2908 if ((frame_data_offset + sizeof(struct ip6_hdr) +
2909 sizeof(struct udphdr) +
2910 inp->inp_keepalive_datalen) >
2911 IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE) {
2912 udp_unlock(so, 1, 0);
2913 continue;
2914 }
2915 if ((sizeof(struct ip6_hdr) + sizeof(struct udphdr) +
2916 inp->inp_keepalive_datalen) > _MHLEN) {
2917 udp_unlock(so, 1, 0);
2918 continue;
2919 }
2920 }
2921 MGETHDR(m, M_WAIT, MT_HEADER);
2922 if (m == NULL) {
2923 udp_unlock(so, 1, 0);
2924 continue;
2925 }
2926 /*
2927 * This inp has all the information that is needed to
2928 * generate an offload frame.
2929 */
2930 if (inp->inp_vflag & INP_IPV4) {
2931 struct ip *ip;
2932 struct udphdr *udp;
2933
2934 frame = &frames_array[frame_index];
2935 frame->length = (uint8_t)(frame_data_offset +
2936 sizeof(struct udpiphdr) +
2937 inp->inp_keepalive_datalen);
2938 frame->ether_type =
2939 IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV4;
2940 frame->interval = inp->inp_keepalive_interval;
2941 switch (inp->inp_keepalive_type) {
2942 case UDP_KEEPALIVE_OFFLOAD_TYPE_AIRPLAY:
2943 frame->type =
2944 IFNET_KEEPALIVE_OFFLOAD_FRAME_AIRPLAY;
2945 break;
2946 default:
2947 break;
2948 }
2949 data = mtod(m, u_int8_t *);
2950 bzero(data, sizeof(struct udpiphdr));
2951 ip = (__typeof__(ip))(void *)data;
2952 udp = (__typeof__(udp))(void *) (data +
2953 sizeof(struct ip));
2954 m->m_len = sizeof(struct udpiphdr);
2955 data = data + sizeof(struct udpiphdr);
2956 if (inp->inp_keepalive_datalen > 0 &&
2957 inp->inp_keepalive_data != NULL) {
2958 bcopy(inp->inp_keepalive_data, data,
2959 inp->inp_keepalive_datalen);
2960 m->m_len += inp->inp_keepalive_datalen;
2961 }
2962 m->m_pkthdr.len = m->m_len;
2963
2964 ip->ip_v = IPVERSION;
2965 ip->ip_hl = (sizeof(struct ip) >> 2);
2966 ip->ip_p = IPPROTO_UDP;
2967 ip->ip_len = htons(sizeof(struct udpiphdr) +
2968 (u_short)inp->inp_keepalive_datalen);
2969 ip->ip_ttl = inp->inp_ip_ttl;
2970 ip->ip_tos |= (inp->inp_ip_tos & ~IPTOS_ECN_MASK);
2971 ip->ip_src = inp->inp_laddr;
2972 ip->ip_dst = inp->inp_faddr;
2973 ip->ip_sum = in_cksum_hdr_opt(ip);
2974
2975 udp->uh_sport = inp->inp_lport;
2976 udp->uh_dport = inp->inp_fport;
2977 udp->uh_ulen = htons(sizeof(struct udphdr) +
2978 (u_short)inp->inp_keepalive_datalen);
2979
2980 if (!(inp->inp_flags & INP_UDP_NOCKSUM)) {
2981 udp->uh_sum = in_pseudo(ip->ip_src.s_addr,
2982 ip->ip_dst.s_addr,
2983 htons(sizeof(struct udphdr) +
2984 (u_short)inp->inp_keepalive_datalen +
2985 IPPROTO_UDP));
2986 m->m_pkthdr.csum_flags =
2987 (CSUM_UDP | CSUM_ZERO_INVERT);
2988 m->m_pkthdr.csum_data = offsetof(struct udphdr,
2989 uh_sum);
2990 }
2991 m->m_pkthdr.pkt_proto = IPPROTO_UDP;
2992 in_delayed_cksum(m);
2993 bcopy(m->m_data, frame->data + frame_data_offset,
2994 m->m_len);
2995 } else {
2996 struct ip6_hdr *ip6;
2997 struct udphdr *udp6;
2998
2999 VERIFY(inp->inp_vflag & INP_IPV6);
3000 frame = &frames_array[frame_index];
3001 frame->length = (uint8_t)(frame_data_offset +
3002 sizeof(struct ip6_hdr) +
3003 sizeof(struct udphdr) +
3004 inp->inp_keepalive_datalen);
3005 frame->ether_type =
3006 IFNET_KEEPALIVE_OFFLOAD_FRAME_ETHERTYPE_IPV6;
3007 frame->interval = inp->inp_keepalive_interval;
3008 switch (inp->inp_keepalive_type) {
3009 case UDP_KEEPALIVE_OFFLOAD_TYPE_AIRPLAY:
3010 frame->type =
3011 IFNET_KEEPALIVE_OFFLOAD_FRAME_AIRPLAY;
3012 break;
3013 default:
3014 break;
3015 }
3016 data = mtod(m, u_int8_t *);
3017 bzero(data, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
3018 ip6 = (__typeof__(ip6))(void *)data;
3019 udp6 = (__typeof__(udp6))(void *)(data +
3020 sizeof(struct ip6_hdr));
3021 m->m_len = sizeof(struct ip6_hdr) +
3022 sizeof(struct udphdr);
3023 data = data + (sizeof(struct ip6_hdr) +
3024 sizeof(struct udphdr));
3025 if (inp->inp_keepalive_datalen > 0 &&
3026 inp->inp_keepalive_data != NULL) {
3027 bcopy(inp->inp_keepalive_data, data,
3028 inp->inp_keepalive_datalen);
3029 m->m_len += inp->inp_keepalive_datalen;
3030 }
3031 m->m_pkthdr.len = m->m_len;
3032 ip6->ip6_flow = inp->inp_flow & IPV6_FLOWINFO_MASK;
3033 ip6->ip6_flow = ip6->ip6_flow & ~IPV6_FLOW_ECN_MASK;
3034 ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
3035 ip6->ip6_vfc |= IPV6_VERSION;
3036 ip6->ip6_nxt = IPPROTO_UDP;
3037 ip6->ip6_hlim = (uint8_t)ip6_defhlim;
3038 ip6->ip6_plen = htons(sizeof(struct udphdr) +
3039 (u_short)inp->inp_keepalive_datalen);
3040 ip6->ip6_src = inp->in6p_laddr;
3041 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
3042 ip6->ip6_src.s6_addr16[1] = 0;
3043 }
3044
3045 ip6->ip6_dst = inp->in6p_faddr;
3046 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
3047 ip6->ip6_dst.s6_addr16[1] = 0;
3048 }
3049
3050 udp6->uh_sport = inp->in6p_lport;
3051 udp6->uh_dport = inp->in6p_fport;
3052 udp6->uh_ulen = htons(sizeof(struct udphdr) +
3053 (u_short)inp->inp_keepalive_datalen);
3054 if (!(inp->inp_flags & INP_UDP_NOCKSUM)) {
3055 udp6->uh_sum = in6_pseudo(&ip6->ip6_src,
3056 &ip6->ip6_dst,
3057 htonl(sizeof(struct udphdr) +
3058 (u_short)inp->inp_keepalive_datalen +
3059 IPPROTO_UDP));
3060 m->m_pkthdr.csum_flags =
3061 (CSUM_UDPIPV6 | CSUM_ZERO_INVERT);
3062 m->m_pkthdr.csum_data = offsetof(struct udphdr,
3063 uh_sum);
3064 }
3065 m->m_pkthdr.pkt_proto = IPPROTO_UDP;
3066 in6_delayed_cksum(m);
3067 bcopy(m->m_data, frame->data + frame_data_offset,
3068 m->m_len);
3069 }
3070 if (m != NULL) {
3071 m_freem(m);
3072 m = NULL;
3073 }
3074 frame_index++;
3075 udp_unlock(so, 1, 0);
3076 }
3077 lck_rw_done(&udbinfo.ipi_lock);
3078 *used_frames_count = frame_index;
3079 }
3080
3081 int
udp_defunct(struct socket * so)3082 udp_defunct(struct socket *so)
3083 {
3084 struct ip_moptions *imo;
3085 struct inpcb *inp;
3086
3087 inp = sotoinpcb(so);
3088 if (inp == NULL) {
3089 return EINVAL;
3090 }
3091
3092 imo = inp->inp_moptions;
3093 if (imo != NULL) {
3094 struct proc *p = current_proc();
3095
3096 SODEFUNCTLOG("%s[%d, %s]: defuncting so 0x%llu drop multicast memberships",
3097 __func__, proc_pid(p), proc_best_name(p),
3098 so->so_gencnt);
3099
3100 inp->inp_moptions = NULL;
3101
3102 IMO_REMREF(imo);
3103 }
3104
3105 return 0;
3106 }
3107