1 /* 2 * Copyright (c) 2017-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 30 #ifndef _NET_IF_PORT_USED_H_ 31 #define _NET_IF_PORT_USED_H_ 32 33 #ifdef PRIVATE 34 35 #include <sys/types.h> 36 #include <stdint.h> 37 #include <sys/proc.h> 38 #include <sys/queue.h> 39 #include <sys/_types/_timeval32.h> 40 #include <net/if.h> 41 #include <netinet/in.h> 42 #include <uuid/uuid.h> 43 #include <stdbool.h> 44 45 #define IP_PORTRANGE_SIZE 65536 46 47 /* 48 * The sysctl "net.link.generic.system.port_used.list" returns: 49 * - one "struct xnpigen" as a preamble 50 * - zero or more "struct net_port_info" according to xng_npi_count 51 * 52 * The list may contain information several interfaces if several drivers 53 * queried the list of port to offload 54 * 55 * The same local port may have more than one "struct net_port_info" on 56 * a given interface, for example when a local server has mutiple clients 57 * connections 58 */ 59 60 struct xnpigen { 61 uint32_t xng_len; /* length of this data structure */ 62 uint32_t xng_gen; /* how many times the list was built */ 63 uint32_t xng_npi_count; /* number of net_port_info following */ 64 uint32_t xng_npi_size; /* number of struct net_port_info */ 65 uuid_t xng_wakeuuid; /* WakeUUID when list was built */ 66 }; 67 68 union in_addr_4_6 { 69 struct in_addr _in_a_4; 70 struct in6_addr _in_a_6; 71 }; 72 73 #define NPIF_IPV4 0x0001 74 #define NPIF_IPV6 0x0002 75 #define NPIF_TCP 0x0004 76 #define NPIF_UDP 0x0008 77 #define NPIF_DELEGATED 0x0010 78 #define NPIF_SOCKET 0x0020 79 #define NPIF_CHANNEL 0x0040 80 #define NPIF_LISTEN 0x0080 81 #define NPIF_WAKEPKT 0x0100 82 #define NPIF_NOWAKE 0x0200 /* flow marked with SO_NOWAKEFROMSLEEP are normally excluded */ 83 #define NPIF_FRAG 0x0400 /* packet is pure fragment (i.e. no src and dst port) */ 84 #define NPIF_ESP 0x0800 /* for logging only */ 85 #define NPIF_COMPLINK 0x1000 /* interface is companion link */ 86 87 #define NPI_HAS_EFFECTIVE_UUID 1 88 89 struct net_port_info { 90 uint16_t npi_if_index; 91 uint16_t npi_flags; /* NPIF_xxx */ 92 struct timeval32 npi_timestamp; /* when passed to driver */ 93 uuid_t npi_flow_uuid; 94 in_port_t npi_local_port; /* network byte order */ 95 in_port_t npi_foreign_port; /* network byte order */ 96 union in_addr_4_6 npi_local_addr_; 97 union in_addr_4_6 npi_foreign_addr_; 98 pid_t npi_owner_pid; 99 pid_t npi_effective_pid; 100 char npi_owner_pname[MAXCOMLEN + 1]; 101 char npi_effective_pname[MAXCOMLEN + 1]; 102 uuid_t npi_owner_uuid; 103 uuid_t npi_effective_uuid; 104 }; 105 106 #define npi_local_addr_in npi_local_addr_._in_a_4 107 #define npi_foreign_addr_in npi_foreign_addr_._in_a_4 108 109 #define npi_local_addr_in6 npi_local_addr_._in_a_6 110 #define npi_foreign_addr_in6 npi_foreign_addr_._in_a_6 111 112 #define NPI_HAS_WAKE_EVENT_TUPLE 1 113 114 struct net_port_info_wake_event { 115 uuid_t wake_uuid; 116 struct timeval32 wake_pkt_timestamp; /* when processed by networking stack */ 117 uint16_t wake_pkt_if_index; /* interface of incoming wake packet */ 118 in_port_t wake_pkt_port; /* local port in network byte order */ 119 uint16_t wake_pkt_flags; /* NPIF_xxx */ 120 pid_t wake_pkt_owner_pid; 121 pid_t wake_pkt_effective_pid; 122 char wake_pkt_owner_pname[MAXCOMLEN + 1]; 123 char wake_pkt_effective_pname[MAXCOMLEN + 1]; 124 uuid_t wake_pkt_owner_uuid; 125 uuid_t wake_pkt_effective_uuid; 126 /* Following added with NPI_HAS_WAKE_EVENT_TUPLE */ 127 in_port_t wake_pkt_foreign_port; /* network byte order */ 128 union in_addr_4_6 wake_pkt_local_addr_; 129 union in_addr_4_6 wake_pkt_foreign_addr_; 130 char wake_pkt_ifname[IFNAMSIZ]; /* name + unit */ 131 }; 132 133 /* 134 * Note: una_wake_ptk_flags is expected to have NPIF_SOCKET or NPIF_CHANNEL 135 */ 136 #define NPI_MAX_UNA_WAKE_PKT_LEN 102 137 struct net_port_info_una_wake_event { 138 uuid_t una_wake_uuid; 139 struct timeval32 una_wake_pkt_timestamp; /* when processed by networking stack */ 140 uint16_t una_wake_pkt_if_index; /* interface of incoming wake packet */ 141 uint16_t una_wake_pkt_flags; /* NPIF_xxx */ 142 uint16_t _una_wake_pkt_reserved; /* not used */ 143 uint16_t una_wake_ptk_len; /* length of una_wake_pkt */ 144 uint8_t una_wake_pkt[NPI_MAX_UNA_WAKE_PKT_LEN]; /* initial portion of the IPv4/IPv6 packet */ 145 /* Following added with NPI_HAS_WAKE_EVENT_TUPLE */ 146 in_port_t una_wake_pkt_local_port; /* network byte order */ 147 in_port_t una_wake_pkt_foreign_port; /* network byte order */ 148 union in_addr_4_6 una_wake_pkt_local_addr_; 149 union in_addr_4_6 una_wake_pkt_foreign_addr_; 150 char una_wake_pkt_ifname[IFNAMSIZ]; /* name + unit */ 151 }; 152 153 #define IFPU_HAS_MATCH_WAKE_PKT_NO_FLAG 1 /* ifpu_match_wake_pkt_no_flag is defined */ 154 155 #define IF_PORTS_USED_STATS_LIST \ 156 X(uint64_t, ifpu_wakeuid_gen, "wakeuuid generation%s", "", "s") \ 157 X(uint64_t, ifpu_wakeuuid_not_set_count, "offload port list quer%s with wakeuuid not set", "y", "ies") \ 158 X(uint64_t, ifpu_npe_total, "total offload port entr%s created since boot", "y", "ies") \ 159 X(uint64_t, ifpu_npe_count, "current offload port entr%s", "y", "ies") \ 160 X(uint64_t, ifpu_npe_max, "max offload port entr%s", "y", "ies") \ 161 X(uint64_t, ifpu_npe_dup, "duplicate offload port entr%s", "y", "ies") \ 162 X(uint64_t, ifpu_npi_hash_search_total, "total table entry search%s", "", "es") \ 163 X(uint64_t, ifpu_npi_hash_search_max, "max hash table entry search%s", "", "es") \ 164 X(uint64_t, ifpu_so_match_wake_pkt, "match so wake packet call%s", "", "s") \ 165 X(uint64_t, ifpu_ch_match_wake_pkt, "match ch wake packet call%s", "", "s") \ 166 X(uint64_t, ifpu_ipv4_wake_pkt, "IPv4 wake packet%s", "", "s") \ 167 X(uint64_t, ifpu_ipv6_wake_pkt, "IPv6 wake packet%s", "", "s") \ 168 X(uint64_t, ifpu_tcp_wake_pkt, "TCP wake packet%s", "", "s") \ 169 X(uint64_t, ifpu_udp_wake_pkt, "UDP wake packet%s", "", "s") \ 170 X(uint64_t, ifpu_isakmp_natt_wake_pkt, "ISAKMP NAT traversal wake packet%s", "", "s") \ 171 X(uint64_t, ifpu_esp_wake_pkt, "ESP wake packet%s", "", "s") \ 172 X(uint64_t, ifpu_bad_proto_wake_pkt, "bad protocol wake packet%s", "", "s") \ 173 X(uint64_t, ifpu_bad_family_wake_pkt, "bad family wake packet%s", "", "s") \ 174 X(uint64_t, ifpu_wake_pkt_event, "wake packet event%s", "", "s") \ 175 X(uint64_t, ifpu_dup_wake_pkt_event, "duplicate wake packet event%s in same wake cycle", "", "s") \ 176 X(uint64_t, ifpu_wake_pkt_event_error, "wake packet event%s undelivered", "", "s") \ 177 X(uint64_t, ifpu_unattributed_wake_event, "unattributed wake packet event%s", "", "s") \ 178 X(uint64_t, ifpu_dup_unattributed_wake_event, "duplicate unattributed wake packet event%s in same wake cycle", "", "s") \ 179 X(uint64_t, ifpu_unattributed_wake_event_error, "unattributed wake packet event%s undelivered", "", "s") \ 180 X(uint64_t, ifpu_unattributed_null_recvif, "unattributed wake packet%s received with null interface", "", "s") \ 181 X(uint64_t, ifpu_match_wake_pkt_no_flag, "bad packet%s without wake flag", "", "s") \ 182 X(uint64_t, ifpu_frag_wake_pkt, "pure fragment wake packet%s", "", "s") \ 183 X(uint64_t, ifpu_incomplete_tcp_hdr_pkt, "packet%s with incomplete TCP header", "", "s") \ 184 X(uint64_t, ifpu_incomplete_udp_hdr_pkt, "packet%s with incomplete UDP header", "", "s") \ 185 X(uint64_t, ifpu_npi_not_added_no_wakeuuid, "port entr%s not added with wakeuuid not set", "y", "ies") \ 186 X(uint64_t, ifpu_deferred_isakmp_natt_wake_pkt, "deferred matching of ISAKMP NAT traversal wake packet%s", "", "s") 187 188 struct if_ports_used_stats { 189 #define X(_type, _field, ...) _type _field; 190 IF_PORTS_USED_STATS_LIST 191 #undef X 192 }; 193 194 #ifdef XNU_KERNEL_PRIVATE 195 196 void if_ports_used_init(void); 197 198 void if_ports_used_update_wakeuuid(struct ifnet *); 199 200 struct inpcb; 201 bool if_ports_used_add_inpcb(const uint32_t ifindex, const struct inpcb *inp); 202 203 #if SKYWALK 204 struct ns_flow_info; 205 struct flow_entry; 206 bool if_ports_used_add_flow_entry(const struct flow_entry *fe, const uint32_t ifindex, 207 const struct ns_flow_info *nfi, uint32_t ns_flags); 208 void if_ports_used_match_pkt(struct ifnet *ifp, struct __kern_packet *pkt); 209 #endif /* SKYWALK */ 210 211 void if_ports_used_match_mbuf(struct ifnet *ifp, protocol_family_t proto_family, 212 struct mbuf *m); 213 214 #endif /* XNU_KERNEL_PRIVATE */ 215 #endif /* PRIVATE */ 216 217 #endif /* _NET_IF_PORT_USED_H_ */ 218