]>
Commit | Line | Data |
---|---|---|
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 | ||
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 }; | |
0c369ddc | 17 | // 5 was BlockFilter, removed in 1.2.0 |
9f4eb5cc RG |
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 }; | |
5f23eb98 | 49 | static const oid ruleServFailOID[] = { DNSDIST_STATS_OID, 37 }; |
f29758cc | 50 | static const oid securityStatusOID[] = { DNSDIST_STATS_OID, 38 }; |
330dcb5c | 51 | static const oid specialMemoryUsageOID[] = { DNSDIST_STATS_OID, 39 }; |
9f4eb5cc RG |
52 | |
53 | static 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 | ||
60 | static 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 | ||
85 | static 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 | ||
105 | static 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 | ||
135 | static 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 | ||
155 | static 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 | ||
178 | static 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 | ||
213 | static const oid backendStatTableOID[] = { DNSDIST_STATS_TABLE_OID }; | |
214 | static const oid backendNameOID[] = { DNSDIST_STATS_TABLE_OID, 1, 2 }; | |
215 | static const oid backendStateOID[] = { DNSDIST_STATS_TABLE_OID, 1, 8}; | |
216 | static const oid backendAddressOID[] = { DNSDIST_STATS_TABLE_OID, 1, 9}; | |
217 | ||
218 | static const oid socketFamilyOID[] = { DNSDIST_TRAP_OBJECTS_OID, 1, 0 }; | |
219 | static const oid socketProtocolOID[] = { DNSDIST_TRAP_OBJECTS_OID, 2, 0 }; | |
220 | static const oid fromAddressOID[] = { DNSDIST_TRAP_OBJECTS_OID, 3, 0 }; | |
221 | static const oid toAddressOID[] = { DNSDIST_TRAP_OBJECTS_OID, 4, 0 }; | |
222 | static const oid queryTypeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 5, 0 }; | |
223 | static const oid querySizeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 6, 0 }; | |
224 | static const oid queryIDOID[] = { DNSDIST_TRAP_OBJECTS_OID, 7, 0 }; | |
225 | static const oid qNameOID[] = { DNSDIST_TRAP_OBJECTS_OID, 8, 0 }; | |
226 | static const oid qClassOID[] = { DNSDIST_TRAP_OBJECTS_OID, 9, 0 }; | |
227 | static const oid qTypeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 10, 0 }; | |
228 | static const oid trapReasonOID[] = { DNSDIST_TRAP_OBJECTS_OID, 11, 0 }; | |
229 | ||
230 | static const oid backendStatusChangeTrapOID[] = { DNSDIST_TRAPS_OID, 1 }; | |
231 | static const oid actionTrapOID[] = { DNSDIST_TRAPS_OID, 2 }; | |
232 | static const oid customTrapOID[] = { DNSDIST_TRAPS_OID, 3 }; | |
233 | ||
234 | static servers_t s_servers; | |
235 | static size_t s_currentServerIdx = 0; | |
236 | ||
237 | static 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 | ||
253 | static 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 | ||
275 | static 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 | 372 | bool 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 | ||
414 | bool 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 | ||
439 | bool 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 | ||
545 | DNSDistSNMPAgent::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 | } |