xref: /xnu-12377.81.4/bsd/net/ntstat.h (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 2010-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 #ifndef __NTSTAT_H__
29 #define __NTSTAT_H__
30 #include <stdbool.h>
31 #include <netinet/in.h>
32 #include <net/if.h>
33 #include <net/if_var.h>
34 #include <net/net_api_stats.h>
35 #include <netinet/in_stat.h>
36 #include <netinet/tcp.h>
37 
38 #ifdef PRIVATE
39 #pragma mark -- Common Data Structures --
40 
41 #define __NSTAT_REVISION__      9
42 
43 typedef u_int32_t       nstat_provider_id_t;
44 typedef u_int64_t       nstat_src_ref_t;
45 typedef u_int64_t       nstat_event_flags_t;
46 
47 // The following event definitions are very provisional..
48 enum{
49 	NSTAT_EVENT_SRC_ADDED                    = 0x00000001
50 	, NSTAT_EVENT_SRC_REMOVED                = 0x00000002
51 	, NSTAT_EVENT_SRC_QUERIED                = 0x00000004
52 	, NSTAT_EVENT_SRC_QUERIED_ALL            = 0x00000008
53 	, NSTAT_EVENT_SRC_WILL_CHANGE_STATE      = 0x00000010
54 	, NSTAT_EVENT_SRC_DID_CHANGE_STATE       = 0x00000020
55 	, NSTAT_EVENT_SRC_WILL_CHANGE_OWNER      = 0x00000040
56 	, NSTAT_EVENT_SRC_DID_CHANGE_OWNER       = 0x00000080
57 	, NSTAT_EVENT_SRC_WILL_CHANGE_PROPERTY   = 0x00000100
58 	, NSTAT_EVENT_SRC_DID_CHANGE_PROPERTY    = 0x00000200
59 	, NSTAT_EVENT_SRC_ENTER_CELLFALLBACK     = 0x00000400
60 	, NSTAT_EVENT_SRC_EXIT_CELLFALLBACK      = 0x00000800
61 	, NSTAT_EVENT_SRC_FLOW_STATE_LISTEN      = 0x00001000
62 	, NSTAT_EVENT_SRC_FLOW_STATE_OUTBOUND    = 0x00002000
63 	, NSTAT_EVENT_SRC_FLOW_UUID_ASSIGNED     = 0x00004000
64 	, NSTAT_EVENT_SRC_FLOW_UUID_CHANGED      = 0x00008000
65 #if (DEBUG || DEVELOPMENT)
66 	, NSTAT_EVENT_SRC_RESERVED_1             = 0x00010000
67 	, NSTAT_EVENT_SRC_RESERVED_2             = 0x00020000
68 #endif /* (DEBUG || DEVELOPMENT) */
69 	, NSTAT_EVENT_SRC_PREV_EVENT_DISCARDED   = 0x80000000
70 };
71 
72 typedef struct nstat_counts {
73 	/* Counters */
74 	u_int64_t       nstat_rxpackets __attribute__((aligned(sizeof(u_int64_t))));
75 	u_int64_t       nstat_rxbytes   __attribute__((aligned(sizeof(u_int64_t))));
76 	u_int64_t       nstat_txpackets __attribute__((aligned(sizeof(u_int64_t))));
77 	u_int64_t       nstat_txbytes   __attribute__((aligned(sizeof(u_int64_t))));
78 
79 	u_int64_t       nstat_cell_rxbytes      __attribute__((aligned(sizeof(u_int64_t))));
80 	u_int64_t       nstat_cell_txbytes      __attribute__((aligned(sizeof(u_int64_t))));
81 	u_int64_t       nstat_wifi_rxbytes      __attribute__((aligned(sizeof(u_int64_t))));
82 	u_int64_t       nstat_wifi_txbytes      __attribute__((aligned(sizeof(u_int64_t))));
83 	u_int64_t       nstat_wired_rxbytes     __attribute__((aligned(sizeof(u_int64_t))));
84 	u_int64_t       nstat_wired_txbytes     __attribute__((aligned(sizeof(u_int64_t))));
85 
86 	u_int32_t       nstat_rxduplicatebytes;
87 	u_int32_t       nstat_rxoutoforderbytes;
88 	u_int32_t       nstat_txretransmit;
89 
90 	u_int32_t       nstat_connectattempts;
91 	u_int32_t       nstat_connectsuccesses;
92 
93 	u_int32_t       nstat_min_rtt;
94 	u_int32_t       nstat_avg_rtt;
95 	u_int32_t       nstat_var_rtt;
96 } nstat_counts;
97 
98 // Note, the nstat_detailed_counts structure is not intended for route statistics,
99 // hence no equivalent of the nstat_connectattempts and nstat_connectsuccesses within nstat_counts
100 typedef struct nstat_detailed_counts {
101 	/* Counters */
102 	struct media_stats  nstat_media_stats   __attribute__((aligned(sizeof(u_int64_t))));
103 
104 	u_int64_t       nstat_rxduplicatebytes;
105 	u_int64_t       nstat_rxoutoforderbytes;
106 	u_int64_t       nstat_txretransmit;
107 
108 	u_int32_t       nstat_min_rtt;
109 	u_int32_t       nstat_avg_rtt;
110 	u_int32_t       nstat_var_rtt;
111 	u_int32_t       nstat_xtra_flags;       // Reserved
112 	uuid_t          nstat_xtra_uuid;        // Reserved
113 } nstat_detailed_counts;
114 
115 #define NSTAT_SYSINFO_KEYVAL_STRING_MAXSIZE     24
116 typedef struct nstat_sysinfo_keyval {
117 	u_int32_t       nstat_sysinfo_key;
118 	u_int32_t       nstat_sysinfo_flags;
119 	union {
120 		int64_t nstat_sysinfo_scalar;
121 		double  nstat_sysinfo_distribution;
122 		u_int8_t nstat_sysinfo_string[NSTAT_SYSINFO_KEYVAL_STRING_MAXSIZE];
123 	} u;
124 	u_int32_t       nstat_sysinfo_valsize;
125 	u_int8_t        reserved[4];
126 }  nstat_sysinfo_keyval;
127 
128 #define NSTAT_SYSINFO_FLAG_SCALAR       0x0001
129 #define NSTAT_SYSINFO_FLAG_DISTRIBUTION 0x0002
130 #define NSTAT_SYSINFO_FLAG_STRING       0x0004
131 
132 #define NSTAT_MAX_MSG_SIZE      4096
133 
134 typedef struct nstat_sysinfo_counts {
135 	/* Counters */
136 	u_int32_t       nstat_sysinfo_len;
137 	u_int32_t       pad;
138 	nstat_sysinfo_keyval        nstat_sysinfo_keyvals[];
139 }  nstat_sysinfo_counts;
140 
141 enum{
142 	NSTAT_SYSINFO_KEY_MBUF_256B_TOTAL        = 1
143 	, NSTAT_SYSINFO_KEY_MBUF_2KB_TOTAL       = 2
144 	, NSTAT_SYSINFO_KEY_MBUF_4KB_TOTAL       = 3
145 	, NSTAT_SYSINFO_KEY_SOCK_MBCNT           = 4
146 	, NSTAT_SYSINFO_KEY_SOCK_ATMBLIMIT       = 5
147 	, NSTAT_SYSINFO_KEY_IPV4_AVGRTT          = 6
148 	, NSTAT_SYSINFO_KEY_IPV6_AVGRTT          = 7
149 	, NSTAT_SYSINFO_KEY_SEND_PLR             = 8
150 	, NSTAT_SYSINFO_KEY_RECV_PLR             = 9
151 	, NSTAT_SYSINFO_KEY_SEND_TLRTO           = 10
152 	, NSTAT_SYSINFO_KEY_SEND_REORDERRATE     = 11
153 	, NSTAT_SYSINFO_CONNECTION_ATTEMPTS      = 12
154 	, NSTAT_SYSINFO_CONNECTION_ACCEPTS       = 13
155 	, NSTAT_SYSINFO_ECN_CLIENT_SETUP         = 14
156 	, NSTAT_SYSINFO_ECN_SERVER_SETUP         = 15
157 	, NSTAT_SYSINFO_ECN_CLIENT_SUCCESS       = 16
158 	, NSTAT_SYSINFO_ECN_SERVER_SUCCESS       = 17
159 	, NSTAT_SYSINFO_ECN_NOT_SUPPORTED        = 18
160 	, NSTAT_SYSINFO_ECN_LOST_SYN             = 19
161 	, NSTAT_SYSINFO_ECN_LOST_SYNACK          = 20
162 	, NSTAT_SYSINFO_ECN_RECV_CE              = 21
163 	, NSTAT_SYSINFO_ECN_RECV_ECE             = 22
164 	, NSTAT_SYSINFO_ECN_SENT_ECE             = 23
165 	, NSTAT_SYSINFO_ECN_CONN_RECV_CE         = 24
166 	, NSTAT_SYSINFO_ECN_CONN_PLNOCE          = 25
167 	, NSTAT_SYSINFO_ECN_CONN_PL_CE           = 26
168 	, NSTAT_SYSINFO_ECN_CONN_NOPL_CE         = 27
169 	, NSTAT_SYSINFO_MBUF_16KB_TOTAL          = 28
170 	, NSTAT_SYSINFO_ECN_CLIENT_ENABLED       = 29
171 	, NSTAT_SYSINFO_ECN_SERVER_ENABLED       = 30
172 	, NSTAT_SYSINFO_ECN_CONN_RECV_ECE        = 31
173 	, NSTAT_SYSINFO_MBUF_MEM_RELEASED        = 32
174 	, NSTAT_SYSINFO_MBUF_DRAIN_CNT           = 33
175 	, NSTAT_SYSINFO_TFO_SYN_DATA_RCV         = 34
176 	, NSTAT_SYSINFO_TFO_COOKIE_REQ_RCV       = 35
177 	, NSTAT_SYSINFO_TFO_COOKIE_SENT          = 36
178 	, NSTAT_SYSINFO_TFO_COOKIE_INVALID       = 37
179 	, NSTAT_SYSINFO_TFO_COOKIE_REQ           = 38
180 	, NSTAT_SYSINFO_TFO_COOKIE_RCV           = 39
181 	, NSTAT_SYSINFO_TFO_SYN_DATA_SENT        = 40
182 	, NSTAT_SYSINFO_TFO_SYN_DATA_ACKED       = 41
183 	, NSTAT_SYSINFO_TFO_SYN_LOSS             = 42
184 	, NSTAT_SYSINFO_TFO_BLACKHOLE            = 43
185 	, NSTAT_SYSINFO_ECN_FALLBACK_SYNLOSS     = 44
186 	, NSTAT_SYSINFO_ECN_FALLBACK_REORDER     = 45
187 	, NSTAT_SYSINFO_ECN_FALLBACK_CE          = 46
188 	, NSTAT_SYSINFO_ECN_IFNET_TYPE           = 47
189 	, NSTAT_SYSINFO_ECN_IFNET_PROTO          = 48
190 	, NSTAT_SYSINFO_ECN_IFNET_CLIENT_SETUP   = 49
191 	, NSTAT_SYSINFO_ECN_IFNET_SERVER_SETUP   = 50
192 	, NSTAT_SYSINFO_ECN_IFNET_CLIENT_SUCCESS = 51
193 	, NSTAT_SYSINFO_ECN_IFNET_SERVER_SUCCESS = 52
194 	, NSTAT_SYSINFO_ECN_IFNET_PEER_NOSUPPORT = 53
195 	, NSTAT_SYSINFO_ECN_IFNET_SYN_LOST       = 54
196 	, NSTAT_SYSINFO_ECN_IFNET_SYNACK_LOST    = 55
197 	, NSTAT_SYSINFO_ECN_IFNET_RECV_CE        = 56
198 	, NSTAT_SYSINFO_ECN_IFNET_RECV_ECE       = 57
199 	, NSTAT_SYSINFO_ECN_IFNET_SENT_ECE       = 58
200 	, NSTAT_SYSINFO_ECN_IFNET_CONN_RECV_CE   = 59
201 	, NSTAT_SYSINFO_ECN_IFNET_CONN_RECV_ECE  = 60
202 	, NSTAT_SYSINFO_ECN_IFNET_CONN_PLNOCE    = 61
203 	, NSTAT_SYSINFO_ECN_IFNET_CONN_PLCE      = 62
204 	, NSTAT_SYSINFO_ECN_IFNET_CONN_NOPLCE    = 63
205 	, NSTAT_SYSINFO_ECN_IFNET_FALLBACK_SYNLOSS = 64
206 	, NSTAT_SYSINFO_ECN_IFNET_FALLBACK_REORDER = 65
207 	, NSTAT_SYSINFO_ECN_IFNET_FALLBACK_CE    = 66
208 	, NSTAT_SYSINFO_ECN_IFNET_ON_RTT_AVG     = 67
209 	, NSTAT_SYSINFO_ECN_IFNET_ON_RTT_VAR     = 68
210 	, NSTAT_SYSINFO_ECN_IFNET_ON_OOPERCENT   = 69
211 	, NSTAT_SYSINFO_ECN_IFNET_ON_SACK_EPISODE = 70
212 	, NSTAT_SYSINFO_ECN_IFNET_ON_REORDER_PERCENT = 71
213 	, NSTAT_SYSINFO_ECN_IFNET_ON_RXMIT_PERCENT = 72
214 	, NSTAT_SYSINFO_ECN_IFNET_ON_RXMIT_DROP  = 73
215 	, NSTAT_SYSINFO_ECN_IFNET_OFF_RTT_AVG    = 74
216 	, NSTAT_SYSINFO_ECN_IFNET_OFF_RTT_VAR    = 75
217 	, NSTAT_SYSINFO_ECN_IFNET_OFF_OOPERCENT  = 76
218 	, NSTAT_SYSINFO_ECN_IFNET_OFF_SACK_EPISODE = 77
219 	, NSTAT_SYSINFO_ECN_IFNET_OFF_REORDER_PERCENT = 78
220 	, NSTAT_SYSINFO_ECN_IFNET_OFF_RXMIT_PERCENT = 79
221 	, NSTAT_SYSINFO_ECN_IFNET_OFF_RXMIT_DROP = 80
222 	, NSTAT_SYSINFO_ECN_IFNET_ON_TOTAL_TXPKTS = 81
223 	, NSTAT_SYSINFO_ECN_IFNET_ON_TOTAL_RXMTPKTS = 82
224 	, NSTAT_SYSINFO_ECN_IFNET_ON_TOTAL_RXPKTS = 83
225 	, NSTAT_SYSINFO_ECN_IFNET_ON_TOTAL_OOPKTS = 84
226 	, NSTAT_SYSINFO_ECN_IFNET_ON_DROP_RST = 85
227 	, NSTAT_SYSINFO_ECN_IFNET_OFF_TOTAL_TXPKTS = 86
228 	, NSTAT_SYSINFO_ECN_IFNET_OFF_TOTAL_RXMTPKTS = 87
229 	, NSTAT_SYSINFO_ECN_IFNET_OFF_TOTAL_RXPKTS = 88
230 	, NSTAT_SYSINFO_ECN_IFNET_OFF_TOTAL_OOPKTS = 89
231 	, NSTAT_SYSINFO_ECN_IFNET_OFF_DROP_RST = 90
232 	, NSTAT_SYSINFO_ECN_IFNET_TOTAL_CONN = 91
233 	, NSTAT_SYSINFO_TFO_COOKIE_WRONG = 92
234 	, NSTAT_SYSINFO_TFO_NO_COOKIE_RCV = 93
235 	, NSTAT_SYSINFO_TFO_HEURISTICS_DISABLE = 94
236 	, NSTAT_SYSINFO_TFO_SEND_BLACKHOLE = 95
237 	, NSTAT_SYSINFO_KEY_SOCK_MBFLOOR = 96
238 	, NSTAT_SYSINFO_IFNET_UNSENT_DATA = 97
239 	, NSTAT_SYSINFO_ECN_IFNET_FALLBACK_DROPRST = 98
240 	, NSTAT_SYSINFO_ECN_IFNET_FALLBACK_DROPRXMT = 99
241 	, NSTAT_SYSINFO_LIM_IFNET_SIGNATURE = 100
242 	, NSTAT_SYSINFO_LIM_IFNET_DL_MAX_BANDWIDTH = 101
243 	, NSTAT_SYSINFO_LIM_IFNET_UL_MAX_BANDWIDTH = 102
244 	, NSTAT_SYSINFO_LIM_IFNET_PACKET_LOSS_PERCENT = 103
245 	, NSTAT_SYSINFO_LIM_IFNET_PACKET_OOO_PERCENT = 104
246 	, NSTAT_SYSINFO_LIM_IFNET_RTT_VARIANCE = 105
247 	, NSTAT_SYSINFO_LIM_IFNET_RTT_MIN = 106
248 	, NSTAT_SYSINFO_LIM_IFNET_RTT_AVG = 107
249 	, NSTAT_SYSINFO_LIM_IFNET_CONN_TIMEOUT_PERCENT = 108
250 	, NSTAT_SYSINFO_LIM_IFNET_DL_DETECTED = 109
251 	, NSTAT_SYSINFO_LIM_IFNET_UL_DETECTED = 110
252 	, NSTAT_SYSINFO_LIM_IFNET_TYPE = 111
253 
254 	, NSTAT_SYSINFO_API_IF_FLTR_ATTACH = 112
255 	, NSTAT_SYSINFO_API_IF_FLTR_ATTACH_OS = 113
256 	, NSTAT_SYSINFO_API_IP_FLTR_ADD = 114
257 	, NSTAT_SYSINFO_API_IP_FLTR_ADD_OS = 115
258 	, NSTAT_SYSINFO_API_SOCK_FLTR_ATTACH = 116
259 	, NSTAT_SYSINFO_API_SOCK_FLTR_ATTACH_OS = 117
260 
261 	, NSTAT_SYSINFO_API_SOCK_ALLOC_TOTAL = 118
262 	, NSTAT_SYSINFO_API_SOCK_ALLOC_KERNEL = 119
263 	, NSTAT_SYSINFO_API_SOCK_ALLOC_KERNEL_OS = 120
264 	, NSTAT_SYSINFO_API_SOCK_NECP_CLIENTUUID = 121
265 
266 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_LOCAL = 122
267 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_ROUTE = 123
268 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_INET = 124
269 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_INET6 = 125
270 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_SYSTEM = 126
271 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_MULTIPATH = 127
272 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_KEY = 128
273 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_NDRV = 129
274 	, NSTAT_SYSINFO_API_SOCK_DOMAIN_OTHER = 130
275 
276 	, NSTAT_SYSINFO_API_SOCK_INET_STREAM= 131
277 	, NSTAT_SYSINFO_API_SOCK_INET_DGRAM = 132
278 	, NSTAT_SYSINFO_API_SOCK_INET_DGRAM_CONNECTED = 133
279 	, NSTAT_SYSINFO_API_SOCK_INET_DGRAM_DNS = 134
280 	, NSTAT_SYSINFO_API_SOCK_INET_DGRAM_NO_DATA = 135
281 
282 	, NSTAT_SYSINFO_API_SOCK_INET6_STREAM= 136
283 	, NSTAT_SYSINFO_API_SOCK_INET6_DGRAM = 137
284 	, NSTAT_SYSINFO_API_SOCK_INET6_DGRAM_CONNECTED = 138
285 	, NSTAT_SYSINFO_API_SOCK_INET6_DGRAM_DNS = 139
286 	, NSTAT_SYSINFO_API_SOCK_INET6_DGRAM_NO_DATA = 140
287 
288 	, NSTAT_SYSINFO_API_SOCK_INET_MCAST_JOIN = 141
289 	, NSTAT_SYSINFO_API_SOCK_INET_MCAST_JOIN_OS = 142
290 
291 	, NSTAT_SYSINFO_API_SOCK_INET6_STREAM_EXTHDR_IN = 143
292 	, NSTAT_SYSINFO_API_SOCK_INET6_STREAM_EXTHDR_OUT = 144
293 	, NSTAT_SYSINFO_API_SOCK_INET6_DGRAM_EXTHDR_IN = 145
294 	, NSTAT_SYSINFO_API_SOCK_INET6_DGRAM_EXTHDR_OUT = 146
295 
296 	, NSTAT_SYSINFO_API_NEXUS_FLOW_INET_STREAM = 147
297 	, NSTAT_SYSINFO_API_NEXUS_FLOW_INET_DATAGRAM = 148
298 
299 	, NSTAT_SYSINFO_API_NEXUS_FLOW_INET6_STREAM = 149
300 	, NSTAT_SYSINFO_API_NEXUS_FLOW_INET6_DATAGRAM = 150
301 
302 	, NSTAT_SYSINFO_API_IFNET_ALLOC = 151
303 	, NSTAT_SYSINFO_API_IFNET_ALLOC_OS = 152
304 
305 	, NSTAT_SYSINFO_API_PF_ADDRULE = 153
306 	, NSTAT_SYSINFO_API_PF_ADDRULE_OS = 154
307 
308 	, NSTAT_SYSINFO_API_VMNET_START = 155
309 
310 	, NSTAT_SYSINFO_API_IF_NETAGENT_ENABLED = 156
311 
312 	, NSTAT_SYSINFO_API_REPORT_INTERVAL = 157
313 
314 	, NSTAT_SYSINFO_MPTCP_HANDOVER_ATTEMPT = 158
315 	, NSTAT_SYSINFO_MPTCP_INTERACTIVE_ATTEMPT = 159
316 	, NSTAT_SYSINFO_MPTCP_AGGREGATE_ATTEMPT = 160
317 	, NSTAT_SYSINFO_MPTCP_FP_HANDOVER_ATTEMPT = 161 /* _FP_ stands for first-party */
318 	, NSTAT_SYSINFO_MPTCP_FP_INTERACTIVE_ATTEMPT = 162
319 	, NSTAT_SYSINFO_MPTCP_FP_AGGREGATE_ATTEMPT = 163
320 	, NSTAT_SYSINFO_MPTCP_HEURISTIC_FALLBACK = 164
321 	, NSTAT_SYSINFO_MPTCP_FP_HEURISTIC_FALLBACK = 165
322 	, NSTAT_SYSINFO_MPTCP_HANDOVER_SUCCESS_WIFI = 166
323 	, NSTAT_SYSINFO_MPTCP_HANDOVER_SUCCESS_CELL = 167
324 	, NSTAT_SYSINFO_MPTCP_INTERACTIVE_SUCCESS = 168
325 	, NSTAT_SYSINFO_MPTCP_AGGREGATE_SUCCESS = 169
326 	, NSTAT_SYSINFO_MPTCP_FP_HANDOVER_SUCCESS_WIFI = 170
327 	, NSTAT_SYSINFO_MPTCP_FP_HANDOVER_SUCCESS_CELL = 171
328 	, NSTAT_SYSINFO_MPTCP_FP_INTERACTIVE_SUCCESS = 172
329 	, NSTAT_SYSINFO_MPTCP_FP_AGGREGATE_SUCCESS = 173
330 	, NSTAT_SYSINFO_MPTCP_HANDOVER_CELL_FROM_WIFI = 174
331 	, NSTAT_SYSINFO_MPTCP_HANDOVER_WIFI_FROM_CELL = 175
332 	, NSTAT_SYSINFO_MPTCP_INTERACTIVE_CELL_FROM_WIFI = 176
333 	, NSTAT_SYSINFO_MPTCP_HANDOVER_CELL_BYTES = 177
334 	, NSTAT_SYSINFO_MPTCP_INTERACTIVE_CELL_BYTES = 178
335 	, NSTAT_SYSINFO_MPTCP_AGGREGATE_CELL_BYTES = 179
336 	, NSTAT_SYSINFO_MPTCP_HANDOVER_ALL_BYTES = 180
337 	, NSTAT_SYSINFO_MPTCP_INTERACTIVE_ALL_BYTES = 181
338 	, NSTAT_SYSINFO_MPTCP_AGGREGATE_ALL_BYTES = 182
339 	, NSTAT_SYSINFO_MPTCP_BACK_TO_WIFI = 183
340 	, NSTAT_SYSINFO_MPTCP_WIFI_PROXY = 184
341 	, NSTAT_SYSINFO_MPTCP_CELL_PROXY = 185
342 	, NSTAT_SYSINFO_ECN_IFNET_FALLBACK_SYNRST = 186
343 	, NSTAT_SYSINFO_MPTCP_TRIGGERED_CELL = 187
344 
345 // NSTAT_SYSINFO_ENUM_VERSION must be updated any time a value is added
346 #define NSTAT_SYSINFO_ENUM_VERSION      20180416
347 };
348 
349 #define NSTAT_SYSINFO_API_FIRST NSTAT_SYSINFO_API_IF_FLTR_ATTACH
350 #define NSTAT_SYSINFO_API_LAST  NSTAT_SYSINFO_API_REPORT_INTERVAL
351 
352 #pragma mark -- Network Statistics Providers --
353 
354 
355 // Interface properties.  These are constrained to fit in a 32 bit word
356 
357 #define NSTAT_IFNET_IS_UNKNOWN_TYPE                 0x00000001
358 #define NSTAT_IFNET_IS_LOOPBACK                     0x00000002
359 #define NSTAT_IFNET_IS_CELLULAR                     0x00000004
360 #define NSTAT_IFNET_IS_WIFI                         0x00000008
361 #define NSTAT_IFNET_IS_WIRED                        0x00000010
362 #define NSTAT_IFNET_IS_AWDL                         0x00000020
363 #define NSTAT_IFNET_IS_EXPENSIVE                    0x00000040
364 #define NSTAT_IFNET_IS_VPN                          0x00000080
365 #define NSTAT_IFNET_VIA_CELLFALLBACK                0x00000100
366 #define NSTAT_IFNET_IS_COMPANIONLINK                0x00000200
367 #define NSTAT_IFNET_IS_CONSTRAINED                  0x00000400
368 
369 // The following local and non-local flags are set only if fully known
370 // They are mutually exclusive but there is no guarantee that one or the other will be set
371 #define NSTAT_IFNET_IS_LOCAL                        0x00000800
372 #define NSTAT_IFNET_IS_NON_LOCAL                    0x00001000
373 
374 // Properties relating to userland providers
375 #define NSTAT_IFNET_ROUTE_VALUE_UNOBTAINABLE        0x00002000
376 #define NSTAT_IFNET_FLOWSWITCH_VALUE_UNOBTAINABLE   0x00004000
377 
378 // Additional interface properties
379 #define NSTAT_IFNET_IS_LLW                          0x00008000
380 #define NSTAT_IFNET_IS_WIFI_INFRA                   0x00010000
381 #define NSTAT_IFNET_PEEREGRESSINTERFACE_IS_CELLULAR 0x00020000
382 #define NSTAT_IFNET_IS_COMPANIONLINK_BT             0x00040000
383 #define NSTAT_IFNET_IS_ULTRA_CONSTRAINED            0x00080000
384 
385 // Not interface properties, but used for filtering in similar fashion
386 #define NSTAT_NECP_CONN_HAS_NET_ACCESS              0x01000000
387 
388 // Not interface properties but conveniently handled in the same flags word
389 #define NSTAT_SOURCE_IS_LISTENER                    0x02000000
390 #define NSTAT_SOURCE_IS_INBOUND                     0x04000000
391 #define NSTAT_SOURCE_IS_OUTBOUND                    0x08000000
392 
393 
394 typedef enum {
395 	NSTAT_PROVIDER_NONE           = 0
396 	, NSTAT_PROVIDER_ROUTE        = 1
397 	, NSTAT_PROVIDER_TCP_KERNEL   = 2
398 	, NSTAT_PROVIDER_TCP_USERLAND = 3
399 	, NSTAT_PROVIDER_UDP_KERNEL   = 4
400 	, NSTAT_PROVIDER_UDP_USERLAND = 5
401 	, NSTAT_PROVIDER_IFNET        = 6
402 	, NSTAT_PROVIDER_SYSINFO      = 7
403 	, NSTAT_PROVIDER_QUIC_USERLAND = 8
404 	, NSTAT_PROVIDER_CONN_USERLAND = 9
405 	, NSTAT_PROVIDER_UDP_SUBFLOW   = 10
406 } nstat_provider_type_t;
407 #define NSTAT_PROVIDER_LAST NSTAT_PROVIDER_UDP_SUBFLOW
408 #define NSTAT_PROVIDER_COUNT (NSTAT_PROVIDER_LAST+1)
409 
410 typedef struct nstat_route_add_param {
411 	union{
412 		struct sockaddr_in      v4;
413 		struct sockaddr_in6     v6;
414 	} dst;
415 	union{
416 		struct sockaddr_in      v4;
417 		struct sockaddr_in6     v6;
418 	} mask;
419 	u_int32_t       ifindex;
420 } nstat_route_add_param;
421 
422 typedef struct nstat_tcp_add_param {
423 	union{
424 		struct sockaddr_in      v4;
425 		struct sockaddr_in6     v6;
426 	} local;
427 	union{
428 		struct sockaddr_in      v4;
429 		struct sockaddr_in6     v6;
430 	} remote;
431 } nstat_tcp_add_param;
432 
433 typedef struct nstat_interface_counts {
434 	u_int64_t       nstat_rxpackets;
435 	u_int64_t       nstat_rxbytes;
436 	u_int64_t       nstat_txpackets;
437 	u_int64_t       nstat_txbytes;
438 } nstat_interface_counts;
439 
440 #define NSTAT_MAX_DOMAIN_NAME_LENGTH           256 /* As per RFC 2181 for full domain name */
441 #define NSTAT_MAX_DOMAIN_OWNER_LENGTH          256
442 #define NSTAT_MAX_DOMAIN_TRACKER_CONTEXT       256
443 #define NSTAT_MAX_DOMAIN_ATTR_BUNDLE_ID        256
444 
445 typedef struct nstat_domain_info {
446 	char            domain_name[NSTAT_MAX_DOMAIN_NAME_LENGTH];
447 	char            domain_owner[NSTAT_MAX_DOMAIN_OWNER_LENGTH];
448 	char            domain_tracker_ctxt[NSTAT_MAX_DOMAIN_TRACKER_CONTEXT];
449 	char            domain_attributed_bundle_id[NSTAT_MAX_DOMAIN_ATTR_BUNDLE_ID];
450 	union{
451 		struct sockaddr_in      v4;
452 		struct sockaddr_in6     v6;
453 	} remote;
454 	bool            is_tracker;
455 	bool            is_non_app_initiated;
456 	bool            is_silent;
457 	uint8_t         reserved[1];
458 } nstat_domain_info __attribute__((aligned(sizeof(u_int64_t))));
459 
460 typedef struct nstat_tcp_descriptor {
461 	u_int64_t       upid __attribute__((aligned(sizeof(u_int64_t))));
462 	u_int64_t       eupid __attribute__((aligned(sizeof(u_int64_t))));
463 	u_int64_t       start_timestamp __attribute__((aligned(sizeof(u_int64_t))));
464 	u_int64_t       timestamp __attribute__((aligned(sizeof(u_int64_t))));
465 
466 	u_int64_t       rx_transfer_size __attribute__((aligned(sizeof(u_int64_t))));
467 	u_int64_t       tx_transfer_size __attribute__((aligned(sizeof(u_int64_t))));
468 
469 	activity_bitmap_t activity_bitmap;
470 
471 	u_int32_t       ifindex;
472 	u_int32_t       state;
473 
474 	u_int32_t       sndbufsize;
475 	u_int32_t       sndbufused;
476 	u_int32_t       rcvbufsize;
477 	u_int32_t       rcvbufused;
478 	u_int32_t       txunacked;
479 	u_int32_t       txwindow;
480 	u_int32_t       txcwindow;
481 	u_int32_t       traffic_class;
482 	u_int32_t       traffic_mgt_flags;
483 
484 	u_int32_t       pid;
485 	u_int32_t       epid;
486 
487 	union{
488 		struct sockaddr_in      v4;
489 		struct sockaddr_in6     v6;
490 	} local;
491 
492 	union{
493 		struct sockaddr_in      v4;
494 		struct sockaddr_in6     v6;
495 	} remote;
496 
497 	char            cc_algo[16];
498 	char            pname[64];
499 
500 	uuid_t          uuid;
501 	uuid_t          euuid;
502 	uuid_t          vuuid;
503 	uuid_t          fuuid;
504 	uid_t           persona_id;
505 	uid_t           uid;
506 	union {
507 		struct tcp_conn_status connstatus;
508 		// On armv7k, tcp_conn_status is 1 byte instead of 4
509 		uint8_t                                 __pad_connstatus[4];
510 	};
511 	uint32_t        ifnet_properties        __attribute__((aligned(4)));
512 	uint8_t         fallback_mode;
513 	uint8_t         reserved[3];
514 } nstat_tcp_descriptor;
515 
516 typedef struct nstat_tcp_add_param      nstat_udp_add_param;
517 
518 typedef struct nstat_udp_descriptor {
519 	u_int64_t       upid __attribute__((aligned(sizeof(u_int64_t))));
520 	u_int64_t       eupid __attribute__((aligned(sizeof(u_int64_t))));
521 	u_int64_t       start_timestamp __attribute__((aligned(sizeof(u_int64_t))));
522 	u_int64_t       timestamp __attribute__((aligned(sizeof(u_int64_t))));
523 
524 	activity_bitmap_t activity_bitmap;
525 
526 	union{
527 		struct sockaddr_in      v4;
528 		struct sockaddr_in6     v6;
529 	} local;
530 
531 	union{
532 		struct sockaddr_in      v4;
533 		struct sockaddr_in6     v6;
534 	} remote;
535 
536 	u_int32_t       ifindex;
537 
538 	u_int32_t       rcvbufsize;
539 	u_int32_t       rcvbufused;
540 	u_int32_t       traffic_class;
541 
542 	u_int32_t       pid;
543 	char            pname[64];
544 	u_int32_t       epid;
545 
546 	uuid_t          uuid;
547 	uuid_t          euuid;
548 	uuid_t          vuuid;
549 	uuid_t          fuuid;
550 	uid_t           persona_id;
551 	uid_t           uid;
552 	uint32_t        ifnet_properties;
553 	uint8_t         fallback_mode;
554 	uint8_t         reserved[3];
555 } nstat_udp_descriptor;
556 
557 /*
558  * XXX For now just typedef'ing TCP Nstat descriptor to nstat_quic_descriptor
559  * as for now they report very similar data.
560  * Later when we extend the QUIC descriptor we can just declare its own
561  * descriptor struct.
562  */
563 typedef struct nstat_tcp_add_param      nstat_quic_add_param;
564 typedef struct nstat_tcp_descriptor     nstat_quic_descriptor;
565 
566 typedef struct nstat_connection_descriptor {
567 	u_int64_t       start_timestamp __attribute__((aligned(sizeof(u_int64_t))));
568 	u_int64_t       timestamp;
569 	u_int64_t       upid;
570 	u_int64_t       eupid;
571 
572 	u_int32_t       pid;
573 	u_int32_t       epid;
574 	u_int32_t       ifnet_properties;
575 	char            pname[64];
576 	uuid_t          uuid;   /* UUID of the app */
577 	uuid_t          euuid;  /* Effective UUID */
578 	uuid_t          cuuid;  /* Connection UUID */
579 	uuid_t          puuid;  /* Parent UUID */
580 	uuid_t          fuuid;  /* Flow UUID */
581 	uid_t           persona_id;
582 	uid_t           uid;
583 	uint8_t         reserved[4];
584 } nstat_connection_descriptor;
585 
586 typedef struct nstat_route_descriptor {
587 	u_int64_t       id __attribute__((aligned(sizeof(u_int64_t))));
588 	u_int64_t       parent_id __attribute__((aligned(sizeof(u_int64_t))));
589 	u_int64_t       gateway_id __attribute__((aligned(sizeof(u_int64_t))));
590 
591 	union{
592 		struct sockaddr_in      v4;
593 		struct sockaddr_in6     v6;
594 		struct sockaddr         sa;
595 	} dst;
596 
597 	union{
598 		struct sockaddr_in      v4;
599 		struct sockaddr_in6     v6;
600 		struct sockaddr         sa;
601 	} mask;
602 
603 	union{
604 		struct sockaddr_in      v4;
605 		struct sockaddr_in6     v6;
606 		struct sockaddr         sa;
607 	} gateway;
608 
609 	u_int32_t       ifindex;
610 	u_int32_t       flags;
611 
612 	u_int8_t        reserved[4];
613 } nstat_route_descriptor;
614 
615 typedef struct nstat_ifnet_add_param {
616 	u_int64_t       threshold __attribute__((aligned(sizeof(u_int64_t))));
617 	u_int32_t       ifindex;
618 
619 	u_int8_t        reserved[4];
620 } nstat_ifnet_add_param;
621 
622 typedef struct nstat_ifnet_desc_cellular_status {
623 	u_int32_t valid_bitmask; /* indicates which fields are valid */
624 #define NSTAT_IFNET_DESC_CELL_LINK_QUALITY_METRIC_VALID         0x1
625 #define NSTAT_IFNET_DESC_CELL_UL_EFFECTIVE_BANDWIDTH_VALID      0x2
626 #define NSTAT_IFNET_DESC_CELL_UL_MAX_BANDWIDTH_VALID            0x4
627 #define NSTAT_IFNET_DESC_CELL_UL_MIN_LATENCY_VALID              0x8
628 #define NSTAT_IFNET_DESC_CELL_UL_EFFECTIVE_LATENCY_VALID        0x10
629 #define NSTAT_IFNET_DESC_CELL_UL_MAX_LATENCY_VALID              0x20
630 #define NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_VALID              0x40
631 #define NSTAT_IFNET_DESC_CELL_UL_BYTES_LOST_VALID               0x80
632 #define NSTAT_IFNET_DESC_CELL_UL_MIN_QUEUE_SIZE_VALID           0x100
633 #define NSTAT_IFNET_DESC_CELL_UL_AVG_QUEUE_SIZE_VALID           0x200
634 #define NSTAT_IFNET_DESC_CELL_UL_MAX_QUEUE_SIZE_VALID           0x400
635 #define NSTAT_IFNET_DESC_CELL_DL_EFFECTIVE_BANDWIDTH_VALID      0x800
636 #define NSTAT_IFNET_DESC_CELL_DL_MAX_BANDWIDTH_VALID            0x1000
637 #define NSTAT_IFNET_DESC_CELL_CONFIG_INACTIVITY_TIME_VALID      0x2000
638 #define NSTAT_IFNET_DESC_CELL_CONFIG_BACKOFF_TIME_VALID         0x4000
639 #define NSTAT_IFNET_DESC_CELL_MSS_RECOMMENDED_VALID             0x8000
640 	u_int32_t link_quality_metric;
641 	u_int32_t ul_effective_bandwidth; /* Measured uplink bandwidth based on
642 	                                   *  current activity (bps) */
643 	u_int32_t ul_max_bandwidth; /* Maximum supported uplink bandwidth
644 	                             *  (bps) */
645 	u_int32_t ul_min_latency; /* min expected uplink latency for first hop
646 	                           *  (ms) */
647 	u_int32_t ul_effective_latency; /* current expected uplink latency for
648 	                                 *  first hop (ms) */
649 	u_int32_t ul_max_latency; /* max expected uplink latency first hop
650 	                           *  (ms) */
651 	u_int32_t ul_retxt_level; /* Retransmission metric */
652 #define NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_NONE       1
653 #define NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_LOW        2
654 #define NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_MEDIUM     3
655 #define NSTAT_IFNET_DESC_CELL_UL_RETXT_LEVEL_HIGH       4
656 
657 	u_int32_t ul_bytes_lost; /* % of total bytes lost on uplink in Q10
658 	                          *  format */
659 	u_int32_t ul_min_queue_size; /* minimum bytes in queue */
660 	u_int32_t ul_avg_queue_size; /* average bytes in queue */
661 	u_int32_t ul_max_queue_size; /* maximum bytes in queue */
662 	u_int32_t dl_effective_bandwidth; /* Measured downlink bandwidth based
663 	                                   *  on current activity (bps) */
664 	u_int32_t dl_max_bandwidth; /* Maximum supported downlink bandwidth
665 	                             *  (bps) */
666 	u_int32_t config_inactivity_time; /* ms */
667 	u_int32_t config_backoff_time; /* new connections backoff time in ms */
668 #define NSTAT_IFNET_DESC_MSS_RECOMMENDED_NONE   0x0
669 #define NSTAT_IFNET_DESC_MSS_RECOMMENDED_MEDIUM 0x1
670 #define NSTAT_IFNET_DESC_MSS_RECOMMENDED_LOW    0x2
671 	u_int16_t mss_recommended; /* recommended MSS */
672 	u_int8_t        reserved[2];
673 } nstat_ifnet_desc_cellular_status;
674 
675 typedef struct nstat_ifnet_desc_wifi_status {
676 	u_int32_t valid_bitmask;
677 #define NSTAT_IFNET_DESC_WIFI_LINK_QUALITY_METRIC_VALID         0x1
678 #define NSTAT_IFNET_DESC_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID      0x2
679 #define NSTAT_IFNET_DESC_WIFI_UL_MAX_BANDWIDTH_VALID            0x4
680 #define NSTAT_IFNET_DESC_WIFI_UL_MIN_LATENCY_VALID              0x8
681 #define NSTAT_IFNET_DESC_WIFI_UL_EFFECTIVE_LATENCY_VALID        0x10
682 #define NSTAT_IFNET_DESC_WIFI_UL_MAX_LATENCY_VALID              0x20
683 #define NSTAT_IFNET_DESC_WIFI_UL_RETXT_LEVEL_VALID              0x40
684 #define NSTAT_IFNET_DESC_WIFI_UL_ERROR_RATE_VALID               0x80
685 #define NSTAT_IFNET_DESC_WIFI_UL_BYTES_LOST_VALID               0x100
686 #define NSTAT_IFNET_DESC_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID      0x200
687 #define NSTAT_IFNET_DESC_WIFI_DL_MAX_BANDWIDTH_VALID            0x400
688 #define NSTAT_IFNET_DESC_WIFI_DL_MIN_LATENCY_VALID              0x800
689 #define NSTAT_IFNET_DESC_WIFI_DL_EFFECTIVE_LATENCY_VALID        0x1000
690 #define NSTAT_IFNET_DESC_WIFI_DL_MAX_LATENCY_VALID              0x2000
691 #define NSTAT_IFNET_DESC_WIFI_DL_ERROR_RATE_VALID               0x4000
692 #define NSTAT_IFNET_DESC_WIFI_CONFIG_FREQUENCY_VALID            0x8000
693 #define NSTAT_IFNET_DESC_WIFI_CONFIG_MULTICAST_RATE_VALID       0x10000
694 #define NSTAT_IFNET_DESC_WIFI_CONFIG_SCAN_COUNT_VALID           0x20000
695 #define NSTAT_IFNET_DESC_WIFI_CONFIG_SCAN_DURATION_VALID        0x40000
696 	u_int32_t link_quality_metric; /* link quality metric */
697 	u_int32_t ul_effective_bandwidth; /* Measured uplink bandwidth based on
698 	                                   *  current activity (bps) */
699 	u_int32_t ul_max_bandwidth; /* Maximum supported uplink bandwidth
700 	                             *  (bps) */
701 	u_int32_t ul_min_latency; /* min expected uplink latency for first hop
702 	                           *  (ms) */
703 	u_int32_t ul_effective_latency; /* current expected uplink latency for
704 	                                 *  first hop (ms) */
705 	u_int32_t ul_max_latency; /* max expected uplink latency for first hop
706 	                           *  (ms) */
707 	u_int32_t ul_retxt_level; /* Retransmission metric */
708 #define NSTAT_IFNET_DESC_WIFI_UL_RETXT_LEVEL_NONE       1
709 #define NSTAT_IFNET_DESC_WIFI_UL_RETXT_LEVEL_LOW        2
710 #define NSTAT_IFNET_DESC_WIFI_UL_RETXT_LEVEL_MEDIUM     3
711 #define NSTAT_IFNET_DESC_WIFI_UL_RETXT_LEVEL_HIGH       4
712 
713 	u_int32_t ul_bytes_lost; /* % of total bytes lost on uplink in Q10
714 	                          *  format */
715 	u_int32_t ul_error_rate; /* % of bytes dropped on uplink after many
716 	                          *  retransmissions in Q10 format */
717 	u_int32_t dl_effective_bandwidth; /* Measured downlink bandwidth based
718 	                                   *  on current activity (bps) */
719 	u_int32_t dl_max_bandwidth; /* Maximum supported downlink bandwidth
720 	                             *  (bps) */
721 	/*
722 	 * The download latency values indicate the time AP may have to wait
723 	 * for the  driver to receive the packet. These values give the range
724 	 * of expected latency mainly due to co-existence events and channel
725 	 * hopping where the interface becomes unavailable.
726 	 */
727 	u_int32_t dl_min_latency; /* min expected latency for first hop in ms */
728 	u_int32_t dl_effective_latency; /* current expected latency for first
729 	                                 *  hop in ms */
730 	u_int32_t dl_max_latency; /* max expected latency for first hop in ms */
731 	u_int32_t dl_error_rate; /* % of CRC or other errors in Q10 format */
732 	u_int32_t config_frequency; /* 2.4 or 5 GHz */
733 #define NSTAT_IFNET_DESC_WIFI_CONFIG_FREQUENCY_2_4_GHZ  1
734 #define NSTAT_IFNET_DESC_WIFI_CONFIG_FREQUENCY_5_0_GHZ  2
735 	u_int32_t config_multicast_rate; /* bps */
736 	u_int32_t scan_count; /* scan count during the previous period */
737 	u_int32_t scan_duration; /* scan duration in ms */
738 } nstat_ifnet_desc_wifi_status;
739 
740 enum{
741 	NSTAT_IFNET_DESC_LINK_STATUS_TYPE_NONE = 0
742 	, NSTAT_IFNET_DESC_LINK_STATUS_TYPE_CELLULAR = 1
743 	, NSTAT_IFNET_DESC_LINK_STATUS_TYPE_WIFI = 2
744 	, NSTAT_IFNET_DESC_LINK_STATUS_TYPE_ETHERNET = 3
745 };
746 
747 typedef struct nstat_ifnet_desc_link_status {
748 	u_int32_t       link_status_type;
749 	union {
750 		nstat_ifnet_desc_cellular_status        cellular;
751 		nstat_ifnet_desc_wifi_status            wifi;
752 	} u;
753 } nstat_ifnet_desc_link_status;
754 
755 #ifndef IF_DESCSIZE
756 #define IF_DESCSIZE 128
757 #endif
758 typedef struct nstat_ifnet_descriptor {
759 	u_int64_t                       threshold __attribute__((aligned(sizeof(u_int64_t))));
760 	u_int32_t                       ifindex;
761 	nstat_ifnet_desc_link_status    link_status;
762 	unsigned int            type;
763 	char                            description[IF_DESCSIZE];
764 	char                            name[IFNAMSIZ + 1];
765 	u_int8_t                        reserved[3];
766 } nstat_ifnet_descriptor;
767 
768 typedef struct nstat_sysinfo_descriptor {
769 	u_int32_t       flags;
770 } nstat_sysinfo_descriptor;
771 
772 typedef struct nstat_sysinfo_add_param {
773 	/* To indicate which system level information should be collected */
774 	u_int32_t       flags;
775 } nstat_sysinfo_add_param;
776 
777 /* 0x0001 is unused */
778 #define NSTAT_SYSINFO_TCP_STATS         0x0002
779 /* 0x0003 is unused */
780 #define NSTAT_SYSINFO_LIM_STATS         0x0004  /* Low Internet mode stats */
781 #define NSTAT_SYSINFO_NET_API_STATS     0x0005  /* API and KPI stats */
782 
783 #pragma mark -- Network Statistics User Client --
784 
785 #define NET_STAT_CONTROL_NAME   "com.apple.network.statistics"
786 
787 enum{
788 	// generic response messages
789 	NSTAT_MSG_TYPE_SUCCESS               = 0
790 	, NSTAT_MSG_TYPE_ERROR               = 1
791 
792 	    // Requests
793 	, NSTAT_MSG_TYPE_ADD_SRC             = 1001
794 	, NSTAT_MSG_TYPE_ADD_ALL_SRCS        = 1002
795 	, NSTAT_MSG_TYPE_REM_SRC             = 1003
796 	, NSTAT_MSG_TYPE_QUERY_SRC           = 1004
797 	, NSTAT_MSG_TYPE_GET_SRC_DESC        = 1005
798 	, NSTAT_MSG_TYPE_SET_FILTER          = 1006 // Obsolete
799 	, NSTAT_MSG_TYPE_GET_UPDATE          = 1007
800 	, NSTAT_MSG_TYPE_SUBSCRIBE_SYSINFO   = 1008
801 	, NSTAT_MSG_TYPE_GET_DETAILS         = 1009
802 
803 	    // Responses/Notfications
804 	, NSTAT_MSG_TYPE_SRC_ADDED           = 10001
805 	, NSTAT_MSG_TYPE_SRC_REMOVED         = 10002
806 	, NSTAT_MSG_TYPE_SRC_DESC            = 10003
807 	, NSTAT_MSG_TYPE_SRC_COUNTS          = 10004
808 	, NSTAT_MSG_TYPE_SYSINFO_COUNTS      = 10005
809 	, NSTAT_MSG_TYPE_SRC_UPDATE          = 10006
810 	, NSTAT_MSG_TYPE_SRC_EXTENDED_UPDATE = 10007
811 	, NSTAT_MSG_TYPE_SRC_DETAILS         = 10008
812 	, NSTAT_MSG_TYPE_SRC_EXTENDED_DETAILS = 10009
813 };
814 
815 enum{
816 	NSTAT_SRC_REF_ALL       = 0xffffffffffffffffULL
817 	, NSTAT_SRC_REF_INVALID  = 0
818 };
819 
820 /* Source-level filters */
821 enum{
822 	NSTAT_FILTER_NOZEROBYTES             = 0x00000001
823 };
824 
825 
826 /* Types of extended update information, used in setting initial filters as well as to identify returned extensions */
827 /* A contiguous range currently limited 1..31 due to being passed as the top 32 bits of filter */
828 enum{
829 	NSTAT_EXTENDED_UPDATE_TYPE_UNKNOWN              = 0
830 	, NSTAT_EXTENDED_UPDATE_TYPE_DOMAIN             = 1
831 	, NSTAT_EXTENDED_UPDATE_TYPE_NECP_TLV           = 2
832 	, NSTAT_EXTENDED_UPDATE_TYPE_ORIGINAL_NECP_TLV  = 3
833 	, NSTAT_EXTENDED_UPDATE_TYPE_ORIGINAL_DOMAIN    = 4
834 	, NSTAT_EXTENDED_UPDATE_TYPE_FUUID              = 5
835 	, NSTAT_EXTENDED_UPDATE_TYPE_BLUETOOTH_COUNTS   = 6
836 };
837 
838 #define NSTAT_EXTENDED_UPDATE_TYPE_MIN  NSTAT_EXTENDED_UPDATE_TYPE_DOMAIN
839 #define NSTAT_EXTENDED_UPDATE_TYPE_MAX  NSTAT_EXTENDED_UPDATE_TYPE_BLUETOOTH_COUNTS
840 
841 
842 #define NSTAT_EXTENDED_UPDATE_FLAG_MASK    0x00ffffffull    /* Maximum of 24 extension types allowed due to restrictions on specifying via filter flags */
843 
844 #define NSTAT_FILTER_ALLOWED_EXTENSIONS_SHIFT   40  /* With extensions expediently passed as the top 24 bits of filters supplied by client, this shift is for extraction */
845 
846 /* Provider-level filters */
847 #define NSTAT_FILTER_ACCEPT_UNKNOWN          0x0000000000000001ull
848 #define NSTAT_FILTER_ACCEPT_LOOPBACK         0x0000000000000002ull
849 #define NSTAT_FILTER_ACCEPT_CELLULAR         0x0000000000000004ull
850 #define NSTAT_FILTER_ACCEPT_WIFI             0x0000000000000008ull
851 #define NSTAT_FILTER_ACCEPT_WIRED            0x0000000000000010ull
852 #define NSTAT_FILTER_ACCEPT_AWDL             0x0000000000000020ull
853 #define NSTAT_FILTER_ACCEPT_EXPENSIVE        0x0000000000000040ull
854 #define NSTAT_FILTER_ACCEPT_CELLFALLBACK     0x0000000000000100ull
855 #define NSTAT_FILTER_ACCEPT_COMPANIONLINK    0x0000000000000200ull
856 #define NSTAT_FILTER_ACCEPT_IS_CONSTRAINED   0x0000000000000400ull
857 #define NSTAT_FILTER_ACCEPT_IS_LOCAL         0x0000000000000800ull
858 #define NSTAT_FILTER_ACCEPT_IS_NON_LOCAL     0x0000000000001000ull
859 #define NSTAT_FILTER_ACCEPT_ROUTE_VAL_ERR    0x0000000000002000ull
860 #define NSTAT_FILTER_ACCEPT_FLOWSWITCH_ERR   0x0000000000004000ull
861 #define NSTAT_FILTER_ACCEPT_WIFI_LLW         0x0000000000008000ull
862 #define NSTAT_FILTER_ACCEPT_WIFI_INFRA       0x0000000000010000ull
863 #define NSTAT_FILTER_ACCEPT_PEERIFEGRESS_CELL 0x0000000000020000ull
864 #define NSTAT_FILTER_ACCEPT_COMPANIONLINK_BT 0x0000000000040000ull
865 #define NSTAT_FILTER_IFNET_FLAGS             0x000000000007FFFFull
866 
867 #define NSTAT_FILTER_UDP_INTERFACE_ATTACH    0x0000000000020000ull  // Subject to removal, do not use
868 #define NSTAT_FILTER_UDP_FLAGS               0x0000000000020000ull
869 
870 #define NSTAT_FILTER_TCP_INTERFACE_ATTACH    0x0000000000040000ull  // Subject to removal, do not use
871 #define NSTAT_FILTER_TCP_NO_EARLY_CLOSE      0x0000000000080000ull
872 #define NSTAT_FILTER_TCP_FLAGS               0x00000000000C0000ull
873 
874 #define NSTAT_FILTER_SUPPRESS_SRC_ADDED      0x0000000000100000ull
875 #define NSTAT_FILTER_USE_UPDATE_FOR_ADD      0x0000000000200000ull
876 #define NSTAT_FILTER_PROVIDER_NOZEROBYTES    0x0000000000400000ull
877 #define NSTAT_FILTER_PROVIDER_NOZERODELTAS   0x0000000000800000ull
878 
879 #define NSTAT_FILTER_CONN_HAS_NET_ACCESS     0x0000000001000000ull
880 #define NSTAT_FILTER_CONN_FLAGS              0x0000000001000000ull
881 
882 #define NSTAT_FILTER_SOURCE_IS_LISTENER      0x0000000002000000ull  // NSTAT_SOURCE_IS_LISTENER
883 #define NSTAT_FILTER_SOURCE_IS_INBOUND       0x0000000004000000ull  // NSTAT_SOURCE_IS_INBOUND
884 #define NSTAT_FILTER_SOURCE_IS_OUTBOUND      0x0000000008000000ull  // NSTAT_SOURCE_IS_OUTBOUND
885 #define NSTAT_FILTER_SOURCE_ROLE_FLAGS       0x000000000E000000ull  // All three of the above
886 
887 /* In this context, boring == no change from previous report */
888 #define NSTAT_FILTER_SUPPRESS_BORING_CLOSE   0x0000000010000000ull  /* No final update, only NSTAT_MSG_TYPE_SRC_REMOVED */
889 #define NSTAT_FILTER_SUPPRESS_BORING_POLL    0x0000000020000000ull  /* Only for poll-all, not poll specific source */
890 #define NSTAT_FILTER_SUPPRESS_BORING_FLAGS   (NSTAT_FILTER_SUPPRESS_BORING_CLOSE|NSTAT_FILTER_SUPPRESS_BORING_POLL)
891 
892 #define NSTAT_FILTER_FLAGS_RESERVED_30       0x0000000040000000ull
893 #define NSTAT_FILTER_FLAGS_RESERVED_31       0x0000000080000000ull
894 
895 /* The filtering for specific user is a speculative option that hasn't been exploited.  It may be removed */
896 #define NSTAT_FILTER_SPECIFIC_USER_BY_PID    0x0000000100000000ull
897 #define NSTAT_FILTER_SPECIFIC_USER_BY_EPID   0x0000000200000000ull
898 #define NSTAT_FILTER_SPECIFIC_USER_BY_UUID   0x0000000400000000ull
899 #define NSTAT_FILTER_SPECIFIC_USER_BY_EUUID  0x0000000800000000ull
900 #define NSTAT_FILTER_SPECIFIC_USER           0x0000000F00000000ull
901 
902 #define NSTAT_FILTER_INITIAL_PROPERTIES      0x0000001000000000ull  /* For providers that give "properties" on open, apply the filter to the properties */
903                                                                     /* and permanently discard unless the filter allows through */
904 #define NSTAT_FILTER_USE_LARGE_BUFFERS       0x0000002000000000ull  /* Not really a filter, place here until we have other mechanisms to pass this */
905 #define NSTAT_FILTER_DELIVER_ONCE            0x0000004000000000ull  /* Single shot delivery */
906 #define NSTAT_FILTER_VERSION_2_PROTOCOL      0x0000008000000000ull
907 
908 
909 #define NSTAT_FILTER_IFNET_AND_CONN_FLAGS    (NSTAT_FILTER_IFNET_FLAGS|NSTAT_FILTER_CONN_FLAGS)
910 
911 #define NSTAT_EXTENSION_FILTER_DOMAIN_INFO              (1ull << (NSTAT_EXTENDED_UPDATE_TYPE_DOMAIN + NSTAT_FILTER_ALLOWED_EXTENSIONS_SHIFT))
912 #define NSTAT_EXTENSION_FILTER_NECP_TLV                 (1ull << (NSTAT_EXTENDED_UPDATE_TYPE_NECP_TLV + NSTAT_FILTER_ALLOWED_EXTENSIONS_SHIFT))
913 #define NSTAT_EXTENSION_FILTER_ORIGINAL_NECP_TLV        (1ull << (NSTAT_EXTENDED_UPDATE_TYPE_ORIGINAL_NECP_TLV + NSTAT_FILTER_ALLOWED_EXTENSIONS_SHIFT))
914 #define NSTAT_EXTENSION_FILTER_ORIGINAL_DOMAIN_INFO     (1ull << (NSTAT_EXTENDED_UPDATE_TYPE_ORIGINAL_DOMAIN + NSTAT_FILTER_ALLOWED_EXTENSIONS_SHIFT))
915 #define NSTAT_EXTENSION_FILTER_BLUETOOTH_COUNTS         (1ull << (NSTAT_EXTENDED_UPDATE_TYPE_BLUETOOTH_COUNTS + NSTAT_FILTER_ALLOWED_EXTENSIONS_SHIFT))
916 #define NSTAT_EXTENSION_FILTER_MASK                     (NSTAT_EXTENDED_UPDATE_FLAG_MASK << NSTAT_FILTER_ALLOWED_EXTENSIONS_SHIFT)
917 
918 // Version one is constrained to use only the following
919 #define NSTAT_FILTER_FLAGS_V1_USAGE     \
920     (NSTAT_FILTER_ACCEPT_UNKNOWN|       \
921     NSTAT_FILTER_ACCEPT_LOOPBACK|       \
922     NSTAT_FILTER_ACCEPT_CELLULAR|       \
923     NSTAT_FILTER_ACCEPT_WIFI|           \
924     NSTAT_FILTER_ACCEPT_WIRED|          \
925     NSTAT_FILTER_ACCEPT_AWDL|           \
926     NSTAT_FILTER_ACCEPT_EXPENSIVE|      \
927     NSTAT_FILTER_ACCEPT_CELLFALLBACK|   \
928     NSTAT_FILTER_ACCEPT_COMPANIONLINK|  \
929     NSTAT_FILTER_ACCEPT_IS_CONSTRAINED| \
930     NSTAT_FILTER_ACCEPT_IS_LOCAL|       \
931     NSTAT_FILTER_ACCEPT_IS_NON_LOCAL)
932 
933 
934 // A note on the header flags
935 //
936 // NSTAT_MSG_HDR_FLAG_SUPPORTS_AGGREGATE was used to indicate that user level code could cope with
937 // multiple counts or descriptor messages within a single overall message on the control socket.
938 // This ability is now mandatory for user level clients.  They may or may not choose to still set
939 // NSTAT_MSG_HDR_FLAG_SUPPORTS_AGGREGATE, but they must support aggregate responses
940 //
941 // For messages from the client, NSTAT_MSG_HDR_FLAG_CONTINUATION was used to indicate that the results
942 // of any NSTAT_SRC_REF_ALL poll could be returned in fragments, each fragment except the last one
943 // having NSTAT_MSG_HDR_FLAG_CONTINUATION set and each intermediate fragment intended to elicit
944 // a further NSTAT_SRC_REF_ALL poll with the same context as the initial one.  This pacing is intended
945 // to prevent overload on what amounts to a producer/consumer interface.  This style is now mandatory,
946 // whether or not NSTAT_MSG_HDR_FLAG_CONTINUATION is set, any polls may result in data being returned
947 // in fragments which each contain just a portion of the requested counts/descriptors/updates.
948 // The user level clients may choose whether or not to set NSTAT_MSG_HDR_FLAG_CONTINUATION in any polls
949 // but they must support getting poll responses in multiple chunks
950 //
951 enum{
952 	NSTAT_MSG_HDR_FLAG_SUPPORTS_AGGREGATE   = 1 << 0,
953 	NSTAT_MSG_HDR_FLAG_CONTINUATION         = 1 << 1,
954 	NSTAT_MSG_HDR_FLAG_CLOSING              = 1 << 2,
955 	NSTAT_MSG_HDR_FLAG_CLOSED_AFTER_DROP    = 1 << 3,
956 	NSTAT_MSG_HDR_FLAG_CLOSED_AFTER_FILTER  = 1 << 4,
957 	NSTAT_MSG_HDR_FLAG_CLOSED_AFTER_GONE    = 1 << 6,
958 };
959 
960 #define DEFINE_NTSTAT_DATA_ACCESSOR(NTSTAT_TYPE)                            \
961 static inline                                                               \
962 __attribute__((always_inline))                                              \
963 __attribute__((overloadable))                                               \
964 uint8_t * __header_indexable                                                \
965 nstat_get_data(NTSTAT_TYPE *__header_indexable desc)                        \
966 {                                                                           \
967     if (desc) {                                                             \
968 	_Pragma("clang diagnostic push");                                       \
969 	_Pragma("clang diagnostic ignored \"-Wunsafe-buffer-usage\"");          \
970 	return (uint8_t *)desc + sizeof(NTSTAT_TYPE);                           \
971 	_Pragma("clang diagnostic pop");                                        \
972     } else {                                                                \
973 	return NULL;                                                            \
974     }                                                                       \
975 }
976 
977 typedef struct nstat_msg_hdr {
978 	u_int64_t       context __attribute__((aligned(sizeof(u_int64_t))));
979 	u_int32_t       type;
980 	u_int16_t       length;
981 	u_int16_t       flags;
982 } nstat_msg_hdr;
983 
984 #define MAX_NSTAT_MSG_HDR_LENGTH    65532
985 
986 typedef struct nstat_msg_error {
987 	nstat_msg_hdr   hdr;
988 	u_int32_t               error;  // errno error
989 	u_int8_t                reserved[4];
990 } nstat_msg_error;
991 
992 #define NSTAT_ADD_SRC_FIELDS            \
993 	nstat_msg_hdr		hdr;            \
994 	nstat_provider_id_t	provider;       \
995 	u_int8_t			reserved[4]     \
996 
997 typedef struct nstat_msg_add_src {
998 	NSTAT_ADD_SRC_FIELDS;
999 	u_int8_t        param[];
1000 } nstat_msg_add_src_req;
1001 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_add_src)
1002 
1003 typedef struct nstat_msg_add_src_header {
1004 	NSTAT_ADD_SRC_FIELDS;
1005 } nstat_msg_add_src_header;
1006 
1007 typedef struct nstat_msg_add_src_convenient {
1008 	nstat_msg_add_src_header        hdr;
1009 	union {
1010 		nstat_route_add_param   route;
1011 		nstat_tcp_add_param     tcp;
1012 		nstat_udp_add_param     udp;
1013 		nstat_ifnet_add_param   ifnet;
1014 		nstat_sysinfo_add_param sysinfo;
1015 	};
1016 } nstat_msg_add_src_convenient;
1017 
1018 #undef NSTAT_ADD_SRC_FIELDS
1019 
1020 typedef struct nstat_msg_add_all_srcs {
1021 	nstat_msg_hdr           hdr;
1022 	u_int64_t               filter __attribute__((aligned(sizeof(u_int64_t))));
1023 	nstat_event_flags_t     events __attribute__((aligned(sizeof(u_int64_t))));
1024 	nstat_provider_id_t     provider;
1025 	pid_t                   target_pid;
1026 	uuid_t                  target_uuid;
1027 } nstat_msg_add_all_srcs;
1028 
1029 typedef struct nstat_msg_src_added {
1030 	nstat_msg_hdr           hdr;
1031 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1032 	nstat_provider_id_t     provider;
1033 	u_int8_t                reserved[4];
1034 } nstat_msg_src_added;
1035 
1036 typedef struct nstat_msg_rem_src {
1037 	nstat_msg_hdr           hdr;
1038 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1039 } nstat_msg_rem_src_req;
1040 
1041 typedef struct nstat_msg_get_src_description {
1042 	nstat_msg_hdr           hdr;
1043 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1044 } nstat_msg_get_src_description;
1045 
1046 typedef struct nstat_msg_set_filter {
1047 	nstat_msg_hdr           hdr;
1048 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1049 	u_int32_t               filter;
1050 	u_int8_t                reserved[4];
1051 } nstat_msg_set_filter;
1052 
1053 #define NSTAT_SRC_DESCRIPTION_FIELDS                                                \
1054 	nstat_msg_hdr		hdr;                                                        \
1055 	nstat_src_ref_t		srcref __attribute__((aligned(sizeof(u_int64_t))));         \
1056 	nstat_event_flags_t	event_flags __attribute__((aligned(sizeof(u_int64_t))));    \
1057 	nstat_provider_id_t	provider;                                                   \
1058 	u_int8_t			reserved[4]
1059 
1060 typedef struct nstat_msg_src_description {
1061 	NSTAT_SRC_DESCRIPTION_FIELDS;
1062 	u_int8_t        data[];
1063 } nstat_msg_src_description;
1064 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_description)
1065 
1066 typedef struct nstat_msg_src_description_header {
1067 	NSTAT_SRC_DESCRIPTION_FIELDS;
1068 } nstat_msg_src_description_header;
1069 
1070 typedef struct nstat_msg_src_description_convenient {
1071 	nstat_msg_src_description_header    hdr;
1072 	union {
1073 		nstat_tcp_descriptor            tcp;
1074 		nstat_udp_descriptor            udp;
1075 		nstat_route_descriptor          route;
1076 		nstat_ifnet_descriptor          ifnet;
1077 		nstat_sysinfo_descriptor        sysinfo;
1078 		nstat_quic_descriptor           quic;
1079 	};
1080 } nstat_msg_src_description_convenient;
1081 
1082 #undef NSTAT_SRC_DESCRIPTION_FIELDS
1083 
1084 typedef struct nstat_msg_query_src {
1085 	nstat_msg_hdr           hdr;
1086 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1087 } nstat_msg_query_src_req;
1088 
1089 typedef struct nstat_msg_src_counts {
1090 	nstat_msg_hdr           hdr;
1091 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1092 	nstat_event_flags_t     event_flags __attribute__((aligned(sizeof(u_int64_t))));
1093 	nstat_counts            counts;
1094 } nstat_msg_src_counts;
1095 
1096 #define NSTAT_SRC_UPDATE_FIELDS                                                     \
1097 	nstat_msg_hdr		hdr;                                                        \
1098 	nstat_src_ref_t		srcref __attribute__((aligned(sizeof(u_int64_t))));         \
1099 	nstat_event_flags_t	event_flags __attribute__((aligned(sizeof(u_int64_t))));    \
1100 	nstat_counts		counts;                                                     \
1101 	nstat_provider_id_t	provider;                                                   \
1102 	u_int8_t			reserved[4]
1103 
1104 typedef struct nstat_msg_src_update {
1105 	NSTAT_SRC_UPDATE_FIELDS;
1106 	u_int8_t        data[];
1107 } nstat_msg_src_update;
1108 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_update)
1109 
1110 typedef struct nstat_msg_src_update_hdr {
1111 	NSTAT_SRC_UPDATE_FIELDS;
1112 } nstat_msg_src_update_hdr;
1113 
1114 typedef struct nstat_msg_src_update_tcp {
1115 	NSTAT_SRC_UPDATE_FIELDS;
1116 	nstat_tcp_descriptor            tcp_desc;
1117 } nstat_msg_src_update_tcp;
1118 
1119 typedef struct nstat_msg_src_update_udp {
1120 	NSTAT_SRC_UPDATE_FIELDS;
1121 	nstat_udp_descriptor            udp_desc;
1122 } nstat_msg_src_update_udp;
1123 
1124 typedef struct nstat_msg_src_update_quic {
1125 	NSTAT_SRC_UPDATE_FIELDS;
1126 	nstat_quic_descriptor           quic_desc;
1127 } nstat_msg_src_update_quic;
1128 
1129 typedef struct nstat_msg_src_update_conn {
1130 	NSTAT_SRC_UPDATE_FIELDS;
1131 	nstat_connection_descriptor     conn_desc;
1132 } nstat_msg_src_update_conn;
1133 
1134 
1135 typedef struct nstat_msg_src_update_convenient {
1136 	nstat_msg_src_update_hdr                hdr;
1137 	union {
1138 		nstat_tcp_descriptor            tcp;
1139 		nstat_udp_descriptor            udp;
1140 		nstat_route_descriptor          route;
1141 		nstat_ifnet_descriptor          ifnet;
1142 		nstat_sysinfo_descriptor        sysinfo;
1143 		nstat_quic_descriptor           quic;
1144 		nstat_connection_descriptor     conn;
1145 	};
1146 } nstat_msg_src_update_convenient;
1147 
1148 #define NSTAT_SRC_DETAILS_FIELDS                                                        \
1149 	nstat_msg_hdr		    hdr;                                                        \
1150 	nstat_src_ref_t		    srcref __attribute__((aligned(sizeof(u_int64_t))));         \
1151 	nstat_event_flags_t	    event_flags __attribute__((aligned(sizeof(u_int64_t))));    \
1152 	nstat_detailed_counts   detailed_counts;                                            \
1153 	nstat_provider_id_t	    provider;                                                   \
1154 	u_int8_t                reserved[4]
1155 
1156 typedef struct nstat_msg_src_details {
1157 	NSTAT_SRC_DETAILS_FIELDS;
1158 	u_int8_t        data[];
1159 } nstat_msg_src_details;
1160 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_details)
1161 
1162 typedef struct nstat_msg_src_details_hdr {
1163 	NSTAT_SRC_DETAILS_FIELDS;
1164 } nstat_msg_src_details_hdr;
1165 
1166 typedef struct nstat_msg_src_details_tcp {
1167 	NSTAT_SRC_DETAILS_FIELDS;
1168 	nstat_tcp_descriptor            tcp_desc;
1169 } nstat_msg_src_details_tcp;
1170 
1171 typedef struct nstat_msg_src_details_udp {
1172 	NSTAT_SRC_DETAILS_FIELDS;
1173 	nstat_udp_descriptor            udp_desc;
1174 } nstat_msg_src_details_udp;
1175 
1176 typedef struct nstat_msg_src_details_quic {
1177 	NSTAT_SRC_DETAILS_FIELDS;
1178 	nstat_quic_descriptor           quic_desc;
1179 } nstat_msg_src_details_quic;
1180 
1181 typedef struct nstat_msg_src_details_conn {
1182 	NSTAT_SRC_DETAILS_FIELDS;
1183 	nstat_connection_descriptor     conn_desc;
1184 } nstat_msg_src_details_conn;
1185 
1186 
1187 typedef struct nstat_msg_src_details_convenient {
1188 	nstat_msg_src_details_hdr                hdr;
1189 	union {
1190 		nstat_tcp_descriptor            tcp;
1191 		nstat_udp_descriptor            udp;
1192 		nstat_route_descriptor          route;
1193 		nstat_ifnet_descriptor          ifnet;
1194 		nstat_sysinfo_descriptor        sysinfo;
1195 		nstat_quic_descriptor           quic;
1196 		nstat_connection_descriptor     conn;
1197 	};
1198 } nstat_msg_src_details_convenient;
1199 
1200 
1201 
1202 typedef struct nstat_msg_src_extended_item_hdr {
1203 	u_int32_t       type;
1204 	u_int32_t       length;
1205 } nstat_msg_src_extended_item_hdr __attribute__((aligned(sizeof(u_int64_t))));;
1206 
1207 typedef struct nstat_msg_src_extended_item {
1208 	nstat_msg_src_extended_item_hdr         hdr;
1209 	u_int8_t                                data[];
1210 } nstat_msg_src_extended_item;
1211 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_extended_item)
1212 
1213 typedef struct nstat_msg_src_extended_tcp_update {
1214 	NSTAT_SRC_UPDATE_FIELDS;
1215 	nstat_tcp_descriptor                    tcp;
1216 	nstat_msg_src_extended_item_hdr         extension_hdr;
1217 	u_int8_t                                data[];
1218 } nstat_msg_src_extended_tcp_update;
1219 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_extended_tcp_update)
1220 
1221 typedef struct nstat_msg_src_extended_udp_update {
1222 	NSTAT_SRC_UPDATE_FIELDS;
1223 	nstat_udp_descriptor                    udp;
1224 	nstat_msg_src_extended_item_hdr         extension_hdr;
1225 	u_int8_t                                data[];
1226 } nstat_msg_src_extended_udp_update;
1227 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_extended_udp_update)
1228 
1229 typedef struct nstat_msg_src_extended_quic_update {
1230 	NSTAT_SRC_UPDATE_FIELDS;
1231 	nstat_quic_descriptor                   quic;
1232 	nstat_msg_src_extended_item_hdr         extension_hdr;
1233 	u_int8_t                                data[];
1234 } nstat_msg_src_extended_quic_update;
1235 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_extended_quic_update)
1236 
1237 typedef struct nstat_msg_src_extended_conn_update {
1238 	NSTAT_SRC_UPDATE_FIELDS;
1239 	nstat_connection_descriptor             conn;
1240 	nstat_msg_src_extended_item_hdr         extension_hdr;
1241 	u_int8_t                                data[];
1242 } nstat_msg_src_extended_conn_update;
1243 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_src_extended_conn_update)
1244 
1245 /* While the only type of extended update is for domain information, we can fully define the structure */
1246 typedef struct nstat_msg_src_tcp_update_domain_extension {
1247 	nstat_msg_src_update_hdr                hdr;
1248 	nstat_tcp_descriptor                    tcp;
1249 	nstat_msg_src_extended_item_hdr         extension_hdr;
1250 	nstat_domain_info                       domain_info;
1251 } nstat_msg_src_tcp_update_domain_extension;
1252 
1253 typedef struct nstat_msg_src_udp_update_domain_extension {
1254 	nstat_msg_src_update_hdr                hdr;
1255 	nstat_udp_descriptor                    udp;
1256 	nstat_msg_src_extended_item_hdr         extension_hdr;
1257 	nstat_domain_info                       domain_info;
1258 } nstat_msg_src_udp_update_domain_extension;
1259 
1260 typedef struct nstat_msg_src_quic_update_domain_extension {
1261 	nstat_msg_src_update_hdr                hdr;
1262 	nstat_quic_descriptor                   quic;
1263 	nstat_msg_src_extended_item_hdr         extension_hdr;
1264 	nstat_domain_info                       domain_info;
1265 } nstat_msg_src_quic_update_domain_extension;
1266 
1267 typedef struct nstat_msg_src_update_domain_extension_convenient {
1268 	nstat_msg_src_tcp_update_domain_extension       tcp;
1269 	nstat_msg_src_udp_update_domain_extension       udp;
1270 	nstat_msg_src_quic_update_domain_extension      quic;
1271 } nstat_msg_src_update_domain_extension_convenient;
1272 
1273 #undef NSTAT_SRC_UPDATE_FIELDS
1274 
1275 typedef struct nstat_msg_src_removed {
1276 	nstat_msg_hdr           hdr;
1277 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1278 } nstat_msg_src_removed;
1279 
1280 typedef struct nstat_msg_sysinfo_counts {
1281 	nstat_msg_hdr           hdr;
1282 	nstat_src_ref_t         srcref __attribute__((aligned(sizeof(u_int64_t))));
1283 	nstat_sysinfo_counts    counts;
1284 }  nstat_msg_sysinfo_counts;
1285 
DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_sysinfo_counts)1286 DEFINE_NTSTAT_DATA_ACCESSOR(struct nstat_msg_sysinfo_counts)
1287 
1288 static inline
1289 __attribute__((always_inline))
1290 struct nstat_sysinfo_keyval * __header_indexable
1291 nstat_sysinfo_get_keyvals(struct nstat_msg_sysinfo_counts *__header_indexable counts)
1292 {
1293 	return (struct nstat_sysinfo_keyval *)(void *)nstat_get_data(counts);
1294 }
1295 
1296 #pragma mark -- Statitiscs about Network Statistics --
1297 
1298 // For historic "netstat -s -p nstat" command
1299 struct nstat_stats {
1300 	u_int32_t nstat_successmsgfailures;
1301 	u_int32_t nstat_sendcountfailures;
1302 	u_int32_t nstat_sysinfofailures;
1303 	u_int32_t nstat_srcupatefailures;
1304 	u_int32_t nstat_descriptionfailures;
1305 	u_int32_t nstat_msgremovedfailures;
1306 	u_int32_t nstat_srcaddedfailures;
1307 	u_int32_t nstat_msgerrorfailures;
1308 	u_int32_t nstat_copy_descriptor_failures;
1309 	u_int32_t nstat_provider_counts_failures;
1310 	u_int32_t nstat_control_send_description_failures;
1311 	u_int32_t nstat_control_send_goodbye_failures;
1312 	u_int32_t nstat_flush_accumulated_msgs_failures;
1313 	u_int32_t nstat_accumulate_msg_failures;
1314 	u_int32_t nstat_control_cleanup_source_failures;
1315 	u_int32_t nstat_handle_msg_failures;
1316 };
1317 
1318 // Additional counts that are "global, i.e. not per client
1319 
1320 #define NSTAT_GLOBAL_COUNTS_VERSION     1
1321 struct nstat_global_counts {
1322 	uint64_t nstat_global_count_version; // current version number for this structure
1323 
1324 	uint64_t nstat_global_exclusive_lock_uncontended;   // Uncontended acquisitions of exlusive lock
1325 	uint64_t nstat_global_exclusive_lock_contended;     // Contended acquisitions of exlusive lock
1326 
1327 	uint64_t nstat_global_shared_lock_uncontended;      // Uncontended acquisitions of shared lock
1328 	uint64_t nstat_global_shared_lock_contended;        // Contended acquisitions of shared lock
1329 
1330 	uint64_t nstat_global_client_current;       // current number of clients overall
1331 	uint64_t nstat_global_client_max;           // max number of clients overall
1332 	uint64_t nstat_global_client_allocs;        // total number of clients allocated
1333 	uint64_t nstat_global_client_alloc_fails;   // total number of failures to allocate a client
1334 
1335 	uint64_t nstat_global_src_current;          // current number of srcs overall
1336 	uint64_t nstat_global_src_max;              // max number of srcs overall
1337 	uint64_t nstat_global_src_allocs;           // total number of sources allocated
1338 	uint64_t nstat_global_src_alloc_fails;      // total number of failures to allocate a source
1339 
1340 	uint64_t nstat_global_tcp_sck_locus_current;    // current number of tcp nstat_sock_locus overall
1341 	uint64_t nstat_global_tcp_sck_locus_max;        // max number of tcp nstat_sock_locus overall
1342 	uint64_t nstat_global_tcp_sck_locus_allocs;     // total number of tcp nstat_sock_locus allocated
1343 	uint64_t nstat_global_tcp_sck_locus_alloc_fails;// total number of failures to allocate a tcp nstat_sock_locus
1344 
1345 	uint64_t nstat_global_udp_sck_locus_current;    // current number of udp nstat_extended_sock_locus overall
1346 	uint64_t nstat_global_udp_sck_locus_max;        // max number of udp nstat_extended_sock_locus overall
1347 	uint64_t nstat_global_udp_sck_locus_allocs;     // total number of udp nstat_extended_sock_locus allocated
1348 	uint64_t nstat_global_udp_sck_locus_alloc_fails;// total number of failures to allocate a udp nstat_extended_sock_locus
1349 
1350 	uint64_t nstat_global_tu_shad_current;  // current number of nstat_tu_shadow objects overall
1351 	uint64_t nstat_global_tu_shad_max;      // max number of tu_shadows overall
1352 	uint64_t nstat_global_tu_shad_allocs;   // total number of tu_shadows allocated
1353 
1354 	uint64_t nstat_global_gshad_current;    // current number of generic shadow objects overall
1355 	uint64_t nstat_global_gshad_max;        // max number of srcs overall
1356 	uint64_t nstat_global_gshad_allocs;     // total number of sources allocated
1357 
1358 	uint64_t nstat_global_procdetails_current;  // current number of procdetails objects overall
1359 	uint64_t nstat_global_procdetails_max;      // max number of procdetails overall
1360 	uint64_t nstat_global_procdetails_allocs;   // total number of procdetails allocated
1361 
1362 	uint64_t nstat_global_idlecheck_tcp_gone;       // idle check removes a TCP locus
1363 	uint64_t nstat_global_idlecheck_udp_gone;       // idle check removes a UDP locus
1364 	uint64_t nstat_global_idlecheck_route_src_gone; // total number of route sources discovered "gone" in idle check
1365 
1366 	// Extra details for sock locus lifecycle
1367 	uint64_t nstat_global_tcp_sck_locus_stop_using; // Socket has WNT_STOPUSING when creating the initial locus
1368 	uint64_t nstat_global_udp_sck_locus_stop_using; // Socket has WNT_STOPUSING when creating the initial locus
1369 	uint64_t nstat_global_pcb_detach_with_locus;    // Expected path, locus on pcb_detach
1370 	uint64_t nstat_global_pcb_detach_with_src;      // Expected path, locus on pcb_detach, an associated source being detached
1371 	uint64_t nstat_global_pcb_detach_without_locus; // Unexpected path, no locus on pcb_detach
1372 	uint64_t nstat_global_pcb_detach_udp;           // pcb detach removes a UDP locus
1373 	uint64_t nstat_global_pcb_detach_tcp;           // pcb detach removes a TCP locus
1374 
1375 	uint64_t nstat_global_sck_update_last_owner;    // nstat_pcb_update_last_owner() was called
1376 	uint64_t nstat_global_sck_fail_first_owner;     // can't set name on sock locus create
1377 	uint64_t nstat_global_sck_fail_last_owner;      // nstat_pcb_update_last_owner() was called, no name available
1378 	uint64_t nstat_global_tcp_desc_new_name;        // Socket ownership discovered to have changed
1379 	uint64_t nstat_global_tcp_desc_fail_name;       // Socket ownership discovered to have changed, fail to get new name
1380 	uint64_t nstat_global_udp_desc_new_name;        // Socket ownership discovered to have changed
1381 	uint64_t nstat_global_udp_desc_fail_name;       // Socket ownership discovered to have changed, fail to get new name
1382 
1383 	// The following are expected to be removed as and when the socket handling code is refined
1384 	uint64_t nstat_global_tucookie_current;
1385 	uint64_t nstat_global_tucookie_max;
1386 	uint64_t nstat_global_tucookie_allocs;
1387 	uint64_t nstat_global_tucookie_alloc_fail;
1388 	uint64_t nstat_global_tucookie_skip_dead;
1389 	uint64_t nstat_global_tucookie_skip_stopusing;
1390 	uint64_t nstat_global_src_idlecheck_gone;
1391 };
1392 
1393 
1394 // Counts that are typically per-client
1395 // They are also accumulated globally for all previous clients
1396 //
1397 // The "net.stats.metrics" systctl can request these metrics either from a specific client,
1398 // the accumulated counts for closed clients, or a summary of all the closed and current clients.
1399 // To collect individual metrics for all clients, an initial request is made targeting
1400 // NSTAT_METRIC_ID_MAX via the mr_id field in the request structure.  The returned metrics will be
1401 // for the client with the highest identifer, as returned in the nstat_client_id field.
1402 // The next request should target that returned identifier minus one, which will collect
1403 // the client with the next highest identifier.  This sequence can continue until metrics
1404 // for all clients have been collected
1405 #define NSTAT_METRIC_VERSION        2
1406 #define NSTAT_METRIC_ID_ACCUMULATED 0x0         /* Accumulation from all clients that have previously closed */
1407 #define NSTAT_METRIC_ID_GRAND_TOTAL 0x1         /* Accumulation from all clients, current and historic */
1408 #define NSTAT_METRIC_ID_MAX         0xffffffff  /* Start scanning all clients with this initial value */
1409 
1410 struct nstat_metrics_req {
1411 	uint32_t mr_version;                // The version of metrics being requested
1412 	uint32_t mr_id;                     // Identifier for the metrics, a client id, or accumulated or grand total
1413 };
1414 
1415 struct nstat_client_details {
1416 	uint32_t nstat_client_id;           // Identifier for this set of metrics, a client id, or accumulated
1417 	pid_t    nstat_client_pid;          // Process id of client that owns these metrics
1418 	uint32_t nstat_client_watching;     // Bitmap of providers being watched
1419 	uint32_t nstat_client_added_src;    // Bitmap of providers with individually added sources
1420 };
1421 
1422 struct nstat_metrics {
1423 	uint32_t nstat_src_current;         // current number of srcs for client
1424 	uint32_t nstat_src_max;             // max number of srcs for client
1425 	uint32_t nstat_first_uint32_count;  // Subsequent fields must be uint32_t values that, if kept per-client,
1426 	                                    // should simply added to the global counts when the client exit
1427 
1428 	// Tracking client requests
1429 	uint32_t nstat_query_request_all;   // Client requests for all counts
1430 	uint32_t nstat_query_request_one;   // Client request for counts on a single source
1431 	uint32_t nstat_query_description_all; // Client requests for all descriptors
1432 	uint32_t nstat_query_description_one; // Client requests for descriptor on a single source
1433 	uint32_t nstat_query_update_all;    // Client requests for all updates
1434 	uint32_t nstat_query_update_one;    // Client requests for update on a single source
1435 	uint32_t nstat_remove_src_found;    // Client request to remove a source which is still in existence
1436 	uint32_t nstat_remove_src_missed;   // Client request to remove a source which is no longer there
1437 
1438 	// Details for nstat_query_request all/one
1439 	uint32_t nstat_query_request_nobuf; // No buffers for message send
1440 	uint32_t nstat_query_request_upgrade; // Successful lock upgrade to handle "gone" source
1441 	uint32_t nstat_query_request_noupgrade; // Unsuccessful lock upgrade to handle "gone" source
1442 	uint32_t nstat_query_request_nodesc; // Can't send a descriptor for "gone" source
1443 	uint32_t nstat_query_request_yield; // Client yields lock due to possibly higher priority processing
1444 	uint32_t nstat_query_request_limit; // Client requests for all counts
1445 
1446 	// Details for nstat_query_description all/one
1447 	uint32_t nstat_query_description_nobuf; // No buffers for message send
1448 	uint32_t nstat_query_description_yield; // Client yields lock due to possibly higher priority processing
1449 	uint32_t nstat_query_description_limit; // Client requests for all counts
1450 
1451 	// Details for nstat_query_details all/one
1452 	uint32_t nstat_query_details_nobuf;  // No buffers for message send
1453 	uint32_t nstat_query_details_upgrade; // Successful lock upgrade to handle "gone" source
1454 	uint32_t nstat_query_details_noupgrade; // Unsuccessful lock upgrade to handle "gone" source
1455 	uint32_t nstat_query_details_yield;  // Client yields lock due to possibly higher priority processing
1456 	uint32_t nstat_query_details_limit;  // Client requests for all counts
1457 	uint32_t nstat_query_details_all;    // Request received for all sources
1458 	uint32_t nstat_query_details_one;    // Request received for a specific source
1459 
1460 	// Details for nstat_query_update all/one
1461 	uint32_t nstat_query_update_nobuf;  // No buffers for message send
1462 	uint32_t nstat_query_update_upgrade; // Successful lock upgrade to handle "gone" source
1463 	uint32_t nstat_query_update_noupgrade; // Unsuccessful lock upgrade to handle "gone" source
1464 	uint32_t nstat_query_update_nodesc; // Can't send a descriptor for "gone" source
1465 	uint32_t nstat_query_update_yield;  // Client yields lock due to possibly higher priority processing
1466 	uint32_t nstat_query_update_limit;  // Client requests for all counts
1467 
1468 	// Details for adding a source
1469 	uint32_t nstat_src_add_success;     // successful src_add
1470 	uint32_t nstat_src_add_no_buf;      // fail to get buffer for initial src-added
1471 	uint32_t nstat_src_add_no_src_mem;  // fail to get memory for nstat_src structure
1472 	uint32_t nstat_src_add_send_err;    // fail to send initial src-added
1473 	uint32_t nstat_src_add_while_cleanup; // fail to add because client is in clean up state
1474 
1475 	// Details for adding the client as a watcher
1476 	uint32_t nstat_add_all_tcp_skip_dead; // Skip a dead PCB when adding all TCP
1477 	uint32_t nstat_add_all_udp_skip_dead; // Skip a dead PCB when adding all UDP
1478 
1479 	// Details for sending "goodbye" on source removal
1480 	uint32_t nstat_src_goodbye_successes;// Successful goodbyes (include cases messages filtered out)
1481 	uint32_t nstat_src_goodbye_failures; // Failed goodbyes, further qualified by..
1482 	uint32_t nstat_src_goodbye_sent_details;    // Sent a concluding details message
1483 	uint32_t nstat_src_goodbye_failed_details;  // Failed to send a details message
1484 	uint32_t nstat_src_goodbye_filtered_details;// Skipped trying to send a details message
1485 	uint32_t nstat_src_goodbye_sent_update;     // Sent a concluding update message
1486 	uint32_t nstat_src_goodbye_failed_update;   // Failed to send an update message
1487 	uint32_t nstat_src_goodbye_filtered_update; // Skipped trying to send an update message
1488 	uint32_t nstat_src_goodbye_sent_counts;     // Sent a concluding counts message
1489 	uint32_t nstat_src_goodbye_failed_counts;   // Failed to send a counts message
1490 	uint32_t nstat_src_goodbye_filtered_counts; // Skipped trying to send both counts and descriptor messages
1491 	uint32_t nstat_src_goodbye_sent_description;// Sent a concluding description message
1492 	uint32_t nstat_src_goodbye_failed_description; // Failed to send a description message
1493 	uint32_t nstat_src_goodbye_sent_removed;    // Sent a concluding removed message
1494 	uint32_t nstat_src_goodbye_failed_removed;  // Failed to send a removed message
1495 	uint32_t nstat_src_goodbye_filtered_removed;  // Skipped on sending a removed message
1496 
1497 	uint32_t nstat_pcb_event;           // send pcb event code called, one precursor to the send_event metrics
1498 	uint32_t nstat_send_event;          // send event successful
1499 	uint32_t nstat_send_event_fail;     // send event fail, likely lack of buffers
1500 	uint32_t nstat_send_event_notsup;   // send event not supported, old style client
1501 
1502 
1503 	uint32_t nstat_route_src_gone_idlecheck;  // route src gone noted during periodic idle check
1504 	uint32_t nstat_src_removed_linkage; // removed src linkages on the way to deletion
1505 
1506 	uint32_t nstat_src_gone_idlecheck;  // Expected to be redundant/removed when socket handling code is refined
1507 
1508 	uint32_t nstat_last_uint32_count;   // Must be the last uint32_t count in the structure
1509 	uint32_t nstat_stats_pad;
1510 };
1511 
1512 struct nstat_client_info {
1513 	struct nstat_client_details nstat_client_details;
1514 	struct nstat_metrics        nstat_metrics;
1515 };
1516 /*
1517  * Structure with information that gives insight into forward progress on an
1518  * interface, exported to user-land via sysctl(3).
1519  */
1520 struct nstat_progress_indicators {
1521 	u_int32_t       np_numflows;            /* Total number of flows */
1522 	u_int32_t       np_conn_probe_fails;    /* Count of connection failures */
1523 	u_int32_t       np_read_probe_fails;    /* Count of read probe failures */
1524 	u_int32_t       np_write_probe_fails;   /* Count of write failures */
1525 	u_int32_t       np_recentflows;         /* Total of "recent" flows */
1526 	u_int32_t       np_recentflows_unacked; /* Total of "recent" flows with unacknowledged data */
1527 	u_int64_t       np_recentflows_rxbytes; /* Total of "recent" flows received bytes */
1528 	u_int64_t       np_recentflows_txbytes; /* Total of "recent" flows transmitted bytes */
1529 	u_int64_t       np_recentflows_rxooo;   /* Total of "recent" flows received out of order bytes */
1530 	u_int64_t       np_recentflows_rxdup;   /* Total of "recent" flows received duplicate bytes */
1531 	u_int64_t       np_recentflows_retx;    /* Total of "recent" flows retransmitted bytes */
1532 	u_int64_t       np_reserved1;           /* Expansion */
1533 	u_int64_t       np_reserved2;           /* Expansion */
1534 	u_int64_t       np_reserved3;           /* Expansion */
1535 	u_int64_t       np_reserved4;           /* Expansion */
1536 };
1537 
1538 struct nstat_progress_req {
1539 	u_int64_t       np_ifindex;                 /* Interface index for progress indicators */
1540 	u_int64_t       np_recentflow_maxduration;  /* In mach_absolute_time, max duration for flow to be counted as "recent" */
1541 	u_int64_t       np_filter_flags;            /* Optional additional filtering, values are interface properties per ntstat.h */
1542 	u_int64_t       np_transport_protocol_mask; /* Transport protocol (currently supports TCP and QUIC) */
1543 #define PR_PROTO_TCP         0x1
1544 #define PR_PROTO_QUIC        0x2
1545 };
1546 
1547 #endif /* PRIVATE */
1548 
1549 #ifdef XNU_KERNEL_PRIVATE
1550 #include <sys/mcache.h>
1551 
1552 #if (DEBUG || DEVELOPMENT)
1553 extern int nstat_test_privacy_transparency;
1554 #endif /* (DEBUG || DEVELOPMENT) */
1555 
1556 #pragma mark -- System Information Internal Support --
1557 
1558 typedef struct nstat_sysinfo_tcp_stats {
1559 	/* When adding/removing here, also adjust NSTAT_SYSINFO_TCP_STATS_COUNT */
1560 	u_int32_t       ipv4_avgrtt;    /* Average RTT for IPv4 */
1561 	u_int32_t       ipv6_avgrtt;    /* Average RTT for IPv6 */
1562 	u_int32_t       send_plr;       /* Average uplink packet loss rate */
1563 	u_int32_t       recv_plr;       /* Average downlink packet loss rate */
1564 	u_int32_t       send_tlrto_rate; /* Average rxt timeout after tail loss */
1565 	u_int32_t       send_reorder_rate; /* Average packet reordering rate */
1566 	u_int32_t       connection_attempts; /* TCP client connection attempts */
1567 	u_int32_t       connection_accepts; /* TCP server connection accepts */
1568 	u_int32_t       ecn_client_enabled; /* Global setting for ECN client side */
1569 	u_int32_t       ecn_server_enabled; /* Global setting for ECN server side */
1570 	u_int32_t       ecn_client_setup; /* Attempts to setup TCP client connection with ECN */
1571 	u_int32_t       ecn_server_setup; /* Attempts to setup TCP server connection with ECN */
1572 	u_int32_t       ecn_client_success; /* Number of successful negotiations of ECN for a client connection */
1573 	u_int32_t       ecn_server_success; /* Number of successful negotiations of ECN for a server connection */
1574 	u_int32_t       ecn_not_supported; /* Number of falbacks to Non-ECN, no support from peer */
1575 	u_int32_t       ecn_lost_syn;   /* Number of SYNs lost with ECN bits */
1576 	u_int32_t       ecn_lost_synack; /* Number of SYN-ACKs lost with ECN bits */
1577 	u_int32_t       ecn_recv_ce;    /* Number of CEs received from network */
1578 	u_int32_t       ecn_recv_ece;   /* Number of ECEs received from receiver */
1579 	u_int32_t       ecn_sent_ece;   /* Number of ECEs sent in response to CE */
1580 	u_int32_t       ecn_conn_recv_ce; /* Number of connections using ECN received CE at least once */
1581 	u_int32_t       ecn_conn_recv_ece; /* Number of connections using ECN received ECE at least once */
1582 	u_int32_t       ecn_conn_plnoce; /* Number of connections using ECN seen packet loss but never received CE */
1583 	u_int32_t       ecn_conn_pl_ce; /* Number of connections using ECN seen packet loss and CE */
1584 	u_int32_t       ecn_conn_nopl_ce; /* Number of connections using ECN with no packet loss but received CE */
1585 	u_int32_t       ecn_fallback_synloss; /* Number of times we did fall back due to SYN-Loss */
1586 	u_int32_t       ecn_fallback_reorder; /* Number of times we fallback because we detected the PAWS-issue */
1587 	u_int32_t       ecn_fallback_ce; /* Number of times we fallback because we received too many CEs */
1588 	u_int32_t       tfo_syn_data_rcv;       /* Number of SYN+data received with valid cookie */
1589 	u_int32_t       tfo_cookie_req_rcv;/* Number of TFO cookie-requests received */
1590 	u_int32_t       tfo_cookie_sent;        /* Number of TFO-cookies offered to the client */
1591 	u_int32_t       tfo_cookie_invalid;/* Number of invalid TFO-cookies received */
1592 	u_int32_t       tfo_cookie_req; /* Number of SYNs with cookie request received*/
1593 	u_int32_t       tfo_cookie_rcv; /* Number of SYN/ACKs with Cookie received */
1594 	u_int32_t       tfo_syn_data_sent;      /* Number of SYNs+data+cookie sent */
1595 	u_int32_t       tfo_syn_data_acked;/* Number of times our SYN+data has been acknowledged */
1596 	u_int32_t       tfo_syn_loss;   /* Number of times SYN+TFO has been lost and we fallback */
1597 	u_int32_t       tfo_blackhole;  /* Number of times SYN+TFO has been lost and we fallback */
1598 	u_int32_t       tfo_cookie_wrong;       /* TFO-cookie we sent was wrong */
1599 	u_int32_t       tfo_no_cookie_rcv;      /* We asked for a cookie but didn't get one */
1600 	u_int32_t       tfo_heuristics_disable; /* TFO got disabled due to heuristics */
1601 	u_int32_t       tfo_sndblackhole;       /* TFO got blackholed in the sending direction */
1602 	u_int32_t       mptcp_handover_attempt; /* Total number of MPTCP-attempts using handover mode */
1603 	u_int32_t       mptcp_interactive_attempt;      /* Total number of MPTCP-attempts using interactive mode */
1604 	u_int32_t       mptcp_aggregate_attempt;        /* Total number of MPTCP-attempts using aggregate mode */
1605 	u_int32_t       mptcp_fp_handover_attempt; /* Same as previous three but only for first-party apps */
1606 	u_int32_t       mptcp_fp_interactive_attempt;
1607 	u_int32_t       mptcp_fp_aggregate_attempt;
1608 	u_int32_t       mptcp_heuristic_fallback;       /* Total number of MPTCP-connections that fell back due to heuristics */
1609 	u_int32_t       mptcp_fp_heuristic_fallback;    /* Same as previous but for first-party apps */
1610 	u_int32_t       mptcp_handover_success_wifi;    /* Total number of successfull handover-mode connections that *started* on WiFi */
1611 	u_int32_t       mptcp_handover_success_cell;    /* Total number of successfull handover-mode connections that *started* on Cell */
1612 	u_int32_t       mptcp_interactive_success;              /* Total number of interactive-mode connections that negotiated MPTCP */
1613 	u_int32_t       mptcp_aggregate_success;                /* Same as previous but for aggregate */
1614 	u_int32_t       mptcp_fp_handover_success_wifi; /* Same as previous four, but for first-party apps */
1615 	u_int32_t       mptcp_fp_handover_success_cell;
1616 	u_int32_t       mptcp_fp_interactive_success;
1617 	u_int32_t       mptcp_fp_aggregate_success;
1618 	u_int32_t       mptcp_handover_cell_from_wifi;  /* Total number of connections that use cell in handover-mode (coming from WiFi) */
1619 	u_int32_t       mptcp_handover_wifi_from_cell;  /* Total number of connections that use WiFi in handover-mode (coming from cell) */
1620 	u_int32_t       mptcp_interactive_cell_from_wifi;       /* Total number of connections that use cell in interactive mode (coming from WiFi) */
1621 	u_int32_t       mptcp_back_to_wifi;     /* Total number of connections that succeed to move traffic away from cell (when starting on cell) */
1622 	u_int64_t       mptcp_handover_cell_bytes;              /* Total number of bytes sent on cell in handover-mode (on new subflows, ignoring initial one) */
1623 	u_int64_t       mptcp_interactive_cell_bytes;   /* Same as previous but for interactive */
1624 	u_int64_t       mptcp_aggregate_cell_bytes;
1625 	u_int64_t       mptcp_handover_all_bytes;               /* Total number of bytes sent in handover */
1626 	u_int64_t       mptcp_interactive_all_bytes;
1627 	u_int64_t       mptcp_aggregate_all_bytes;
1628 	u_int32_t       mptcp_wifi_proxy;               /* Total number of new subflows that fell back to regular TCP on cell */
1629 	u_int32_t       mptcp_cell_proxy;               /* Total number of new subflows that fell back to regular TCP on WiFi */
1630 	u_int32_t       mptcp_triggered_cell;           /* Total number of times an MPTCP-connection triggered cell bringup */
1631 	u_int32_t       _padding;
1632 	/* When adding/removing here, also adjust NSTAT_SYSINFO_TCP_STATS_COUNT */
1633 } nstat_sysinfo_tcp_stats;
1634 #define NSTAT_SYSINFO_TCP_STATS_COUNT   71
1635 
1636 enum {
1637 	NSTAT_IFNET_ECN_PROTO_IPV4 = 1
1638 	, NSTAT_IFNET_ECN_PROTO_IPV6
1639 };
1640 
1641 enum {
1642 	NSTAT_IFNET_ECN_TYPE_CELLULAR = 1
1643 	, NSTAT_IFNET_ECN_TYPE_WIFI
1644 	, NSTAT_IFNET_ECN_TYPE_ETHERNET
1645 };
1646 
1647 /* Total number of Low Internet stats that will be reported */
1648 #define NSTAT_LIM_STAT_KEYVAL_COUNT     12
1649 typedef struct nstat_sysinfo_lim_stats {
1650 	u_int8_t                ifnet_signature[NSTAT_SYSINFO_KEYVAL_STRING_MAXSIZE];
1651 	u_int32_t               ifnet_siglen;
1652 	u_int32_t               ifnet_type;
1653 	struct if_lim_perf_stat lim_stat;
1654 } nstat_sysinfo_lim_stats;
1655 
1656 #define NSTAT_NET_API_STAT_KEYVAL_COUNT (NSTAT_SYSINFO_API_LAST - NSTAT_SYSINFO_API_FIRST + 1)
1657 typedef struct nstat_sysinfo_net_api_stats {
1658 	u_int32_t               report_interval;
1659 	u_int32_t               _padding;
1660 	struct net_api_stats    net_api_stats;
1661 } nstat_sysinfo_net_api_stats;
1662 
1663 typedef struct nstat_sysinfo_data {
1664 	uint32_t                flags;
1665 	uint32_t                unsent_data_cnt; /* Before sleeping */
1666 	union {
1667 		nstat_sysinfo_tcp_stats tcp_stats;
1668 		nstat_sysinfo_lim_stats lim_stats;
1669 		nstat_sysinfo_net_api_stats net_api_stats;
1670 	} u;
1671 } nstat_sysinfo_data;
1672 
1673 #pragma mark -- Route Statistics Gathering Functions --
1674 struct rtentry;
1675 
1676 enum{
1677 	NSTAT_TX_FLAG_RETRANSMIT        = 1
1678 };
1679 
1680 enum{
1681 	NSTAT_RX_FLAG_DUPLICATE         = 1,
1682 	NSTAT_RX_FLAG_OUT_OF_ORDER      = 2
1683 };
1684 
1685 // indicates whether or not collection of statistics is enabled
1686 extern int      nstat_collect;
1687 
1688 void nstat_init(void);
1689 
1690 // Route collection routines
1691 void nstat_route_connect_attempt(struct rtentry *rte);
1692 void nstat_route_connect_success(struct rtentry *rte);
1693 void nstat_route_tx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags);
1694 void nstat_route_rx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags);
1695 void nstat_route_rtt(struct rtentry *rte, u_int32_t rtt, u_int32_t rtt_var);
1696 void nstat_route_update(struct rtentry *rte, uint32_t connect_attempts, uint32_t connect_successes,
1697     uint32_t rx_packets, uint32_t rx_bytes, uint32_t rx_duplicatebytes, uint32_t rx_outoforderbytes,
1698     uint32_t tx_packets, uint32_t tx_bytes, uint32_t tx_retransmit,
1699     uint32_t rtt, uint32_t rtt_var);
1700 struct nstat_counts* nstat_route_attach(struct rtentry  *rte);
1701 void nstat_route_detach(struct rtentry *rte);
1702 
1703 // watcher support
1704 struct inpcb;
1705 void nstat_tcp_new_pcb(struct inpcb *inp);
1706 void nstat_udp_new_pcb(struct inpcb *inp);
1707 void nstat_route_new_entry(struct rtentry *rt);
1708 void nstat_pcb_detach(struct inpcb *inp);
1709 void nstat_pcb_event(struct inpcb *inp, u_int64_t event);
1710 void nstat_udp_pcb_cache(struct inpcb *inp);
1711 void nstat_udp_pcb_invalidate_cache(struct inpcb *inp);
1712 void nstat_pcb_update_last_owner(struct inpcb *inp);
1713 
1714 
1715 void nstat_ifnet_threshold_reached(unsigned int ifindex);
1716 
1717 void nstat_sysinfo_send_data(struct nstat_sysinfo_data *);
1718 
1719 int ntstat_tcp_progress_enable(struct sysctl_req *req);
1720 
1721 #if SKYWALK
1722 
1723 // Userland stats reporting
1724 
1725 // Each side, NetworkStatistics and the kernel provider for userland,
1726 // pass opaque references.
1727 typedef void *userland_stats_provider_context;
1728 typedef void *nstat_userland_context;
1729 
1730 typedef struct nstat_progress_digest {
1731 	u_int64_t       rxbytes;
1732 	u_int64_t       txbytes;
1733 	u_int32_t       rxduplicatebytes;
1734 	u_int32_t       rxoutoforderbytes;
1735 	u_int32_t       txretransmit;
1736 	u_int32_t       ifindex;
1737 	u_int32_t       state;
1738 	u_int32_t       txunacked;
1739 	u_int32_t       txwindow;
1740 	union {
1741 		struct tcp_conn_status connstatus;
1742 		// On armv7k, tcp_conn_status is 1 byte instead of 4
1743 		uint8_t                                 __pad_connstatus[4];
1744 	};
1745 } nstat_progress_digest;
1746 
1747 // When things have been set up, Netstats can request a refresh of its data.
1748 typedef bool (userland_stats_request_vals_fn)(userland_stats_provider_context *ctx,
1749     u_int32_t *ifflagsp,
1750     nstat_progress_digest *digestp,
1751     nstat_counts *countsp,
1752     nstat_detailed_counts *detailed_countsp,
1753     void *metadatap);
1754 
1755 // Netstats can also request "extension" items, specified by the allowed_extensions flag
1756 // The return value is the amount of space currently required for the extension
1757 typedef size_t (userland_stats_request_extension_fn)(userland_stats_provider_context *ctx,
1758     int requested_extension,        /* The extension to be returned */
1759     void *__sized_by(buf_size)buf,  /* If not NULL, the address for the extension to be returned in */
1760     size_t buf_size);               /* The size of the buffer space, typically matching the return from a previous call with null buffer pointer */
1761 
1762 // Things get started with a call to netstats to say that there’s a new connection:
1763 nstat_userland_context ntstat_userland_stats_open(userland_stats_provider_context *ctx,
1764     int provider_id,
1765     u_int64_t properties,
1766     userland_stats_request_vals_fn req_fn,
1767     userland_stats_request_extension_fn req_extension_fn);
1768 
1769 void ntstat_userland_stats_close(nstat_userland_context nstat_ctx);
1770 
1771 
1772 void ntstat_userland_stats_event(nstat_userland_context nstat_ctx, uint64_t event);
1773 
1774 void nstats_userland_stats_defunct_for_process(int pid);
1775 
1776 errno_t nstat_userland_mark_rnf_override(uuid_t fuuid, bool rnf_override);
1777 
1778 typedef struct nstat_flow_data {
1779 	nstat_counts        counts;
1780 	union {
1781 		nstat_udp_descriptor    udp_descriptor;
1782 		nstat_tcp_descriptor    tcp_descriptor;
1783 	} flow_descriptor;
1784 } nstat_flow_data;
1785 
1786 // Servicing a sysctl for information of TCP or UDP flows
1787 int ntstat_userland_count(short proto);
1788 int nstat_userland_get_snapshot(short proto, void *__sized_by(*snapshot_size) * snapshotp, size_t *snapshot_size, int *countp);
1789 int nstat_userland_list_snapshot(short proto, struct sysctl_req *req, void *__sized_by(nuserland * sizeof(nstat_flow_data)) userlandsnapshot, int nuserland);
1790 void nstat_userland_release_snapshot(void *snapshot, int nuserland);
1791 
1792 #if NTSTAT_SUPPORTS_STANDALONE_SYSCTL
1793 int ntstat_userland_list_n(short proto, struct sysctl_req *req);
1794 #endif
1795 #endif /* SKYWALK */
1796 
1797 // Utilities for userland stats reporting
1798 
1799 u_int32_t nstat_ifnet_to_flags(struct ifnet *ifp);
1800 
1801 // Generic external provider reporting
1802 
1803 // Each side passes opaque references.
1804 typedef void *nstat_provider_context;   /* This is quoted to the external provider */
1805 typedef void *nstat_context;            /* This is quoted by the external provider when calling nstat */
1806 
1807 // After nstat_provider_stats_open() has been called (and potentially while the open is still executing), netstats can request a refresh of its data
1808 // The various return pointer parameters may be null if the item is not required
1809 // The return code is true for success
1810 typedef bool (nstat_provider_request_vals_fn)(nstat_provider_context ctx,
1811     u_int32_t *ifflagsp,    /* Flags for being on cell/wifi etc, used for filtering */
1812     nstat_counts *countsp,  /* Counts to be filled in */
1813     nstat_detailed_counts *detailsp,  /* Detailed Counts to be filled in */
1814     void *metadatap);       /* A descriptor for the particular provider */
1815 
1816 // Netstats can also request "extension" items, specified by the allowed_extensions flag
1817 // The return value is the amount of space currently required for the extension
1818 typedef size_t (nstat_provider_request_extensions_fn)(nstat_provider_context ctx,
1819     int requested_extension,    /* The extension to be returned */
1820     void *__sized_by (buf_size)buf,                  /* If not NULL, the address for the extension to be returned in */
1821     size_t buf_size);           /* The size of the buffer space, typically matching the return from a previous call with null buffer pointer */
1822 
1823 // Things get started with a call to netstats to say that there’s a new item to become a netstats source
1824 nstat_context nstat_provider_stats_open(nstat_provider_context ctx,
1825     int provider_id,
1826     u_int64_t properties,                   /* The bottom 32 bits can be used as per the interface / connection flags ifflagsp */
1827     nstat_provider_request_vals_fn req_fn,
1828     nstat_provider_request_extensions_fn req_extensions_fn);
1829 
1830 // Note that when the source is closed, netstats will make one last call on the request functions to retrieve final values
1831 void nstat_provider_stats_close(nstat_context nstat_ctx);
1832 
1833 // Events that cause a significant change may be reported via a flags word
1834 void nstat_provider_stats_event(nstat_context nstat_ctx, uint64_t event);
1835 
1836 // locked_add_64 uses atomic operations on 32bit so the 64bit
1837 // value can be properly read. The values are only ever incremented
1838 // while under the socket lock, so on 64bit we don't actually need
1839 // atomic operations to increment.
1840 #if defined(__LP64__)
1841 #define locked_add_64(__addr, __count) do { \
1842 	*(__addr) += (__count); \
1843 } while (0)
1844 #else
1845 #define locked_add_64(__addr, __count) do { \
1846 	os_atomic_add((__addr), (__count), relaxed); \
1847 } while (0)
1848 #endif
1849 
1850 #endif /* XNU_KERNEL_PRIVATE */
1851 
1852 #endif /* __NTSTAT_H__ */
1853