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