]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/if_ports_used.c
xnu-7195.81.3.tar.gz
[apple/xnu.git] / bsd / net / if_ports_used.c
index 378d834fccce819a8cddeddee724df7eb584a9f9..586b2ed102bf5da30dd585d2f08e0b849acb3091 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2017-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -47,6 +47,8 @@
 #include <net/if_ports_used.h>
 
 #include <netinet/in_pcb.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
 
 
 #include <stdbool.h>
@@ -147,10 +149,8 @@ struct net_port_entry {
        struct net_port_info            npe_npi;
 };
 
-static struct zone *net_port_entry_zone = NULL;
-
-#define NET_PORT_ENTRY_ZONE_MAX 128
-#define NET_PORT_ENTRY_ZONE_NAME "net_port_entry"
+static ZONE_DECLARE(net_port_entry_zone, "net_port_entry",
+    sizeof(struct net_port_entry), ZC_NONE);
 
 static SLIST_HEAD(net_port_entry_list, net_port_entry) net_port_entry_list =
     SLIST_HEAD_INITIALIZER(&net_port_entry_list);
@@ -181,16 +181,6 @@ if_ports_used_init(void)
                    lck_attributes);
 
                net_port_entry_count = 0;
-               net_port_entry_zone = zinit(sizeof(struct net_port_entry),
-                   NET_PORT_ENTRY_ZONE_MAX * sizeof(struct net_port_entry),
-                   0, NET_PORT_ENTRY_ZONE_NAME);
-               if (net_port_entry_zone == NULL) {
-                       panic("%s: zinit(%s) failed", __func__,
-                           NET_PORT_ENTRY_ZONE_NAME);
-               }
-               zone_change(net_port_entry_zone, Z_EXPAND, TRUE);
-               zone_change(net_port_entry_zone, Z_CALLERACCT, FALSE);
-
                if_ports_used_inited = 1;
 
                lck_attr_free(lck_attributes);
@@ -359,7 +349,7 @@ net_port_info_add_entry(const struct net_port_info *npi)
 
        if (__improbable(is_wakeuuid_set() == false)) {
                if (if_ports_used_verbose > 0) {
-                       log(LOG_ERR, "%s: wakeuuid not set %u not adding "
+                       log(LOG_ERR, "%s: wakeuuid not set not adding "
                            "port: %u flags: 0x%xif: %u pid: %u epid %u\n",
                            __func__,
                            ntohs(npi->npi_local_port),
@@ -507,7 +497,7 @@ sysctl_wakeuuid_not_set_last_time SYSCTL_HANDLER_ARGS
        } else {
                struct user32_timeval tv = {};
 
-               tv.tv_sec = wakeuuid_not_set_last_time.tv_sec;
+               tv.tv_sec = (user32_time_t)wakeuuid_not_set_last_time.tv_sec;
                tv.tv_usec = wakeuuid_not_set_last_time.tv_usec;
                return SYSCTL_OUT(req, &tv, sizeof(tv));
        }
@@ -654,15 +644,25 @@ if_ports_used_add_inpcb(const uint32_t ifindex, const struct inpcb *inp)
 
        bzero(&npi, sizeof(struct net_port_info));
 
-       npi.npi_if_index = ifindex;
+       /* This is unlikely to happen but better be safe than sorry */
+       if (ifindex > UINT16_MAX) {
+               os_log(OS_LOG_DEFAULT, "%s: ifindex %u too big\n", __func__, ifindex);
+               return;
+       }
+       npi.npi_if_index = (uint16_t)ifindex;
 
        npi.npi_flags |= NPIF_SOCKET;
 
-       npi.npi_timestamp.tv_sec = wakeuiid_last_check.tv_sec;
+       npi.npi_timestamp.tv_sec = (int32_t)wakeuiid_last_check.tv_sec;
        npi.npi_timestamp.tv_usec = wakeuiid_last_check.tv_usec;
 
        if (SOCK_PROTO(so) == IPPROTO_TCP) {
+               struct tcpcb *tp = intotcpcb(inp);
+
                npi.npi_flags |= NPIF_TCP;
+               if (tp != NULL && tp->t_state == TCPS_LISTEN) {
+                       npi.npi_flags |= NPIF_LISTEN;
+               }
        } else if (SOCK_PROTO(so) == IPPROTO_UDP) {
                npi.npi_flags |= NPIF_UDP;
        } else {
@@ -675,7 +675,15 @@ if_ports_used_add_inpcb(const uint32_t ifindex, const struct inpcb *inp)
        npi.npi_local_port = inp->inp_lport;
        npi.npi_foreign_port = inp->inp_fport;
 
-       if (inp->inp_vflag & INP_IPV4) {
+       /*
+        * Take in account IPv4 addresses mapped on IPv6
+        */
+       if ((inp->inp_vflag & INP_IPV6) != 0 && (inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
+           (inp->inp_vflag & (INP_IPV6 | INP_IPV4)) == (INP_IPV6 | INP_IPV4)) {
+               npi.npi_flags |= NPIF_IPV6 | NPIF_IPV4;
+               memcpy(&npi.npi_local_addr_in6,
+                   &inp->in6p_laddr, sizeof(struct in6_addr));
+       } else if (inp->inp_vflag & INP_IPV4) {
                npi.npi_flags |= NPIF_IPV4;
                npi.npi_local_addr_in = inp->inp_laddr;
                npi.npi_foreign_addr_in = inp->inp_faddr;
@@ -685,6 +693,14 @@ if_ports_used_add_inpcb(const uint32_t ifindex, const struct inpcb *inp)
                    &inp->in6p_laddr, sizeof(struct in6_addr));
                memcpy(&npi.npi_foreign_addr_in6,
                    &inp->in6p_faddr, sizeof(struct in6_addr));
+
+               /* Clear the embedded scope ID */
+               if (IN6_IS_ADDR_LINKLOCAL(&npi.npi_local_addr_in6)) {
+                       npi.npi_local_addr_in6.s6_addr16[1] = 0;
+               }
+               if (IN6_IS_ADDR_LINKLOCAL(&npi.npi_foreign_addr_in6)) {
+                       npi.npi_foreign_addr_in6.s6_addr16[1] = 0;
+               }
        }
 
        npi.npi_owner_pid = so->last_pid;