1
-// SPDX-License-Identifier: GPL-3.0-or-later
2
-
3
-#include "windows_plugin.h"
4
-#include "windows-internals.h"
5
-
6
-
7
-#define ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, counter) \
8
- do { \
9
- if ((p)->packets.counter.key) { \
10
- packets += perflibGetObjectCounter((pDataBlock), (pObjectType), &(p)->packets.counter) ? 1 : 0; \
11
- } \
12
- } while (0)
13
-
14
-#define SET_DIM_IF_KEY_AND_UPDATED(p, field) \
15
- do { \
16
- if ((p)->packets.field.key && (p)->packets.field.updated) { \
17
- rrddim_set_by_pointer( \
18
- (p)->packets.st, (p)->packets.rd_##field, (collected_number)(p)->packets.field.current.Data); \
19
- } \
20
- } while (0)
21
-
22
-#define ADD_RRD_DIM_IF_KEY(packet_field, id, name, multiplier, algorithm) \
23
- do { \
24
- if (p->packets.packet_field.key) \
25
- p->packets.rd_##packet_field = rrddim_add(st, id, name, multiplier, 1, algorithm); \
26
- } while (0)
27
-
28
-// --------------------------------------------------------------------------------------------------------------------
29
-// network protocols
30
-
31
-struct network_protocol {
32
- const char *protocol;
33
-
34
- struct {
35
- COUNTER_DATA received;
36
- COUNTER_DATA sent;
37
- COUNTER_DATA delivered;
38
- COUNTER_DATA forwarded;
39
-
40
- COUNTER_DATA InDiscards;
41
- COUNTER_DATA OutDiscards;
42
- COUNTER_DATA InHdrErrors;
43
- COUNTER_DATA InAddrErrors;
44
- COUNTER_DATA InUnknownProtos;
45
- COUNTER_DATA InTooBigErrors;
46
- COUNTER_DATA InTruncatedPkts;
47
- COUNTER_DATA InNoRoutes;
48
- COUNTER_DATA OutNoRoutes;
49
-
50
- COUNTER_DATA InEchoReps;
51
- COUNTER_DATA OutEchoReps;
52
- COUNTER_DATA InDestUnreachs;
53
- COUNTER_DATA OutDestUnreachs;
54
- COUNTER_DATA InRedirects;
55
- COUNTER_DATA OutRedirects;
56
- COUNTER_DATA InEchos;
57
- COUNTER_DATA OutEchos;
58
- COUNTER_DATA InRouterAdvert;
59
- COUNTER_DATA OutRouterAdvert;
60
- COUNTER_DATA InRouterSelect;
61
- COUNTER_DATA OutRouterSelect;
62
- COUNTER_DATA InTimeExcds;
63
- COUNTER_DATA OutTimeExcds;
64
- COUNTER_DATA InParmProbs;
65
- COUNTER_DATA OutParmProbs;
66
- COUNTER_DATA InTimestamps;
67
- COUNTER_DATA OutTimestamps;
68
- COUNTER_DATA InTimestampReps;
69
- COUNTER_DATA OutTimestampReps;
70
-
71
- RRDSET *st;
72
- RRDDIM *rd_received;
73
- RRDDIM *rd_sent;
74
- RRDDIM *rd_forwarded;
75
- RRDDIM *rd_delivered;
76
-
77
- RRDDIM *rd_InDiscards;
78
- RRDDIM *rd_OutDiscards;
79
- RRDDIM *rd_InHdrErrors;
80
- RRDDIM *rd_InAddrErrors;
81
- RRDDIM *rd_InUnknownProtos;
82
- RRDDIM *rd_InTooBigErrors;
83
- RRDDIM *rd_InTruncatedPkts;
84
- RRDDIM *rd_InNoRoutes;
85
- RRDDIM *rd_OutNoRoutes;
86
-
87
- RRDDIM *rd_InEchoReps;
88
- RRDDIM *rd_OutEchoReps;
89
- RRDDIM *rd_InDestUnreachs;
90
- RRDDIM *rd_OutDestUnreachs;
91
- RRDDIM *rd_InRedirects;
92
- RRDDIM *rd_OutRedirects;
93
- RRDDIM *rd_InEchos;
94
- RRDDIM *rd_OutEchos;
95
- RRDDIM *rd_InRouterAdvert;
96
- RRDDIM *rd_OutRouterAdvert;
97
- RRDDIM *rd_InRouterSelect;
98
- RRDDIM *rd_OutRouterSelect;
99
- RRDDIM *rd_InTimeExcds;
100
- RRDDIM *rd_OutTimeExcds;
101
- RRDDIM *rd_InParmProbs;
102
- RRDDIM *rd_OutParmProbs;
103
- RRDDIM *rd_InTimestamps;
104
- RRDDIM *rd_OutTimestamps;
105
- RRDDIM *rd_InTimestampReps;
106
- RRDDIM *rd_OutTimestampReps;
107
-
108
- const char *type;
109
- const char *id;
110
- const char *family;
111
- const char *context;
112
- const char *title;
113
- long priority;
114
- } packets;
115
-
116
-} networks[] = {
117
- {
118
- .protocol = "IPv4",
119
- .packets = {
120
- .received = { .key = "Datagrams Received/sec" },
121
- .sent = { .key = "Datagrams Sent/sec" },
122
- .delivered = { .key = "Datagrams Received Delivered/sec" },
123
- .forwarded = { .key = "Datagrams Forwarded/sec" },
124
- .type = "ipv4",
125
- .id = "packets",
126
- .family = "packets",
127
- .context = "ipv4.packets",
128
- .title = "IPv4 Packets",
129
- .priority = NETDATA_CHART_PRIO_IPV4_PACKETS,
130
- },
131
- },
132
- {
133
- .protocol = "IPv6",
134
- .packets = {
135
- .received = { .key = "Datagrams Received/sec" },
136
- .sent = { .key = "Datagrams Sent/sec" },
137
- .delivered = { .key = "Datagrams Received Delivered/sec" },
138
- .forwarded = { .key = "Datagrams Forwarded/sec" },
139
- .type = "ipv6",
140
- .id = "packets",
141
- .family = "packets",
142
- .context = "ip6.packets",
143
- .title = "IPv6 Packets",
144
- .priority = NETDATA_CHART_PRIO_IPV6_PACKETS,
145
- },
146
- },
147
- {
148
- .protocol = "TCPv4",
149
- .packets = {
150
- .received = { .key = "Segments Received/sec" },
151
- .sent = { .key = "Segments Sent/sec" },
152
- .type = "ipv4",
153
- .id = "tcppackets",
154
- .family = "tcp",
155
- .context = "ipv4.tcppackets",
156
- .title = "IPv4 TCP Packets",
157
- .priority = NETDATA_CHART_PRIO_IPV4_TCP_PACKETS,
158
- },
159
- },
160
- {
161
- .protocol = "TCPv6",
162
- .packets = {
163
- .received = { .key = "Segments Received/sec" },
164
- .sent = { .key = "Segments Sent/sec" },
165
- .type = "ipv6",
166
- .id = "tcppackets",
167
- .family = "tcp6",
168
- .context = "ipv6.tcppackets",
169
- .title = "IPv6 TCP Packets",
170
- .priority = NETDATA_CHART_PRIO_IPV6_TCP_PACKETS,
171
- },
172
- },
173
- {
174
- .protocol = "UDPv4",
175
- .packets = {
176
- .received = { .key = "Datagrams Received/sec" },
177
- .sent = { .key = "Datagrams Sent/sec" },
178
- .type = "ipv4",
179
- .id = "udppackets",
180
- .family = "udp",
181
- .context = "ipv4.udppackets",
182
- .title = "IPv4 UDP Packets",
183
- .priority = NETDATA_CHART_PRIO_IPV4_UDP_PACKETS,
184
- },
185
- },
186
- {
187
- .protocol = "UDPv6",
188
- .packets = {
189
- .received = { .key = "Datagrams Received/sec" },
190
- .sent = { .key = "Datagrams Sent/sec" },
191
- .type = "ipv6",
192
- .id = "udppackets",
193
- .family = "udp6",
194
- .context = "ipv6.udppackets",
195
- .title = "IPv6 UDP Packets",
196
- .priority = NETDATA_CHART_PRIO_IPV6_UDP_PACKETS,
197
- },
198
- },
199
- {
200
- .protocol = "ICMP",
201
- .packets = {
202
- .received = { .key = "Messages Received/sec" },
203
- .sent = { .key = "Messages Sent/sec" },
204
- .type = "ipv4",
205
- .id = "icmp",
206
- .family = "icmp",
207
- .context = "ipv4.icmp",
208
- .title = "IPv4 ICMP Packets",
209
- .priority = NETDATA_CHART_PRIO_IPV4_ICMP_PACKETS,
210
- },
211
- },
212
- {
213
- .protocol = "ICMPv6",
214
- .packets = {
215
- .received = { .key = "Messages Received/sec" },
216
- .sent = { .key = "Messages Sent/sec" },
217
- .type = "ipv6",
218
- .id = "icmp",
219
- .family = "icmp6",
220
- .context = "ipv6.icmp",
221
- .title = "IPv6 ICMP Packets",
222
- .priority = NETDATA_CHART_PRIO_IPV6_ICMP_PACKETS,
223
- },
224
- },
225
-
226
- {
227
- .protocol = "IPv4",
228
- .packets = {
229
- .InDiscards = { .key = "Datagrams Received Discarded" },
230
- .OutDiscards = { .key = "Datagrams Outbound Discarded" },
231
- .OutNoRoutes = { .key = "Datagrams Outbound No Route" },
232
- .InAddrErrors = { .key = "Datagrams Received Address Errors" },
233
- .InHdrErrors = { .key = "Datagrams Received Header Errors" },
234
- .InUnknownProtos = { .key = "Datagrams Received Unknown Protocol" },
235
- .type = "ipv4",
236
- .id = "errors",
237
- .family = "errors",
238
- .context = "ipv4.errors",
239
- .title = "IPv4 errors",
240
- .priority = NETDATA_CHART_PRIO_IPV4_ERRORS,
241
- },
242
- },
243
- {
244
- .protocol = "IPv6",
245
- .packets = {
246
- .InDiscards = { .key = "Datagrams Received Discarded" },
247
- .OutDiscards = { .key = "Datagrams Outbound Discarded" },
248
- .OutNoRoutes = { .key = "Datagrams Outbound No Route" },
249
- .InAddrErrors = { .key = "Datagrams Received Address Errors" },
250
- .InHdrErrors = { .key = "Datagrams Received Header Errors" },
251
- .InUnknownProtos = { .key = "Datagrams Received Unknown Protocol" },
252
- .type = "ipv6",
253
- .id = "errors",
254
- .family = "errors",
255
- .context = "ipv6.errors",
256
- .title = "IPv6 errors",
257
- .priority = NETDATA_CHART_PRIO_IPV6_ERRORS,
258
- },
259
- },
260
- {
261
- .protocol = "ICMP",
262
- .packets =
263
- {
264
- .InEchoReps = {.key = "Received Echo Reply/sec"},
265
- .OutEchoReps = {.key = "Received Echo Reply/sec"},
266
- .InDestUnreachs = {.key = "Received Dest. Unreachable"},
267
- .OutDestUnreachs = {.key = "Sent Destination Unreachable"},
268
- .InRedirects = {.key = "Received Redirect/sec"},
269
- .OutRedirects = {.key = "Sent Redirect/sec"},
270
- .InEchos = {.key = "Received Echo/sec"},
271
- .OutEchos = {.key = "Sent Echo/sec"},
272
- .InRouterAdvert = {.key = NULL},
273
- .OutRouterAdvert = {.key = NULL},
274
- .InRouterSelect = {.key = NULL},
275
- .OutRouterSelect = {.key = NULL},
276
- .InTimeExcds = {.key = "Received Time Exceeded"},
277
- .OutTimeExcds = {.key = "Sent Time Exceeded"},
278
- .InParmProbs = {.key = "Received Parameter Problem"},
279
- .OutParmProbs = {.key = "Sent Parameter Problem"},
280
- .InTimestamps = {.key = "Received Timestamp/sec"},
281
- .OutTimestamps = {.key = "Sent Timestamp/sec"},
282
- .InTimestampReps = {.key = "Received Timestamp Reply/sec"},
283
- .OutTimestampReps = {.key = "Sent Timestamp Reply/sec"},
284
-
285
- .type = "ipv4",
286
- .id = "icmpmsg",
287
- .family = "icmp",
288
- .context = "ipv4.icmpmsg",
289
- .title = "IPv4 ICMP Packets",
290
- .priority = NETDATA_CHART_PRIO_IPV4_ICMP_MESSAGES,
291
- },
292
- },
293
- {
294
- .protocol = "ICMPv6",
295
- .packets =
296
- {
297
- .InEchoReps = {.key = "Received Echo Reply/sec"},
298
- .OutEchoReps = {.key = "Received Echo Reply/sec"},
299
- .InDestUnreachs = {.key = "Received Dest. Unreachable"},
300
- .OutDestUnreachs = {.key = "Sent Destination Unreachable"},
301
- .InRedirects = {.key = "Received Redirect/sec"},
302
- .OutRedirects = {.key = "Sent Redirect/sec"},
303
- .InEchos = {.key = "Received Echo/sec"},
304
- .OutEchos = {.key = "Sent Echo/sec"},
305
- .InRouterAdvert = {.key = NULL},
306
- .OutRouterAdvert = {.key = NULL},
307
- .InRouterSelect = {.key = NULL},
308
- .OutRouterSelect = {.key = NULL},
309
- .InTimeExcds = {.key = "Received Time Exceeded"},
310
- .OutTimeExcds = {.key = "Sent Time Exceeded"},
311
- .InParmProbs = {.key = "Received Parameter Problem"},
312
- .OutParmProbs = {.key = "Sent Parameter Problem"},
313
- .InTimestamps = {.key = "Received Timestamp/sec"},
314
- .OutTimestamps = {.key = "Sent Timestamp/sec"},
315
- .InTimestampReps = {.key = "Received Timestamp Reply/sec"},
316
- .OutTimestampReps = {.key = "Sent Timestamp Reply/sec"},
317
-
318
- .type = "ipv6",
319
- .id = "icmpmsg",
320
- .family = "icmp",
321
- .context = "ipv6.icmpmsg",
322
- .title = "IPv6 ICMP Packets",
323
- .priority = NETDATA_CHART_PRIO_IPV6_ICMP_MESSAGES,
324
- },
325
- },
326
-
327
- // terminator
328
- {
329
- .protocol = NULL,
330
- }
331
-};
332
-
333
-struct network_protocol tcp46 = {
334
- .packets = {
335
- .type = "ip",
336
- .id = "tcppackets",
337
- .family = "tcp",
338
- .context = "ip.tcppackets",
339
- .title = "TCP Packets",
340
- .priority = NETDATA_CHART_PRIO_IP_TCP_PACKETS,
341
- }
342
-};
343
-
344
-static void protocol_packets_chart_update(struct network_protocol *p, int update_every) {
345
- if(!p->packets.st) {
346
- p->packets.st = rrdset_create_localhost(
347
- p->packets.type
348
- , p->packets.id
349
- , NULL
350
- , p->packets.family
351
- , NULL
352
- , p->packets.title
353
- , "packets/s"
354
- , PLUGIN_WINDOWS_NAME
355
- , "PerflibNetwork"
356
- , p->packets.priority
357
- , update_every
358
- , RRDSET_TYPE_AREA
359
- );
360
-
361
- RRDSET *st = p->packets.st;
362
-
363
- ADD_RRD_DIM_IF_KEY(received, "received", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
364
- ADD_RRD_DIM_IF_KEY(sent, "sent", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
365
- ADD_RRD_DIM_IF_KEY(forwarded, "forwarded", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
366
- ADD_RRD_DIM_IF_KEY(delivered, "delivered", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
367
- ADD_RRD_DIM_IF_KEY(InDiscards, "InDiscards", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
368
- ADD_RRD_DIM_IF_KEY(OutDiscards, "OutDiscards", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
369
- ADD_RRD_DIM_IF_KEY(InHdrErrors, "InHdrErrors", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
370
- ADD_RRD_DIM_IF_KEY(InAddrErrors, "InAddrErrors", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
371
- ADD_RRD_DIM_IF_KEY(InUnknownProtos, "InUnknownProtos", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
372
- ADD_RRD_DIM_IF_KEY(InTooBigErrors, "InTooBigErrors", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
373
- ADD_RRD_DIM_IF_KEY(InTruncatedPkts, "InTruncatedPkts", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
374
- ADD_RRD_DIM_IF_KEY(InNoRoutes, "InNoRoutes", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
375
- ADD_RRD_DIM_IF_KEY(OutNoRoutes, "OutNoRoutes", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
376
- ADD_RRD_DIM_IF_KEY(InEchoReps, "InType0", "InEchoReps", 1, RRD_ALGORITHM_INCREMENTAL);
377
- ADD_RRD_DIM_IF_KEY(OutEchoReps, "OutType0", "OutEchoReps", -1, RRD_ALGORITHM_INCREMENTAL);
378
- ADD_RRD_DIM_IF_KEY(InDestUnreachs, "InType3", "InDestUnreachs", 1, RRD_ALGORITHM_INCREMENTAL);
379
- ADD_RRD_DIM_IF_KEY(OutDestUnreachs, "OutType3", "OutDestUnreachs", -1, RRD_ALGORITHM_INCREMENTAL);
380
- ADD_RRD_DIM_IF_KEY(InRedirects, "InType5", "InRedirects", 1, RRD_ALGORITHM_INCREMENTAL);
381
- ADD_RRD_DIM_IF_KEY(OutRedirects, "OutType5", "OutRedirects", -1, RRD_ALGORITHM_INCREMENTAL);
382
- ADD_RRD_DIM_IF_KEY(InEchos, "InType8", "InEchos", 1, RRD_ALGORITHM_INCREMENTAL);
383
- ADD_RRD_DIM_IF_KEY(OutEchos, "OutType8", "OutEchos", -1, RRD_ALGORITHM_INCREMENTAL);
384
- ADD_RRD_DIM_IF_KEY(InRouterAdvert, "InType9", "InRouterAdvert", 1, RRD_ALGORITHM_INCREMENTAL);
385
- ADD_RRD_DIM_IF_KEY(OutRouterAdvert, "OutType9", "OutRouterAdvert", -1, RRD_ALGORITHM_INCREMENTAL);
386
- ADD_RRD_DIM_IF_KEY(InRouterSelect, "InType10", "InRouterSelect", 1, RRD_ALGORITHM_INCREMENTAL);
387
- ADD_RRD_DIM_IF_KEY(OutRouterSelect, "OutType10", "OutRouterSelect", -1, RRD_ALGORITHM_INCREMENTAL);
388
- ADD_RRD_DIM_IF_KEY(InTimeExcds, "InType11", "InTimeExcds", 1, RRD_ALGORITHM_INCREMENTAL);
389
- ADD_RRD_DIM_IF_KEY(OutTimeExcds, "OutType11", "OutTimeExcds", -1, RRD_ALGORITHM_INCREMENTAL);
390
- ADD_RRD_DIM_IF_KEY(InParmProbs, "InType12", "InParmProbs", 1, RRD_ALGORITHM_INCREMENTAL);
391
- ADD_RRD_DIM_IF_KEY(OutParmProbs, "OutType12", "OutParmProbs", -1, RRD_ALGORITHM_INCREMENTAL);
392
- ADD_RRD_DIM_IF_KEY(InTimestamps, "InType13", "InTimestamps", 1, RRD_ALGORITHM_INCREMENTAL);
393
- ADD_RRD_DIM_IF_KEY(OutTimestamps, "OutType13", "OutTimestamps", -1, RRD_ALGORITHM_INCREMENTAL);
394
- ADD_RRD_DIM_IF_KEY(InTimestampReps, "InType14", "InTimestampReps", 1, RRD_ALGORITHM_INCREMENTAL);
395
- ADD_RRD_DIM_IF_KEY(OutTimestampReps, "OutType14", "OutTimestampReps", -1, RRD_ALGORITHM_INCREMENTAL);
396
-
397
- }
398
-
399
- SET_DIM_IF_KEY_AND_UPDATED(p, received);
400
- SET_DIM_IF_KEY_AND_UPDATED(p, sent);
401
-
402
- SET_DIM_IF_KEY_AND_UPDATED(p, forwarded);
403
- SET_DIM_IF_KEY_AND_UPDATED(p, delivered);
404
- SET_DIM_IF_KEY_AND_UPDATED(p, InDiscards);
405
- SET_DIM_IF_KEY_AND_UPDATED(p, OutDiscards);
406
- SET_DIM_IF_KEY_AND_UPDATED(p, InHdrErrors);
407
- SET_DIM_IF_KEY_AND_UPDATED(p, InAddrErrors);
408
- SET_DIM_IF_KEY_AND_UPDATED(p, InUnknownProtos);
409
- SET_DIM_IF_KEY_AND_UPDATED(p, InTooBigErrors);
410
- SET_DIM_IF_KEY_AND_UPDATED(p, InTruncatedPkts);
411
- SET_DIM_IF_KEY_AND_UPDATED(p, InNoRoutes);
412
- SET_DIM_IF_KEY_AND_UPDATED(p, OutNoRoutes);
413
- SET_DIM_IF_KEY_AND_UPDATED(p, InEchoReps);
414
- SET_DIM_IF_KEY_AND_UPDATED(p, OutEchoReps);
415
- SET_DIM_IF_KEY_AND_UPDATED(p, InDestUnreachs);
416
- SET_DIM_IF_KEY_AND_UPDATED(p, OutDestUnreachs);
417
- SET_DIM_IF_KEY_AND_UPDATED(p, InRedirects);
418
- SET_DIM_IF_KEY_AND_UPDATED(p, OutRedirects);
419
- SET_DIM_IF_KEY_AND_UPDATED(p, InEchos);
420
- SET_DIM_IF_KEY_AND_UPDATED(p, OutEchos);
421
- SET_DIM_IF_KEY_AND_UPDATED(p, InRouterAdvert);
422
- SET_DIM_IF_KEY_AND_UPDATED(p, OutRouterAdvert);
423
- SET_DIM_IF_KEY_AND_UPDATED(p, InRouterSelect);
424
- SET_DIM_IF_KEY_AND_UPDATED(p, OutRouterSelect);
425
- SET_DIM_IF_KEY_AND_UPDATED(p, InTimeExcds);
426
- SET_DIM_IF_KEY_AND_UPDATED(p, OutTimeExcds);
427
- SET_DIM_IF_KEY_AND_UPDATED(p, InParmProbs);
428
- SET_DIM_IF_KEY_AND_UPDATED(p, OutParmProbs);
429
- SET_DIM_IF_KEY_AND_UPDATED(p, InTimestamps);
430
- SET_DIM_IF_KEY_AND_UPDATED(p, OutTimestamps);
431
- SET_DIM_IF_KEY_AND_UPDATED(p, InTimestampReps);
432
- SET_DIM_IF_KEY_AND_UPDATED(p, OutTimestampReps);
433
-
434
- rrdset_done(p->packets.st);
435
-}
436
-
437
-static bool do_network_protocol(PERF_DATA_BLOCK *pDataBlock, int update_every, struct network_protocol *p) {
438
- if(!p || !p->protocol) return false;
439
-
440
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->protocol);
441
- if(!pObjectType) return false;
442
-
443
- size_t packets = 0;
444
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, received);
445
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, sent);
446
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, delivered);
447
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, forwarded);
448
-
449
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InDiscards);
450
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutDiscards);
451
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InHdrErrors);
452
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InAddrErrors);
453
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InUnknownProtos);
454
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTooBigErrors);
455
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTruncatedPkts);
456
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InNoRoutes);
457
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutNoRoutes);
458
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InEchoReps);
459
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutEchoReps);
460
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InDestUnreachs);
461
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutDestUnreachs);
462
-
463
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InRedirects);
464
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutRedirects);
465
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InEchos);
466
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutEchos);
467
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InRouterAdvert);
468
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutRouterAdvert);
469
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InRouterSelect);
470
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutRouterSelect);
471
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTimeExcds);
472
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutTimeExcds);
473
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InParmProbs);
474
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutParmProbs);
475
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTimestamps);
476
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutTimestamps);
477
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTimestampReps);
478
- ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutTimestampReps);
479
-
480
- if(packets)
481
- protocol_packets_chart_update(p, update_every);
482
-
483
- return true;
484
-}
485
-
486
-// --------------------------------------------------------------------------------------------------------------------
487
-// network interfaces
488
-
489
-struct network_interface {
490
- bool collected_metadata;
491
-
492
- struct {
493
- COUNTER_DATA received;
494
- COUNTER_DATA sent;
495
-
496
- RRDSET *st;
497
- RRDDIM *rd_received;
498
- RRDDIM *rd_sent;
499
- } packets;
500
-
501
- struct {
502
- COUNTER_DATA received;
503
- COUNTER_DATA sent;
504
-
505
- RRDSET *st;
506
- RRDDIM *rd_received;
507
- RRDDIM *rd_sent;
508
- } traffic;
509
-};
510
-
511
-static DICTIONARY *physical_interfaces = NULL, *virtual_interfaces = NULL;
512
-
513
-static void network_interface_init(struct network_interface *ni) {
514
- ni->packets.received.key = "Packets Received/sec";
515
- ni->packets.sent.key = "Packets Sent/sec";
516
-
517
- ni->traffic.received.key = "Bytes Received/sec";
518
- ni->traffic.sent.key = "Bytes Sent/sec";
519
-}
520
-
521
-void dict_interface_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
522
- struct network_interface *ni = value;
523
- network_interface_init(ni);
524
-}
525
-
526
-static void initialize(void) {
527
- physical_interfaces = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
528
- DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct network_interface));
529
-
530
- virtual_interfaces = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
531
- DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct network_interface));
532
-
533
- dictionary_register_insert_callback(physical_interfaces, dict_interface_insert_cb, NULL);
534
- dictionary_register_insert_callback(virtual_interfaces, dict_interface_insert_cb, NULL);
535
-}
536
-
537
-static void add_interface_labels(RRDSET *st, const char *name, bool physical) {
538
- rrdlabels_add(st->rrdlabels, "device", name, RRDLABEL_SRC_AUTO);
539
- rrdlabels_add(st->rrdlabels, "interface_type", physical ? "real" : "virtual", RRDLABEL_SRC_AUTO);
540
-}
541
-
542
-static bool is_physical_interface(const char *name) {
543
- void *d = dictionary_get(physical_interfaces, name);
544
- return d ? true : false;
545
-}
546
-
547
-static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every, bool physical) {
548
- DICTIONARY *dict = physical_interfaces;
549
-
550
- PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, physical ? "Network Interface" : "Network Adapter");
551
- if(!pObjectType) return false;
552
-
553
- uint64_t total_received = 0, total_sent = 0;
554
-
555
- PERF_INSTANCE_DEFINITION *pi = NULL;
556
- for(LONG i = 0; i < pObjectType->NumInstances ; i++) {
557
- pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
558
- if(!pi) break;
559
-
560
- if(!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
561
- strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
562
-
563
- if(strcasecmp(windows_shared_buffer, "_Total") == 0)
564
- continue;
565
-
566
- if(!physical && is_physical_interface(windows_shared_buffer))
567
- // this virtual interface is already reported as physical interface
568
- continue;
569
-
570
- struct network_interface *d = dictionary_set(dict, windows_shared_buffer, NULL, sizeof(*d));
571
-
572
- if(!d->collected_metadata) {
573
- // TODO - get metadata about the network interface
574
- d->collected_metadata = true;
575
- }
576
-
577
- if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->traffic.received) &&
578
- perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->traffic.sent)) {
579
-
580
- if(d->traffic.received.current.Data == 0 && d->traffic.sent.current.Data == 0)
581
- // this interface has not received or sent any traffic
582
- continue;
583
-
584
- if (unlikely(!d->traffic.st)) {
585
- d->traffic.st = rrdset_create_localhost(
586
- "net",
587
- windows_shared_buffer,
588
- NULL,
589
- windows_shared_buffer,
590
- "net.net",
591
- "Bandwidth",
592
- "kilobits/s",
593
- PLUGIN_WINDOWS_NAME,
594
- "PerflibNetwork",
595
- NETDATA_CHART_PRIO_FIRST_NET_IFACE,
596
- update_every,
597
- RRDSET_TYPE_AREA);
598
-
599
- rrdset_flag_set(d->traffic.st, RRDSET_FLAG_DETAIL);
600
-
601
- add_interface_labels(d->traffic.st, windows_shared_buffer, physical);
602
-
603
- d->traffic.rd_received = rrddim_add(d->traffic.st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
604
- d->traffic.rd_sent = rrddim_add(d->traffic.st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
605
- }
606
-
607
- total_received += d->traffic.received.current.Data;
608
- total_sent += d->traffic.sent.current.Data;
609
-
610
- rrddim_set_by_pointer(d->traffic.st, d->traffic.rd_received, (collected_number)d->traffic.received.current.Data);
611
- rrddim_set_by_pointer(d->traffic.st, d->traffic.rd_sent, (collected_number)d->traffic.sent.current.Data);
612
- rrdset_done(d->traffic.st);
613
- }
614
-
615
- if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->packets.received) &&
616
- perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->packets.sent)) {
617
-
618
- if (unlikely(!d->packets.st)) {
619
- d->packets.st = rrdset_create_localhost(
620
- "net_packets",
621
- windows_shared_buffer,
622
- NULL,
623
- windows_shared_buffer,
624
- "net.packets",
625
- "Packets",
626
- "packets/s",
627
- PLUGIN_WINDOWS_NAME,
628
- "PerflibNetwork",
629
- NETDATA_CHART_PRIO_FIRST_NET_IFACE + 1,
630
- update_every,
631
- RRDSET_TYPE_LINE);
632
-
633
- rrdset_flag_set(d->packets.st, RRDSET_FLAG_DETAIL);
634
-
635
- add_interface_labels(d->traffic.st, windows_shared_buffer, physical);
636
-
637
- d->packets.rd_received = rrddim_add(d->packets.st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
638
- d->packets.rd_sent = rrddim_add(d->packets.st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
639
- }
640
-
641
- rrddim_set_by_pointer(d->packets.st, d->packets.rd_received, (collected_number)d->packets.received.current.Data);
642
- rrddim_set_by_pointer(d->packets.st, d->packets.rd_sent, (collected_number)d->packets.sent.current.Data);
643
- rrdset_done(d->packets.st);
644
- }
645
- }
646
-
647
- if(physical) {
648
- static RRDSET *st = NULL;
649
- static RRDDIM *rd_received = NULL, *rd_sent = NULL;
650
-
651
- if (unlikely(!st)) {
652
- st = rrdset_create_localhost(
653
- "system",
654
- "net",
655
- NULL,
656
- "network",
657
- "system.net",
658
- "Physical Network Interfaces Aggregated Bandwidth",
659
- "kilobits/s",
660
- PLUGIN_WINDOWS_NAME,
661
- "PerflibNetwork",
662
- NETDATA_CHART_PRIO_SYSTEM_NET,
663
- update_every,
664
- RRDSET_TYPE_AREA);
665
-
666
- rd_received = rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
667
- rd_sent = rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
668
- }
669
-
670
- rrddim_set_by_pointer(st, rd_received, (collected_number)total_received);
671
- rrddim_set_by_pointer(st, rd_sent, (collected_number)total_sent);
672
- rrdset_done(st);
673
- }
674
-
675
- return true;
676
-}
677
-
678
-int do_PerflibNetwork(int update_every, usec_t dt __maybe_unused) {
679
- static bool initialized = false;
680
-
681
- if(unlikely(!initialized)) {
682
- initialize();
683
- initialized = true;
684
- }
685
-
686
- DWORD id = RegistryFindIDByName("Network Interface");
687
- if(id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
688
- return -1;
689
-
690
- PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
691
- if(!pDataBlock) return -1;
692
-
693
- do_network_interface(pDataBlock, update_every, true);
694
- do_network_interface(pDataBlock, update_every, false);
695
-
696
- struct network_protocol *tcp4 = NULL, *tcp6 = NULL;
697
- for(size_t i = 0; networks[i].protocol ;i++) {
698
- do_network_protocol(pDataBlock, update_every, &networks[i]);
699
-
700
- if(!tcp4 && strcmp(networks[i].protocol, "TCPv4") == 0)
701
- tcp4 = &networks[i];
702
- if(!tcp6 && strcmp(networks[i].protocol, "TCPv6") == 0)
703
- tcp6 = &networks[i];
704
- }
705
-
706
- if(tcp4 && tcp6) {
707
- tcp46.packets.received = tcp4->packets.received;
708
- tcp46.packets.sent = tcp4->packets.sent;
709
- tcp46.packets.received.current.Data += tcp6->packets.received.current.Data;
710
- tcp46.packets.sent.current.Data += tcp6->packets.sent.current.Data;
711
- protocol_packets_chart_update(&tcp46, update_every);
712
- }
713
- return 0;
714
-}
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#include "windows_plugin.h"
4
+#include "windows-internals.h"
5
+
6
+#define ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, counter) \
7
+ do { \
8
+ if ((p)->packets.counter.key) { \
9
+ packets += perflibGetObjectCounter((pDataBlock), (pObjectType), &(p)->packets.counter) ? 1 : 0; \
10
+ } \
11
+ } while (0)
12
+
13
+#define SET_DIM_IF_KEY_AND_UPDATED(p, field) \
14
+ do { \
15
+ if ((p)->packets.field.key && (p)->packets.field.updated) { \
16
+ rrddim_set_by_pointer( \
17
+ (p)->packets.st, (p)->packets.rd_##field, (collected_number)(p)->packets.field.current.Data); \
18
+ } \
19
+ } while (0)
20
+
21
+#define ADD_RRD_DIM_IF_KEY(packet_field, id, name, multiplier, algorithm) \
22
+ do { \
23
+ if (p->packets.packet_field.key) \
24
+ p->packets.rd_##packet_field = rrddim_add(st, id, name, multiplier, 1, algorithm); \
25
+ } while (0)
26
+
27
+// --------------------------------------------------------------------------------------------------------------------
28
+// network protocols
29
+
30
+struct network_protocol {
31
+ const char *protocol;
32
+
33
+ struct {
34
+ COUNTER_DATA received;
35
+ COUNTER_DATA sent;
36
+ COUNTER_DATA delivered;
37
+ COUNTER_DATA forwarded;
38
+
39
+ COUNTER_DATA InDiscards;
40
+ COUNTER_DATA OutDiscards;
41
+ COUNTER_DATA InHdrErrors;
42
+ COUNTER_DATA InAddrErrors;
43
+ COUNTER_DATA InUnknownProtos;
44
+ COUNTER_DATA InTooBigErrors;
45
+ COUNTER_DATA InTruncatedPkts;
46
+ COUNTER_DATA InNoRoutes;
47
+ COUNTER_DATA OutNoRoutes;
48
+
49
+ COUNTER_DATA InEchoReps;
50
+ COUNTER_DATA OutEchoReps;
51
+ COUNTER_DATA InDestUnreachs;
52
+ COUNTER_DATA OutDestUnreachs;
53
+ COUNTER_DATA InRedirects;
54
+ COUNTER_DATA OutRedirects;
55
+ COUNTER_DATA InEchos;
56
+ COUNTER_DATA OutEchos;
57
+ COUNTER_DATA InRouterAdvert;
58
+ COUNTER_DATA OutRouterAdvert;
59
+ COUNTER_DATA InRouterSelect;
60
+ COUNTER_DATA OutRouterSelect;
61
+ COUNTER_DATA InTimeExcds;
62
+ COUNTER_DATA OutTimeExcds;
63
+ COUNTER_DATA InParmProbs;
64
+ COUNTER_DATA OutParmProbs;
65
+ COUNTER_DATA InTimestamps;
66
+ COUNTER_DATA OutTimestamps;
67
+ COUNTER_DATA InTimestampReps;
68
+ COUNTER_DATA OutTimestampReps;
69
+
70
+ RRDSET *st;
71
+ RRDDIM *rd_received;
72
+ RRDDIM *rd_sent;
73
+ RRDDIM *rd_forwarded;
74
+ RRDDIM *rd_delivered;
75
+
76
+ RRDDIM *rd_InDiscards;
77
+ RRDDIM *rd_OutDiscards;
78
+ RRDDIM *rd_InHdrErrors;
79
+ RRDDIM *rd_InAddrErrors;
80
+ RRDDIM *rd_InUnknownProtos;
81
+ RRDDIM *rd_InTooBigErrors;
82
+ RRDDIM *rd_InTruncatedPkts;
83
+ RRDDIM *rd_InNoRoutes;
84
+ RRDDIM *rd_OutNoRoutes;
85
+
86
+ RRDDIM *rd_InEchoReps;
87
+ RRDDIM *rd_OutEchoReps;
88
+ RRDDIM *rd_InDestUnreachs;
89
+ RRDDIM *rd_OutDestUnreachs;
90
+ RRDDIM *rd_InRedirects;
91
+ RRDDIM *rd_OutRedirects;
92
+ RRDDIM *rd_InEchos;
93
+ RRDDIM *rd_OutEchos;
94
+ RRDDIM *rd_InRouterAdvert;
95
+ RRDDIM *rd_OutRouterAdvert;
96
+ RRDDIM *rd_InRouterSelect;
97
+ RRDDIM *rd_OutRouterSelect;
98
+ RRDDIM *rd_InTimeExcds;
99
+ RRDDIM *rd_OutTimeExcds;
100
+ RRDDIM *rd_InParmProbs;
101
+ RRDDIM *rd_OutParmProbs;
102
+ RRDDIM *rd_InTimestamps;
103
+ RRDDIM *rd_OutTimestamps;
104
+ RRDDIM *rd_InTimestampReps;
105
+ RRDDIM *rd_OutTimestampReps;
106
+
107
+ const char *type;
108
+ const char *id;
109
+ const char *family;
110
+ const char *context;
111
+ const char *title;
112
+ long priority;
113
+ } packets;
114
+
115
+} networks[] = {
116
+ {
117
+ .protocol = "IPv4",
118
+ .packets = {
119
+ .received = { .key = "Datagrams Received/sec" },
120
+ .sent = { .key = "Datagrams Sent/sec" },
121
+ .delivered = { .key = "Datagrams Received Delivered/sec" },
122
+ .forwarded = { .key = "Datagrams Forwarded/sec" },
123
+ .type = "ipv4",
124
+ .id = "packets",
125
+ .family = "packets",
126
+ .context = "ipv4.packets",
127
+ .title = "IPv4 Packets",
128
+ .priority = NETDATA_CHART_PRIO_IPV4_PACKETS,
129
+ },
130
+ },
131
+ {
132
+ .protocol = "IPv6",
133
+ .packets = {
134
+ .received = { .key = "Datagrams Received/sec" },
135
+ .sent = { .key = "Datagrams Sent/sec" },
136
+ .delivered = { .key = "Datagrams Received Delivered/sec" },
137
+ .forwarded = { .key = "Datagrams Forwarded/sec" },
138
+ .type = "ipv6",
139
+ .id = "packets",
140
+ .family = "packets",
141
+ .context = "ip6.packets",
142
+ .title = "IPv6 Packets",
143
+ .priority = NETDATA_CHART_PRIO_IPV6_PACKETS,
144
+ },
145
+ },
146
+ {
147
+ .protocol = "TCPv4",
148
+ .packets = {
149
+ .received = { .key = "Segments Received/sec" },
150
+ .sent = { .key = "Segments Sent/sec" },
151
+ .type = "ipv4",
152
+ .id = "tcppackets",
153
+ .family = "tcp",
154
+ .context = "ipv4.tcppackets",
155
+ .title = "IPv4 TCP Packets",
156
+ .priority = NETDATA_CHART_PRIO_IPV4_TCP_PACKETS,
157
+ },
158
+ },
159
+ {
160
+ .protocol = "TCPv6",
161
+ .packets = {
162
+ .received = { .key = "Segments Received/sec" },
163
+ .sent = { .key = "Segments Sent/sec" },
164
+ .type = "ipv6",
165
+ .id = "tcppackets",
166
+ .family = "tcp6",
167
+ .context = "ipv6.tcppackets",
168
+ .title = "IPv6 TCP Packets",
169
+ .priority = NETDATA_CHART_PRIO_IPV6_TCP_PACKETS,
170
+ },
171
+ },
172
+ {
173
+ .protocol = "UDPv4",
174
+ .packets = {
175
+ .received = { .key = "Datagrams Received/sec" },
176
+ .sent = { .key = "Datagrams Sent/sec" },
177
+ .type = "ipv4",
178
+ .id = "udppackets",
179
+ .family = "udp",
180
+ .context = "ipv4.udppackets",
181
+ .title = "IPv4 UDP Packets",
182
+ .priority = NETDATA_CHART_PRIO_IPV4_UDP_PACKETS,
183
+ },
184
+ },
185
+ {
186
+ .protocol = "UDPv6",
187
+ .packets = {
188
+ .received = { .key = "Datagrams Received/sec" },
189
+ .sent = { .key = "Datagrams Sent/sec" },
190
+ .type = "ipv6",
191
+ .id = "udppackets",
192
+ .family = "udp6",
193
+ .context = "ipv6.udppackets",
194
+ .title = "IPv6 UDP Packets",
195
+ .priority = NETDATA_CHART_PRIO_IPV6_UDP_PACKETS,
196
+ },
197
+ },
198
+ {
199
+ .protocol = "ICMP",
200
+ .packets = {
201
+ .received = { .key = "Messages Received/sec" },
202
+ .sent = { .key = "Messages Sent/sec" },
203
+ .type = "ipv4",
204
+ .id = "icmp",
205
+ .family = "icmp",
206
+ .context = "ipv4.icmp",
207
+ .title = "IPv4 ICMP Packets",
208
+ .priority = NETDATA_CHART_PRIO_IPV4_ICMP_PACKETS,
209
+ },
210
+ },
211
+ {
212
+ .protocol = "ICMPv6",
213
+ .packets = {
214
+ .received = { .key = "Messages Received/sec" },
215
+ .sent = { .key = "Messages Sent/sec" },
216
+ .type = "ipv6",
217
+ .id = "icmp",
218
+ .family = "icmp6",
219
+ .context = "ipv6.icmp",
220
+ .title = "IPv6 ICMP Packets",
221
+ .priority = NETDATA_CHART_PRIO_IPV6_ICMP_PACKETS,
222
+ },
223
+ },
224
+
225
+ {
226
+ .protocol = "IPv4",
227
+ .packets = {
228
+ .InDiscards = { .key = "Datagrams Received Discarded" },
229
+ .OutDiscards = { .key = "Datagrams Outbound Discarded" },
230
+ .OutNoRoutes = { .key = "Datagrams Outbound No Route" },
231
+ .InAddrErrors = { .key = "Datagrams Received Address Errors" },
232
+ .InHdrErrors = { .key = "Datagrams Received Header Errors" },
233
+ .InUnknownProtos = { .key = "Datagrams Received Unknown Protocol" },
234
+ .type = "ipv4",
235
+ .id = "errors",
236
+ .family = "errors",
237
+ .context = "ipv4.errors",
238
+ .title = "IPv4 errors",
239
+ .priority = NETDATA_CHART_PRIO_IPV4_ERRORS,
240
+ },
241
+ },
242
+ {
243
+ .protocol = "IPv6",
244
+ .packets = {
245
+ .InDiscards = { .key = "Datagrams Received Discarded" },
246
+ .OutDiscards = { .key = "Datagrams Outbound Discarded" },
247
+ .OutNoRoutes = { .key = "Datagrams Outbound No Route" },
248
+ .InAddrErrors = { .key = "Datagrams Received Address Errors" },
249
+ .InHdrErrors = { .key = "Datagrams Received Header Errors" },
250
+ .InUnknownProtos = { .key = "Datagrams Received Unknown Protocol" },
251
+ .type = "ipv6",
252
+ .id = "errors",
253
+ .family = "errors",
254
+ .context = "ipv6.errors",
255
+ .title = "IPv6 errors",
256
+ .priority = NETDATA_CHART_PRIO_IPV6_ERRORS,
257
+ },
258
+ },
259
+ {
260
+ .protocol = "ICMP",
261
+ .packets =
262
+ {
263
+ .InEchoReps = {.key = "Received Echo Reply/sec"},
264
+ .OutEchoReps = {.key = "Received Echo Reply/sec"},
265
+ .InDestUnreachs = {.key = "Received Dest. Unreachable"},
266
+ .OutDestUnreachs = {.key = "Sent Destination Unreachable"},
267
+ .InRedirects = {.key = "Received Redirect/sec"},
268
+ .OutRedirects = {.key = "Sent Redirect/sec"},
269
+ .InEchos = {.key = "Received Echo/sec"},
270
+ .OutEchos = {.key = "Sent Echo/sec"},
271
+ .InRouterAdvert = {.key = NULL},
272
+ .OutRouterAdvert = {.key = NULL},
273
+ .InRouterSelect = {.key = NULL},
274
+ .OutRouterSelect = {.key = NULL},
275
+ .InTimeExcds = {.key = "Received Time Exceeded"},
276
+ .OutTimeExcds = {.key = "Sent Time Exceeded"},
277
+ .InParmProbs = {.key = "Received Parameter Problem"},
278
+ .OutParmProbs = {.key = "Sent Parameter Problem"},
279
+ .InTimestamps = {.key = "Received Timestamp/sec"},
280
+ .OutTimestamps = {.key = "Sent Timestamp/sec"},
281
+ .InTimestampReps = {.key = "Received Timestamp Reply/sec"},
282
+ .OutTimestampReps = {.key = "Sent Timestamp Reply/sec"},
283
+
284
+ .type = "ipv4",
285
+ .id = "icmpmsg",
286
+ .family = "icmp",
287
+ .context = "ipv4.icmpmsg",
288
+ .title = "IPv4 ICMP Packets",
289
+ .priority = NETDATA_CHART_PRIO_IPV4_ICMP_MESSAGES,
290
+ },
291
+ },
292
+ {
293
+ .protocol = "ICMPv6",
294
+ .packets =
295
+ {
296
+ .InEchoReps = {.key = "Received Echo Reply/sec"},
297
+ .OutEchoReps = {.key = "Received Echo Reply/sec"},
298
+ .InDestUnreachs = {.key = "Received Dest. Unreachable"},
299
+ .OutDestUnreachs = {.key = "Sent Destination Unreachable"},
300
+ .InRedirects = {.key = "Received Redirect/sec"},
301
+ .OutRedirects = {.key = "Sent Redirect/sec"},
302
+ .InEchos = {.key = "Received Echo/sec"},
303
+ .OutEchos = {.key = "Sent Echo/sec"},
304
+ .InRouterAdvert = {.key = NULL},
305
+ .OutRouterAdvert = {.key = NULL},
306
+ .InRouterSelect = {.key = NULL},
307
+ .OutRouterSelect = {.key = NULL},
308
+ .InTimeExcds = {.key = "Received Time Exceeded"},
309
+ .OutTimeExcds = {.key = "Sent Time Exceeded"},
310
+ .InParmProbs = {.key = "Received Parameter Problem"},
311
+ .OutParmProbs = {.key = "Sent Parameter Problem"},
312
+ .InTimestamps = {.key = "Received Timestamp/sec"},
313
+ .OutTimestamps = {.key = "Sent Timestamp/sec"},
314
+ .InTimestampReps = {.key = "Received Timestamp Reply/sec"},
315
+ .OutTimestampReps = {.key = "Sent Timestamp Reply/sec"},
316
+
317
+ .type = "ipv6",
318
+ .id = "icmpmsg",
319
+ .family = "icmp",
320
+ .context = "ipv6.icmpmsg",
321
+ .title = "IPv6 ICMP Packets",
322
+ .priority = NETDATA_CHART_PRIO_IPV6_ICMP_MESSAGES,
323
+ },
324
+ },
325
+
326
+ // terminator
327
+ {
328
+ .protocol = NULL,
329
+ }
330
+};
331
+
332
+struct network_protocol tcp46 = {
333
+ .packets = {
334
+ .type = "ip",
335
+ .id = "tcppackets",
336
+ .family = "tcp",
337
+ .context = "ip.tcppackets",
338
+ .title = "TCP Packets",
339
+ .priority = NETDATA_CHART_PRIO_IP_TCP_PACKETS,
340
+ }
341
+};
342
+
343
+static void protocol_packets_chart_update(struct network_protocol *p, int update_every) {
344
+ if(!p->packets.st) {
345
+ p->packets.st = rrdset_create_localhost(
346
+ p->packets.type
347
+ , p->packets.id
348
+ , NULL
349
+ , p->packets.family
350
+ , NULL
351
+ , p->packets.title
352
+ , "packets/s"
353
+ , PLUGIN_WINDOWS_NAME
354
+ , "PerflibNetwork"
355
+ , p->packets.priority
356
+ , update_every
357
+ , RRDSET_TYPE_AREA
358
+ );
359
+
360
+ RRDSET *st = p->packets.st;
361
+
362
+ ADD_RRD_DIM_IF_KEY(received, "received", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
363
+ ADD_RRD_DIM_IF_KEY(sent, "sent", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
364
+ ADD_RRD_DIM_IF_KEY(forwarded, "forwarded", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
365
+ ADD_RRD_DIM_IF_KEY(delivered, "delivered", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
366
+ ADD_RRD_DIM_IF_KEY(InDiscards, "InDiscards", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
367
+ ADD_RRD_DIM_IF_KEY(OutDiscards, "OutDiscards", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
368
+ ADD_RRD_DIM_IF_KEY(InHdrErrors, "InHdrErrors", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
369
+ ADD_RRD_DIM_IF_KEY(InAddrErrors, "InAddrErrors", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
370
+ ADD_RRD_DIM_IF_KEY(InUnknownProtos, "InUnknownProtos", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
371
+ ADD_RRD_DIM_IF_KEY(InTooBigErrors, "InTooBigErrors", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
372
+ ADD_RRD_DIM_IF_KEY(InTruncatedPkts, "InTruncatedPkts", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
373
+ ADD_RRD_DIM_IF_KEY(InNoRoutes, "InNoRoutes", NULL, 1, RRD_ALGORITHM_INCREMENTAL);
374
+ ADD_RRD_DIM_IF_KEY(OutNoRoutes, "OutNoRoutes", NULL, -1, RRD_ALGORITHM_INCREMENTAL);
375
+ ADD_RRD_DIM_IF_KEY(InEchoReps, "InType0", "InEchoReps", 1, RRD_ALGORITHM_INCREMENTAL);
376
+ ADD_RRD_DIM_IF_KEY(OutEchoReps, "OutType0", "OutEchoReps", -1, RRD_ALGORITHM_INCREMENTAL);
377
+ ADD_RRD_DIM_IF_KEY(InDestUnreachs, "InType3", "InDestUnreachs", 1, RRD_ALGORITHM_INCREMENTAL);
378
+ ADD_RRD_DIM_IF_KEY(OutDestUnreachs, "OutType3", "OutDestUnreachs", -1, RRD_ALGORITHM_INCREMENTAL);
379
+ ADD_RRD_DIM_IF_KEY(InRedirects, "InType5", "InRedirects", 1, RRD_ALGORITHM_INCREMENTAL);
380
+ ADD_RRD_DIM_IF_KEY(OutRedirects, "OutType5", "OutRedirects", -1, RRD_ALGORITHM_INCREMENTAL);
381
+ ADD_RRD_DIM_IF_KEY(InEchos, "InType8", "InEchos", 1, RRD_ALGORITHM_INCREMENTAL);
382
+ ADD_RRD_DIM_IF_KEY(OutEchos, "OutType8", "OutEchos", -1, RRD_ALGORITHM_INCREMENTAL);
383
+ ADD_RRD_DIM_IF_KEY(InRouterAdvert, "InType9", "InRouterAdvert", 1, RRD_ALGORITHM_INCREMENTAL);
384
+ ADD_RRD_DIM_IF_KEY(OutRouterAdvert, "OutType9", "OutRouterAdvert", -1, RRD_ALGORITHM_INCREMENTAL);
385
+ ADD_RRD_DIM_IF_KEY(InRouterSelect, "InType10", "InRouterSelect", 1, RRD_ALGORITHM_INCREMENTAL);
386
+ ADD_RRD_DIM_IF_KEY(OutRouterSelect, "OutType10", "OutRouterSelect", -1, RRD_ALGORITHM_INCREMENTAL);
387
+ ADD_RRD_DIM_IF_KEY(InTimeExcds, "InType11", "InTimeExcds", 1, RRD_ALGORITHM_INCREMENTAL);
388
+ ADD_RRD_DIM_IF_KEY(OutTimeExcds, "OutType11", "OutTimeExcds", -1, RRD_ALGORITHM_INCREMENTAL);
389
+ ADD_RRD_DIM_IF_KEY(InParmProbs, "InType12", "InParmProbs", 1, RRD_ALGORITHM_INCREMENTAL);
390
+ ADD_RRD_DIM_IF_KEY(OutParmProbs, "OutType12", "OutParmProbs", -1, RRD_ALGORITHM_INCREMENTAL);
391
+ ADD_RRD_DIM_IF_KEY(InTimestamps, "InType13", "InTimestamps", 1, RRD_ALGORITHM_INCREMENTAL);
392
+ ADD_RRD_DIM_IF_KEY(OutTimestamps, "OutType13", "OutTimestamps", -1, RRD_ALGORITHM_INCREMENTAL);
393
+ ADD_RRD_DIM_IF_KEY(InTimestampReps, "InType14", "InTimestampReps", 1, RRD_ALGORITHM_INCREMENTAL);
394
+ ADD_RRD_DIM_IF_KEY(OutTimestampReps, "OutType14", "OutTimestampReps", -1, RRD_ALGORITHM_INCREMENTAL);
395
+
396
+ }
397
+
398
+ SET_DIM_IF_KEY_AND_UPDATED(p, received);
399
+ SET_DIM_IF_KEY_AND_UPDATED(p, sent);
400
+
401
+ SET_DIM_IF_KEY_AND_UPDATED(p, forwarded);
402
+ SET_DIM_IF_KEY_AND_UPDATED(p, delivered);
403
+ SET_DIM_IF_KEY_AND_UPDATED(p, InDiscards);
404
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutDiscards);
405
+ SET_DIM_IF_KEY_AND_UPDATED(p, InHdrErrors);
406
+ SET_DIM_IF_KEY_AND_UPDATED(p, InAddrErrors);
407
+ SET_DIM_IF_KEY_AND_UPDATED(p, InUnknownProtos);
408
+ SET_DIM_IF_KEY_AND_UPDATED(p, InTooBigErrors);
409
+ SET_DIM_IF_KEY_AND_UPDATED(p, InTruncatedPkts);
410
+ SET_DIM_IF_KEY_AND_UPDATED(p, InNoRoutes);
411
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutNoRoutes);
412
+ SET_DIM_IF_KEY_AND_UPDATED(p, InEchoReps);
413
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutEchoReps);
414
+ SET_DIM_IF_KEY_AND_UPDATED(p, InDestUnreachs);
415
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutDestUnreachs);
416
+ SET_DIM_IF_KEY_AND_UPDATED(p, InRedirects);
417
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutRedirects);
418
+ SET_DIM_IF_KEY_AND_UPDATED(p, InEchos);
419
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutEchos);
420
+ SET_DIM_IF_KEY_AND_UPDATED(p, InRouterAdvert);
421
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutRouterAdvert);
422
+ SET_DIM_IF_KEY_AND_UPDATED(p, InRouterSelect);
423
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutRouterSelect);
424
+ SET_DIM_IF_KEY_AND_UPDATED(p, InTimeExcds);
425
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutTimeExcds);
426
+ SET_DIM_IF_KEY_AND_UPDATED(p, InParmProbs);
427
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutParmProbs);
428
+ SET_DIM_IF_KEY_AND_UPDATED(p, InTimestamps);
429
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutTimestamps);
430
+ SET_DIM_IF_KEY_AND_UPDATED(p, InTimestampReps);
431
+ SET_DIM_IF_KEY_AND_UPDATED(p, OutTimestampReps);
432
+
433
+ rrdset_done(p->packets.st);
434
+}
435
+
436
+static bool do_network_protocol(PERF_DATA_BLOCK *pDataBlock, int update_every, struct network_protocol *p) {
437
+ if(!p || !p->protocol) return false;
438
+
439
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, p->protocol);
440
+ if(!pObjectType) return false;
441
+
442
+ size_t packets = 0;
443
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, received);
444
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, sent);
445
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, delivered);
446
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, forwarded);
447
+
448
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InDiscards);
449
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutDiscards);
450
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InHdrErrors);
451
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InAddrErrors);
452
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InUnknownProtos);
453
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTooBigErrors);
454
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTruncatedPkts);
455
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InNoRoutes);
456
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutNoRoutes);
457
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InEchoReps);
458
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutEchoReps);
459
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InDestUnreachs);
460
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutDestUnreachs);
461
+
462
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InRedirects);
463
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutRedirects);
464
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InEchos);
465
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutEchos);
466
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InRouterAdvert);
467
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutRouterAdvert);
468
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InRouterSelect);
469
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutRouterSelect);
470
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTimeExcds);
471
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutTimeExcds);
472
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InParmProbs);
473
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutParmProbs);
474
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTimestamps);
475
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutTimestamps);
476
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, InTimestampReps);
477
+ ADD_PACKET_IF_KEY(p, packets, pDataBlock, pObjectType, OutTimestampReps);
478
+
479
+ if(packets)
480
+ protocol_packets_chart_update(p, update_every);
481
+
482
+ return true;
483
+}
484
+
485
+// --------------------------------------------------------------------------------------------------------------------
486
+// network interfaces
487
+
488
+struct network_interface {
489
+ bool collected_metadata;
490
+
491
+ struct {
492
+ COUNTER_DATA received;
493
+ COUNTER_DATA sent;
494
+
495
+ RRDSET *st;
496
+ RRDDIM *rd_received;
497
+ RRDDIM *rd_sent;
498
+ } packets;
499
+
500
+ struct {
501
+ COUNTER_DATA received;
502
+ COUNTER_DATA sent;
503
+
504
+ RRDSET *st;
505
+ RRDDIM *rd_received;
506
+ RRDDIM *rd_sent;
507
+ } traffic;
508
+};
509
+
510
+static DICTIONARY *physical_interfaces = NULL, *virtual_interfaces = NULL;
511
+
512
+static void network_interface_init(struct network_interface *ni) {
513
+ ni->packets.received.key = "Packets Received/sec";
514
+ ni->packets.sent.key = "Packets Sent/sec";
515
+
516
+ ni->traffic.received.key = "Bytes Received/sec";
517
+ ni->traffic.sent.key = "Bytes Sent/sec";
518
+}
519
+
520
+void dict_interface_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
521
+ struct network_interface *ni = value;
522
+ network_interface_init(ni);
523
+}
524
+
525
+static void initialize(void) {
526
+ physical_interfaces = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
527
+ DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct network_interface));
528
+
529
+ virtual_interfaces = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
530
+ DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct network_interface));
531
+
532
+ dictionary_register_insert_callback(physical_interfaces, dict_interface_insert_cb, NULL);
533
+ dictionary_register_insert_callback(virtual_interfaces, dict_interface_insert_cb, NULL);
534
+}
535
+
536
+static void add_interface_labels(RRDSET *st, const char *name, bool physical) {
537
+ rrdlabels_add(st->rrdlabels, "device", name, RRDLABEL_SRC_AUTO);
538
+ rrdlabels_add(st->rrdlabels, "interface_type", physical ? "real" : "virtual", RRDLABEL_SRC_AUTO);
539
+}
540
+
541
+static bool is_physical_interface(const char *name) {
542
+ void *d = dictionary_get(physical_interfaces, name);
543
+ return d ? true : false;
544
+}
545
+
546
+static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every, bool physical) {
547
+ DICTIONARY *dict = physical_interfaces;
548
+
549
+ PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, physical ? "Network Interface" : "Network Adapter");
550
+ if(!pObjectType) return false;
551
+
552
+ uint64_t total_received = 0, total_sent = 0;
553
+
554
+ PERF_INSTANCE_DEFINITION *pi = NULL;
555
+ for(LONG i = 0; i < pObjectType->NumInstances ; i++) {
556
+ pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
557
+ if(!pi) break;
558
+
559
+ if(!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
560
+ strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
561
+
562
+ if(strcasecmp(windows_shared_buffer, "_Total") == 0)
563
+ continue;
564
+
565
+ if(!physical && is_physical_interface(windows_shared_buffer))
566
+ // this virtual interface is already reported as physical interface
567
+ continue;
568
+
569
+ struct network_interface *d = dictionary_set(dict, windows_shared_buffer, NULL, sizeof(*d));
570
+
571
+ if(!d->collected_metadata) {
572
+ // TODO - get metadata about the network interface
573
+ d->collected_metadata = true;
574
+ }
575
+
576
+ if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->traffic.received) &&
577
+ perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->traffic.sent)) {
578
+
579
+ if(d->traffic.received.current.Data == 0 && d->traffic.sent.current.Data == 0)
580
+ // this interface has not received or sent any traffic
581
+ continue;
582
+
583
+ if (unlikely(!d->traffic.st)) {
584
+ d->traffic.st = rrdset_create_localhost(
585
+ "net",
586
+ windows_shared_buffer,
587
+ NULL,
588
+ windows_shared_buffer,
589
+ "net.net",
590
+ "Bandwidth",
591
+ "kilobits/s",
592
+ PLUGIN_WINDOWS_NAME,
593
+ "PerflibNetwork",
594
+ NETDATA_CHART_PRIO_FIRST_NET_IFACE,
595
+ update_every,
596
+ RRDSET_TYPE_AREA);
597
+
598
+ rrdset_flag_set(d->traffic.st, RRDSET_FLAG_DETAIL);
599
+
600
+ add_interface_labels(d->traffic.st, windows_shared_buffer, physical);
601
+
602
+ d->traffic.rd_received = rrddim_add(d->traffic.st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
603
+ d->traffic.rd_sent = rrddim_add(d->traffic.st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
604
+ }
605
+
606
+ total_received += d->traffic.received.current.Data;
607
+ total_sent += d->traffic.sent.current.Data;
608
+
609
+ rrddim_set_by_pointer(d->traffic.st, d->traffic.rd_received, (collected_number)d->traffic.received.current.Data);
610
+ rrddim_set_by_pointer(d->traffic.st, d->traffic.rd_sent, (collected_number)d->traffic.sent.current.Data);
611
+ rrdset_done(d->traffic.st);
612
+ }
613
+
614
+ if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->packets.received) &&
615
+ perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->packets.sent)) {
616
+
617
+ if (unlikely(!d->packets.st)) {
618
+ d->packets.st = rrdset_create_localhost(
619
+ "net_packets",
620
+ windows_shared_buffer,
621
+ NULL,
622
+ windows_shared_buffer,
623
+ "net.packets",
624
+ "Packets",
625
+ "packets/s",
626
+ PLUGIN_WINDOWS_NAME,
627
+ "PerflibNetwork",
628
+ NETDATA_CHART_PRIO_FIRST_NET_IFACE + 1,
629
+ update_every,
630
+ RRDSET_TYPE_LINE);
631
+
632
+ rrdset_flag_set(d->packets.st, RRDSET_FLAG_DETAIL);
633
+
634
+ add_interface_labels(d->traffic.st, windows_shared_buffer, physical);
635
+
636
+ d->packets.rd_received = rrddim_add(d->packets.st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
637
+ d->packets.rd_sent = rrddim_add(d->packets.st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
638
+ }
639
+
640
+ rrddim_set_by_pointer(d->packets.st, d->packets.rd_received, (collected_number)d->packets.received.current.Data);
641
+ rrddim_set_by_pointer(d->packets.st, d->packets.rd_sent, (collected_number)d->packets.sent.current.Data);
642
+ rrdset_done(d->packets.st);
643
+ }
644
+ }
645
+
646
+ if(physical) {
647
+ static RRDSET *st = NULL;
648
+ static RRDDIM *rd_received = NULL, *rd_sent = NULL;
649
+
650
+ if (unlikely(!st)) {
651
+ st = rrdset_create_localhost(
652
+ "system",
653
+ "net",
654
+ NULL,
655
+ "network",
656
+ "system.net",
657
+ "Physical Network Interfaces Aggregated Bandwidth",
658
+ "kilobits/s",
659
+ PLUGIN_WINDOWS_NAME,
660
+ "PerflibNetwork",
661
+ NETDATA_CHART_PRIO_SYSTEM_NET,
662
+ update_every,
663
+ RRDSET_TYPE_AREA);
664
+
665
+ rd_received = rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
666
+ rd_sent = rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
667
+ }
668
+
669
+ rrddim_set_by_pointer(st, rd_received, (collected_number)total_received);
670
+ rrddim_set_by_pointer(st, rd_sent, (collected_number)total_sent);
671
+ rrdset_done(st);
672
+ }
673
+
674
+ return true;
675
+}
676
+
677
+int do_PerflibNetwork(int update_every, usec_t dt __maybe_unused) {
678
+ static bool initialized = false;
679
+
680
+ if(unlikely(!initialized)) {
681
+ initialize();
682
+ initialized = true;
683
+ }
684
+
685
+ DWORD id = RegistryFindIDByName("Network Interface");
686
+ if(id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
687
+ return -1;
688
+
689
+ PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
690
+ if(!pDataBlock) return -1;
691
+
692
+ do_network_interface(pDataBlock, update_every, true);
693
+ do_network_interface(pDataBlock, update_every, false);
694
+
695
+ struct network_protocol *tcp4 = NULL, *tcp6 = NULL;
696
+ for(size_t i = 0; networks[i].protocol ;i++) {
697
+ do_network_protocol(pDataBlock, update_every, &networks[i]);
698
+
699
+ if(!tcp4 && strcmp(networks[i].protocol, "TCPv4") == 0)
700
+ tcp4 = &networks[i];
701
+ if(!tcp6 && strcmp(networks[i].protocol, "TCPv6") == 0)
702
+ tcp6 = &networks[i];
703
+ }
704
+
705
+ if(tcp4 && tcp6) {
706
+ tcp46.packets.received = tcp4->packets.received;
707
+ tcp46.packets.sent = tcp4->packets.sent;
708
+ tcp46.packets.received.current.Data += tcp6->packets.received.current.Data;
709
+ tcp46.packets.sent.current.Data += tcp6->packets.sent.current.Data;
710
+ protocol_packets_chart_update(&tcp46, update_every);
711
+ }
712
+ return 0;
713
+}