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