]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdist-snmp.cc
Merge pull request #6100 from pieterlexis/ipv4-ipv6-equiv
[thirdparty/pdns.git] / pdns / dnsdist-snmp.cc
1
2 #include "dnsdist-snmp.hh"
3 #include "dolog.hh"
4
5 #ifdef HAVE_NET_SNMP
6
7 #define DNSDIST_OID 1, 3, 6, 1, 4, 1, 43315, 3
8 #define DNSDIST_STATS_OID DNSDIST_OID, 1
9 #define DNSDIST_STATS_TABLE_OID DNSDIST_OID, 2
10 #define DNSDIST_TRAPS_OID DNSDIST_OID, 10, 0
11 #define DNSDIST_TRAP_OBJECTS_OID DNSDIST_OID, 11
12
13 static const oid queriesOID[] = { DNSDIST_STATS_OID, 1 };
14 static const oid responsesOID[] = { DNSDIST_STATS_OID, 2 };
15 static const oid servfailResponsesOID[] = { DNSDIST_STATS_OID, 3 };
16 static const oid aclDropsOID[] = { DNSDIST_STATS_OID, 4 };
17 // 5 was BlockFilter, removed in 1.2.0
18 static const oid ruleDropOID[] = { DNSDIST_STATS_OID, 6 };
19 static const oid ruleNXDomainOID[] = { DNSDIST_STATS_OID, 7 };
20 static const oid ruleRefusedOID[] = { DNSDIST_STATS_OID, 8 };
21 static const oid selfAnsweredOID[] = { DNSDIST_STATS_OID, 9 };
22 static const oid downstreamTimeoutsOID[] = { DNSDIST_STATS_OID, 10 };
23 static const oid downstreamSendErrorsOID[] = { DNSDIST_STATS_OID, 11 };
24 static const oid truncFailOID[] = { DNSDIST_STATS_OID, 12 };
25 static const oid noPolicyOID[] = { DNSDIST_STATS_OID, 13 };
26 static const oid latency0_1OID[] = { DNSDIST_STATS_OID, 14 };
27 static const oid latency1_10OID[] = { DNSDIST_STATS_OID, 15 };
28 static const oid latency10_50OID[] = { DNSDIST_STATS_OID, 16 };
29 static const oid latency50_100OID[] = { DNSDIST_STATS_OID, 17 };
30 static const oid latency100_1000OID[] = { DNSDIST_STATS_OID, 18 };
31 static const oid latencySlowOID[] = { DNSDIST_STATS_OID, 19 };
32 static const oid latencyAvg100OID[] = { DNSDIST_STATS_OID, 20 };
33 static const oid latencyAvg1000OID[] = { DNSDIST_STATS_OID, 21 };
34 static const oid latencyAvg10000OID[] = { DNSDIST_STATS_OID, 22 };
35 static const oid latencyAvg1000000OID[] = { DNSDIST_STATS_OID, 23 };
36 static const oid uptimeOID[] = { DNSDIST_STATS_OID, 24 };
37 static const oid realMemoryUsageOID[] = { DNSDIST_STATS_OID, 25 };
38 static const oid nonCompliantQueriesOID[] = { DNSDIST_STATS_OID, 26 };
39 static const oid nonCompliantResponsesOID[] = { DNSDIST_STATS_OID, 27 };
40 static const oid rdQueriesOID[] = { DNSDIST_STATS_OID, 28 };
41 static const oid emptyQueriesOID[] = { DNSDIST_STATS_OID, 29 };
42 static const oid cacheHitsOID[] = { DNSDIST_STATS_OID, 30 };
43 static const oid cacheMissesOID[] = { DNSDIST_STATS_OID, 31 };
44 static const oid cpuUserMSecOID[] = { DNSDIST_STATS_OID, 32 };
45 static const oid cpuSysMSecOID[] = { DNSDIST_STATS_OID, 33 };
46 static const oid fdUsageOID[] = { DNSDIST_STATS_OID, 34 };
47 static const oid dynBlockedOID[] = { DNSDIST_STATS_OID, 35 };
48 static const oid dynBlockedNMGSizeOID[] = { DNSDIST_STATS_OID, 36 };
49 static const oid ruleServFailOID[] = { DNSDIST_STATS_OID, 37 };
50
51 static std::unordered_map<oid, DNSDistStats::entry_t> s_statsMap;
52
53 /* We are never called for a GETNEXT if it's registered as a
54 "instance", as it's "magically" handled for us. */
55 /* a instance handler also only hands us one request at a time, so
56 we don't need to loop over a list of requests; we'll only get one. */
57
58 static int handleCounter64Stats(netsnmp_mib_handler* handler,
59 netsnmp_handler_registration* reginfo,
60 netsnmp_agent_request_info* reqinfo,
61 netsnmp_request_info* requests)
62 {
63 if (reqinfo->mode != MODE_GET) {
64 return SNMP_ERR_GENERR;
65 }
66
67 if (reginfo->rootoid_len != OID_LENGTH(queriesOID) + 1) {
68 return SNMP_ERR_GENERR;
69 }
70
71 const auto& it = s_statsMap.find(reginfo->rootoid[reginfo->rootoid_len - 2]);
72 if (it == s_statsMap.end()) {
73 return SNMP_ERR_GENERR;
74 }
75
76 if (const auto& val = boost::get<DNSDistStats::stat_t*>(&it->second)) {
77 return DNSDistSNMPAgent::setCounter64Value(requests, (*val)->load());
78 }
79
80 return SNMP_ERR_GENERR;
81 }
82
83 static void registerCounter64Stat(const char* name, const oid statOID[], size_t statOIDLength, std::atomic<uint64_t>* ptr)
84 {
85 if (statOIDLength != OID_LENGTH(queriesOID)) {
86 errlog("Invalid OID for SNMP Counter64 statistic %s", name);
87 return;
88 }
89
90 if (s_statsMap.find(statOID[statOIDLength - 1]) != s_statsMap.end()) {
91 errlog("OID for SNMP Counter64 statistic %s has already been registered", name);
92 return;
93 }
94
95 s_statsMap[statOID[statOIDLength - 1]] = ptr;
96 netsnmp_register_scalar(netsnmp_create_handler_registration(name,
97 handleCounter64Stats,
98 statOID,
99 statOIDLength,
100 HANDLER_CAN_RONLY));
101 }
102
103 static int handleFloatStats(netsnmp_mib_handler* handler,
104 netsnmp_handler_registration* reginfo,
105 netsnmp_agent_request_info* reqinfo,
106 netsnmp_request_info* requests)
107 {
108 if (reqinfo->mode != MODE_GET) {
109 return SNMP_ERR_GENERR;
110 }
111
112 if (reginfo->rootoid_len != OID_LENGTH(queriesOID) + 1) {
113 return SNMP_ERR_GENERR;
114 }
115
116 const auto& it = s_statsMap.find(reginfo->rootoid[reginfo->rootoid_len - 2]);
117 if (it == s_statsMap.end()) {
118 return SNMP_ERR_GENERR;
119 }
120
121 if (const auto& val = boost::get<double*>(&it->second)) {
122 std::string str(std::to_string(**val));
123 snmp_set_var_typed_value(requests->requestvb,
124 ASN_OCTET_STR,
125 str.c_str(),
126 str.size());
127 return SNMP_ERR_NOERROR;
128 }
129
130 return SNMP_ERR_GENERR;
131 }
132
133 static void registerFloatStat(const char* name, const oid statOID[], size_t statOIDLength, double* ptr)
134 {
135 if (statOIDLength != OID_LENGTH(queriesOID)) {
136 errlog("Invalid OID for SNMP Float statistic %s", name);
137 return;
138 }
139
140 if (s_statsMap.find(statOID[statOIDLength - 1]) != s_statsMap.end()) {
141 errlog("OID for SNMP Float statistic %s has already been registered", name);
142 return;
143 }
144
145 s_statsMap[statOID[statOIDLength - 1]] = ptr;
146 netsnmp_register_scalar(netsnmp_create_handler_registration(name,
147 handleFloatStats,
148 statOID,
149 statOIDLength,
150 HANDLER_CAN_RONLY));
151 }
152
153 static int handleGauge64Stats(netsnmp_mib_handler* handler,
154 netsnmp_handler_registration* reginfo,
155 netsnmp_agent_request_info* reqinfo,
156 netsnmp_request_info* requests)
157 {
158 if (reqinfo->mode != MODE_GET) {
159 return SNMP_ERR_GENERR;
160 }
161
162 if (reginfo->rootoid_len != OID_LENGTH(queriesOID) + 1) {
163 return SNMP_ERR_GENERR;
164 }
165
166 const auto& it = s_statsMap.find(reginfo->rootoid[reginfo->rootoid_len - 2]);
167 if (it == s_statsMap.end()) {
168 return SNMP_ERR_GENERR;
169 }
170
171 std::string str;
172 uint64_t value = (*boost::get<DNSDistStats::statfunction_t>(&it->second))(str);
173 return DNSDistSNMPAgent::setCounter64Value(requests, value);
174 }
175
176 static void registerGauge64Stat(const char* name, const oid statOID[], size_t statOIDLength, DNSDistStats::statfunction_t ptr)
177 {
178 if (statOIDLength != OID_LENGTH(queriesOID)) {
179 errlog("Invalid OID for SNMP Gauge64 statistic %s", name);
180 return;
181 }
182
183 if (s_statsMap.find(statOID[statOIDLength - 1]) != s_statsMap.end()) {
184 errlog("OID for SNMP Gauge64 statistic %s has already been registered", name);
185 return;
186 }
187
188 s_statsMap[statOID[statOIDLength - 1]] = ptr;
189 netsnmp_register_scalar(netsnmp_create_handler_registration(name,
190 handleGauge64Stats,
191 statOID,
192 statOIDLength,
193 HANDLER_CAN_RONLY));
194 }
195
196 /* column number definitions for table backendStatTable */
197 #define COLUMN_BACKENDID 1
198 #define COLUMN_BACKENDNAME 2
199 #define COLUMN_BACKENDLATENCY 3
200 #define COLUMN_BACKENDWEIGHT 4
201 #define COLUMN_BACKENDOUTSTANDING 5
202 #define COLUMN_BACKENDQPSLIMIT 6
203 #define COLUMN_BACKENDREUSED 7
204 #define COLUMN_BACKENDSTATE 8
205 #define COLUMN_BACKENDADDRESS 9
206 #define COLUMN_BACKENDPOOLS 10
207 #define COLUMN_BACKENDQPS 11
208 #define COLUMN_BACKENDQUERIES 12
209 #define COLUMN_BACKENDORDER 13
210
211 static const oid backendStatTableOID[] = { DNSDIST_STATS_TABLE_OID };
212 static const oid backendNameOID[] = { DNSDIST_STATS_TABLE_OID, 1, 2 };
213 static const oid backendStateOID[] = { DNSDIST_STATS_TABLE_OID, 1, 8};
214 static const oid backendAddressOID[] = { DNSDIST_STATS_TABLE_OID, 1, 9};
215
216 static const oid socketFamilyOID[] = { DNSDIST_TRAP_OBJECTS_OID, 1, 0 };
217 static const oid socketProtocolOID[] = { DNSDIST_TRAP_OBJECTS_OID, 2, 0 };
218 static const oid fromAddressOID[] = { DNSDIST_TRAP_OBJECTS_OID, 3, 0 };
219 static const oid toAddressOID[] = { DNSDIST_TRAP_OBJECTS_OID, 4, 0 };
220 static const oid queryTypeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 5, 0 };
221 static const oid querySizeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 6, 0 };
222 static const oid queryIDOID[] = { DNSDIST_TRAP_OBJECTS_OID, 7, 0 };
223 static const oid qNameOID[] = { DNSDIST_TRAP_OBJECTS_OID, 8, 0 };
224 static const oid qClassOID[] = { DNSDIST_TRAP_OBJECTS_OID, 9, 0 };
225 static const oid qTypeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 10, 0 };
226 static const oid trapReasonOID[] = { DNSDIST_TRAP_OBJECTS_OID, 11, 0 };
227
228 static const oid backendStatusChangeTrapOID[] = { DNSDIST_TRAPS_OID, 1 };
229 static const oid actionTrapOID[] = { DNSDIST_TRAPS_OID, 2 };
230 static const oid customTrapOID[] = { DNSDIST_TRAPS_OID, 3 };
231
232 static servers_t s_servers;
233 static size_t s_currentServerIdx = 0;
234
235 static netsnmp_variable_list* backendStatTable_get_next_data_point(void** loop_context,
236 void** my_data_context,
237 netsnmp_variable_list* put_index_data,
238 netsnmp_iterator_info* mydata)
239 {
240 if (s_currentServerIdx >= s_servers.size()) {
241 return NULL;
242 }
243
244 *my_data_context = (void*) (s_servers[s_currentServerIdx]).get();
245 snmp_set_var_typed_integer(put_index_data, ASN_UNSIGNED, s_currentServerIdx);
246 s_currentServerIdx++;
247
248 return put_index_data;
249 }
250
251 static netsnmp_variable_list* backendStatTable_get_first_data_point(void** loop_context,
252 void** data_context,
253 netsnmp_variable_list* put_index_data,
254 netsnmp_iterator_info* data)
255 {
256 s_currentServerIdx = 0;
257
258 /* get a copy of the shared_ptrs so they are not
259 destroyed while we process the request */
260 const auto& dstates = g_dstates.getCopy();
261 s_servers.clear();
262 s_servers.reserve(dstates.size());
263 for (const auto& server : dstates) {
264 s_servers.push_back(server);
265 }
266
267 return backendStatTable_get_next_data_point(loop_context,
268 data_context,
269 put_index_data,
270 data);
271 }
272
273 static int backendStatTable_handler(netsnmp_mib_handler* handler,
274 netsnmp_handler_registration* reginfo,
275 netsnmp_agent_request_info* reqinfo,
276 netsnmp_request_info* requests)
277 {
278 netsnmp_request_info* request;
279
280 switch (reqinfo->mode) {
281 case MODE_GET:
282 for (request = requests; request; request = request->next) {
283 netsnmp_table_request_info* table_info = netsnmp_extract_table_info(request);
284 const DownstreamState* server = (const DownstreamState*) netsnmp_extract_iterator_context(request);
285
286 if (!server) {
287 continue;
288 }
289
290 switch (table_info->colnum) {
291 case COLUMN_BACKENDNAME:
292 snmp_set_var_typed_value(request->requestvb,
293 ASN_OCTET_STR,
294 server->name.c_str(),
295 server->name.size());
296 break;
297 case COLUMN_BACKENDLATENCY:
298 DNSDistSNMPAgent::setCounter64Value(request,
299 server->latencyUsec/1000.0);
300 break;
301 case COLUMN_BACKENDWEIGHT:
302 DNSDistSNMPAgent::setCounter64Value(request,
303 server->weight);
304 break;
305 case COLUMN_BACKENDOUTSTANDING:
306 DNSDistSNMPAgent::setCounter64Value(request,
307 server->outstanding);
308 break;
309 case COLUMN_BACKENDQPSLIMIT:
310 DNSDistSNMPAgent::setCounter64Value(request,
311 server->qps.getRate());
312 break;
313 case COLUMN_BACKENDREUSED:
314 DNSDistSNMPAgent::setCounter64Value(request, server->reuseds);
315 break;
316 case COLUMN_BACKENDSTATE:
317 {
318 std::string state(server->getStatus());
319 snmp_set_var_typed_value(request->requestvb,
320 ASN_OCTET_STR,
321 state.c_str(),
322 state.size());
323 break;
324 }
325 case COLUMN_BACKENDADDRESS:
326 {
327 std::string addr(server->remote.toStringWithPort());
328 snmp_set_var_typed_value(request->requestvb,
329 ASN_OCTET_STR,
330 addr.c_str(),
331 addr.size());
332 break;
333 }
334 case COLUMN_BACKENDPOOLS:
335 {
336 std::string pools;
337 for(auto& p : server->pools) {
338 if(!pools.empty())
339 pools+=" ";
340 pools+=p;
341 }
342 snmp_set_var_typed_value(request->requestvb,
343 ASN_OCTET_STR,
344 pools.c_str(),
345 pools.size());
346 break;
347 }
348 case COLUMN_BACKENDQPS:
349 DNSDistSNMPAgent::setCounter64Value(request, server->queryLoad);
350 break;
351 case COLUMN_BACKENDQUERIES:
352 DNSDistSNMPAgent::setCounter64Value(request, server->queries);
353 break;
354 case COLUMN_BACKENDORDER:
355 DNSDistSNMPAgent::setCounter64Value(request, server->order);
356 break;
357 default:
358 netsnmp_set_request_error(reqinfo,
359 request,
360 SNMP_NOSUCHOBJECT);
361 break;
362 }
363 }
364 break;
365 }
366 return SNMP_ERR_NOERROR;
367 }
368 #endif /* HAVE_NET_SNMP */
369
370 bool DNSDistSNMPAgent::sendBackendStatusChangeTrap(const std::shared_ptr<DownstreamState> dss)
371 {
372 #ifdef HAVE_NET_SNMP
373 const string backendAddress = dss->remote.toStringWithPort();
374 const string backendStatus = dss->getStatus();
375 netsnmp_variable_list* varList = nullptr;
376
377 snmp_varlist_add_variable(&varList,
378 snmpTrapOID,
379 snmpTrapOIDLen,
380 ASN_OBJECT_ID,
381 backendStatusChangeTrapOID,
382 OID_LENGTH(backendStatusChangeTrapOID) * sizeof(oid));
383
384
385 snmp_varlist_add_variable(&varList,
386 backendNameOID,
387 OID_LENGTH(backendNameOID),
388 ASN_OCTET_STR,
389 dss->name.c_str(),
390 dss->name.size());
391
392 snmp_varlist_add_variable(&varList,
393 backendAddressOID,
394 OID_LENGTH(backendAddressOID),
395 ASN_OCTET_STR,
396 backendAddress.c_str(),
397 backendAddress.size());
398
399 snmp_varlist_add_variable(&varList,
400 backendStateOID,
401 OID_LENGTH(backendStateOID),
402 ASN_OCTET_STR,
403 backendStatus.c_str(),
404 backendStatus.size());
405
406 return sendTrap(d_trapPipe[1], varList);
407 #endif /* HAVE_NET_SNMP */
408 return true;
409 }
410
411 bool DNSDistSNMPAgent::sendCustomTrap(const std::string& reason)
412 {
413 #ifdef HAVE_NET_SNMP
414 netsnmp_variable_list* varList = nullptr;
415
416 snmp_varlist_add_variable(&varList,
417 snmpTrapOID,
418 snmpTrapOIDLen,
419 ASN_OBJECT_ID,
420 customTrapOID,
421 OID_LENGTH(customTrapOID) * sizeof(oid));
422
423 snmp_varlist_add_variable(&varList,
424 trapReasonOID,
425 OID_LENGTH(trapReasonOID),
426 ASN_OCTET_STR,
427 reason.c_str(),
428 reason.size());
429
430 return sendTrap(d_trapPipe[1], varList);
431 #endif /* HAVE_NET_SNMP */
432 return true;
433 }
434
435 bool DNSDistSNMPAgent::sendDNSTrap(const DNSQuestion& dq, const std::string& reason)
436 {
437 #ifdef HAVE_NET_SNMP
438 std::string local = dq.local->toString();
439 std::string remote = dq.remote->toString();
440 std::string qname = dq.qname->toStringNoDot();
441 const uint32_t socketFamily = dq.remote->isIPv4() ? 1 : 2;
442 const uint32_t socketProtocol = dq.tcp ? 2 : 1;
443 const uint32_t queryType = dq.dh->qr ? 2 : 1;
444 const uint32_t querySize = (uint32_t) dq.len;
445 const uint32_t queryID = (uint32_t) ntohs(dq.dh->id);
446 const uint32_t qType = (uint32_t) dq.qtype;
447 const uint32_t qClass = (uint32_t) dq.qclass;
448
449 netsnmp_variable_list* varList = nullptr;
450
451 snmp_varlist_add_variable(&varList,
452 snmpTrapOID,
453 snmpTrapOIDLen,
454 ASN_OBJECT_ID,
455 actionTrapOID,
456 OID_LENGTH(actionTrapOID) * sizeof(oid));
457
458 snmp_varlist_add_variable(&varList,
459 socketFamilyOID,
460 OID_LENGTH(socketFamilyOID),
461 ASN_INTEGER,
462 (u_char *) &socketFamily,
463 sizeof(socketFamily));
464
465 snmp_varlist_add_variable(&varList,
466 socketProtocolOID,
467 OID_LENGTH(socketProtocolOID),
468 ASN_INTEGER,
469 (u_char *) &socketProtocol,
470 sizeof(socketProtocol));
471
472 snmp_varlist_add_variable(&varList,
473 fromAddressOID,
474 OID_LENGTH(fromAddressOID),
475 ASN_OCTET_STR,
476 remote.c_str(),
477 remote.size());
478
479 snmp_varlist_add_variable(&varList,
480 toAddressOID,
481 OID_LENGTH(toAddressOID),
482 ASN_OCTET_STR,
483 local.c_str(),
484 local.size());
485
486 snmp_varlist_add_variable(&varList,
487 queryTypeOID,
488 OID_LENGTH(queryTypeOID),
489 ASN_INTEGER,
490 (u_char *) &queryType,
491 sizeof(queryType));
492
493 snmp_varlist_add_variable(&varList,
494 querySizeOID,
495 OID_LENGTH(querySizeOID),
496 ASN_UNSIGNED,
497 (u_char *) &querySize,
498 sizeof(querySize));
499
500 snmp_varlist_add_variable(&varList,
501 queryIDOID,
502 OID_LENGTH(queryIDOID),
503 ASN_UNSIGNED,
504 (u_char *) &queryID,
505 sizeof(queryID));
506
507 snmp_varlist_add_variable(&varList,
508 qNameOID,
509 OID_LENGTH(qNameOID),
510 ASN_OCTET_STR,
511 qname.c_str(),
512 qname.size());
513
514 snmp_varlist_add_variable(&varList,
515 qClassOID,
516 OID_LENGTH(qClassOID),
517 ASN_UNSIGNED,
518 (u_char *) &qClass,
519 sizeof(qClass));
520
521 snmp_varlist_add_variable(&varList,
522 qTypeOID,
523 OID_LENGTH(qTypeOID),
524 ASN_UNSIGNED,
525 (u_char *) &qType,
526 sizeof(qType));
527
528 snmp_varlist_add_variable(&varList,
529 trapReasonOID,
530 OID_LENGTH(trapReasonOID),
531 ASN_OCTET_STR,
532 reason.c_str(),
533 reason.size());
534
535 return sendTrap(d_trapPipe[1], varList);
536 #endif /* HAVE_NET_SNMP */
537 return true;
538 }
539
540 DNSDistSNMPAgent::DNSDistSNMPAgent(const std::string& name, const std::string& masterSocket): SNMPAgent(name, masterSocket)
541 {
542 #ifdef HAVE_NET_SNMP
543
544 registerCounter64Stat("queries", queriesOID, OID_LENGTH(queriesOID), &g_stats.queries);
545 registerCounter64Stat("responses", responsesOID, OID_LENGTH(responsesOID), &g_stats.responses);
546 registerCounter64Stat("servfailResponses", servfailResponsesOID, OID_LENGTH(servfailResponsesOID), &g_stats.servfailResponses);
547 registerCounter64Stat("aclDrops", aclDropsOID, OID_LENGTH(aclDropsOID), &g_stats.aclDrops);
548 registerCounter64Stat("ruleDrop", ruleDropOID, OID_LENGTH(ruleDropOID), &g_stats.ruleDrop);
549 registerCounter64Stat("ruleNXDomain", ruleNXDomainOID, OID_LENGTH(ruleNXDomainOID), &g_stats.ruleNXDomain);
550 registerCounter64Stat("ruleRefused", ruleRefusedOID, OID_LENGTH(ruleRefusedOID), &g_stats.ruleRefused);
551 registerCounter64Stat("ruleServFail", ruleServFailOID, OID_LENGTH(ruleServFailOID), &g_stats.ruleServFail);
552 registerCounter64Stat("selfAnswered", selfAnsweredOID, OID_LENGTH(selfAnsweredOID), &g_stats.selfAnswered);
553 registerCounter64Stat("downstreamTimeouts", downstreamTimeoutsOID, OID_LENGTH(downstreamTimeoutsOID), &g_stats.downstreamTimeouts);
554 registerCounter64Stat("downstreamSendErrors", downstreamSendErrorsOID, OID_LENGTH(downstreamSendErrorsOID), &g_stats.downstreamSendErrors);
555 registerCounter64Stat("truncFail", truncFailOID, OID_LENGTH(truncFailOID), &g_stats.truncFail);
556 registerCounter64Stat("noPolicy", noPolicyOID, OID_LENGTH(noPolicyOID), &g_stats.noPolicy);
557 registerCounter64Stat("latency0_1", latency0_1OID, OID_LENGTH(latency0_1OID), &g_stats.latency0_1);
558 registerCounter64Stat("latency1_10", latency1_10OID, OID_LENGTH(latency1_10OID), &g_stats.latency1_10);
559 registerCounter64Stat("latency10_50", latency10_50OID, OID_LENGTH(latency10_50OID), &g_stats.latency10_50);
560 registerCounter64Stat("latency50_100", latency50_100OID, OID_LENGTH(latency50_100OID), &g_stats.latency50_100);
561 registerCounter64Stat("latency100_1000", latency100_1000OID, OID_LENGTH(latency100_1000OID), &g_stats.latency100_1000);
562 registerCounter64Stat("latencySlow", latencySlowOID, OID_LENGTH(latencySlowOID), &g_stats.latencySlow);
563 registerCounter64Stat("nonCompliantQueries", nonCompliantQueriesOID, OID_LENGTH(nonCompliantQueriesOID), &g_stats.nonCompliantQueries);
564 registerCounter64Stat("nonCompliantResponses", nonCompliantResponsesOID, OID_LENGTH(nonCompliantResponsesOID), &g_stats.nonCompliantResponses);
565 registerCounter64Stat("rdQueries", rdQueriesOID, OID_LENGTH(rdQueriesOID), &g_stats.rdQueries);
566 registerCounter64Stat("emptyQueries", emptyQueriesOID, OID_LENGTH(emptyQueriesOID), &g_stats.emptyQueries);
567 registerCounter64Stat("cacheHits", cacheHitsOID, OID_LENGTH(cacheHitsOID), &g_stats.cacheHits);
568 registerCounter64Stat("cacheMisses", cacheMissesOID, OID_LENGTH(cacheMissesOID), &g_stats.cacheMisses);
569 registerCounter64Stat("dynBlocked", dynBlockedOID, OID_LENGTH(dynBlockedOID), &g_stats.dynBlocked);
570 registerFloatStat("latencyAvg100", latencyAvg100OID, OID_LENGTH(latencyAvg100OID), &g_stats.latencyAvg100);
571 registerFloatStat("latencyAvg1000", latencyAvg1000OID, OID_LENGTH(latencyAvg1000OID), &g_stats.latencyAvg1000);
572 registerFloatStat("latencyAvg10000", latencyAvg10000OID, OID_LENGTH(latencyAvg10000OID), &g_stats.latencyAvg10000);
573 registerFloatStat("latencyAvg1000000", latencyAvg1000000OID, OID_LENGTH(latencyAvg1000000OID), &g_stats.latencyAvg1000000);
574 registerGauge64Stat("uptime", uptimeOID, OID_LENGTH(uptimeOID), &uptimeOfProcess);
575 registerGauge64Stat("realMemoryUsage", realMemoryUsageOID, OID_LENGTH(realMemoryUsageOID), &getRealMemoryUsage);
576 registerGauge64Stat("cpuUserMSec", cpuUserMSecOID, OID_LENGTH(cpuUserMSecOID), &getCPUTimeUser);
577 registerGauge64Stat("cpuSysMSec", cpuSysMSecOID, OID_LENGTH(cpuSysMSecOID), &getCPUTimeSystem);
578 registerGauge64Stat("fdUsage", fdUsageOID, OID_LENGTH(fdUsageOID), &getOpenFileDescriptors);
579 registerGauge64Stat("dynBlockedNMGSize", dynBlockedNMGSizeOID, OID_LENGTH(dynBlockedNMGSizeOID), [](const std::string&) { return g_dynblockNMG.getLocal()->size(); });
580
581
582 netsnmp_table_registration_info* table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
583 netsnmp_table_helper_add_indexes(table_info,
584 ASN_GAUGE, /* index: backendId */
585 0);
586 table_info->min_column = COLUMN_BACKENDNAME;
587 table_info->max_column = COLUMN_BACKENDORDER;
588 netsnmp_iterator_info* iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
589 iinfo->get_first_data_point = backendStatTable_get_first_data_point;
590 iinfo->get_next_data_point = backendStatTable_get_next_data_point;
591 iinfo->table_reginfo = table_info;
592
593 netsnmp_register_table_iterator(netsnmp_create_handler_registration("backendStatTable",
594 backendStatTable_handler,
595 backendStatTableOID,
596 OID_LENGTH(backendStatTableOID),
597 HANDLER_CAN_RONLY),
598 iinfo);
599
600 #endif /* HAVE_NET_SNMP */
601 }