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