]> git.ipfire.org Git - thirdparty/squid.git/blob - src/snmp_agent.cc
From: Henrik Nordstrom <hno@hem.passagen.se>
[thirdparty/squid.git] / src / snmp_agent.cc
1
2 /*
3 * $Id: snmp_agent.cc,v 1.63 1999/01/21 23:15:38 wessels Exp $
4 *
5 * DEBUG: section 49 SNMP Interface
6 * AUTHOR: Kostas Anagnostakis
7 *
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * 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
40 extern StatCounters *snmpStatGet(int);
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;
52
53 debug(49, 5) ("snmp_sysFn: Processing request:\n", Var->name[LEN_SQ_SYS]);
54 snmpDebugOid(5, Var->name, Var->name_length);
55
56 Answer = snmp_var_new(Var->name, Var->name_length);
57 *ErrP = SNMP_ERR_NOERROR;
58
59 switch (Var->name[LEN_SQ_SYS]) {
60 case SYSVMSIZ:
61 Answer->val_len = sizeof(snint);
62 Answer->val.integer = xmalloc(Answer->val_len);
63 Answer->type = ASN_INTEGER;
64 *(Answer->val.integer) = store_mem_size;
65 break;
66 case SYSSTOR:
67 Answer->val_len = sizeof(snint);
68 Answer->val.integer = xmalloc(Answer->val_len);
69 Answer->type = ASN_INTEGER;
70 *(Answer->val.integer) = store_swap_size;
71 break;
72 case SYS_UPTIME:
73 Answer->val_len = sizeof(snint);
74 Answer->val.integer = xmalloc(Answer->val_len);
75 Answer->type = SMI_TIMETICKS;
76 *(Answer->val.integer) = tvSubDsec(squid_start, current_time) * 100;
77 break;
78 default:
79 *ErrP = SNMP_ERR_NOSUCHNAME;
80 snmp_var_free(Answer);
81 return (NULL);
82 }
83 return Answer;
84 }
85
86 variable_list *
87 snmp_confFn(variable_list * Var, snint * ErrP)
88 {
89 variable_list *Answer;
90 char *cp = NULL;
91 char *pp = NULL;
92 debug(49, 5) ("snmp_confFn: Processing request with magic %d!\n", Var->name[8]);
93
94 Answer = snmp_var_new(Var->name, Var->name_length);
95 *ErrP = SNMP_ERR_NOERROR;
96
97 switch (Var->name[LEN_SQ_CONF]) {
98 case CONF_ADMIN:
99 Answer->type = ASN_OCTET_STR;
100 Answer->val_len = strlen(Config.adminEmail);
101 Answer->val.string = (u_char *) xstrdup(Config.adminEmail);
102 break;
103 case CONF_VERSION:
104 Answer->type = ASN_OCTET_STR;
105 Answer->val_len = strlen(appname);
106 Answer->val.string = (u_char *) xstrdup(appname);
107 break;
108 case CONF_VERSION_ID:
109 pp = SQUID_VERSION;
110 Answer->type = ASN_OCTET_STR;
111 Answer->val_len = strlen(pp);
112 Answer->val.string = (u_char *) xstrdup(pp);
113 break;
114 case CONF_STORAGE:
115 switch (Var->name[LEN_SQ_CONF + 1]) {
116 case CONF_ST_MMAXSZ:
117 Answer->val_len = sizeof(snint);
118 Answer->val.integer = xmalloc(Answer->val_len);
119 Answer->type = ASN_INTEGER;
120 *(Answer->val.integer) = (snint) Config.MemMaxSize;
121 break;
122 case CONF_ST_MHIWM: /* DELETE ME */
123 Answer->val_len = sizeof(snint);
124 Answer->val.integer = xmalloc(Answer->val_len);
125 Answer->type = ASN_INTEGER;
126 *(Answer->val.integer) = (snint) 0;
127 break;
128 case CONF_ST_MLOWM: /* DELETE ME */
129 Answer->val_len = sizeof(snint);
130 Answer->val.integer = xmalloc(Answer->val_len);
131 Answer->type = ASN_INTEGER;
132 *(Answer->val.integer) = (snint) 0;
133 break;
134 case CONF_ST_SWMAXSZ:
135 Answer->val_len = sizeof(snint);
136 Answer->val.integer = xmalloc(Answer->val_len);
137 Answer->type = ASN_INTEGER;
138 *(Answer->val.integer) = (snint) Config.Swap.maxSize;
139 break;
140 case CONF_ST_SWHIWM:
141 Answer->val_len = sizeof(snint);
142 Answer->val.integer = xmalloc(Answer->val_len);
143 Answer->type = ASN_INTEGER;
144 *(Answer->val.integer) = (snint) Config.Swap.highWaterMark;
145 break;
146 case CONF_ST_SWLOWM:
147 Answer->val_len = sizeof(snint);
148 Answer->val.integer = xmalloc(Answer->val_len);
149 Answer->type = ASN_INTEGER;
150 *(Answer->val.integer) = (snint) Config.Swap.lowWaterMark;
151 break;
152 default:
153 *ErrP = SNMP_ERR_NOSUCHNAME;
154 snmp_var_free(Answer);
155 return (NULL);
156 }
157 break;
158 case CONF_LOG_FAC:
159 if (!(cp = Config.debugOptions))
160 cp = "None";
161 Answer->type = ASN_OCTET_STR;
162 Answer->val_len = strlen(cp);
163 Answer->val.string = (u_char *) xstrdup(cp);
164 break;
165 default:
166 *ErrP = SNMP_ERR_NOSUCHNAME;
167 snmp_var_free(Answer);
168 return (NULL);
169 }
170 return Answer;
171 }
172
173 variable_list *
174 snmp_meshPtblFn(variable_list * Var, snint * ErrP)
175 {
176 variable_list *Answer;
177 struct in_addr *laddr;
178 char *cp = NULL;
179 peer *p = NULL;
180 int cnt = 0;
181 debug(49, 5) ("snmp_meshPtblFn: peer %d requested!\n", Var->name[LEN_SQ_MESH + 3]);
182
183 Answer = snmp_var_new(Var->name, Var->name_length);
184 *ErrP = SNMP_ERR_NOERROR;
185
186 laddr = oid2addr(&Var->name[LEN_SQ_MESH + 3]);
187
188 for (p = Config.peers; p != NULL; p = p->next, cnt++)
189 if (p->in_addr.sin_addr.s_addr == laddr->s_addr)
190 break;
191
192 #if SNMP_OLD_INDEX
193 p = Config.peers;
194 cnt = Var->name[LEN_SQ_MESH + 3];
195 debug(49, 5) ("snmp_meshPtblFn: we want .x.%d\n", Var->name[10]);
196 while (--cnt)
197 if (!(p = p->next));
198 #endif
199 if (p == NULL) {
200 *ErrP = SNMP_ERR_NOSUCHNAME;
201 snmp_var_free(Answer);
202 return (NULL);
203 }
204 switch (Var->name[LEN_SQ_MESH + 2]) {
205 case MESH_PTBL_NAME:
206 cp = p->host;
207 Answer->type = ASN_OCTET_STR;
208 Answer->val_len = strlen(cp);
209 Answer->val.string = (u_char *) xstrdup(cp);
210 break;
211 case MESH_PTBL_IP:
212 Answer->type = SMI_IPADDRESS;
213 Answer->val_len = sizeof(snint);
214 Answer->val.integer = xmalloc(Answer->val_len);
215 *(Answer->val.integer) = (snint) (p->in_addr.sin_addr.s_addr);
216 break;
217 case MESH_PTBL_HTTP:
218 Answer->val_len = sizeof(snint);
219 Answer->val.integer = xmalloc(Answer->val_len);
220 Answer->type = ASN_INTEGER;
221 *(Answer->val.integer) = (snint) p->http_port;
222 break;
223 case MESH_PTBL_ICP:
224 Answer->val_len = sizeof(snint);
225 Answer->val.integer = xmalloc(Answer->val_len);
226 Answer->type = ASN_INTEGER;
227 *(Answer->val.integer) = (snint) p->icp.port;
228 break;
229 case MESH_PTBL_TYPE:
230 Answer->val_len = sizeof(snint);
231 Answer->val.integer = xmalloc(Answer->val_len);
232 Answer->type = ASN_INTEGER;
233 *(Answer->val.integer) = (snint) p->type;
234 break;
235 case MESH_PTBL_STATE:
236 Answer->val_len = sizeof(snint);
237 Answer->val.integer = xmalloc(Answer->val_len);
238 Answer->type = ASN_INTEGER;
239 *(Answer->val.integer) = (snint) neighborUp(p);
240 break;
241 case MESH_PTBL_SENT:
242 Answer->val_len = sizeof(snint);
243 Answer->val.integer = xmalloc(Answer->val_len);
244 Answer->type = SMI_COUNTER32;
245 *(Answer->val.integer) = p->stats.pings_sent;
246 break;
247 case MESH_PTBL_PACKED:
248 Answer->val_len = sizeof(snint);
249 Answer->val.integer = xmalloc(Answer->val_len);
250 Answer->type = SMI_COUNTER32;
251 *(Answer->val.integer) = p->stats.pings_acked;
252 break;
253 case MESH_PTBL_FETCHES:
254 Answer->val_len = sizeof(snint);
255 Answer->val.integer = xmalloc(Answer->val_len);
256 Answer->type = SMI_COUNTER32;
257 *(Answer->val.integer) = p->stats.fetches;
258 break;
259 case MESH_PTBL_RTT:
260 Answer->val_len = sizeof(snint);
261 Answer->val.integer = xmalloc(Answer->val_len);
262 Answer->type = ASN_INTEGER;
263 *(Answer->val.integer) = p->stats.rtt;
264 break;
265 case MESH_PTBL_IGN:
266 Answer->val_len = sizeof(snint);
267 Answer->val.integer = xmalloc(Answer->val_len);
268 Answer->type = SMI_COUNTER32;
269 *(Answer->val.integer) = p->stats.ignored_replies;
270 break;
271 case MESH_PTBL_KEEPAL_S:
272 Answer->val_len = sizeof(snint);
273 Answer->val.integer = xmalloc(Answer->val_len);
274 Answer->type = SMI_COUNTER32;
275 *(Answer->val.integer) = p->stats.n_keepalives_sent;
276 break;
277 case MESH_PTBL_KEEPAL_R:
278 Answer->val_len = sizeof(snint);
279 Answer->val.integer = xmalloc(Answer->val_len);
280 Answer->type = SMI_COUNTER32;
281 *(Answer->val.integer) = p->stats.n_keepalives_recv;
282 break;
283
284 default:
285 *ErrP = SNMP_ERR_NOSUCHNAME;
286 snmp_var_free(Answer);
287 return (NULL);
288 }
289 return Answer;
290 }
291
292 variable_list *
293 snmp_prfSysFn(variable_list * Var, snint * ErrP)
294 {
295 variable_list *Answer;
296 static struct rusage rusage;
297
298 debug(49, 5) ("snmp_prfSysFn: Processing request with magic %d!\n", Var->name[LEN_SQ_PRF + 1]);
299
300 Answer = snmp_var_new(Var->name, Var->name_length);
301 *ErrP = SNMP_ERR_NOERROR;
302 Answer->val_len = sizeof(snint);
303 Answer->val.integer = xmalloc(Answer->val_len);
304 Answer->type = ASN_INTEGER;
305
306 switch (Var->name[LEN_SQ_PRF + 1]) {
307 case PERF_SYS_PF:
308 squid_getrusage(&rusage);
309 *(Answer->val.integer) = rusage_pagefaults(&rusage);
310 Answer->type = SMI_COUNTER32;
311 break;
312 case PERF_SYS_NUMR:
313 *(Answer->val.integer) = IOStats.Http.reads;
314 Answer->type = SMI_COUNTER32;
315 break;
316 case PERF_SYS_DEFR: /* XXX unused, remove me */
317 Answer->type = SMI_COUNTER32;
318 *(Answer->val.integer) = 0;
319 break;
320 case PERF_SYS_MEMUSAGE:
321 *(Answer->val.integer) = (snint) memTotalAllocated() >> 10;
322 break;
323 case PERF_SYS_CPUUSAGE:
324 squid_getrusage(&rusage);
325 *(Answer->val.integer) = (snint) rusage_cputime(&rusage);
326 break;
327 case PERF_SYS_MAXRESSZ:
328 squid_getrusage(&rusage);
329 *(Answer->val.integer) = (snint) rusage_maxrss(&rusage);
330 break;
331 case PERF_SYS_CURLRUEXP:
332 Answer->type = SMI_TIMETICKS;
333 *(Answer->val.integer) = (snint) (storeExpiredReferenceAge() * 100);
334 break;
335 case PERF_SYS_CURUNLREQ:
336 *(Answer->val.integer) = (snint) Counter.unlink.requests;
337 Answer->type = SMI_COUNTER32;
338 break;
339 case PERF_SYS_CURUNUSED_FD:
340 *(Answer->val.integer) = (snint) Squid_MaxFD - Number_FD;
341 Answer->type = SMI_GAUGE32;
342 break;
343 case PERF_SYS_CURRESERVED_FD:
344 *(Answer->val.integer) = (snint) Number_FD;
345 Answer->type = SMI_GAUGE32;
346 break;
347 case PERF_SYS_NUMOBJCNT:
348 *(Answer->val.integer) = (snint) memInUse(MEM_STOREENTRY);
349 Answer->type = SMI_COUNTER32;
350 break;
351 default:
352 *ErrP = SNMP_ERR_NOSUCHNAME;
353 snmp_var_free(Answer);
354 return (NULL);
355 }
356 return Answer;
357 }
358
359 variable_list *
360 snmp_prfProtoFn(variable_list * Var, snint * ErrP)
361 {
362 variable_list *Answer;
363 static StatCounters *f = NULL;
364 static StatCounters *l = NULL;
365 double x;
366 int minutes;
367
368 debug(49, 5) ("snmp_prfProtoFn: Processing request with magic %d!\n", Var->name[LEN_SQ_PRF]);
369
370 Answer = snmp_var_new(Var->name, Var->name_length);
371 *ErrP = SNMP_ERR_NOERROR;
372
373 switch (Var->name[LEN_SQ_PRF + 1]) {
374 case PERF_PROTOSTAT_AGGR: /* cacheProtoAggregateStats */
375 Answer->type = SMI_COUNTER32;
376 Answer->val_len = sizeof(snint);
377 Answer->val.integer = xmalloc(Answer->val_len);
378 switch (Var->name[LEN_SQ_PRF + 2]) {
379 case PERF_PROTOSTAT_AGGR_HTTP_REQ:
380 *(Answer->val.integer) = (snint) Counter.client_http.requests;
381 break;
382 case PERF_PROTOSTAT_AGGR_HTTP_HITS:
383 *(Answer->val.integer) = (snint) Counter.client_http.hits;
384 break;
385 case PERF_PROTOSTAT_AGGR_HTTP_ERRORS:
386 *(Answer->val.integer) = (snint) Counter.client_http.errors;
387 break;
388 case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN:
389 *(Answer->val.integer) = (snint) Counter.client_http.kbytes_in.kb;
390 break;
391 case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT:
392 *(Answer->val.integer) = (snint) Counter.client_http.kbytes_out.kb;
393 break;
394 case PERF_PROTOSTAT_AGGR_ICP_S:
395 *(Answer->val.integer) = (snint) Counter.icp.pkts_sent;
396 break;
397 case PERF_PROTOSTAT_AGGR_ICP_R:
398 *(Answer->val.integer) = (snint) Counter.icp.pkts_recv;
399 break;
400 case PERF_PROTOSTAT_AGGR_ICP_SKB:
401 *(Answer->val.integer) = (snint) Counter.icp.kbytes_sent.kb;
402 break;
403 case PERF_PROTOSTAT_AGGR_ICP_RKB:
404 *(Answer->val.integer) = (snint) Counter.icp.kbytes_recv.kb;
405 break;
406 case PERF_PROTOSTAT_AGGR_REQ:
407 *(Answer->val.integer) = (snint) Counter.server.all.requests;
408 Answer->type = SMI_INTEGER;
409 break;
410 case PERF_PROTOSTAT_AGGR_ERRORS:
411 *(Answer->val.integer) = (snint) Counter.server.all.errors;
412 Answer->type = SMI_INTEGER;
413 break;
414 case PERF_PROTOSTAT_AGGR_KBYTES_IN:
415 *(Answer->val.integer) = (snint) Counter.server.all.kbytes_in.kb;
416 break;
417 case PERF_PROTOSTAT_AGGR_KBYTES_OUT:
418 *(Answer->val.integer) = (snint) Counter.server.all.kbytes_out.kb;
419 break;
420 case PERF_PROTOSTAT_AGGR_CURSWAP:
421 *(Answer->val.integer) = (snint) store_swap_size;
422 break;
423 case PERF_PROTOSTAT_AGGR_CLIENTS:
424 *(Answer->val.integer) = (snint) Counter.client_http.clients;
425 break;
426 default:
427 *ErrP = SNMP_ERR_NOSUCHNAME;
428 snmp_var_free(Answer);
429 return (NULL);
430 }
431 return Answer;
432 case PERF_PROTOSTAT_MEDIAN:
433
434 minutes = Var->name[LEN_SQ_PRF + 4];
435
436 f = snmpStatGet(0);
437 l = snmpStatGet(minutes);
438
439 debug(49, 8) ("median: min= %d, %d l= %x , f = %x\n", minutes,
440 Var->name[LEN_SQ_PRF + 3], l, f);
441 Answer->type = SMI_INTEGER;
442 Answer->val_len = sizeof(snint);
443 Answer->val.integer = xmalloc(Answer->val_len);
444
445 debug(49, 8) ("median: l= %x , f = %x\n", l, f);
446 switch (Var->name[LEN_SQ_PRF + 3]) {
447 case PERF_MEDIAN_TIME:
448 x = minutes;
449 break;
450 case PERF_MEDIAN_HTTP_ALL:
451 x = statHistDeltaMedian(&l->client_http.all_svc_time,
452 &f->client_http.all_svc_time);
453 break;
454 case PERF_MEDIAN_HTTP_MISS:
455 x = statHistDeltaMedian(&l->client_http.miss_svc_time,
456 &f->client_http.miss_svc_time);
457 break;
458 case PERF_MEDIAN_HTTP_NM:
459 x = statHistDeltaMedian(&l->client_http.nm_svc_time,
460 &f->client_http.nm_svc_time);
461 break;
462 case PERF_MEDIAN_HTTP_HIT:
463 x = statHistDeltaMedian(&l->client_http.hit_svc_time,
464 &f->client_http.hit_svc_time);
465 break;
466 case PERF_MEDIAN_ICP_QUERY:
467 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
468 break;
469 case PERF_MEDIAN_ICP_REPLY:
470 x = statHistDeltaMedian(&l->icp.reply_svc_time, &f->icp.reply_svc_time);
471 break;
472 case PERF_MEDIAN_DNS:
473 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
474 break;
475 case PERF_MEDIAN_RHR:
476 x = statRequestHitRatio(minutes);
477 break;
478 case PERF_MEDIAN_BHR:
479 x = statByteHitRatio(minutes);
480 break;
481 default:
482 *ErrP = SNMP_ERR_NOSUCHNAME;
483 snmp_var_free(Answer);
484 return (NULL);
485 }
486 *(Answer->val.integer) = (snint) x;
487 return Answer;
488 }
489 *ErrP = SNMP_ERR_NOSUCHNAME;
490 snmp_var_free(Answer);
491 return (NULL);
492 }
493
494 void
495 addr2oid(struct in_addr addr, oid * Dest)
496 {
497 u_char *cp;
498 cp = (u_char *) & (addr.s_addr);
499 Dest[0] = *cp++;
500 Dest[1] = *cp++;
501 Dest[2] = *cp++;
502 Dest[3] = *cp++;
503 }
504
505 struct in_addr *
506 oid2addr(oid * id)
507 {
508 static struct in_addr laddr;
509 u_char *cp = (u_char *) & (laddr.s_addr);
510 cp[0] = id[0];
511 cp[1] = id[1];
512 cp[2] = id[2];
513 cp[3] = id[3];
514 return &laddr;
515 }