]> git.ipfire.org Git - thirdparty/squid.git/blob - src/snmp_agent.cc
Merge from trunk
[thirdparty/squid.git] / src / snmp_agent.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 49 SNMP Interface
5 * AUTHOR: Kostas Anagnostakis
6 *
7 * SQUID Web Proxy Cache http://www.squid-cache.org/
8 * ----------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 *
33 */
34
35 #include "squid.h"
36 #include "cache_snmp.h"
37 #include "Store.h"
38 #include "mem_node.h"
39 #include "SquidMath.h"
40 #include "SquidTime.h"
41
42 /************************************************************************
43
44 SQUID MIB Implementation
45
46 ************************************************************************/
47
48 /*
49 * cacheSystem group
50 */
51
52 variable_list *
53 snmp_sysFn(variable_list * Var, snint * ErrP)
54 {
55 variable_list *Answer = NULL;
56 MemBuf tmp;
57 debugs(49, 5, "snmp_sysFn: Processing request:" << snmpDebugOid(Var->name, Var->name_length, tmp));
58 *ErrP = SNMP_ERR_NOERROR;
59
60 switch (Var->name[LEN_SQ_SYS]) {
61
62 case SYSVMSIZ:
63 Answer = snmp_var_new_integer(Var->name, Var->name_length,
64 mem_node::StoreMemSize() >> 10,
65 ASN_INTEGER);
66 break;
67
68 case SYSSTOR:
69 Answer = snmp_var_new_integer(Var->name, Var->name_length,
70 store_swap_size,
71 ASN_INTEGER);
72 break;
73
74 case SYS_UPTIME:
75 Answer = snmp_var_new_integer(Var->name, Var->name_length,
76 (int)(tvSubDsec(squid_start, current_time) * 100),
77 SMI_TIMETICKS);
78 break;
79
80 default:
81 *ErrP = SNMP_ERR_NOSUCHNAME;
82 break;
83 }
84
85 return Answer;
86 }
87
88 /*
89 * cacheConfig group
90 */
91 variable_list *
92 snmp_confFn(variable_list * Var, snint * ErrP)
93 {
94 variable_list *Answer = NULL;
95 const char *cp = NULL;
96 debugs(49, 5, "snmp_confFn: Processing request with magic " << Var->name[8] << "!");
97 *ErrP = SNMP_ERR_NOERROR;
98
99 switch (Var->name[LEN_SQ_CONF]) {
100
101 case CONF_ADMIN:
102 Answer = snmp_var_new(Var->name, Var->name_length);
103 Answer->type = ASN_OCTET_STR;
104 Answer->val_len = strlen(Config.adminEmail);
105 Answer->val.string = (u_char *) xstrdup(Config.adminEmail);
106 break;
107
108 case CONF_VERSION:
109 Answer = snmp_var_new(Var->name, Var->name_length);
110 Answer->type = ASN_OCTET_STR;
111 Answer->val_len = strlen(APP_SHORTNAME);
112 Answer->val.string = (u_char *) xstrdup(APP_SHORTNAME);
113 break;
114
115 case CONF_VERSION_ID:
116 Answer = snmp_var_new(Var->name, Var->name_length);
117 Answer->type = ASN_OCTET_STR;
118 Answer->val_len = strlen(VERSION);
119 Answer->val.string = (u_char *) xstrdup(VERSION);
120 break;
121
122 case CONF_STORAGE:
123
124 switch (Var->name[LEN_SQ_CONF + 1]) {
125
126 case CONF_ST_MMAXSZ:
127 Answer = snmp_var_new_integer(Var->name, Var->name_length,
128 (snint) (Config.memMaxSize >> 20),
129 ASN_INTEGER);
130 break;
131
132 case CONF_ST_SWMAXSZ:
133 Answer = snmp_var_new_integer(Var->name, Var->name_length,
134 (snint) (Store::Root().maxSize() >> 10),
135 ASN_INTEGER);
136 break;
137
138 case CONF_ST_SWHIWM:
139 Answer = snmp_var_new_integer(Var->name, Var->name_length,
140 (snint) Config.Swap.highWaterMark,
141 ASN_INTEGER);
142 break;
143
144 case CONF_ST_SWLOWM:
145 Answer = snmp_var_new_integer(Var->name, Var->name_length,
146 (snint) Config.Swap.lowWaterMark,
147 ASN_INTEGER);
148 break;
149
150 default:
151 *ErrP = SNMP_ERR_NOSUCHNAME;
152 break;
153 }
154
155 break;
156
157 case CONF_LOG_FAC:
158 Answer = snmp_var_new(Var->name, Var->name_length);
159
160 if (!(cp = Debug::debugOptions))
161 cp = "None";
162
163 Answer->type = ASN_OCTET_STR;
164
165 Answer->val_len = strlen(cp);
166
167 Answer->val.string = (u_char *) xstrdup(cp);
168
169 break;
170
171 case CONF_UNIQNAME:
172 Answer = snmp_var_new(Var->name, Var->name_length);
173
174 cp = uniqueHostname();
175
176 Answer->type = ASN_OCTET_STR;
177
178 Answer->val_len = strlen(cp);
179
180 Answer->val.string = (u_char *) xstrdup(cp);
181
182 break;
183
184 default:
185 *ErrP = SNMP_ERR_NOSUCHNAME;
186
187 break;
188 }
189
190 return Answer;
191 }
192
193
194 /*
195 * cacheMesh group
196 * - cachePeerTable
197 */
198 variable_list *
199 snmp_meshPtblFn(variable_list * Var, snint * ErrP)
200 {
201 variable_list *Answer = NULL;
202
203 IpAddress laddr;
204 char *cp = NULL;
205 peer *p = NULL;
206 int cnt = 0;
207 debugs(49, 5, "snmp_meshPtblFn: peer " << Var->name[LEN_SQ_MESH + 3] << " requested!");
208 *ErrP = SNMP_ERR_NOERROR;
209
210 u_int index = Var->name[LEN_SQ_MESH + 3] ;
211 for (p = Config.peers; p != NULL; p = p->next, cnt++) {
212 if (p->index == index) {
213 laddr = p->in_addr ;
214 break;
215 }
216 }
217
218 if (p == NULL) {
219 *ErrP = SNMP_ERR_NOSUCHNAME;
220 return NULL;
221 }
222
223
224 switch (Var->name[LEN_SQ_MESH + 2]) {
225 case MESH_PTBL_INDEX: { // FIXME INET6: Should be visible?
226 Answer = snmp_var_new_integer(Var->name, Var->name_length,
227 (snint)p->index, SMI_INTEGER);
228 }
229 break;
230
231
232 case MESH_PTBL_NAME:
233 cp = p->host;
234 Answer = snmp_var_new(Var->name, Var->name_length);
235 Answer->type = ASN_OCTET_STR;
236 Answer->val_len = strlen(cp);
237 Answer->val.string = (u_char *) xstrdup(cp);
238
239 break;
240
241 case MESH_PTBL_ADDR_TYPE: {
242 int ival;
243 ival = laddr.IsIPv4() ? INETADDRESSTYPE_IPV4 : INETADDRESSTYPE_IPV6 ;
244 Answer = snmp_var_new_integer(Var->name, Var->name_length,
245 ival, SMI_INTEGER);
246 }
247 break;
248 case MESH_PTBL_ADDR: {
249 Answer = snmp_var_new(Var->name, Var->name_length);
250 // InetAddress doesn't have its own ASN.1 type,
251 // like IpAddr does (SMI_IPADDRESS)
252 // See: rfc4001.txt
253 Answer->type = ASN_OCTET_STR;
254 char host[MAX_IPSTRLEN];
255 laddr.NtoA(host,MAX_IPSTRLEN);
256 Answer->val_len = strlen(host);
257 Answer->val.string = (u_char *) xstrdup(host);
258 }
259 break;
260
261 case MESH_PTBL_HTTP:
262 Answer = snmp_var_new_integer(Var->name, Var->name_length,
263 (snint) p->http_port,
264 ASN_INTEGER);
265 break;
266
267 case MESH_PTBL_ICP:
268 Answer = snmp_var_new_integer(Var->name, Var->name_length,
269 (snint) p->icp.port,
270 ASN_INTEGER);
271 break;
272
273 case MESH_PTBL_TYPE:
274 Answer = snmp_var_new_integer(Var->name, Var->name_length,
275 (snint) p->type,
276 ASN_INTEGER);
277 break;
278
279 case MESH_PTBL_STATE:
280 Answer = snmp_var_new_integer(Var->name, Var->name_length,
281 (snint) neighborUp(p),
282 ASN_INTEGER);
283 break;
284
285 case MESH_PTBL_SENT:
286 Answer = snmp_var_new_integer(Var->name, Var->name_length,
287 p->stats.pings_sent,
288 SMI_COUNTER32);
289 break;
290
291 case MESH_PTBL_PACKED:
292 Answer = snmp_var_new_integer(Var->name, Var->name_length,
293 p->stats.pings_acked,
294 SMI_COUNTER32);
295 break;
296
297 case MESH_PTBL_FETCHES:
298 Answer = snmp_var_new_integer(Var->name, Var->name_length,
299 p->stats.fetches,
300 SMI_COUNTER32);
301 break;
302
303 case MESH_PTBL_RTT:
304 Answer = snmp_var_new_integer(Var->name, Var->name_length,
305 p->stats.rtt,
306 ASN_INTEGER);
307 break;
308
309 case MESH_PTBL_IGN:
310 Answer = snmp_var_new_integer(Var->name, Var->name_length,
311 p->stats.ignored_replies,
312 SMI_COUNTER32);
313 break;
314
315 case MESH_PTBL_KEEPAL_S:
316 Answer = snmp_var_new_integer(Var->name, Var->name_length,
317 p->stats.n_keepalives_sent,
318 SMI_COUNTER32);
319 break;
320
321 case MESH_PTBL_KEEPAL_R:
322 Answer = snmp_var_new_integer(Var->name, Var->name_length,
323 p->stats.n_keepalives_recv,
324 SMI_COUNTER32);
325 break;
326
327 default:
328 *ErrP = SNMP_ERR_NOSUCHNAME;
329 break;
330 }
331
332 return Answer;
333 }
334
335 variable_list *
336 snmp_prfSysFn(variable_list * Var, snint * ErrP)
337 {
338 variable_list *Answer = NULL;
339
340 static struct rusage rusage;
341 debugs(49, 5, "snmp_prfSysFn: Processing request with magic " << Var->name[LEN_SQ_PRF + 1] << "!");
342 *ErrP = SNMP_ERR_NOERROR;
343
344 switch (Var->name[LEN_SQ_PRF + 1]) {
345
346 case PERF_SYS_PF:
347 squid_getrusage(&rusage);
348 Answer = snmp_var_new_integer(Var->name, Var->name_length,
349 rusage_pagefaults(&rusage),
350 SMI_COUNTER32);
351 break;
352
353 case PERF_SYS_NUMR:
354 Answer = snmp_var_new_integer(Var->name, Var->name_length,
355 IOStats.Http.reads,
356 SMI_COUNTER32);
357 break;
358
359 case PERF_SYS_MEMUSAGE:
360 Answer = snmp_var_new_integer(Var->name, Var->name_length,
361 (snint) statMemoryAccounted() >> 10,
362 ASN_INTEGER);
363 break;
364
365 case PERF_SYS_CPUTIME:
366 squid_getrusage(&rusage);
367 Answer = snmp_var_new_integer(Var->name, Var->name_length,
368 (snint) rusage_cputime(&rusage),
369 ASN_INTEGER);
370 break;
371
372 case PERF_SYS_CPUUSAGE:
373 squid_getrusage(&rusage);
374 Answer = snmp_var_new_integer(Var->name, Var->name_length,
375 (snint) Math::doublePercent(rusage_cputime(&rusage), tvSubDsec(squid_start, current_time)),
376 ASN_INTEGER);
377 break;
378
379 case PERF_SYS_MAXRESSZ:
380 squid_getrusage(&rusage);
381 Answer = snmp_var_new_integer(Var->name, Var->name_length,
382 (snint) rusage_maxrss(&rusage),
383 ASN_INTEGER);
384 break;
385
386 case PERF_SYS_CURLRUEXP:
387 /* No global LRU info anymore */
388 Answer = snmp_var_new_integer(Var->name, Var->name_length,
389 0,
390 SMI_TIMETICKS);
391 break;
392
393 case PERF_SYS_CURUNLREQ:
394 Answer = snmp_var_new_integer(Var->name, Var->name_length,
395 (snint) statCounter.unlink.requests,
396 SMI_GAUGE32);
397 break;
398
399 case PERF_SYS_CURUNUSED_FD:
400 Answer = snmp_var_new_integer(Var->name, Var->name_length,
401 (snint) Squid_MaxFD - Number_FD,
402 SMI_GAUGE32);
403 break;
404
405 case PERF_SYS_CURRESERVED_FD:
406 Answer = snmp_var_new_integer(Var->name, Var->name_length,
407 (snint) RESERVED_FD,
408 SMI_GAUGE32);
409 break;
410
411 case PERF_SYS_CURUSED_FD:
412 Answer = snmp_var_new_integer(Var->name, Var->name_length,
413 (snint) Number_FD,
414 SMI_GAUGE32);
415 break;
416
417 case PERF_SYS_CURMAX_FD:
418 Answer = snmp_var_new_integer(Var->name, Var->name_length,
419 (snint) Biggest_FD,
420 SMI_GAUGE32);
421 break;
422
423 case PERF_SYS_NUMOBJCNT:
424 Answer = snmp_var_new_integer(Var->name, Var->name_length,
425 (snint) StoreEntry::inUseCount(),
426 SMI_GAUGE32);
427 break;
428
429 default:
430 *ErrP = SNMP_ERR_NOSUCHNAME;
431 break;
432 }
433
434 return Answer;
435 }
436
437 variable_list *
438 snmp_prfProtoFn(variable_list * Var, snint * ErrP)
439 {
440 variable_list *Answer = NULL;
441 static StatCounters *f = NULL;
442 static StatCounters *l = NULL;
443 double x;
444 int minutes;
445 debugs(49, 5, "snmp_prfProtoFn: Processing request with magic " << Var->name[LEN_SQ_PRF] << "!");
446 *ErrP = SNMP_ERR_NOERROR;
447
448 switch (Var->name[LEN_SQ_PRF + 1]) {
449
450 case PERF_PROTOSTAT_AGGR: /* cacheProtoAggregateStats */
451
452 switch (Var->name[LEN_SQ_PRF + 2]) {
453
454 case PERF_PROTOSTAT_AGGR_HTTP_REQ:
455 Answer = snmp_var_new_integer(Var->name, Var->name_length,
456 (snint) statCounter.client_http.requests,
457 SMI_COUNTER32);
458 break;
459
460 case PERF_PROTOSTAT_AGGR_HTTP_HITS:
461 Answer = snmp_var_new_integer(Var->name, Var->name_length,
462 (snint) statCounter.client_http.hits,
463 SMI_COUNTER32);
464 break;
465
466 case PERF_PROTOSTAT_AGGR_HTTP_ERRORS:
467 Answer = snmp_var_new_integer(Var->name, Var->name_length,
468 (snint) statCounter.client_http.errors,
469 SMI_COUNTER32);
470 break;
471
472 case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN:
473 Answer = snmp_var_new_integer(Var->name, Var->name_length,
474 (snint) statCounter.client_http.kbytes_in.kb,
475 SMI_COUNTER32);
476 break;
477
478 case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT:
479 Answer = snmp_var_new_integer(Var->name, Var->name_length,
480 (snint) statCounter.client_http.kbytes_out.kb,
481 SMI_COUNTER32);
482 break;
483
484 case PERF_PROTOSTAT_AGGR_ICP_S:
485 Answer = snmp_var_new_integer(Var->name, Var->name_length,
486 (snint) statCounter.icp.pkts_sent,
487 SMI_COUNTER32);
488 break;
489
490 case PERF_PROTOSTAT_AGGR_ICP_R:
491 Answer = snmp_var_new_integer(Var->name, Var->name_length,
492 (snint) statCounter.icp.pkts_recv,
493 SMI_COUNTER32);
494 break;
495
496 case PERF_PROTOSTAT_AGGR_ICP_SKB:
497 Answer = snmp_var_new_integer(Var->name, Var->name_length,
498 (snint) statCounter.icp.kbytes_sent.kb,
499 SMI_COUNTER32);
500 break;
501
502 case PERF_PROTOSTAT_AGGR_ICP_RKB:
503 Answer = snmp_var_new_integer(Var->name, Var->name_length,
504 (snint) statCounter.icp.kbytes_recv.kb,
505 SMI_COUNTER32);
506 break;
507
508 case PERF_PROTOSTAT_AGGR_REQ:
509 Answer = snmp_var_new_integer(Var->name, Var->name_length,
510 (snint) statCounter.server.all.requests,
511 SMI_INTEGER);
512 break;
513
514 case PERF_PROTOSTAT_AGGR_ERRORS:
515 Answer = snmp_var_new_integer(Var->name, Var->name_length,
516 (snint) statCounter.server.all.errors,
517 SMI_INTEGER);
518 break;
519
520 case PERF_PROTOSTAT_AGGR_KBYTES_IN:
521 Answer = snmp_var_new_integer(Var->name, Var->name_length,
522 (snint) statCounter.server.all.kbytes_in.kb,
523 SMI_COUNTER32);
524 break;
525
526 case PERF_PROTOSTAT_AGGR_KBYTES_OUT:
527 Answer = snmp_var_new_integer(Var->name, Var->name_length,
528 (snint) statCounter.server.all.kbytes_out.kb,
529 SMI_COUNTER32);
530 break;
531
532 case PERF_PROTOSTAT_AGGR_CURSWAP:
533 Answer = snmp_var_new_integer(Var->name, Var->name_length,
534 (snint) store_swap_size,
535 SMI_GAUGE32);
536 break;
537
538 case PERF_PROTOSTAT_AGGR_CLIENTS:
539 Answer = snmp_var_new_integer(Var->name, Var->name_length,
540 (snint) statCounter.client_http.clients,
541 SMI_GAUGE32);
542 break;
543
544 default:
545 *ErrP = SNMP_ERR_NOSUCHNAME;
546 break;
547 }
548
549 return Answer;
550
551 case PERF_PROTOSTAT_MEDIAN:
552
553 if (Var->name_length == LEN_SQ_PRF + 5)
554 minutes = Var->name[LEN_SQ_PRF + 4];
555 else
556 break;
557
558 if ((minutes < 1) || (minutes > 60))
559 break;
560
561 f = snmpStatGet(0);
562
563 l = snmpStatGet(minutes);
564
565 debugs(49, 8, "median: min= " << minutes << ", " << Var->name[LEN_SQ_PRF + 3] << " l= " << l << " , f = " << f);
566 debugs(49, 8, "median: l= " << l << " , f = " << f);
567
568 switch (Var->name[LEN_SQ_PRF + 3]) {
569
570 case PERF_MEDIAN_TIME:
571 x = minutes;
572 break;
573
574 case PERF_MEDIAN_HTTP_ALL:
575 x = statHistDeltaMedian(&l->client_http.all_svc_time,
576 &f->client_http.all_svc_time);
577 break;
578
579 case PERF_MEDIAN_HTTP_MISS:
580 x = statHistDeltaMedian(&l->client_http.miss_svc_time,
581 &f->client_http.miss_svc_time);
582 break;
583
584 case PERF_MEDIAN_HTTP_NM:
585 x = statHistDeltaMedian(&l->client_http.nm_svc_time,
586 &f->client_http.nm_svc_time);
587 break;
588
589 case PERF_MEDIAN_HTTP_HIT:
590 x = statHistDeltaMedian(&l->client_http.hit_svc_time,
591 &f->client_http.hit_svc_time);
592 break;
593
594 case PERF_MEDIAN_ICP_QUERY:
595 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
596 break;
597
598 case PERF_MEDIAN_ICP_REPLY:
599 x = statHistDeltaMedian(&l->icp.reply_svc_time, &f->icp.reply_svc_time);
600 break;
601
602 case PERF_MEDIAN_DNS:
603 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
604 break;
605
606 case PERF_MEDIAN_RHR:
607 x = statRequestHitRatio(minutes);
608 break;
609
610 case PERF_MEDIAN_BHR:
611 x = statByteHitRatio(minutes);
612 break;
613
614 case PERF_MEDIAN_HTTP_NH:
615 x = statHistDeltaMedian(&l->client_http.nh_svc_time,
616 &f->client_http.nh_svc_time);
617 break;
618
619 default:
620 *ErrP = SNMP_ERR_NOSUCHNAME;
621 return NULL;
622 }
623
624 return snmp_var_new_integer(Var->name, Var->name_length,
625 (snint) x,
626 SMI_INTEGER);
627 }
628
629 *ErrP = SNMP_ERR_NOSUCHNAME;
630 return NULL;
631 }