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