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