1/* 2 * Copyright (c) 2010-2014 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 <netinet/in.h> 31#include <net/if.h> 32#include <net/if_var.h> 33 34#ifdef PRIVATE 35#pragma pack(push, 4) 36#pragma mark -- Common Data Structures -- 37 38#define __NSTAT_REVISION__ 6 39 40typedef u_int32_t nstat_provider_id_t; 41typedef u_int32_t nstat_src_ref_t; 42 43typedef struct nstat_counts 44{ 45 /* Counters */ 46 u_int64_t nstat_rxpackets __attribute__((aligned(8))); 47 u_int64_t nstat_rxbytes __attribute__((aligned(8))); 48 u_int64_t nstat_txpackets __attribute__((aligned(8))); 49 u_int64_t nstat_txbytes __attribute__((aligned(8))); 50 51 u_int32_t nstat_rxduplicatebytes; 52 u_int32_t nstat_rxoutoforderbytes; 53 u_int32_t nstat_txretransmit; 54 55 u_int32_t nstat_connectattempts; 56 u_int32_t nstat_connectsuccesses; 57 58 u_int32_t nstat_min_rtt; 59 u_int32_t nstat_avg_rtt; 60 u_int32_t nstat_var_rtt; 61 62 u_int64_t nstat_cell_rxbytes __attribute__((aligned(8))); 63 u_int64_t nstat_cell_txbytes __attribute__((aligned(8))); 64 u_int64_t nstat_wifi_rxbytes __attribute__((aligned(8))); 65 u_int64_t nstat_wifi_txbytes __attribute__((aligned(8))); 66 u_int64_t nstat_wired_rxbytes __attribute__((aligned(8))); 67 u_int64_t nstat_wired_txbytes __attribute__((aligned(8))); 68} nstat_counts; 69 70typedef struct nstat_sysinfo_keyval 71{ 72 u_int32_t nstat_sysinfo_key; 73 u_int32_t nstat_sysinfo_flags; 74 union { 75 int64_t nstat_sysinfo_scalar; 76 double nstat_sysinfo_distribution; 77 } u; 78} nstat_sysinfo_keyval; 79 80#define NSTAT_SYSINFO_FLAG_SCALAR 0x0001 81#define NSTAT_SYSINFO_FLAG_DISTRIBUTION 0x0002 82 83typedef struct nstat_sysinfo_counts 84{ 85 /* Counters */ 86 u_int32_t nstat_sysinfo_len; 87 u_int32_t pad; 88 u_int8_t nstat_sysinfo_keyvals[]; 89} nstat_sysinfo_counts; 90 91enum 92{ 93 NSTAT_SYSINFO_KEY_MBUF_256B_TOTAL = 1 94 ,NSTAT_SYSINFO_KEY_MBUF_2KB_TOTAL = 2 95 ,NSTAT_SYSINFO_KEY_MBUF_4KB_TOTAL = 3 96 ,NSTAT_SYSINFO_KEY_SOCK_MBCNT = 4 97 ,NSTAT_SYSINFO_KEY_SOCK_ATMBLIMIT = 5 98 ,NSTAT_SYSINFO_KEY_IPV4_AVGRTT = 6 99 ,NSTAT_SYSINFO_KEY_IPV6_AVGRTT = 7 100 ,NSTAT_SYSINFO_KEY_SEND_PLR = 8 101 ,NSTAT_SYSINFO_KEY_RECV_PLR = 9 102 ,NSTAT_SYSINFO_KEY_SEND_TLRTO = 10 103 ,NSTAT_SYSINFO_KEY_SEND_REORDERRATE = 11 104 105}; 106 107#pragma mark -- Network Statistics Providers -- 108 109enum 110{ 111 NSTAT_PROVIDER_ROUTE = 1 112 ,NSTAT_PROVIDER_TCP = 2 113 ,NSTAT_PROVIDER_UDP = 3 114 ,NSTAT_PROVIDER_IFNET = 4 115 ,NSTAT_PROVIDER_SYSINFO = 5 116}; 117 118typedef struct nstat_route_add_param 119{ 120 union 121 { 122 struct sockaddr_in v4; 123 struct sockaddr_in6 v6; 124 } dst; 125 union 126 { 127 struct sockaddr_in v4; 128 struct sockaddr_in6 v6; 129 } mask; 130 u_int32_t ifindex; 131} nstat_route_add_param; 132 133typedef struct nstat_tcp_add_param 134{ 135 union 136 { 137 struct sockaddr_in v4; 138 struct sockaddr_in6 v6; 139 } local; 140 union 141 { 142 struct sockaddr_in v4; 143 struct sockaddr_in6 v6; 144 } remote; 145} nstat_tcp_add_param; 146 147typedef struct nstat_tcp_descriptor 148{ 149 union 150 { 151 struct sockaddr_in v4; 152 struct sockaddr_in6 v6; 153 } local; 154 155 union 156 { 157 struct sockaddr_in v4; 158 struct sockaddr_in6 v6; 159 } remote; 160 161 u_int32_t ifindex; 162 163 u_int32_t state; 164 165 u_int32_t sndbufsize; 166 u_int32_t sndbufused; 167 u_int32_t rcvbufsize; 168 u_int32_t rcvbufused; 169 u_int32_t txunacked; 170 u_int32_t txwindow; 171 u_int32_t txcwindow; 172 u_int32_t traffic_class; 173 u_int32_t traffic_mgt_flags; 174 char cc_algo[16]; 175 176 u_int64_t upid; 177 u_int32_t pid; 178 char pname[64]; 179 u_int64_t eupid; 180 u_int32_t epid; 181 182 uint8_t uuid[16]; 183 uint8_t euuid[16]; 184 uint8_t vuuid[16]; 185} nstat_tcp_descriptor; 186 187typedef struct nstat_tcp_add_param nstat_udp_add_param; 188 189typedef struct nstat_udp_descriptor 190{ 191 union 192 { 193 struct sockaddr_in v4; 194 struct sockaddr_in6 v6; 195 } local; 196 197 union 198 { 199 struct sockaddr_in v4; 200 struct sockaddr_in6 v6; 201 } remote; 202 203 u_int32_t ifindex; 204 205 u_int32_t rcvbufsize; 206 u_int32_t rcvbufused; 207 u_int32_t traffic_class; 208 209 u_int64_t upid; 210 u_int32_t pid; 211 char pname[64]; 212 u_int64_t eupid; 213 u_int32_t epid; 214 215 uint8_t uuid[16]; 216 uint8_t euuid[16]; 217 uint8_t vuuid[16]; 218} nstat_udp_descriptor; 219 220typedef struct nstat_route_descriptor 221{ 222 u_int64_t id; 223 u_int64_t parent_id; 224 u_int64_t gateway_id; 225 226 union 227 { 228 struct sockaddr_in v4; 229 struct sockaddr_in6 v6; 230 struct sockaddr sa; 231 } dst; 232 233 union 234 { 235 struct sockaddr_in v4; 236 struct sockaddr_in6 v6; 237 struct sockaddr sa; 238 } mask; 239 240 union 241 { 242 struct sockaddr_in v4; 243 struct sockaddr_in6 v6; 244 struct sockaddr sa; 245 } gateway; 246 247 u_int32_t ifindex; 248 u_int32_t flags; 249 250} nstat_route_descriptor; 251 252typedef struct nstat_ifnet_add_param 253{ 254 u_int32_t ifindex; 255 u_int64_t threshold; 256} nstat_ifnet_add_param; 257 258#ifndef IF_DESCSIZE 259#define IF_DESCSIZE 128 260#endif 261typedef struct nstat_ifnet_descriptor 262{ 263 char name[IFNAMSIZ+1]; 264 u_int32_t ifindex; 265 u_int64_t threshold; 266 unsigned int type; 267 char description[IF_DESCSIZE]; 268} nstat_ifnet_descriptor; 269 270typedef struct nstat_sysinfo_descriptor 271{ 272 u_int32_t flags; 273} nstat_sysinfo_descriptor; 274 275typedef struct nstat_sysinfo_add_param 276{ 277 /* To indicate which system level information should be collected */ 278 u_int32_t flags; 279} nstat_sysinfo_add_param; 280 281#define NSTAT_SYSINFO_MBUF_STATS 0x0001 282#define NSTAT_SYSINFO_TCP_STATS 0x0002 283 284#pragma mark -- Network Statistics User Client -- 285 286#define NET_STAT_CONTROL_NAME "com.apple.network.statistics" 287 288enum 289{ 290 // generic response messages 291 NSTAT_MSG_TYPE_SUCCESS = 0 292 ,NSTAT_MSG_TYPE_ERROR = 1 293 294 // Requests 295 ,NSTAT_MSG_TYPE_ADD_SRC = 1001 296 ,NSTAT_MSG_TYPE_ADD_ALL_SRCS = 1002 297 ,NSTAT_MSG_TYPE_REM_SRC = 1003 298 ,NSTAT_MSG_TYPE_QUERY_SRC = 1004 299 ,NSTAT_MSG_TYPE_GET_SRC_DESC = 1005 300 ,NSTAT_MSG_TYPE_SET_FILTER = 1006 301 302 // Responses/Notfications 303 ,NSTAT_MSG_TYPE_SRC_ADDED = 10001 304 ,NSTAT_MSG_TYPE_SRC_REMOVED = 10002 305 ,NSTAT_MSG_TYPE_SRC_DESC = 10003 306 ,NSTAT_MSG_TYPE_SRC_COUNTS = 10004 307 ,NSTAT_MSG_TYPE_SYSINFO_COUNTS = 10005 308}; 309 310enum 311{ 312 NSTAT_SRC_REF_ALL = 0xffffffff 313 ,NSTAT_SRC_REF_INVALID = 0 314}; 315 316enum 317{ 318 NSTAT_FILTER_NOZEROBYTES = 0x01, 319}; 320 321typedef struct nstat_msg_hdr 322{ 323 u_int64_t context; 324 u_int32_t type; 325 u_int32_t pad; // unused for now 326} nstat_msg_hdr; 327 328typedef struct nstat_msg_error 329{ 330 nstat_msg_hdr hdr; 331 u_int32_t error; // errno error 332} nstat_msg_error; 333 334typedef struct nstat_msg_add_src 335{ 336 nstat_msg_hdr hdr; 337 nstat_provider_id_t provider; 338 u_int8_t param[]; 339} nstat_msg_add_src_req; 340 341typedef struct nstat_msg_add_all_srcs 342{ 343 nstat_msg_hdr hdr; 344 nstat_provider_id_t provider; 345} nstat_msg_add_all_srcs; 346 347typedef struct nstat_msg_src_added 348{ 349 nstat_msg_hdr hdr; 350 nstat_provider_id_t provider; 351 nstat_src_ref_t srcref; 352} nstat_msg_src_added; 353 354typedef struct nstat_msg_rem_src 355{ 356 nstat_msg_hdr hdr; 357 nstat_src_ref_t srcref; 358} nstat_msg_rem_src_req; 359 360typedef struct nstat_msg_get_src_description 361{ 362 nstat_msg_hdr hdr; 363 nstat_src_ref_t srcref; 364} nstat_msg_get_src_description; 365 366typedef struct nstat_msg_set_filter 367{ 368 nstat_msg_hdr hdr; 369 nstat_src_ref_t srcref; 370 u_int32_t filter; 371} nstat_msg_set_filter; 372 373typedef struct nstat_msg_src_description 374{ 375 nstat_msg_hdr hdr; 376 nstat_src_ref_t srcref; 377 nstat_provider_id_t provider; 378 u_int8_t data[]; 379} nstat_msg_src_description; 380 381typedef struct nstat_msg_query_src 382{ 383 nstat_msg_hdr hdr; 384 nstat_src_ref_t srcref; 385} nstat_msg_query_src_req; 386 387typedef struct nstat_msg_src_counts 388{ 389 nstat_msg_hdr hdr; 390 nstat_src_ref_t srcref; 391 nstat_counts counts; 392} nstat_msg_src_counts; 393 394typedef struct nstat_msg_src_removed 395{ 396 nstat_msg_hdr hdr; 397 nstat_src_ref_t srcref; 398} nstat_msg_src_removed; 399 400typedef struct nstat_msg_sysinfo_counts 401{ 402 nstat_msg_hdr hdr; 403 nstat_src_ref_t srcref; 404 nstat_sysinfo_counts counts; 405} nstat_msg_sysinfo_counts; 406 407typedef struct nstat_sysinfo_mbuf_stats 408{ 409 u_int32_t total_256b; 410 u_int32_t total_2kb; 411 u_int32_t total_4kb; 412 u_int32_t sbmb_total; 413 u_int32_t sb_atmbuflimit; 414 u_int32_t draincnt; 415 u_int32_t memreleased; 416} nstat_sysinfo_mbuf_stats; 417 418typedef struct nstat_sysinfo_tcp_stats 419{ 420 u_int32_t ipv4_avgrtt; 421 u_int32_t ipv6_avgrtt; 422 u_int32_t send_plr; 423 u_int32_t recv_plr; 424 u_int32_t send_tlrto_rate; 425 u_int32_t send_reorder_rate; 426} nstat_sysinfo_tcp_stats; 427 428typedef struct nstat_sysinfo_data 429{ 430 u_int32_t flags; 431 union { 432 nstat_sysinfo_mbuf_stats mb_stats; 433 nstat_sysinfo_tcp_stats tcp_stats; 434 } u; 435} nstat_sysinfo_data; 436 437#pragma pack(pop) 438 439#endif /* PRIVATE */ 440 441#ifdef XNU_KERNEL_PRIVATE 442#include <sys/mcache.h> 443 444#pragma mark -- Generic Network Statistics Provider -- 445 446typedef void * nstat_provider_cookie_t; 447 448#pragma mark -- Route Statistics Gathering Functions -- 449struct rtentry; 450 451enum 452{ 453 NSTAT_TX_FLAG_RETRANSMIT = 1 454}; 455 456enum 457{ 458 NSTAT_RX_FLAG_DUPLICATE = 1, 459 NSTAT_RX_FLAG_OUT_OF_ORDER = 2 460}; 461 462// indicates whether or not collection of statistics is enabled 463extern int nstat_collect; 464 465void nstat_init(void); 466 467// Route collection routines 468void nstat_route_connect_attempt(struct rtentry *rte); 469void nstat_route_connect_success(struct rtentry *rte); 470void nstat_route_tx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 471void nstat_route_rx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 472void nstat_route_rtt(struct rtentry *rte, u_int32_t rtt, u_int32_t rtt_var); 473void nstat_route_detach(struct rtentry *rte); 474 475// watcher support 476struct inpcb; 477void nstat_tcp_new_pcb(struct inpcb *inp); 478void nstat_udp_new_pcb(struct inpcb *inp); 479void nstat_route_new_entry(struct rtentry *rt); 480void nstat_pcb_detach(struct inpcb *inp); 481void nstat_pcb_cache(struct inpcb *inp); 482void nstat_pcb_invalidate_cache(struct inpcb *inp); 483 484 485void nstat_ifnet_threshold_reached(unsigned int ifindex); 486 487void nstat_sysinfo_send_data(struct nstat_sysinfo_data *); 488 489// locked_add_64 uses atomic operations on 32bit so the 64bit 490// value can be properly read. The values are only ever incremented 491// while under the socket lock, so on 64bit we don't actually need 492// atomic operations to increment. 493#if defined(__LP64__) 494#define locked_add_64(__addr, __count) do { \ 495 *(__addr) += (__count); \ 496} while (0) 497#else 498#define locked_add_64(__addr, __count) do { \ 499 atomic_add_64((__addr), (__count)); \ 500} while (0) 501#endif 502 503#endif /* XNU_KERNEL_PRIVATE */ 504 505#endif /* __NTSTAT_H__ */ 506