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