-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathNetworkStatisticsClient.hpp
More file actions
185 lines (151 loc) · 4.8 KB
/
NetworkStatisticsClient.hpp
File metadata and controls
185 lines (151 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// NetworkStatisticsClient.hpp
// Copyright © 2017 Alex Malone. All rights reserved.
#ifndef NetworkStatisticsClient_hpp
#define NetworkStatisticsClient_hpp
#include <stdint.h>
#include <netinet/in.h>
struct NTStatStream;
/*
* NetworkStatisticsListener
*
* Applications need to implement this interface to receive callbacks
* from the NetworkStatisticsClient.
*
* Note: Darwin reports bidirectional UDP conversations as two separate streams
*
*/
class NetworkStatisticsListener
{
public:
virtual void onStreamAdded(const NTStatStream *stream)=0;
virtual void onStreamRemoved(const NTStatStream *stream)=0;
virtual void onStreamStatsUpdate(const NTStatStream *stream)=0;
};
// this is for testing... you can ignore
class NTStatClientEmulation
{
public:
// saves all messages (requests and responses) to "./ntstat-xnu-<version>.bin"
virtual void enableRecording() = 0;
// in the place of run(), this will process messages from filename
virtual void runRecording(char *filename, unsigned int xnuVersion) = 0;
};
const int NTSTAT_LOGF_ERROR = (1 << 1);
const int NTSTAT_LOGF_SENDRECV = (1 << 2);
const int NTSTAT_LOGF_DEBUG = (1 << 3);
const int NTSTAT_LOGF_TRACE = (1 << 4);
const int NTSTAT_LOGF_DROPS = (1 << 5);
/*
* NetworkStatisticsClient
*
* This is the interface to interact with the com.apple.network.statistics data.
* Behind the scenes, the implementation creates a system socket, subscribes
* to TCP and UDP sources, and passes along the data to the listener.
*/
class NetworkStatisticsClient : public NTStatClientEmulation
{
public:
/*
* This should be done before call to run().
*/
virtual bool connectToKernel() = 0;
/*
* returns true if connectToKernel() was called and was successful.
*/
virtual bool isConnected() = 0;
/*
* Blocking: run from dedicated thread. Subscribes to TCP/UDP and continuously reads messages.
* The connection to the kernel will be disconnected when run() exits.
*/
virtual void run() = 0;
/*
* configure() - needs to be called prior to run()
*
* @param wantTcp If true, include TCP streams. Default: true.
* @param wantUdp If true, include UDP streams. Default: false.
* @param updateIntervalSeconds Interval in seconds to receive stat updates on persistent
* connections. If zero, this feature is turned off. Default: 30.
*/
virtual void configure(bool wantTcp, bool wantUdp, uint32_t updateIntervalSeconds) = 0;
/*
* Will set the stop flag, so run() will exit.
*/
virtual void stop() = 0;
/*
* configure logging. Default flags == 0, no logging.
*/
virtual void setLogging(uint8_t flags) = 0;
/*
* returns the number of ENOBUFS errors received from kernel, indicating
* the inability to send some requested information due to full buffer.
* See docs/protocol.md for more details.
*/
virtual uint32_t getNumDrops() = 0;
};
// Instantiate (singleton) the NetworkStatisticsClient
NetworkStatisticsClient* NetworkStatisticsClientNew(NetworkStatisticsListener* l);
// Data types for reporting
typedef union {
struct in_addr addr4;
struct in6_addr addr6;
} addr_t;
struct NTStatCounters
{
uint64_t rxpackets; // failed if TCP && rxpackets == 0 && txpackets > 0
uint64_t txpackets;
uint64_t rxbytes;
uint64_t txbytes;
uint64_t cell_rxbytes;
uint64_t cell_txbytes;
uint64_t wifi_rxbytes;
uint64_t wifi_txbytes;
uint64_t wired_rxbytes; // wnot present for XNU v2422 and earlier
uint64_t wired_txbytes;
};
struct NTStatStreamState
{
uint32_t state; // TCPS_LISTEN, TCPS_SYN_SENT, etc.
uint32_t txcwindow; // TCP only
uint32_t txwindow; // TCP only
};
struct NTStatStreamKey
{
uint8_t isV6;
uint8_t ipproto; // IPPROTO_TCP or IPPROTO_UDP
uint16_t pad;
uint32_t ifindex;
uint16_t lport; // local port (network-endian)
uint16_t rport; // remove port (network-endian)
addr_t local;
addr_t remote;
bool operator<(const NTStatStreamKey& b) const; // needed to be a key type for std::map
};
struct NTStatProcess
{
uint32_t pid;
char name[64];
};
struct NTStatStream
{
// these are constant once we see the stream
uint64_t id; // Stream ID provided by kernel. Unique for app runtime. Can rollover at uint32_t, so id can be reused.
NTStatStreamKey key;
NTStatProcess process;
// these get updated
NTStatCounters stats;
NTStatStreamState states;
};
/*
#include <string>
struct NTStatInterface
{
std::string name;
uint32_t ifindex;
uint64_t threshold;
unsigned int type;
std::string description;
};
*/
// convenience macros
#define IS_LISTEN_PORT(pstream) (0 == (pstream)->key.rport)
#endif /* NetworkStatisticsClient_hpp */