1 /* 2 * Copyright (c) 2017-2024 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 #ifndef _NET_IF_PORT_USED_H_ 30 #define _NET_IF_PORT_USED_H_ 31 32 #ifdef PRIVATE 33 34 #include <sys/types.h> 35 #include <stdint.h> 36 #include <sys/proc.h> 37 #include <sys/queue.h> 38 #include <sys/_types/_timeval32.h> 39 #include <net/if.h> 40 #include <netinet/in.h> 41 #include <uuid/uuid.h> 42 #include <stdbool.h> 43 44 #define IP_PORTRANGE_SIZE 65536 45 46 #define WAKE_PKT_EVENT_CONTROL_ENTITLEMENT "com.apple.private.network.wake_pkt.control" 47 48 /* 49 * The sysctl "net.link.generic.system.port_used.list" returns: 50 * - one "struct xnpigen" as a preamble 51 * - zero or more "struct net_port_info" according to xng_npi_count 52 * 53 * The list may contain information several interfaces if several drivers 54 * queried the list of port to offload 55 * 56 * The same local port may have more than one "struct net_port_info" on 57 * a given interface, for example when a local server has mutiple clients 58 * connections 59 */ 60 61 struct xnpigen { 62 uint32_t xng_len; /* length of this data structure */ 63 uint32_t xng_gen; /* how many times the list was built */ 64 uint32_t xng_npi_count; /* number of net_port_info following */ 65 uint32_t xng_npi_size; /* number of struct net_port_info */ 66 uuid_t xng_wakeuuid; /* WakeUUID when list was built */ 67 }; 68 69 union in_addr_4_6 { 70 struct in_addr _in_a_4; 71 struct in6_addr _in_a_6; 72 }; 73 74 #define NPIF_IPV4 0x0001 75 #define NPIF_IPV6 0x0002 76 #define NPIF_TCP 0x0004 77 #define NPIF_UDP 0x0008 78 #define NPIF_DELEGATED 0x0010 79 #define NPIF_SOCKET 0x0020 80 #define NPIF_CHANNEL 0x0040 81 #define NPIF_LISTEN 0x0080 82 #define NPIF_WAKEPKT 0x0100 83 #define NPIF_NOWAKE 0x0200 /* flow marked with SO_NOWAKEFROMSLEEP are normally excluded */ 84 #define NPIF_FRAG 0x0400 /* packet is pure fragment (i.e. no src and dst port) */ 85 #define NPIF_ESP 0x0800 /* for logging only */ 86 #define NPIF_COMPLINK 0x1000 /* interface is companion link */ 87 88 #define NPI_HAS_EFFECTIVE_UUID 1 89 90 struct net_port_info { 91 uint16_t npi_if_index; 92 uint16_t npi_flags; /* NPIF_xxx */ 93 struct timeval32 npi_timestamp; /* when passed to driver */ 94 uuid_t npi_flow_uuid; 95 in_port_t npi_local_port; /* network byte order */ 96 in_port_t npi_foreign_port; /* network byte order */ 97 union in_addr_4_6 npi_local_addr_; 98 union in_addr_4_6 npi_foreign_addr_; 99 pid_t npi_owner_pid; 100 pid_t npi_effective_pid; 101 char npi_owner_pname[MAXCOMLEN + 1]; 102 char npi_effective_pname[MAXCOMLEN + 1]; 103 uuid_t npi_owner_uuid; 104 uuid_t npi_effective_uuid; 105 }; 106 107 #define npi_local_addr_in npi_local_addr_._in_a_4 108 #define npi_foreign_addr_in npi_foreign_addr_._in_a_4 109 110 #define npi_local_addr_in6 npi_local_addr_._in_a_6 111 #define npi_foreign_addr_in6 npi_foreign_addr_._in_a_6 112 113 #define NPI_HAS_WAKE_EVENT_TUPLE 1 114 #define NPI_HAS_PACKET_INFO 1 115 #define NPI_HAS_PHYSICAL_LINK 1 /* npi_if_info and phy_if fields are present */ 116 117 /* 118 * struct npi_if_info provides detailed information about the kind of interface 119 * 120 * See <net/if_private.h> for definitions of possible values of each field 121 * 122 * Note: the IFRTYPE_xxx values are the same as the IFNET_xxx used inside the kernel 123 */ 124 struct npi_if_info { 125 uint32_t npi_if_family; /* IFRTYPE_FAMILY_xxx */ 126 uint32_t npi_if_subfamily; /* IFRTYPE_SUBFAMILY_xxx */ 127 uint32_t npi_if_functional_type; /* IFRTYPE_FUNCTIONAL_xxx */ 128 }; 129 130 #define NPI_IF_INFO_IS_ETHERNET(_npi) \ 131 ((_npi)->npi_if_family == IFRTYPE_FAMILY_ETHERNET) 132 133 #define NPI_IF_INFO_IS_ETHERNET_WIRED(_npi) \ 134 (NPI_IF_INFO_IS_ETHERNET(_npi) && \ 135 (_npi)->npi_if_subfamily != IFRTYPE_SUBFAMILY_WIFI) 136 137 #define NPI_IF_INFO_IS_WIFI(_npi) \ 138 (NPI_IF_INFO_IS_ETHERNET(_npi) && \ 139 (_npi)->npi_if_subfamily == IFRTYPE_SUBFAMILY_WIFI) 140 141 #define NPI_IF_INFO_IS_CELLULAR(_npi) \ 142 ((_npi)->npi_if_family == IFRTYPE_FAMILY_CELLULAR) 143 144 #define NPI_IF_INFO_IS_IPSEC(_npi) \ 145 ((_npi)->npi_if_family == IFRTYPE_FAMILY_IPSEC) 146 147 #define NPI_IF_INFO_IS_IPSEC_COMPANIONLINK(_npi) \ 148 ((_npi)->npi_if_family == IFRTYPE_FAMILY_IPSEC && \ 149 (_npi)->npi_if_functional_type == IFRTYPE_FUNCTIONAL_COMPANIONLINK) 150 151 #define NPI_IF_INFO_IS_IPSEC_COMPANIONLINK_BLUETOOTH(_npi) \ 152 (NPI_IF_INFO_IS_IPSEC_COMPANIONLINK(_npi) && \ 153 (_npi)->npi_if_subfamily == IFRTYPE_SUBFAMILY_BLUETOOTH) 154 155 #define NPI_IF_INFO_IS_IPSEC_COMPANIONLINK_WIFI(_npi) \ 156 (NPI_IF_INFO_IS_IPSEC_COMPANIONLINK(_npi) && \ 157 (_npi)->npi_if_subfamily == IFRTYPE_SUBFAMILY_WIFI) 158 159 #define NPI_IF_INFO_IS_IPSEC_COMPANIONLINK_QUICKRELAY(_npi) \ 160 (NPI_IF_INFO_IS_IPSEC_COMPANIONLINK(_npi) && \ 161 (_npi)->npi_if_subfamily == IFRTYPE_SUBFAMILY_QUICKRELAY) 162 163 #define NPI_IF_INFO_IS_UTUN(_npi) \ 164 ((_npi)->npi_if_family == IFRTYPE_FAMILY_UTUN) 165 166 /* 167 * Symbolic names for bits of wake_pkt_control_flags and una_wake_pkt_control_flags 168 * When the protocol is TCP (flag NPIF_TCP set) the lower 8 bits correspond to the TCP header flag 169 */ 170 #define NPICF_TH_FIN 0x01 171 #define NPICF_TH_SYN 0x02 172 #define NPICF_TH_RST 0x04 173 #define NPICF_TH_PUSH 0x08 174 #define NPICF_TH_ACK 0x10 175 #define NPICF_TH_URG 0x20 176 #define NPICF_TH_ECE 0x40 177 #define NPICF_TH_CWR 0x80 178 #define NPICF_NOWAKE 0x1000 179 180 /* 181 * struct net_port_info_una_wake_event is the event data for KEV_POWER_WAKE_PACKE 182 * 183 * See <net/if_private.h> for definiton of values of these kinds of fields: 184 * - xxx_if_family IFRTYPE_FAMILY_YYY 185 * - xxx_if_subfamily IFRTYPE_SUBFAMILY_YYY 186 * - xxx_if_functional_type IFRTYPE_FUNCTIONAL_YYY 187 */ 188 struct net_port_info_wake_event { 189 uuid_t wake_uuid; 190 struct timeval32 wake_pkt_timestamp; /* when processed by networking stack */ 191 uint16_t wake_pkt_if_index; /* interface of incoming wake packet */ 192 in_port_t wake_pkt_port; /* local port in network byte order */ 193 uint16_t wake_pkt_flags; /* NPIF_xxx */ 194 pid_t wake_pkt_owner_pid; 195 pid_t wake_pkt_effective_pid; 196 char wake_pkt_owner_pname[MAXCOMLEN + 1]; 197 char wake_pkt_effective_pname[MAXCOMLEN + 1]; 198 uuid_t wake_pkt_owner_uuid; 199 uuid_t wake_pkt_effective_uuid; 200 in_port_t wake_pkt_foreign_port; /* network byte order */ 201 union in_addr_4_6 wake_pkt_local_addr_; 202 union in_addr_4_6 wake_pkt_foreign_addr_; 203 char wake_pkt_ifname[IFNAMSIZ]; /* name + unit */ 204 205 /* Following fields added with NPI_HAS_PACKET_INFO */ 206 uint32_t wake_pkt_total_len; /* actual length of packet */ 207 uint32_t wake_pkt_data_len; /* exclude transport (TCP/UDP) header length */ 208 uint16_t wake_pkt_control_flags; /* see NPICF_xxx above */ 209 210 /* Followings fields added with NPI_HAS_PHYSICAL_LINK */ 211 struct npi_if_info wake_pkt_if_info; /* inner-most interface of TCP/UDP packet */ 212 213 char wake_pkt_phy_ifname[IFNAMSIZ]; /* name + unit */ 214 struct npi_if_info wake_pkt_phy_if_info; /* outer-most interface of wake packet */ 215 }; 216 217 /* 218 * struct net_port_info_una_wake_event is the event data for KEV_POWER_UNATTRIBUTED_WAKE 219 * 220 * una_wake_pkt_proto is useful to track unexpected wake packets when NPIF_IPV4 or 221 * NPIF_IPV6 is set this is the IP protocol -- see IPPROTO_x from netinet/in.h. 222 * When NPIF_IPV4 and NPIF_IPV6 are not set the cotent of una_wake_pkt can give clues 223 * on the type of unexpected wake packet 224 */ 225 #define NPI_MAX_UNA_WAKE_PKT_LEN 102 226 struct net_port_info_una_wake_event { 227 uuid_t una_wake_uuid; 228 struct timeval32 una_wake_pkt_timestamp; /* when processed by networking stack */ 229 uint16_t una_wake_pkt_if_index; /* interface of incoming wake packet */ 230 uint16_t una_wake_pkt_flags; /* NPIF_xxx */ 231 uint16_t _una_wake_pkt_reserved; /* not used */ 232 uint16_t una_wake_ptk_len; /* length of una_wake_pkt */ 233 uint8_t una_wake_pkt[NPI_MAX_UNA_WAKE_PKT_LEN]; /* initial portion of the IPv4/IPv6 packet */ 234 in_port_t una_wake_pkt_local_port; /* network byte order */ 235 in_port_t una_wake_pkt_foreign_port; /* network byte order */ 236 union in_addr_4_6 una_wake_pkt_local_addr_; 237 union in_addr_4_6 una_wake_pkt_foreign_addr_; 238 char una_wake_pkt_ifname[IFNAMSIZ]; /* name + unit */ 239 240 /* Following fields added with NPI_HAS_PACKET_INFO */ 241 uint32_t una_wake_pkt_total_len; /* actual length of packet */ 242 uint32_t una_wake_pkt_data_len; /* exclude transport (TCP/UDP) header length */ 243 uint16_t una_wake_pkt_control_flags; /* see NPICF_xxx above */ 244 uint16_t una_wake_pkt_proto; /* IPv4 or IPv6 protocol */ 245 246 /* Followings fields added with NPI_HAS_PHYSICAL_LINK */ 247 struct npi_if_info una_wake_pkt_if_info; /* inner-most interface for TCP/UDP tuple */ 248 249 char una_wake_pkt_phy_ifname[IFNAMSIZ]; /* name + unit */ 250 struct npi_if_info una_wake_pkt_phy_if_info; /* outer-most interface of wake packet */ 251 }; 252 253 #define IFPU_HAS_MATCH_WAKE_PKT_NO_FLAG 1 /* ifpu_match_wake_pkt_no_flag is defined */ 254 255 #define IF_PORTS_USED_STATS_LIST \ 256 X(uint64_t, ifpu_wakeuid_gen, "wakeuuid generation%s", "", "s") \ 257 X(uint64_t, ifpu_wakeuuid_not_set_count, "offload port list quer%s with wakeuuid not set", "y", "ies") \ 258 X(uint64_t, ifpu_npe_total, "total offload port entr%s created since boot", "y", "ies") \ 259 X(uint64_t, ifpu_npe_count, "current offload port entr%s", "y", "ies") \ 260 X(uint64_t, ifpu_npe_max, "max offload port entr%s", "y", "ies") \ 261 X(uint64_t, ifpu_npe_dup, "duplicate offload port entr%s", "y", "ies") \ 262 X(uint64_t, ifpu_npi_hash_search_total, "total table entry search%s", "", "es") \ 263 X(uint64_t, ifpu_npi_hash_search_max, "max hash table entry search%s", "", "es") \ 264 X(uint64_t, ifpu_so_match_wake_pkt, "match so wake packet call%s", "", "s") \ 265 X(uint64_t, ifpu_ch_match_wake_pkt, "match ch wake packet call%s", "", "s") \ 266 X(uint64_t, ifpu_ipv4_wake_pkt, "IPv4 wake packet%s", "", "s") \ 267 X(uint64_t, ifpu_ipv6_wake_pkt, "IPv6 wake packet%s", "", "s") \ 268 X(uint64_t, ifpu_tcp_wake_pkt, "TCP wake packet%s", "", "s") \ 269 X(uint64_t, ifpu_udp_wake_pkt, "UDP wake packet%s", "", "s") \ 270 X(uint64_t, ifpu_isakmp_natt_wake_pkt, "ISAKMP NAT traversal wake packet%s", "", "s") \ 271 X(uint64_t, ifpu_esp_wake_pkt, "ESP wake packet%s", "", "s") \ 272 X(uint64_t, ifpu_bad_proto_wake_pkt, "bad protocol wake packet%s", "", "s") \ 273 X(uint64_t, ifpu_bad_family_wake_pkt, "bad family wake packet%s", "", "s") \ 274 X(uint64_t, ifpu_wake_pkt_event, "wake packet event%s", "", "s") \ 275 X(uint64_t, ifpu_dup_wake_pkt_event, "duplicate wake packet event%s in same wake cycle", "", "s") \ 276 X(uint64_t, ifpu_wake_pkt_event_error, "wake packet event%s undelivered", "", "s") \ 277 X(uint64_t, ifpu_unattributed_wake_event, "unattributed wake packet event%s", "", "s") \ 278 X(uint64_t, ifpu_dup_unattributed_wake_event, "duplicate unattributed wake packet event%s in same wake cycle", "", "s") \ 279 X(uint64_t, ifpu_unattributed_wake_event_error, "unattributed wake packet event%s undelivered", "", "s") \ 280 X(uint64_t, ifpu_unattributed_null_recvif, "unattributed wake packet%s received with null interface", "", "s") \ 281 X(uint64_t, ifpu_match_wake_pkt_no_flag, "bad packet%s without wake flag", "", "s") \ 282 X(uint64_t, ifpu_frag_wake_pkt, "pure fragment wake packet%s", "", "s") \ 283 X(uint64_t, ifpu_incomplete_tcp_hdr_pkt, "packet%s with incomplete TCP header", "", "s") \ 284 X(uint64_t, ifpu_incomplete_udp_hdr_pkt, "packet%s with incomplete UDP header", "", "s") \ 285 X(uint64_t, ifpu_npi_not_added_no_wakeuuid, "port entr%s not added with wakeuuid not set", "y", "ies") \ 286 X(uint64_t, ifpu_deferred_isakmp_natt_wake_pkt, "deferred matching of ISAKMP NAT traversal wake packet%s", "", "s") \ 287 X(uint64_t, ifpu_spurious_wake_event, "spurious wake packet event%s", "", "s") \ 288 X(uint64_t, ifpu_delayed_attributed_wake_event, "delayed attributed wake packet event%s", "", "s") \ 289 X(uint64_t, ifpu_delayed_unattributed_wake_event, "delayed unattributed wake packet event%s", "", "s") \ 290 X(uint64_t, ifpu_delayed_wake_event_undelivered, "undelivered delayed wake packet event%s", "", "s") 291 292 struct if_ports_used_stats { 293 #define X(_type, _field, ...) _type _field; 294 IF_PORTS_USED_STATS_LIST 295 #undef X 296 }; 297 298 #ifdef XNU_KERNEL_PRIVATE 299 300 extern int if_ports_used_verbose; 301 302 void if_ports_used_init(void); 303 304 void if_ports_used_update_wakeuuid(struct ifnet *); 305 306 struct inpcb; 307 bool if_ports_used_add_inpcb(const uint32_t ifindex, const struct inpcb *inp); 308 309 #if SKYWALK 310 struct ns_flow_info; 311 struct flow_entry; 312 bool if_ports_used_add_flow_entry(const struct flow_entry *fe, const uint32_t ifindex, 313 const struct ns_flow_info *nfi, uint32_t ns_flags); 314 void if_ports_used_match_pkt(struct ifnet *ifp, struct __kern_packet *pkt); 315 #endif /* SKYWALK */ 316 317 void if_ports_used_match_mbuf(struct ifnet *ifp, protocol_family_t proto_family, 318 struct mbuf *m); 319 320 #endif /* XNU_KERNEL_PRIVATE */ 321 #endif /* PRIVATE */ 322 323 #endif /* _NET_IF_PORT_USED_H_ */ 324