1 /*
2 * Copyright (c) 2010-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, 1990, 1993
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
61 #include <sys/types.h>
62 #include <sys/malloc.h>
63 #include <sys/socket.h>
64 #include <sys/socketvar.h>
65 #include <sys/protosw.h>
66 #include <sys/domain.h>
67 #include <sys/filedesc.h>
68 #include <sys/file_internal.h>
69 #include <sys/kernel.h>
70 #include <sys/sysctl.h>
71 #include <sys/dtrace.h>
72 #include <sys/kauth.h>
73
74 #include <net/route.h>
75 #include <net/if_var.h>
76 #include <net/if_ports_used.h>
77 #include <net/ntstat.h>
78
79 #include <netinet/in.h>
80 #include <netinet/in_pcb.h>
81 #include <netinet/in_var.h>
82 #include <netinet/ip_var.h>
83
84 #include <netinet/udp.h>
85 #include <netinet/udp_var.h>
86
87 #include <netinet/tcp.h>
88 #include <netinet/tcp_fsm.h>
89 #include <netinet/tcp_seq.h>
90 #include <netinet/tcp_timer.h>
91 #include <netinet/tcp_var.h>
92 #include <netinet6/in6_var.h>
93
94 #include <os/log.h>
95
96 #ifndef ROUNDUP64
97 #define ROUNDUP64(x) P2ROUNDUP((x), sizeof (u_int64_t))
98 #endif
99
100 #ifndef ADVANCE64
101 #define ADVANCE64(p, n) (void*)((char *)(p) + ROUNDUP64(n))
102 #endif
103
104 static void inpcb_to_xinpcb_n(struct inpcb *, struct xinpcb_n *);
105 static void tcpcb_to_xtcpcb_n(struct tcpcb *, struct xtcpcb_n *);
106 void shutdown_sockets_on_interface(struct ifnet *ifp);
107
108
109 __private_extern__ void
sotoxsocket_n(struct socket * so,struct xsocket_n * xso)110 sotoxsocket_n(struct socket *so, struct xsocket_n *xso)
111 {
112 xso->xso_len = sizeof(struct xsocket_n);
113 xso->xso_kind = XSO_SOCKET;
114
115 if (so == NULL) {
116 return;
117 }
118
119 xso->xso_so = (uint64_t)VM_KERNEL_ADDRPERM(so);
120 xso->so_type = so->so_type;
121 xso->so_options = so->so_options;
122 xso->so_linger = so->so_linger;
123 xso->so_state = so->so_state;
124 xso->so_pcb = (uint64_t)VM_KERNEL_ADDRPERM(so->so_pcb);
125 if (so->so_proto) {
126 xso->xso_protocol = SOCK_PROTO(so);
127 xso->xso_family = SOCK_DOM(so);
128 } else {
129 xso->xso_protocol = xso->xso_family = 0;
130 }
131 xso->so_qlen = so->so_qlen;
132 xso->so_incqlen = so->so_incqlen;
133 xso->so_qlimit = so->so_qlimit;
134 xso->so_timeo = so->so_timeo;
135 xso->so_error = so->so_error;
136 xso->so_pgid = so->so_pgid;
137 xso->so_oobmark = so->so_oobmark;
138 xso->so_uid = kauth_cred_getuid(so->so_cred);
139 xso->so_last_pid = so->last_pid;
140 xso->so_e_pid = so->e_pid;
141 xso->so_gencnt = so->so_gencnt;
142 xso->so_flags = so->so_flags;
143 xso->so_flags1 = so->so_flags1;
144 xso->so_usecount = so->so_usecount;
145 xso->so_retaincnt = so->so_retaincnt;
146 if (so->so_filt != NULL) {
147 xso->xso_filter_flags |= XSOFF_SO_FILT;
148 }
149 if (so->so_flow_db != NULL) {
150 xso->xso_filter_flags |= XSOFF_FLOW_DB;
151 }
152 if (so->so_cfil != NULL) {
153 xso->xso_filter_flags |= XSOFF_CFIL;
154 }
155 if (so->so_fd_pcb != NULL) {
156 xso->xso_filter_flags |= XSOFF_FLOW_DIV;
157 }
158 }
159
160 __private_extern__ void
sbtoxsockbuf_n(struct sockbuf * sb,struct xsockbuf_n * xsb)161 sbtoxsockbuf_n(struct sockbuf *sb, struct xsockbuf_n *xsb)
162 {
163 xsb->xsb_len = sizeof(struct xsockbuf_n);
164
165 if (sb == NULL) {
166 return;
167 }
168
169 xsb->xsb_kind = (sb->sb_flags & SB_RECV) ? XSO_RCVBUF : XSO_SNDBUF;
170 xsb->sb_cc = sb->sb_cc;
171 xsb->sb_hiwat = sb->sb_hiwat;
172 xsb->sb_mbcnt = sb->sb_mbcnt;
173 xsb->sb_mbmax = sb->sb_mbmax;
174 xsb->sb_lowat = sb->sb_lowat;
175 xsb->sb_flags = (short)sb->sb_flags;
176 xsb->sb_timeo = (short)((sb->sb_timeo.tv_sec * hz) +
177 sb->sb_timeo.tv_usec / tick);
178 if (xsb->sb_timeo == 0 && sb->sb_timeo.tv_usec != 0) {
179 xsb->sb_timeo = 1;
180 }
181 }
182
183 __private_extern__ void
sbtoxsockstat_n(struct socket * so,struct xsockstat_n * xst)184 sbtoxsockstat_n(struct socket *so, struct xsockstat_n *xst)
185 {
186 int i;
187
188 xst->xst_len = sizeof(struct xsockstat_n);
189 xst->xst_kind = XSO_STATS;
190
191 if (so == NULL) {
192 return;
193 }
194
195 for (i = 0; i < SO_TC_STATS_MAX; i++) {
196 xst->xst_tc_stats[i].rxpackets = so->so_tc_stats[i].rxpackets;
197 xst->xst_tc_stats[i].rxbytes = so->so_tc_stats[i].rxbytes;
198 xst->xst_tc_stats[i].txpackets = so->so_tc_stats[i].txpackets;
199 xst->xst_tc_stats[i].txbytes = so->so_tc_stats[i].txbytes;
200 }
201 }
202
203 static void
inpcb_to_xinpcb_n(struct inpcb * inp,struct xinpcb_n * xinp)204 inpcb_to_xinpcb_n(struct inpcb *inp, struct xinpcb_n *xinp)
205 {
206 xinp->xi_len = sizeof(struct xinpcb_n);
207 xinp->xi_kind = XSO_INPCB;
208 xinp->xi_inpp = (uint64_t)VM_KERNEL_ADDRPERM(inp);
209 xinp->inp_fport = inp->inp_fport;
210 xinp->inp_lport = inp->inp_lport;
211 xinp->inp_ppcb = (uint64_t)VM_KERNEL_ADDRPERM(inp->inp_ppcb);
212 xinp->inp_gencnt = inp->inp_gencnt;
213 xinp->inp_flags = inp->inp_flags;
214 xinp->inp_flow = inp->inp_flow;
215 xinp->inp_vflag = inp->inp_vflag;
216 xinp->inp_ip_ttl = inp->inp_ip_ttl;
217 xinp->inp_ip_p = inp->inp_ip_p;
218 xinp->inp_dependfaddr.inp6_foreign = inp->inp_dependfaddr.inp6_foreign;
219 xinp->inp_dependladdr.inp6_local = inp->inp_dependladdr.inp6_local;
220 xinp->inp_depend4.inp4_ip_tos = inp->inp_depend4.inp4_ip_tos;
221 xinp->inp_depend6.inp6_hlim = 0;
222 xinp->inp_depend6.inp6_cksum = inp->inp_depend6.inp6_cksum;
223 xinp->inp_depend6.inp6_ifindex = 0;
224 xinp->inp_depend6.inp6_hops = inp->inp_depend6.inp6_hops;
225 xinp->inp_flowhash = inp->inp_flowhash;
226 xinp->inp_flags2 = inp->inp_flags2;
227 }
228
229 __private_extern__ void
tcpcb_to_xtcpcb_n(struct tcpcb * tp,struct xtcpcb_n * xt)230 tcpcb_to_xtcpcb_n(struct tcpcb *tp, struct xtcpcb_n *xt)
231 {
232 xt->xt_len = sizeof(struct xtcpcb_n);
233 xt->xt_kind = XSO_TCPCB;
234
235 xt->t_segq = (uint32_t)VM_KERNEL_ADDRPERM(tp->t_segq.lh_first);
236 xt->t_dupacks = tp->t_dupacks;
237 xt->t_timer[TCPT_REXMT_EXT] = tp->t_timer[TCPT_REXMT];
238 xt->t_timer[TCPT_PERSIST_EXT] = tp->t_timer[TCPT_PERSIST];
239 xt->t_timer[TCPT_KEEP_EXT] = tp->t_timer[TCPT_KEEP];
240 xt->t_timer[TCPT_2MSL_EXT] = tp->t_timer[TCPT_2MSL];
241 xt->t_state = tp->t_state;
242 xt->t_flags = tp->t_flags;
243 xt->t_force = (tp->t_flagsext & TF_FORCE) ? 1 : 0;
244 xt->snd_una = tp->snd_una;
245 xt->snd_max = tp->snd_max;
246 xt->snd_nxt = tp->snd_nxt;
247 xt->snd_up = tp->snd_up;
248 xt->snd_wl1 = tp->snd_wl1;
249 xt->snd_wl2 = tp->snd_wl2;
250 xt->iss = tp->iss;
251 xt->irs = tp->irs;
252 xt->rcv_nxt = tp->rcv_nxt;
253 xt->rcv_adv = tp->rcv_adv;
254 xt->rcv_wnd = tp->rcv_wnd;
255 xt->rcv_up = tp->rcv_up;
256 xt->snd_wnd = tp->snd_wnd;
257 xt->snd_cwnd = tp->snd_cwnd;
258 xt->snd_ssthresh = tp->snd_ssthresh;
259 xt->t_maxopd = tp->t_maxopd;
260 xt->t_rcvtime = tp->t_rcvtime;
261 xt->t_starttime = tp->t_starttime;
262 xt->t_rtttime = tp->t_rtttime;
263 xt->t_rtseq = tp->t_rtseq;
264 xt->t_rxtcur = tp->t_rxtcur;
265 xt->t_maxseg = tp->t_maxseg;
266 xt->t_srtt = tp->t_srtt;
267 xt->t_rttvar = tp->t_rttvar;
268 xt->t_rxtshift = tp->t_rxtshift;
269 xt->t_rttmin = tp->t_rttmin;
270 xt->t_rttupdated = tp->t_rttupdated;
271 xt->max_sndwnd = tp->max_sndwnd;
272 xt->t_softerror = tp->t_softerror;
273 xt->t_oobflags = tp->t_oobflags;
274 xt->t_iobc = tp->t_iobc;
275 xt->snd_scale = tp->snd_scale;
276 xt->rcv_scale = tp->rcv_scale;
277 xt->request_r_scale = tp->request_r_scale;
278 xt->requested_s_scale = tp->requested_s_scale;
279 xt->ts_recent = tp->ts_recent;
280 xt->ts_recent_age = tp->ts_recent_age;
281 xt->last_ack_sent = tp->last_ack_sent;
282 xt->cc_send = 0;
283 xt->cc_recv = 0;
284 xt->snd_recover = tp->snd_recover;
285 xt->snd_cwnd_prev = tp->snd_cwnd_prev;
286 xt->snd_ssthresh_prev = tp->snd_ssthresh_prev;
287 }
288
289 __private_extern__ int
get_pcblist_n(short proto,struct sysctl_req * req,struct inpcbinfo * pcbinfo)290 get_pcblist_n(short proto, struct sysctl_req *req, struct inpcbinfo *pcbinfo)
291 {
292 int error = 0;
293 int i, n, sz;
294 struct inpcb *inp, **inp_list = NULL;
295 inp_gen_t gencnt;
296 struct xinpgen xig;
297 void *buf = NULL;
298 size_t item_size = ROUNDUP64(sizeof(struct xinpcb_n)) +
299 ROUNDUP64(sizeof(struct xsocket_n)) +
300 2 * ROUNDUP64(sizeof(struct xsockbuf_n)) +
301 ROUNDUP64(sizeof(struct xsockstat_n));
302 #if SKYWALK
303 int nuserland;
304 void *userlandsnapshot = NULL;
305 #endif /* SKYWALK */
306
307 if (proto == IPPROTO_TCP) {
308 item_size += ROUNDUP64(sizeof(struct xtcpcb_n));
309 }
310
311 if (req->oldptr == USER_ADDR_NULL) {
312 n = pcbinfo->ipi_count;
313 #if SKYWALK
314 n += ntstat_userland_count(proto);
315 #endif /* SKYWALK */
316 req->oldidx = 2 * (sizeof(xig)) + (n + n / 8 + 1) * item_size;
317 return 0;
318 }
319
320 if (req->newptr != USER_ADDR_NULL) {
321 return EPERM;
322 }
323
324 #if SKYWALK
325 /*
326 * Get a snapshot of the state of the user level flows so we know
327 * the exact number of results to give back to the user.
328 * This could take a while and use other locks, so do this prior
329 * to taking any locks of our own.
330 */
331 error = nstat_userland_get_snapshot(proto, &userlandsnapshot, &nuserland);
332
333 if (error) {
334 return error;
335 }
336 #endif /* SKYWALK */
337
338 /*
339 * The process of preparing the PCB list is too time-consuming and
340 * resource-intensive to repeat twice on every request.
341 */
342 lck_rw_lock_exclusive(&pcbinfo->ipi_lock);
343 /*
344 * OK, now we're committed to doing something.
345 */
346 gencnt = pcbinfo->ipi_gencnt;
347 n = sz = pcbinfo->ipi_count;
348
349 bzero(&xig, sizeof(xig));
350 xig.xig_len = sizeof(xig);
351 xig.xig_count = n;
352 #if SKYWALK
353 xig.xig_count += nuserland;
354 #endif /* SKYWALK */
355 xig.xig_gen = gencnt;
356 xig.xig_sogen = so_gencnt;
357 error = SYSCTL_OUT(req, &xig, sizeof(xig));
358 if (error) {
359 goto done;
360 }
361 /*
362 * We are done if there is no pcb
363 */
364 if (xig.xig_count == 0) {
365 goto done;
366 }
367
368 buf = kalloc_data(item_size, Z_WAITOK);
369 if (buf == NULL) {
370 error = ENOMEM;
371 goto done;
372 }
373
374 inp_list = kalloc_type(struct inpcb *, n, Z_WAITOK);
375 if (inp_list == NULL) {
376 error = ENOMEM;
377 goto done;
378 }
379
380 /*
381 * Special case TCP to include the connections in time wait
382 */
383 if (proto == IPPROTO_TCP) {
384 n = get_tcp_inp_list(inp_list, n, gencnt);
385 } else {
386 for (inp = pcbinfo->ipi_listhead->lh_first, i = 0; inp && i < n;
387 inp = inp->inp_list.le_next) {
388 if (inp->inp_gencnt <= gencnt &&
389 inp->inp_state != INPCB_STATE_DEAD) {
390 inp_list[i++] = inp;
391 }
392 }
393 n = i;
394 }
395
396
397 error = 0;
398 for (i = 0; i < n; i++) {
399 inp = inp_list[i];
400 if (inp->inp_gencnt <= gencnt &&
401 inp->inp_state != INPCB_STATE_DEAD) {
402 struct xinpcb_n *xi = (struct xinpcb_n *)buf;
403 struct xsocket_n *xso = (struct xsocket_n *)
404 ADVANCE64(xi, sizeof(*xi));
405 struct xsockbuf_n *xsbrcv = (struct xsockbuf_n *)
406 ADVANCE64(xso, sizeof(*xso));
407 struct xsockbuf_n *xsbsnd = (struct xsockbuf_n *)
408 ADVANCE64(xsbrcv, sizeof(*xsbrcv));
409 struct xsockstat_n *xsostats = (struct xsockstat_n *)
410 ADVANCE64(xsbsnd, sizeof(*xsbsnd));
411
412 bzero(buf, item_size);
413
414 inpcb_to_xinpcb_n(inp, xi);
415 sotoxsocket_n(inp->inp_socket, xso);
416 sbtoxsockbuf_n(inp->inp_socket ?
417 &inp->inp_socket->so_rcv : NULL, xsbrcv);
418 sbtoxsockbuf_n(inp->inp_socket ?
419 &inp->inp_socket->so_snd : NULL, xsbsnd);
420 sbtoxsockstat_n(inp->inp_socket, xsostats);
421 if (proto == IPPROTO_TCP) {
422 struct xtcpcb_n *xt = (struct xtcpcb_n *)
423 ADVANCE64(xsostats, sizeof(*xsostats));
424
425 /*
426 * inp->inp_ppcb, can only be NULL on
427 * an initialization race window.
428 * No need to lock.
429 */
430 if (inp->inp_ppcb == NULL) {
431 continue;
432 }
433
434 tcpcb_to_xtcpcb_n((struct tcpcb *)
435 inp->inp_ppcb, xt);
436 }
437 error = SYSCTL_OUT(req, buf, item_size);
438 if (error) {
439 break;
440 }
441 }
442 }
443 #if SKYWALK
444 if (!error && nuserland > 0) {
445 error = nstat_userland_list_snapshot(proto, req, userlandsnapshot, nuserland);
446 }
447 #endif /* SKYWALK */
448
449 if (!error) {
450 /*
451 * Give the user an updated idea of our state.
452 * If the generation differs from what we told
453 * her before, she knows that something happened
454 * while we were processing this request, and it
455 * might be necessary to retry.
456 */
457 bzero(&xig, sizeof(xig));
458 xig.xig_len = sizeof(xig);
459 xig.xig_gen = pcbinfo->ipi_gencnt;
460 xig.xig_sogen = so_gencnt;
461 xig.xig_count = pcbinfo->ipi_count;
462 #if SKYWALK
463 xig.xig_count += nuserland;
464 #endif /* SKYWALK */
465 error = SYSCTL_OUT(req, &xig, sizeof(xig));
466 }
467 done:
468 lck_rw_done(&pcbinfo->ipi_lock);
469
470 #if SKYWALK
471 nstat_userland_release_snapshot(userlandsnapshot, nuserland);
472 #endif /* SKYWALK */
473
474 kfree_type(struct inpcb *, sz, inp_list);
475 if (buf != NULL) {
476 kfree_data(buf, item_size);
477 }
478 return error;
479 }
480
481 static void
inpcb_get_if_ports_used(ifnet_t ifp,int protocol,uint32_t flags,bitstr_t * bitfield,struct inpcbinfo * pcbinfo)482 inpcb_get_if_ports_used(ifnet_t ifp, int protocol, uint32_t flags,
483 bitstr_t *bitfield, struct inpcbinfo *pcbinfo)
484 {
485 struct inpcb *inp;
486 struct socket *so;
487 inp_gen_t gencnt;
488 bool iswildcard, wildcardok, nowakeok;
489 bool recvanyifonly, extbgidleok;
490 bool activeonly;
491 bool anytcpstateok;
492
493 if (ifp == NULL) {
494 return;
495 }
496
497 wildcardok = ((flags & IFNET_GET_LOCAL_PORTS_WILDCARDOK) != 0);
498 nowakeok = ((flags & IFNET_GET_LOCAL_PORTS_NOWAKEUPOK) != 0);
499 recvanyifonly = ((flags & IFNET_GET_LOCAL_PORTS_RECVANYIFONLY) != 0);
500 extbgidleok = ((flags & IFNET_GET_LOCAL_PORTS_EXTBGIDLEONLY) != 0);
501 activeonly = ((flags & IFNET_GET_LOCAL_PORTS_ACTIVEONLY) != 0);
502 anytcpstateok = ((flags & IFNET_GET_LOCAL_PORTS_ANYTCPSTATEOK) != 0);
503
504 lck_rw_lock_shared(&pcbinfo->ipi_lock);
505 gencnt = pcbinfo->ipi_gencnt;
506
507 for (inp = LIST_FIRST(pcbinfo->ipi_listhead); inp;
508 inp = LIST_NEXT(inp, inp_list)) {
509 if (inp->inp_gencnt > gencnt ||
510 inp->inp_state == INPCB_STATE_DEAD ||
511 inp->inp_wantcnt == WNT_STOPUSING) {
512 continue;
513 }
514
515 if ((so = inp->inp_socket) == NULL || inp->inp_lport == 0) {
516 continue;
517 }
518
519 /*
520 * ANYTCPSTATEOK means incoming packets cannot be filtered
521 * reception so cast a wide net of possibilities
522 */
523 if (!anytcpstateok &&
524 ((so->so_state & SS_DEFUNCT) ||
525 (so->so_state & SS_ISDISCONNECTED))) {
526 continue;
527 }
528
529 /*
530 * If protocol is specified, filter out inpcbs that
531 * are not relevant to the protocol family of interest.
532 */
533 if (protocol != PF_UNSPEC) {
534 if (protocol == PF_INET) {
535 /*
536 * If protocol of interest is IPv4, skip the inpcb
537 * if the family is not IPv4.
538 * OR
539 * If the family is IPv4, skip if the IPv4 flow is
540 * CLAT46 translated.
541 */
542 if ((inp->inp_vflag & INP_IPV4) == 0 ||
543 (inp->inp_flags2 & INP2_CLAT46_FLOW) != 0) {
544 continue;
545 }
546 } else if (protocol == PF_INET6) {
547 /*
548 * If protocol of interest is IPv6, skip the inpcb
549 * if the family is not IPv6.
550 * AND
551 * The flow is not a CLAT46'd flow.
552 */
553 if ((inp->inp_vflag & INP_IPV6) == 0 &&
554 (inp->inp_flags2 & INP2_CLAT46_FLOW) == 0) {
555 continue;
556 }
557 } else {
558 /* Protocol family not supported */
559 continue;
560 }
561 }
562
563 if (SOCK_PROTO(inp->inp_socket) != IPPROTO_UDP &&
564 SOCK_PROTO(inp->inp_socket) != IPPROTO_TCP) {
565 continue;
566 }
567
568 iswildcard = (((inp->inp_vflag & INP_IPV4) &&
569 inp->inp_laddr.s_addr == INADDR_ANY) ||
570 ((inp->inp_vflag & INP_IPV6) &&
571 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)));
572
573 if (!wildcardok && iswildcard) {
574 continue;
575 }
576
577 if ((so->so_options & SO_NOWAKEFROMSLEEP) &&
578 !nowakeok) {
579 #if DEBUG || DEVELOPMENT
580 char lbuf[MAX_IPv6_STR_LEN + 6] = {};
581 char fbuf[MAX_IPv6_STR_LEN + 6] = {};
582 char pname[MAXCOMLEN + 1];
583
584 proc_name(so->last_pid, pname, sizeof(pname));
585
586 if (protocol == PF_INET) {
587 inet_ntop(PF_INET, &inp->inp_laddr.s_addr,
588 lbuf, sizeof(lbuf));
589 inet_ntop(PF_INET, &inp->inp_faddr.s_addr,
590 fbuf, sizeof(fbuf));
591 } else {
592 inet_ntop(PF_INET6, &inp->in6p_laddr.s6_addr,
593 lbuf, sizeof(lbuf));
594 inet_ntop(PF_INET6, &inp->in6p_faddr.s6_addr,
595 fbuf, sizeof(fbuf));
596 }
597
598 os_log(OS_LOG_DEFAULT,
599 "inpcb_get_if_ports_used: no wake from sleep %s %s:%u %s:%u ifp %s proc %s:%d",
600 SOCK_PROTO(inp->inp_socket) == IPPROTO_TCP ? "tcp" : "udp",
601 lbuf, ntohs(inp->inp_lport), fbuf, ntohs(inp->inp_fport),
602 ifp->if_xname, pname, so->last_pid);
603 #endif /* DEBUG || DEVELOPMENT */
604 continue;
605 }
606
607 if (!(inp->inp_flags & INP_RECV_ANYIF) &&
608 recvanyifonly) {
609 continue;
610 }
611
612 if (!(so->so_flags1 & SOF1_EXTEND_BK_IDLE_WANTED) &&
613 extbgidleok) {
614 continue;
615 }
616
617 if (!iswildcard &&
618 !(inp->inp_last_outifp == NULL || ifp == inp->inp_last_outifp)) {
619 continue;
620 }
621
622 if (SOCK_PROTO(inp->inp_socket) == IPPROTO_UDP &&
623 so->so_state & SS_CANTRCVMORE) {
624 continue;
625 }
626
627 if (SOCK_PROTO(inp->inp_socket) == IPPROTO_TCP) {
628 struct tcpcb *tp = sototcpcb(inp->inp_socket);
629
630 /*
631 * Workaround race where inp_ppcb is NULL during
632 * socket initialization
633 */
634 if (tp == NULL) {
635 continue;
636 }
637
638 switch (tp->t_state) {
639 case TCPS_CLOSED:
640 if (anytcpstateok && inp->inp_fport != 0) {
641 /*
642 * A foreign port means we had a 4 tuple at
643 * least a connection attempt so packets
644 * may be received for the 4 tuple after the
645 * connection is gone
646 */
647 break;
648 }
649 continue;
650 /* NOT REACHED */
651 case TCPS_LISTEN:
652 case TCPS_SYN_SENT:
653 case TCPS_SYN_RECEIVED:
654 case TCPS_ESTABLISHED:
655 case TCPS_FIN_WAIT_1:
656 /*
657 * Note: FIN_WAIT_1 is an active state
658 * because we need our FIN to be
659 * acknowledged
660 */
661 break;
662 case TCPS_CLOSE_WAIT:
663 case TCPS_CLOSING:
664 case TCPS_LAST_ACK:
665 case TCPS_FIN_WAIT_2:
666 /*
667 * In the closing states, the connection
668 * is active when there is outgoing
669 * data having to be acknowledged
670 */
671 if (!anytcpstateok &&
672 (activeonly && so->so_snd.sb_cc == 0)) {
673 continue;
674 }
675 break;
676 case TCPS_TIME_WAIT:
677 if (anytcpstateok) {
678 /*
679 * Packets may still be received for the 4 tuple
680 * after the connection is gone
681 */
682 break;
683 }
684 continue;
685 /* NOT REACHED */
686 }
687 }
688
689 bitstr_set(bitfield, ntohs(inp->inp_lport));
690
691 (void) if_ports_used_add_inpcb(ifp->if_index, inp);
692 }
693 lck_rw_done(&pcbinfo->ipi_lock);
694 }
695
696 __private_extern__ void
inpcb_get_ports_used(ifnet_t ifp,int protocol,uint32_t flags,bitstr_t * bitfield,struct inpcbinfo * pcbinfo)697 inpcb_get_ports_used(ifnet_t ifp, int protocol, uint32_t flags,
698 bitstr_t *bitfield, struct inpcbinfo *pcbinfo)
699 {
700 if (ifp != NULL) {
701 inpcb_get_if_ports_used(ifp, protocol, flags, bitfield, pcbinfo);
702 } else {
703 errno_t error;
704 ifnet_t *ifp_list;
705 uint32_t count, i;
706
707 error = ifnet_list_get_all(IFNET_FAMILY_ANY, &ifp_list, &count);
708 if (error != 0) {
709 os_log_error(OS_LOG_DEFAULT,
710 "%s: ifnet_list_get_all() failed %d",
711 __func__, error);
712 return;
713 }
714 for (i = 0; i < count; i++) {
715 if (TAILQ_EMPTY(&ifp_list[i]->if_addrhead)) {
716 continue;
717 }
718 inpcb_get_if_ports_used(ifp_list[i], protocol, flags,
719 bitfield, pcbinfo);
720 }
721 ifnet_list_free(ifp_list);
722 }
723 }
724
725 __private_extern__ uint32_t
inpcb_count_opportunistic(unsigned int ifindex,struct inpcbinfo * pcbinfo,u_int32_t flags)726 inpcb_count_opportunistic(unsigned int ifindex, struct inpcbinfo *pcbinfo,
727 u_int32_t flags)
728 {
729 uint32_t opportunistic = 0;
730 struct inpcb *inp;
731 inp_gen_t gencnt;
732
733 lck_rw_lock_shared(&pcbinfo->ipi_lock);
734 gencnt = pcbinfo->ipi_gencnt;
735 for (inp = LIST_FIRST(pcbinfo->ipi_listhead);
736 inp != NULL; inp = LIST_NEXT(inp, inp_list)) {
737 if (inp->inp_gencnt <= gencnt &&
738 inp->inp_state != INPCB_STATE_DEAD &&
739 inp->inp_socket != NULL &&
740 so_get_opportunistic(inp->inp_socket) &&
741 inp->inp_last_outifp != NULL &&
742 ifindex == inp->inp_last_outifp->if_index) {
743 opportunistic++;
744 struct socket *so = inp->inp_socket;
745 if ((flags & INPCB_OPPORTUNISTIC_SETCMD) &&
746 (so->so_state & SS_ISCONNECTED)) {
747 socket_lock(so, 1);
748 if (flags & INPCB_OPPORTUNISTIC_THROTTLEON) {
749 so->so_flags |= SOF_SUSPENDED;
750 soevent(so,
751 (SO_FILT_HINT_LOCKED |
752 SO_FILT_HINT_SUSPEND));
753 } else {
754 so->so_flags &= ~(SOF_SUSPENDED);
755 soevent(so,
756 (SO_FILT_HINT_LOCKED |
757 SO_FILT_HINT_RESUME));
758 }
759 SOTHROTTLELOG("throttle[%d]: so 0x%llx "
760 "[%d,%d] %s\n", so->last_pid,
761 (uint64_t)VM_KERNEL_ADDRPERM(so),
762 SOCK_DOM(so), SOCK_TYPE(so),
763 (so->so_flags & SOF_SUSPENDED) ?
764 "SUSPENDED" : "RESUMED");
765 socket_unlock(so, 1);
766 }
767 }
768 }
769
770 lck_rw_done(&pcbinfo->ipi_lock);
771
772 return opportunistic;
773 }
774
775 __private_extern__ uint32_t
inpcb_find_anypcb_byaddr(struct ifaddr * ifa,struct inpcbinfo * pcbinfo)776 inpcb_find_anypcb_byaddr(struct ifaddr *ifa, struct inpcbinfo *pcbinfo)
777 {
778 struct inpcb *inp;
779 inp_gen_t gencnt = pcbinfo->ipi_gencnt;
780 struct socket *so = NULL;
781 int af;
782
783 if ((ifa->ifa_addr->sa_family != AF_INET) &&
784 (ifa->ifa_addr->sa_family != AF_INET6)) {
785 return 0;
786 }
787
788 lck_rw_lock_shared(&pcbinfo->ipi_lock);
789 for (inp = LIST_FIRST(pcbinfo->ipi_listhead);
790 inp != NULL; inp = LIST_NEXT(inp, inp_list)) {
791 if (inp->inp_gencnt <= gencnt &&
792 inp->inp_state != INPCB_STATE_DEAD &&
793 inp->inp_socket != NULL) {
794 so = inp->inp_socket;
795 af = SOCK_DOM(so);
796 if (af != ifa->ifa_addr->sa_family) {
797 continue;
798 }
799 if (inp->inp_last_outifp != ifa->ifa_ifp) {
800 continue;
801 }
802
803 if (af == AF_INET) {
804 if (inp->inp_laddr.s_addr ==
805 (satosin(ifa->ifa_addr))->sin_addr.s_addr) {
806 lck_rw_done(&pcbinfo->ipi_lock);
807 return 1;
808 }
809 }
810 if (af == AF_INET6) {
811 if (in6_are_addr_equal_scoped(IFA_IN6(ifa), &inp->in6p_laddr, ((struct sockaddr_in6 *)(void *)(ifa->ifa_addr))->sin6_scope_id, inp->inp_lifscope)) {
812 lck_rw_done(&pcbinfo->ipi_lock);
813 return 1;
814 }
815 }
816 }
817 }
818 lck_rw_done(&pcbinfo->ipi_lock);
819 return 0;
820 }
821
822 static int
shutdown_sockets_on_interface_proc_callout(proc_t p,void * arg)823 shutdown_sockets_on_interface_proc_callout(proc_t p, void *arg)
824 {
825 struct fileproc *fp;
826 struct ifnet *ifp = (struct ifnet *)arg;
827
828 if (ifp == NULL) {
829 return PROC_RETURNED;
830 }
831
832 proc_fdlock(p);
833
834 fdt_foreach(fp, p) {
835 struct fileglob *fg = fp->fp_glob;
836 struct socket *so;
837 struct inpcb *inp;
838 struct ifnet *inp_ifp;
839 int error;
840
841 if (FILEGLOB_DTYPE(fg) != DTYPE_SOCKET) {
842 continue;
843 }
844
845 so = (struct socket *)fp_get_data(fp);
846 if (SOCK_DOM(so) != PF_INET && SOCK_DOM(so) != PF_INET6) {
847 continue;
848 }
849
850 inp = (struct inpcb *)so->so_pcb;
851
852 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) == WNT_STOPUSING) {
853 continue;
854 }
855
856 socket_lock(so, 1);
857
858 if (in_pcb_checkstate(inp, WNT_RELEASE, 1) == WNT_STOPUSING) {
859 socket_unlock(so, 1);
860 continue;
861 }
862
863 if (inp->inp_boundifp != NULL) {
864 inp_ifp = inp->inp_boundifp;
865 } else if (inp->inp_last_outifp != NULL) {
866 inp_ifp = inp->inp_last_outifp;
867 } else {
868 socket_unlock(so, 1);
869 continue;
870 }
871
872 if (inp_ifp != ifp && inp_ifp->if_delegated.ifp != ifp) {
873 socket_unlock(so, 1);
874 continue;
875 }
876 error = sosetdefunct(p, so, 0, TRUE);
877 if (error != 0) {
878 log(LOG_ERR, "%s: sosetdefunct() error %d",
879 __func__, error);
880 } else {
881 error = sodefunct(p, so, 0);
882 if (error != 0) {
883 log(LOG_ERR, "%s: sodefunct() error %d",
884 __func__, error);
885 }
886 }
887
888 socket_unlock(so, 1);
889 }
890 proc_fdunlock(p);
891
892 return PROC_RETURNED;
893 }
894
895 void
shutdown_sockets_on_interface(struct ifnet * ifp)896 shutdown_sockets_on_interface(struct ifnet *ifp)
897 {
898 proc_iterate(PROC_ALLPROCLIST,
899 shutdown_sockets_on_interface_proc_callout,
900 ifp, NULL, NULL);
901 }
902
903 __private_extern__ int
inp_limit_companion_link(struct inpcbinfo * pcbinfo,u_int32_t limit)904 inp_limit_companion_link(struct inpcbinfo *pcbinfo, u_int32_t limit)
905 {
906 struct inpcb *inp;
907 struct socket *so = NULL;
908
909 lck_rw_lock_shared(&pcbinfo->ipi_lock);
910 inp_gen_t gencnt = pcbinfo->ipi_gencnt;
911 for (inp = LIST_FIRST(pcbinfo->ipi_listhead);
912 inp != NULL; inp = LIST_NEXT(inp, inp_list)) {
913 if (inp->inp_gencnt <= gencnt &&
914 inp->inp_state != INPCB_STATE_DEAD &&
915 inp->inp_socket != NULL) {
916 so = inp->inp_socket;
917
918 if ((so->so_state & SS_DEFUNCT) || so->so_state & SS_ISDISCONNECTED ||
919 SOCK_PROTO(so) != IPPROTO_TCP || inp->inp_last_outifp == NULL ||
920 !IFNET_IS_COMPANION_LINK(inp->inp_last_outifp)) {
921 continue;
922 }
923 so->so_snd.sb_flags &= ~SB_LIMITED;
924 u_int32_t new_size = MAX(MIN(limit, so->so_snd.sb_lowat), so->so_snd.sb_cc);
925 sbreserve(&so->so_snd, new_size);
926 so->so_snd.sb_flags |= SB_LIMITED;
927 }
928 }
929 lck_rw_done(&pcbinfo->ipi_lock);
930 return 0;
931 }
932
933 __private_extern__ int
inp_recover_companion_link(struct inpcbinfo * pcbinfo)934 inp_recover_companion_link(struct inpcbinfo *pcbinfo)
935 {
936 struct inpcb *inp;
937 inp_gen_t gencnt = pcbinfo->ipi_gencnt;
938 struct socket *so = NULL;
939
940 lck_rw_lock_shared(&pcbinfo->ipi_lock);
941 for (inp = LIST_FIRST(pcbinfo->ipi_listhead);
942 inp != NULL; inp = LIST_NEXT(inp, inp_list)) {
943 if (inp->inp_gencnt <= gencnt &&
944 inp->inp_state != INPCB_STATE_DEAD &&
945 inp->inp_socket != NULL) {
946 so = inp->inp_socket;
947
948 if (SOCK_PROTO(so) != IPPROTO_TCP || inp->inp_last_outifp == NULL ||
949 !(so->so_snd.sb_flags & SB_LIMITED)) {
950 continue;
951 }
952
953 so->so_snd.sb_flags &= ~SB_LIMITED;
954 }
955 }
956 lck_rw_done(&pcbinfo->ipi_lock);
957 return 0;
958 }
959