1/* 2 * Copyright (c) 2010-2013 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__ 4 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} nstat_counts; 67 68#pragma mark -- Network Statistics Providers -- 69 70enum 71{ 72 NSTAT_PROVIDER_ROUTE = 1 73 ,NSTAT_PROVIDER_TCP = 2 74 ,NSTAT_PROVIDER_UDP = 3 75 ,NSTAT_PROVIDER_IFNET = 4 76}; 77 78typedef struct nstat_route_add_param 79{ 80 union 81 { 82 struct sockaddr_in v4; 83 struct sockaddr_in6 v6; 84 } dst; 85 union 86 { 87 struct sockaddr_in v4; 88 struct sockaddr_in6 v6; 89 } mask; 90 u_int32_t ifindex; 91} nstat_route_add_param; 92 93typedef struct nstat_tcp_add_param 94{ 95 union 96 { 97 struct sockaddr_in v4; 98 struct sockaddr_in6 v6; 99 } local; 100 union 101 { 102 struct sockaddr_in v4; 103 struct sockaddr_in6 v6; 104 } remote; 105} nstat_tcp_add_param; 106 107typedef struct nstat_tcp_descriptor 108{ 109 union 110 { 111 struct sockaddr_in v4; 112 struct sockaddr_in6 v6; 113 } local; 114 115 union 116 { 117 struct sockaddr_in v4; 118 struct sockaddr_in6 v6; 119 } remote; 120 121 u_int32_t ifindex; 122 123 u_int32_t state; 124 125 u_int32_t sndbufsize; 126 u_int32_t sndbufused; 127 u_int32_t rcvbufsize; 128 u_int32_t rcvbufused; 129 u_int32_t txunacked; 130 u_int32_t txwindow; 131 u_int32_t txcwindow; 132 u_int32_t traffic_class; 133 134 u_int64_t upid; 135 u_int32_t pid; 136 char pname[64]; 137 u_int64_t eupid; 138 u_int32_t epid; 139 140 uint8_t uuid[16]; 141 uint8_t euuid[16]; 142} nstat_tcp_descriptor; 143 144typedef struct nstat_tcp_add_param nstat_udp_add_param; 145 146typedef struct nstat_udp_descriptor 147{ 148 union 149 { 150 struct sockaddr_in v4; 151 struct sockaddr_in6 v6; 152 } local; 153 154 union 155 { 156 struct sockaddr_in v4; 157 struct sockaddr_in6 v6; 158 } remote; 159 160 u_int32_t ifindex; 161 162 u_int32_t rcvbufsize; 163 u_int32_t rcvbufused; 164 u_int32_t traffic_class; 165 166 u_int64_t upid; 167 u_int32_t pid; 168 char pname[64]; 169 u_int64_t eupid; 170 u_int32_t epid; 171 172 uint8_t uuid[16]; 173 uint8_t euuid[16]; 174} nstat_udp_descriptor; 175 176typedef struct nstat_route_descriptor 177{ 178 u_int64_t id; 179 u_int64_t parent_id; 180 u_int64_t gateway_id; 181 182 union 183 { 184 struct sockaddr_in v4; 185 struct sockaddr_in6 v6; 186 struct sockaddr sa; 187 } dst; 188 189 union 190 { 191 struct sockaddr_in v4; 192 struct sockaddr_in6 v6; 193 struct sockaddr sa; 194 } mask; 195 196 union 197 { 198 struct sockaddr_in v4; 199 struct sockaddr_in6 v6; 200 struct sockaddr sa; 201 } gateway; 202 203 u_int32_t ifindex; 204 u_int32_t flags; 205 206} nstat_route_descriptor; 207 208typedef struct nstat_ifnet_add_param 209{ 210 u_int32_t ifindex; 211 u_int64_t threshold; 212} nstat_ifnet_add_param; 213 214#ifndef IF_DESCSIZE 215#define IF_DESCSIZE 128 216#endif 217typedef struct nstat_ifnet_descriptor 218{ 219 char name[IFNAMSIZ+1]; 220 u_int32_t ifindex; 221 u_int64_t threshold; 222 unsigned int type; 223 char description[IF_DESCSIZE]; 224} nstat_ifnet_descriptor; 225 226#pragma mark -- Network Statistics User Client -- 227 228#define NET_STAT_CONTROL_NAME "com.apple.network.statistics" 229 230enum 231{ 232 // generic response messages 233 NSTAT_MSG_TYPE_SUCCESS = 0 234 ,NSTAT_MSG_TYPE_ERROR = 1 235 236 // Requests 237 ,NSTAT_MSG_TYPE_ADD_SRC = 1001 238 ,NSTAT_MSG_TYPE_ADD_ALL_SRCS = 1002 239 ,NSTAT_MSG_TYPE_REM_SRC = 1003 240 ,NSTAT_MSG_TYPE_QUERY_SRC = 1004 241 ,NSTAT_MSG_TYPE_GET_SRC_DESC = 1005 242 ,NSTAT_MSG_TYPE_SET_FILTER = 1006 243 244 // Responses/Notfications 245 ,NSTAT_MSG_TYPE_SRC_ADDED = 10001 246 ,NSTAT_MSG_TYPE_SRC_REMOVED = 10002 247 ,NSTAT_MSG_TYPE_SRC_DESC = 10003 248 ,NSTAT_MSG_TYPE_SRC_COUNTS = 10004 249}; 250 251enum 252{ 253 NSTAT_SRC_REF_ALL = 0xffffffff 254 ,NSTAT_SRC_REF_INVALID = 0 255}; 256 257enum 258{ 259 NSTAT_FILTER_NOZEROBYTES = 0x01, 260}; 261 262typedef struct nstat_msg_hdr 263{ 264 u_int64_t context; 265 u_int32_t type; 266 u_int32_t pad; // unused for now 267} nstat_msg_hdr; 268 269typedef struct nstat_msg_error 270{ 271 nstat_msg_hdr hdr; 272 u_int32_t error; // errno error 273} nstat_msg_error; 274 275typedef struct nstat_msg_add_src 276{ 277 nstat_msg_hdr hdr; 278 nstat_provider_id_t provider; 279 u_int8_t param[]; 280} nstat_msg_add_src_req; 281 282typedef struct nstat_msg_add_all_srcs 283{ 284 nstat_msg_hdr hdr; 285 nstat_provider_id_t provider; 286} nstat_msg_add_all_srcs; 287 288typedef struct nstat_msg_src_added 289{ 290 nstat_msg_hdr hdr; 291 nstat_provider_id_t provider; 292 nstat_src_ref_t srcref; 293} nstat_msg_src_added; 294 295typedef struct nstat_msg_rem_src 296{ 297 nstat_msg_hdr hdr; 298 nstat_src_ref_t srcref; 299} nstat_msg_rem_src_req; 300 301typedef struct nstat_msg_get_src_description 302{ 303 nstat_msg_hdr hdr; 304 nstat_src_ref_t srcref; 305} nstat_msg_get_src_description; 306 307typedef struct nstat_msg_set_filter 308{ 309 nstat_msg_hdr hdr; 310 nstat_src_ref_t srcref; 311 u_int32_t filter; 312} nstat_msg_set_filter; 313 314typedef struct nstat_msg_src_description 315{ 316 nstat_msg_hdr hdr; 317 nstat_src_ref_t srcref; 318 nstat_provider_id_t provider; 319 u_int8_t data[]; 320} nstat_msg_src_description; 321 322typedef struct nstat_msg_query_src 323{ 324 nstat_msg_hdr hdr; 325 nstat_src_ref_t srcref; 326} nstat_msg_query_src_req; 327 328typedef struct nstat_msg_src_counts 329{ 330 nstat_msg_hdr hdr; 331 nstat_src_ref_t srcref; 332 nstat_counts counts; 333} nstat_msg_src_counts; 334 335typedef struct nstat_msg_src_removed 336{ 337 nstat_msg_hdr hdr; 338 nstat_src_ref_t srcref; 339} nstat_msg_src_removed; 340 341#pragma pack(pop) 342 343#endif /* PRIVATE */ 344 345#ifdef XNU_KERNEL_PRIVATE 346#include <sys/mcache.h> 347 348#pragma mark -- Generic Network Statistics Provider -- 349 350typedef void * nstat_provider_cookie_t; 351 352#pragma mark -- Route Statistics Gathering Functions -- 353struct rtentry; 354 355enum 356{ 357 NSTAT_TX_FLAG_RETRANSMIT = 1 358}; 359 360enum 361{ 362 NSTAT_RX_FLAG_DUPLICATE = 1, 363 NSTAT_RX_FLAG_OUT_OF_ORDER = 2 364}; 365 366// indicates whether or not collection of statistics is enabled 367extern int nstat_collect; 368 369void nstat_init(void); 370 371// Route collection routines 372void nstat_route_connect_attempt(struct rtentry *rte); 373void nstat_route_connect_success(struct rtentry *rte); 374void nstat_route_tx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 375void nstat_route_rx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 376void nstat_route_rtt(struct rtentry *rte, u_int32_t rtt, u_int32_t rtt_var); 377void nstat_route_detach(struct rtentry *rte); 378 379// watcher support 380struct inpcb; 381void nstat_tcp_new_pcb(struct inpcb *inp); 382void nstat_udp_new_pcb(struct inpcb *inp); 383void nstat_route_new_entry(struct rtentry *rt); 384void nstat_pcb_detach(struct inpcb *inp); 385 386 387void nstat_ifnet_threshold_reached(unsigned int ifindex); 388 389// locked_add_64 uses atomic operations on 32bit so the 64bit 390// value can be properly read. The values are only ever incremented 391// while under the socket lock, so on 64bit we don't actually need 392// atomic operations to increment. 393#if defined(__LP64__) 394#define locked_add_64(__addr, __count) do { \ 395 *(__addr) += (__count); \ 396} while (0) 397#else 398#define locked_add_64(__addr, __count) do { \ 399 atomic_add_64((__addr), (__count)); \ 400} while (0) 401#endif 402 403#endif /* XNU_KERNEL_PRIVATE */ 404 405#endif /* __NTSTAT_H__ */ 406