]> git.ipfire.org Git - thirdparty/squid.git/blame - src/snmp_agent.cc
1.2.beta19
[thirdparty/squid.git] / src / snmp_agent.cc
CommitLineData
25c1b8b7 1#include "squid.h"
2
3#include "snmp.h"
4#include "snmp_impl.h"
5#include "asn1.h"
6#include "snmp_api.h"
7#include "snmp_client.h"
571c3b88 8#include "snmp_vars.h"
9#include "snmp_oidlist.h"
10#include "cache_snmp.h"
25c1b8b7 11
12#include "mib.h"
13
d0e0c8d2 14enum {
15 HTTP_SVC, ICP_SVC, DNS_SVC
16};
25c1b8b7 17
bdf18524 18void snmpAclCheckDone(int answer, void *);
571c3b88 19static struct snmp_pdu *snmp_agent_response(struct snmp_pdu *PDU);
2ac76861 20static int community_check(char *b, oid * name, int namelen);
571c3b88 21struct snmp_session *Session;
d0e0c8d2 22extern int get_median_svc(int, int);
451b07c5 23extern StatCounters *snmpStatGet(int);
bdf18524 24extern void snmp_agent_parse_done(int, snmp_request_t *);
451b07c5 25
2ac76861 26void snmpAclCheckStart(snmp_request_t * rq);
bdf18524 27
25c1b8b7 28
571c3b88 29/* returns:
d0e0c8d2 30 * 2: no such object in this mib
31 * 1: ok
32 * 0: failed */
25c1b8b7 33
bdf18524 34void
2ac76861 35snmp_agent_parse(snmp_request_t * rq)
25c1b8b7 36{
c6da280c 37 snint this_reqid;
2ac76861 38 u_char *buf = rq->buf;
39 int len = rq->len;
40
bdf18524 41 struct snmp_pdu *PDU;
d0e0c8d2 42 u_char *Community;
bdf18524 43
d0e0c8d2 44 /* Now that we have the data, turn it into a PDU */
2ac76861 45 cbdataAdd(rq, MEM_NONE);
d0e0c8d2 46 PDU = snmp_pdu_create(0);
47 Community = snmp_parse(Session, PDU, buf, len);
399e85ea 48
49 if (!snmp_coexist_V2toV1(PDU)) { /* incompatibility */
50 debug(49, 3) ("snmp_agent_parse: Incompatible V2 packet.\n");
51 snmp_free_pdu(PDU);
52 snmp_agent_parse_done(0, rq);
53 return;
bf7cf2fa 54 }
2ac76861 55 rq->community = Community;
56 rq->PDU = PDU;
57 this_reqid = PDU->reqid;
bdf18524 58 debug(49, 5) ("snmp_agent_parse: reqid=%d\n", PDU->reqid);
59
d0e0c8d2 60 if (Community == NULL) {
61 debug(49, 8) ("snmp_agent_parse: Community == NULL\n");
62
63 snmp_free_pdu(PDU);
2ac76861 64 snmp_agent_parse_done(0, rq);
0856c124 65 return;
d0e0c8d2 66 }
bdf18524 67 snmpAclCheckStart(rq);
68}
69
70void
2ac76861 71snmpAclCheckStart(snmp_request_t * rq)
bdf18524 72{
2ac76861 73 communityEntry *cp;
74 for (cp = Config.Snmp.communities; cp != NULL; cp = cp->next)
a561a1c4 75 if (!strcmp((char *) rq->community, cp->name) && cp->acls) {
2ac76861 76 rq->acl_checklist = aclChecklistCreate(cp->acls,
77 NULL, rq->from.sin_addr, NULL, NULL);
78 aclNBCheck(rq->acl_checklist, snmpAclCheckDone, rq);
79 return;
80 }
81 snmpAclCheckDone(ACCESS_ALLOWED, rq);
bdf18524 82}
83
84void
85snmpAclCheckDone(int answer, void *data)
86{
2ac76861 87 snmp_request_t *rq = data;
88 u_char *outbuf = rq->outbuf;
89
bdf18524 90 struct snmp_pdu *PDU, *RespPDU;
91 u_char *Community;
92 variable_list *VarPtr;
93 variable_list **VarPtrP;
94 int ret;
2ac76861 95
96 debug(49, 5) ("snmpAclCheckDone: called with answer=%d.\n", answer);
bdf18524 97 rq->acl_checklist = NULL;
2ac76861 98 PDU = rq->PDU;
99 Community = rq->community;
451b07c5 100
2ac76861 101 if (answer == ACCESS_DENIED) {
102 debug(49, 5) ("snmpAclCheckDone: failed on acl.\n");
103 snmp_agent_parse_done(0, rq);
104 return;
bdf18524 105 }
d370007c 106 for (VarPtrP = &(PDU->variables);
2ac76861 107 *VarPtrP;
108 VarPtrP = &((*VarPtrP)->next_variable)) {
109 VarPtr = *VarPtrP;
d370007c 110
2ac76861 111 debug(49, 5) ("snmpAclCheckDone: checking.\n");
bdf18524 112 /* access check for each variable */
113
a561a1c4 114 if (!community_check((char *) Community, VarPtr->name, VarPtr->name_length)) {
2ac76861 115 debug(49, 5) ("snmpAclCheckDone: failed on community_check.\n");
116 snmp_agent_parse_done(0, rq);
117 return;
118 }
d0e0c8d2 119 }
c8f322d5 120 Session->community = Community;
a561a1c4 121 Session->community_len = strlen((char *) Community);
d0e0c8d2 122 RespPDU = snmp_agent_response(PDU);
123 snmp_free_pdu(PDU);
124 if (RespPDU == NULL) {
bdf18524 125 debug(49, 8) ("snmpAclCheckDone: RespPDU == NULL. Returning code 2.\n");
2ac76861 126 debug(49, 5) ("snmpAclCheckDone: failed on RespPDU==NULL.\n");
127 snmp_agent_parse_done(2, rq);
bdf18524 128 return;
d0e0c8d2 129 }
bdf18524 130 debug(49, 8) ("snmpAclCheckDone: Response pdu (%x) errstat=%d reqid=%d.\n",
d0e0c8d2 131 RespPDU, RespPDU->errstat, RespPDU->reqid);
bdf18524 132
d0e0c8d2 133 /* Encode it */
bdf18524 134 ret = snmp_build(Session, RespPDU, outbuf, &rq->outlen);
d0e0c8d2 135 /* XXXXX Handle failure */
136 snmp_free_pdu(RespPDU);
2ac76861 137 /* XXX maybe here */
138 debug(49, 5) ("snmpAclCheckDone: ok!\n");
bdf18524 139 snmp_agent_parse_done(1, rq);
571c3b88 140}
25c1b8b7 141
25c1b8b7 142
571c3b88 143
d0e0c8d2 144static struct snmp_pdu *
145snmp_agent_response(struct snmp_pdu *PDU)
571c3b88 146{
d0e0c8d2 147 struct snmp_pdu *Answer = NULL;
148 variable_list *VarPtr, *VarNew = NULL;
149 variable_list **VarPtrP, **RespVars;
150 int index = 0;
151 oid_ParseFn *ParseFn;
152
9b230786 153 debug(49, 9) ("snmp_agent_response: Received a %d PDU\n", PDU->command);
d0e0c8d2 154
155 /* Create a response */
156 Answer = snmp_pdu_create(SNMP_PDU_RESPONSE);
157 if (Answer == NULL)
158 return (NULL);
159 Answer->reqid = PDU->reqid;
160 Answer->errindex = 0;
161
162 if (PDU->command == SNMP_PDU_GET) {
163
164 RespVars = &(Answer->variables);
165 /* Loop through all variables */
166 for (VarPtrP = &(PDU->variables);
167 *VarPtrP;
168 VarPtrP = &((*VarPtrP)->next_variable)) {
169 VarPtr = *VarPtrP;
170
171 index++;
172
173 /* Find the parsing function for this variable */
174 ParseFn = oidlist_Find(VarPtr->name, VarPtr->name_length);
175
176 if (ParseFn == NULL) {
177 Answer->errstat = SNMP_ERR_NOSUCHNAME;
178 debug(49, 5) ("snmp_agent_response: No such oid. ");
179 } else
c6da280c 180 VarNew = (*ParseFn) (VarPtr, (snint *) &(Answer->errstat));
d0e0c8d2 181
182 /* Was there an error? */
183 if ((Answer->errstat != SNMP_ERR_NOERROR) ||
184 (VarNew == NULL)) {
185 Answer->errindex = index;
186 debug(49, 5) ("snmp_agent_parse: successful.\n");
187 /* Just copy the rest of the variables. Quickly. */
188 *RespVars = VarPtr;
189 *VarPtrP = NULL;
190 return (Answer);
191 }
192 /* No error. Insert this var at the end, and move on to the next.
193 */
194 *RespVars = VarNew;
195 RespVars = &(VarNew->next_variable);
196 }
571c3b88 197
d0e0c8d2 198 return (Answer);
199 } else if (PDU->command == SNMP_PDU_GETNEXT) {
200 oid *TmpOidName;
201 int TmpOidNameLen = 0;
202
203 /* Find the next OID. */
204 VarPtr = PDU->variables;
205
206 ParseFn = oidlist_Next(VarPtr->name, VarPtr->name_length,
c6da280c 207 &(TmpOidName), (snint *) &(TmpOidNameLen));
d0e0c8d2 208
209 if (ParseFn == NULL) {
210 Answer->errstat = SNMP_ERR_NOSUCHNAME;
9b230786 211 debug(49, 9) ("snmp_agent_response: No such oid: ");
d0e0c8d2 212 print_oid(VarPtr->name, VarPtr->name_length);
213 } else {
214 xfree(VarPtr->name);
215 VarPtr->name = TmpOidName;
216 VarPtr->name_length = TmpOidNameLen;
c6da280c 217 VarNew = (*ParseFn) (VarPtr, (snint *) &(Answer->errstat));
d0e0c8d2 218 }
25c1b8b7 219
d0e0c8d2 220 /* Was there an error? */
221 if (Answer->errstat != SNMP_ERR_NOERROR) {
222 Answer->errindex = 1;
25c1b8b7 223
d0e0c8d2 224 /* Just copy this variable */
225 Answer->variables = VarPtr;
226 PDU->variables = NULL;
227 } else {
228 Answer->variables = VarNew;
229 }
25c1b8b7 230
d0e0c8d2 231 /* Done. Return this PDU */
232 return (Answer);
233 } /* end SNMP_PDU_GETNEXT */
9b230786 234 debug(49, 9) ("snmp_agent_response: Ignoring PDU %d\n", PDU->command);
d0e0c8d2 235 snmp_free_pdu(Answer);
236 return (NULL);
25c1b8b7 237}
238
d0e0c8d2 239int
d370007c 240in_view(oid * name, int namelen, int viewIndex)
25c1b8b7 241{
d370007c 242 viewEntry *vwp, *savedvwp = NULL;
243
2ac76861 244 debug(49, 8) ("in_view: called with index=%d\n", viewIndex);
d370007c 245 for (vwp = Config.Snmp.views; vwp; vwp = vwp->next) {
2ac76861 246 if (vwp->viewIndex != viewIndex)
247 continue;
248 debug(49, 8) ("in_view: found view for subtree:\n");
d370007c 249 print_oid(vwp->viewSubtree, vwp->viewSubtreeLen);
2ac76861 250 if (vwp->viewSubtreeLen > namelen
251 || memcmp(vwp->viewSubtree, name, vwp->viewSubtreeLen * sizeof(oid)))
252 continue;
253 /* no wildcards here yet */
254 if (!savedvwp) {
255 savedvwp = vwp;
256 } else {
257 if (vwp->viewSubtreeLen > savedvwp->viewSubtreeLen)
258 savedvwp = vwp;
259 }
d370007c 260 }
261 if (!savedvwp)
2ac76861 262 return FALSE;
d370007c 263 if (savedvwp->viewType == VIEWINCLUDED)
2ac76861 264 return TRUE;
d370007c 265 return FALSE;
266}
267
268
269static int
2ac76861 270community_check(char *b, oid * name, int namelen)
d370007c 271{
272 communityEntry *cp;
2ac76861 273 debug(49, 8) ("community_check: %s against:\n", b);
274 print_oid(name, namelen);
275 for (cp = Config.Snmp.communities; cp; cp = cp->next)
276 if (!strcmp(b, cp->name)) {
2ac76861 277 return in_view(name, namelen, cp->readView);
d370007c 278 }
279 return 0;
25c1b8b7 280}
281
d0e0c8d2 282int
283init_agent_auth()
25c1b8b7 284{
d0e0c8d2 285 Session = (struct snmp_session *) xmalloc(sizeof(struct snmp_session));
d0e0c8d2 286 Session->Version = SNMP_VERSION_1;
287 Session->authenticator = NULL;
288 Session->community = (u_char *) xstrdup("public");
289 Session->community_len = 6;
290 return 1;
571c3b88 291}
25c1b8b7 292
571c3b88 293/************************************************************************
25c1b8b7 294
571c3b88 295 SQUID MIB Implementation
25c1b8b7 296
571c3b88 297 ************************************************************************/
25c1b8b7 298
d0e0c8d2 299variable_list *
c6da280c 300snmp_basicFn(variable_list * Var, snint *ErrP)
571c3b88 301{
d0e0c8d2 302 variable_list *Answer;
303 char *pp;
571c3b88 304
d0e0c8d2 305 debug(49, 5) ("snmp_basicFn: Processing request with magic %d!\n", Var->name[7]);
571c3b88 306
d0e0c8d2 307 Answer = snmp_var_new(Var->name, Var->name_length);
308 *ErrP = SNMP_ERR_NOERROR;
571c3b88 309
d0e0c8d2 310 switch (Var->name[7]) {
571c3b88 311 case VERSION_DESCR:
312 case VERSION_ID:
d0e0c8d2 313 pp = SQUID_VERSION;
314 Answer->type = ASN_OCTET_STR;
315 Answer->val_len = strlen(pp);
316 Answer->val.string = (u_char *) xstrdup(pp);
317 break;
571c3b88 318 case UPTIME:
319 case SYSORLASTCHANGE:
c6da280c 320 Answer->val_len = sizeof(snint);
d0e0c8d2 321 Answer->val.integer = xmalloc(Answer->val_len);
451b07c5 322 Answer->type = SMI_TIMETICKS;
d0e0c8d2 323 *(Answer->val.integer) = tvSubDsec(squid_start, current_time);
324 break;
571c3b88 325 case SYSCONTACT:
d0e0c8d2 326 Answer->type = ASN_OCTET_STR;
327 Answer->val_len = strlen(Config.adminEmail);
328 Answer->val.string = (u_char *) xstrdup(Config.adminEmail);
571c3b88 329 case SYSYSNAME:
d0e0c8d2 330 if ((pp = Config.visibleHostname) == NULL)
331 pp = (char *) getMyHostname();
332 Answer->type = ASN_OCTET_STR;
333 Answer->val_len = strlen(pp);
334 Answer->val.string = (u_char *) xstrdup(pp);
335 break;
571c3b88 336 case SYSLOCATION:
d0e0c8d2 337 pp = "Cyberspace";
338 Answer->type = ASN_OCTET_STR;
339 Answer->val_len = strlen(pp);
340 Answer->val.string = (u_char *) xstrdup(pp);
341 break;
571c3b88 342 case SYSSERVICES:
c6da280c 343 Answer->val_len = sizeof(snint);
d0e0c8d2 344 Answer->val.integer = xmalloc(Answer->val_len);
345 Answer->type = ASN_INTEGER;
346 *(Answer->val.integer) = 72;
347 break;
348 default:
349 *ErrP = SNMP_ERR_NOSUCHNAME;
350 snmp_var_free(Answer);
351 return (NULL);
352 }
d0e0c8d2 353 return (Answer);
571c3b88 354}
25c1b8b7 355
d0e0c8d2 356variable_list *
c6da280c 357snmp_sysFn(variable_list * Var, snint *ErrP)
571c3b88 358{
d0e0c8d2 359 variable_list *Answer;
360 static fde *f = NULL;
361 int num = 1, cnt = 0;
362 static struct in_addr addr;
c6da280c 363 static snint snint_return;
d0e0c8d2 364
365 debug(49, 5) ("snmp_sysFn: Processing request with magic %d: \n", Var->name[8]);
366 print_oid(Var->name, Var->name_length);
367
368 Answer = snmp_var_new(Var->name, Var->name_length);
369 *ErrP = SNMP_ERR_NOERROR;
370
371 switch (Var->name[8]) {
372 case SYSVMSIZ:
c6da280c 373 Answer->val_len = sizeof(snint);
d0e0c8d2 374 Answer->val.integer = xmalloc(Answer->val_len);
375 Answer->type = ASN_INTEGER;
376 *(Answer->val.integer) = store_mem_size;
377 break;
378 case SYSSTOR:
c6da280c 379 Answer->val_len = sizeof(snint);
d0e0c8d2 380 Answer->val.integer = xmalloc(Answer->val_len);
381 Answer->type = ASN_INTEGER;
382 *(Answer->val.integer) = store_swap_size;
383 break;
384 case SYSFDTBL:
385 num = Var->name[11];
9b230786 386 debug(49, 9) ("snmp_sysFn: FD Table, num=%d\n", num);
d0e0c8d2 387 while (num && cnt < Squid_MaxFD) {
388 f = &fd_table[cnt++];
389 if (!f->open)
390 continue;
391 num--;
571c3b88 392 }
d0e0c8d2 393 if (num != 0 || !f) {
394 debug(49, 9) ("snmp_sysFn: no such name. %x\n", f);
395 *ErrP = SNMP_ERR_NOSUCHNAME;
396 snmp_var_free(Answer);
397 return (NULL);
571c3b88 398 }
399 switch (Var->name[10]) {
400 case SYS_FD_NUMBER:
c6da280c 401 Answer->val_len = sizeof(snint);
d0e0c8d2 402 Answer->val.integer = xmalloc(Answer->val_len);
403 Answer->type = ASN_INTEGER;
404 *(Answer->val.integer) = Var->name[11];
405 break;
406 case SYS_FD_TYPE:
c6da280c 407 Answer->val_len = sizeof(snint);
d0e0c8d2 408 Answer->val.integer = xmalloc(Answer->val_len);
409 Answer->type = ASN_INTEGER;
410 *(Answer->val.integer) = f->type;
411 break;
412 case SYS_FD_TOUT:
c6da280c 413 Answer->val_len = sizeof(snint);
d0e0c8d2 414 Answer->val.integer = xmalloc(Answer->val_len);
415 Answer->type = ASN_INTEGER;
c6da280c 416 *(Answer->val.integer) = (snint) (f->timeout_handler ? (f->timeout - squid_curtime) / 60 : 0);
d0e0c8d2 417 break;
418 case SYS_FD_NREAD:
c6da280c 419 Answer->val_len = sizeof(snint);
d0e0c8d2 420 Answer->val.integer = xmalloc(Answer->val_len);
421 Answer->type = ASN_INTEGER;
c6da280c 422 *(Answer->val.integer) = (snint) f->bytes_read;
d0e0c8d2 423 break;
424 case SYS_FD_NWRITE:
c6da280c 425 Answer->val_len = sizeof(snint);
d0e0c8d2 426 Answer->val.integer = xmalloc(Answer->val_len);
427 Answer->type = ASN_INTEGER;
c6da280c 428 *(Answer->val.integer) = (snint) f->bytes_written;
d0e0c8d2 429 break;
430 case SYS_FD_ADDR:
431 if (f->type != FD_SOCKET)
c6da280c 432 snint_return = (snint) 0;
d0e0c8d2 433 else {
434 safe_inet_addr(f->ipaddr, &addr);
c6da280c 435 snint_return = (snint) addr.s_addr;
d0e0c8d2 436 }
c6da280c 437 Answer->val_len = sizeof(snint);
d0e0c8d2 438 Answer->val.integer = xmalloc(Answer->val_len);
439 Answer->type = SMI_IPADDRESS;
c6da280c 440 *(Answer->val.integer) = (snint) snint_return;
d0e0c8d2 441 break;
442 case SYS_FD_NAME:
443 Answer->type = ASN_OCTET_STR;
444 Answer->val_len = strlen(f->desc);
445 Answer->val.string = (u_char *) xstrdup(f->desc);
446 break;
571c3b88 447 default:
d0e0c8d2 448 *ErrP = SNMP_ERR_NOSUCHNAME;
449 snmp_var_free(Answer);
450 return (NULL);
571c3b88 451 }
452 break;
d0e0c8d2 453 default:
454 *ErrP = SNMP_ERR_NOSUCHNAME;
455 snmp_var_free(Answer);
456 return (NULL);
457 }
d0e0c8d2 458 return Answer;
25c1b8b7 459}
460
d0e0c8d2 461variable_list *
c6da280c 462snmp_confFn(variable_list * Var, snint *ErrP)
25c1b8b7 463{
d0e0c8d2 464 variable_list *Answer;
465 char *cp = NULL;
571c3b88 466
d0e0c8d2 467 debug(49, 5) ("snmp_confFn: Processing request with magic %d!\n", Var->name[8]);
571c3b88 468
d0e0c8d2 469 Answer = snmp_var_new(Var->name, Var->name_length);
470 *ErrP = SNMP_ERR_NOERROR;
571c3b88 471
d0e0c8d2 472 switch (Var->name[8]) {
571c3b88 473 case CONF_ADMIN:
d0e0c8d2 474 Answer->type = ASN_OCTET_STR;
475 Answer->val_len = strlen(Config.adminEmail);
476 Answer->val.string = (u_char *) xstrdup(Config.adminEmail);
477 break;
571c3b88 478 case CONF_UPTIME:
c6da280c 479 Answer->val_len = sizeof(snint);
d0e0c8d2 480 Answer->val.integer = xmalloc(Answer->val_len);
86115da5 481 Answer->type = SMI_TIMETICKS;
d0e0c8d2 482 *(Answer->val.integer) = tvSubDsec(squid_start, current_time);
483 break;
571c3b88 484 case CONF_STORAGE:
d0e0c8d2 485 switch (Var->name[9]) {
571c3b88 486 case CONF_ST_MMAXSZ:
c6da280c 487 Answer->val_len = sizeof(snint);
d0e0c8d2 488 Answer->val.integer = xmalloc(Answer->val_len);
489 Answer->type = ASN_INTEGER;
c6da280c 490 *(Answer->val.integer) = (snint) Config.Mem.maxSize;
d0e0c8d2 491 break;
492 case CONF_ST_MHIWM:
c6da280c 493 Answer->val_len = sizeof(snint);
d0e0c8d2 494 Answer->val.integer = xmalloc(Answer->val_len);
495 Answer->type = ASN_INTEGER;
c6da280c 496 *(Answer->val.integer) = (snint) Config.Mem.highWaterMark;
d0e0c8d2 497 break;
498 case CONF_ST_MLOWM:
c6da280c 499 Answer->val_len = sizeof(snint);
d0e0c8d2 500 Answer->val.integer = xmalloc(Answer->val_len);
501 Answer->type = ASN_INTEGER;
c6da280c 502 *(Answer->val.integer) = (snint) Config.Mem.lowWaterMark;
d0e0c8d2 503 break;
504 case CONF_ST_SWMAXSZ:
c6da280c 505 Answer->val_len = sizeof(snint);
d0e0c8d2 506 Answer->val.integer = xmalloc(Answer->val_len);
507 Answer->type = ASN_INTEGER;
c6da280c 508 *(Answer->val.integer) = (snint) Config.Swap.maxSize;
d0e0c8d2 509 break;
510 case CONF_ST_SWHIWM:
c6da280c 511 Answer->val_len = sizeof(snint);
d0e0c8d2 512 Answer->val.integer = xmalloc(Answer->val_len);
513 Answer->type = ASN_INTEGER;
c6da280c 514 *(Answer->val.integer) = (snint) Config.Swap.highWaterMark;
d0e0c8d2 515 break;
516 case CONF_ST_SWLOWM:
c6da280c 517 Answer->val_len = sizeof(snint);
d0e0c8d2 518 Answer->val.integer = xmalloc(Answer->val_len);
519 Answer->type = ASN_INTEGER;
c6da280c 520 *(Answer->val.integer) = (snint) Config.Swap.lowWaterMark;
d0e0c8d2 521 break;
571c3b88 522 default:
d0e0c8d2 523 *ErrP = SNMP_ERR_NOSUCHNAME;
524 snmp_var_free(Answer);
525 return (NULL);
571c3b88 526 }
527 break;
d0e0c8d2 528 case CONF_WAIS_RHOST:
529 if (Config.Wais.relayHost)
530 cp = Config.Wais.relayHost;
531 else
532 cp = "None";
533 Answer->type = ASN_OCTET_STR;
534 Answer->val_len = strlen(cp);
535 Answer->val.string = (u_char *) xstrdup(cp);
536 break;
571c3b88 537 case CONF_WAIS_RPORT:
c6da280c 538 Answer->val_len = sizeof(snint);
d0e0c8d2 539 Answer->val.integer = xmalloc(Answer->val_len);
540 Answer->type = ASN_INTEGER;
c6da280c 541 *(Answer->val.integer) = (snint) Config.Wais.relayPort;
571c3b88 542 break;
543 case CONF_TIO:
544 switch (Var->name[9]) {
545 case CONF_TIO_RD:
c6da280c 546 Answer->val_len = sizeof(snint);
d0e0c8d2 547 Answer->val.integer = xmalloc(Answer->val_len);
548 Answer->type = ASN_INTEGER;
c6da280c 549 *(Answer->val.integer) = (snint) Config.Timeout.read;
d0e0c8d2 550 break;
551 case CONF_TIO_CON:
c6da280c 552 Answer->val_len = sizeof(snint);
d0e0c8d2 553 Answer->val.integer = xmalloc(Answer->val_len);
554 Answer->type = ASN_INTEGER;
c6da280c 555 *(Answer->val.integer) = (snint) Config.Timeout.connect;
d0e0c8d2 556 break;
557 case CONF_TIO_REQ:
c6da280c 558 Answer->val_len = sizeof(snint);
d0e0c8d2 559 Answer->val.integer = xmalloc(Answer->val_len);
560 Answer->type = ASN_INTEGER;
c6da280c 561 *(Answer->val.integer) = (snint) Config.Timeout.request;
d0e0c8d2 562 break;
571c3b88 563 default:
d0e0c8d2 564 *ErrP = SNMP_ERR_NOSUCHNAME;
565 snmp_var_free(Answer);
566 return (NULL);
571c3b88 567 }
451b07c5 568 break;
571c3b88 569 case CONF_LOG_LVL:
d0e0c8d2 570 if (!(cp = Config.debugOptions))
571 cp = "None";
572 Answer->type = ASN_OCTET_STR;
573 Answer->val_len = strlen(cp);
574 Answer->val.string = (u_char *) xstrdup(cp);
575 break;
571c3b88 576 default:
d0e0c8d2 577 *ErrP = SNMP_ERR_NOSUCHNAME;
578 snmp_var_free(Answer);
579 return (NULL);
25c1b8b7 580 }
571c3b88 581 return Answer;
582}
25c1b8b7 583
d0e0c8d2 584variable_list *
c6da280c 585snmp_confPtblFn(variable_list * Var, snint *ErrP)
571c3b88 586{
d0e0c8d2 587 variable_list *Answer;
588 char *cp = NULL;
589 peer *p = NULL;
590 int cnt;
591 debug(49, 5) ("snmp_confPtblFn: peer %d requested!\n", Var->name[11]);
592
593 Answer = snmp_var_new(Var->name, Var->name_length);
594 *ErrP = SNMP_ERR_NOERROR;
595
596 p = Config.peers;
597 cnt = Var->name[11];
598 debug(49, 5) ("snmp_confPtblFn: we want .x.%d\n", Var->name[10]);
599 while (--cnt)
600 if (!(p = p->next));
601 if (p == NULL) {
602 *ErrP = SNMP_ERR_NOSUCHNAME;
603 snmp_var_free(Answer);
604 return (NULL);
605 }
606 switch (Var->name[10]) {
571c3b88 607 case CONF_PTBL_ID:
c6da280c 608 Answer->val_len = sizeof(snint);
d0e0c8d2 609 Answer->val.integer = xmalloc(Answer->val_len);
610 Answer->type = ASN_INTEGER;
c6da280c 611 *(Answer->val.integer) = (snint) Var->name[10];
571c3b88 612 break;
613 case CONF_PTBL_NAME:
d0e0c8d2 614 cp = p->host;
615 Answer->type = ASN_OCTET_STR;
616 Answer->val_len = strlen(cp);
617 Answer->val.string = (u_char *) xstrdup(cp);
618 break;
571c3b88 619 case CONF_PTBL_IP:
d0e0c8d2 620 Answer->type = SMI_IPADDRESS;
c6da280c 621 Answer->val_len = sizeof(snint);
451b07c5 622 Answer->val.integer = xmalloc(Answer->val_len);
c6da280c 623 *(Answer->val.integer) = (snint) (p->in_addr.sin_addr.s_addr);
d0e0c8d2 624 break;
571c3b88 625 case CONF_PTBL_HTTP:
c6da280c 626 Answer->val_len = sizeof(snint);
d0e0c8d2 627 Answer->val.integer = xmalloc(Answer->val_len);
628 Answer->type = ASN_INTEGER;
c6da280c 629 *(Answer->val.integer) = (snint) p->http_port;
571c3b88 630 break;
631 case CONF_PTBL_ICP:
c6da280c 632 Answer->val_len = sizeof(snint);
d0e0c8d2 633 Answer->val.integer = xmalloc(Answer->val_len);
634 Answer->type = ASN_INTEGER;
c6da280c 635 *(Answer->val.integer) = (snint) p->icp_port;
571c3b88 636 break;
637 case CONF_PTBL_TYPE:
c6da280c 638 Answer->val_len = sizeof(snint);
d0e0c8d2 639 Answer->val.integer = xmalloc(Answer->val_len);
640 Answer->type = ASN_INTEGER;
c6da280c 641 *(Answer->val.integer) = (snint) p->type;
571c3b88 642 break;
643 case CONF_PTBL_STATE:
c6da280c 644 Answer->val_len = sizeof(snint);
d0e0c8d2 645 Answer->val.integer = xmalloc(Answer->val_len);
646 Answer->type = ASN_INTEGER;
c6da280c 647 *(Answer->val.integer) = (snint) neighborUp(p);
571c3b88 648 break;
649 default:
d0e0c8d2 650 *ErrP = SNMP_ERR_NOSUCHNAME;
651 snmp_var_free(Answer);
652 return (NULL);
653 }
654 return Answer;
571c3b88 655}
25c1b8b7 656
d0e0c8d2 657variable_list *
c6da280c 658snmp_prfSysFn(variable_list * Var, snint *ErrP)
571c3b88 659{
d0e0c8d2 660 variable_list *Answer;
661 static struct rusage rusage;
571c3b88 662
d0e0c8d2 663 debug(49, 5) ("snmp_prfSysFn: Processing request with magic %d!\n", Var->name[9]);
571c3b88 664
d0e0c8d2 665 Answer = snmp_var_new(Var->name, Var->name_length);
666 *ErrP = SNMP_ERR_NOERROR;
c6da280c 667 Answer->val_len = sizeof(snint);
d0e0c8d2 668 Answer->val.integer = xmalloc(Answer->val_len);
669 Answer->type = ASN_INTEGER;
571c3b88 670
d0e0c8d2 671 switch (Var->name[9]) {
571c3b88 672 case PERF_SYS_PF:
d0e0c8d2 673 squid_getrusage(&rusage);
674 *(Answer->val.integer) = rusage_pagefaults(&rusage);
675 break;
571c3b88 676 case PERF_SYS_NUMR:
d0e0c8d2 677 *(Answer->val.integer) = IOStats.Http.reads;
678 break;
571c3b88 679 case PERF_SYS_DEFR:
d0e0c8d2 680 *(Answer->val.integer) = IOStats.Http.reads_deferred;
681 break;
571c3b88 682 case PERF_SYS_MEMUSAGE:
c6da280c 683 *(Answer->val.integer) = (snint) memTotalAllocated() >> 10;
d0e0c8d2 684 break;
571c3b88 685 case PERF_SYS_CPUUSAGE:
d0e0c8d2 686 squid_getrusage(&rusage);
c6da280c 687 *(Answer->val.integer) = (snint) rusage_cputime(&rusage);
d0e0c8d2 688 break;
571c3b88 689 case PERF_SYS_MAXRESSZ:
d0e0c8d2 690 squid_getrusage(&rusage);
c6da280c 691 *(Answer->val.integer) = (snint) rusage_maxrss(&rusage);
d0e0c8d2 692 break;
571c3b88 693 case PERF_SYS_CURLRUEXP:
d0e0c8d2 694 Answer->type = SMI_TIMETICKS;
c6da280c 695 *(Answer->val.integer) = (snint) storeExpiredReferenceAge();
d0e0c8d2 696 break;
571c3b88 697 case PERF_SYS_CURUNLREQ:
c6da280c 698 *(Answer->val.integer) = (snint) Counter.unlink.requests;
d0e0c8d2 699 break;
571c3b88 700 case PERF_SYS_CURUNUSED_FD:
c6da280c 701 *(Answer->val.integer) = (snint) Squid_MaxFD - Number_FD;
d0e0c8d2 702 break;
571c3b88 703 case PERF_SYS_CURRESERVED_FD:
c6da280c 704 *(Answer->val.integer) = (snint) Number_FD;
d0e0c8d2 705 break;
571c3b88 706 case PERF_SYS_NUMOBJCNT:
c6da280c 707 *(Answer->val.integer) = (snint) memInUse(MEM_STOREENTRY);
d0e0c8d2 708 break;
571c3b88 709 default:
d0e0c8d2 710 *ErrP = SNMP_ERR_NOSUCHNAME;
711 snmp_var_free(Answer);
712 return (NULL);
713 }
714 return Answer;
25c1b8b7 715}
716
d0e0c8d2 717variable_list *
c6da280c 718snmp_prfPeerFn(variable_list * Var, snint *ErrP)
25c1b8b7 719{
d0e0c8d2 720 variable_list *Answer;
721 peer *p = NULL;
722 int cnt;
723 debug(49, 5) ("snmp_prfPeerFn: Processing request with magic %d!\n", Var->name[9]);
724
725 Answer = snmp_var_new(Var->name, Var->name_length);
726 *ErrP = SNMP_ERR_NOERROR;
727
728 p = Config.peers;
729 cnt = Var->name[12];
730 debug(49, 5) ("snmp_prfPeerFn: we want .%d.%d\n", Var->name[11], cnt);
731 while (--cnt)
732 if (!(p = p->next));
733 if (p == NULL) {
734 *ErrP = SNMP_ERR_NOSUCHNAME;
735 snmp_var_free(Answer);
736 return (NULL);
737 }
738 Answer->type = SMI_COUNTER32;
c6da280c 739 Answer->val_len = sizeof(snint);
d0e0c8d2 740 Answer->val.integer = xmalloc(Answer->val_len);
741
742 switch (Var->name[11]) {
571c3b88 743 case PERF_PEERSTAT_ID:
d0e0c8d2 744 Answer->type = ASN_INTEGER;
745 *(Answer->val.integer) = Var->name[11];
571c3b88 746 break;
747 case PERF_PEERSTAT_SENT:
d0e0c8d2 748 *(Answer->val.integer) = p->stats.pings_sent;
571c3b88 749 break;
750 case PERF_PEERSTAT_PACKED:
d0e0c8d2 751 *(Answer->val.integer) = p->stats.pings_acked;
571c3b88 752 break;
753 case PERF_PEERSTAT_FETCHES:
d0e0c8d2 754 *(Answer->val.integer) = p->stats.fetches;
571c3b88 755 break;
756 case PERF_PEERSTAT_RTT:
d0e0c8d2 757 Answer->type = ASN_INTEGER;
758 *(Answer->val.integer) = p->stats.rtt;
571c3b88 759 break;
760 case PERF_PEERSTAT_IGN:
d0e0c8d2 761 *(Answer->val.integer) = p->stats.ignored_replies;
571c3b88 762 break;
763 case PERF_PEERSTAT_KEEPAL_S:
d0e0c8d2 764 *(Answer->val.integer) = p->stats.n_keepalives_sent;
571c3b88 765 break;
766 case PERF_PEERSTAT_KEEPAL_R:
d0e0c8d2 767 *(Answer->val.integer) = p->stats.n_keepalives_recv;
571c3b88 768 break;
769 default:
d0e0c8d2 770 *ErrP = SNMP_ERR_NOSUCHNAME;
771 snmp_var_free(Answer);
d0e0c8d2 772 return (NULL);
773 }
774 return Answer;
25c1b8b7 775}
776
777
d0e0c8d2 778variable_list *
c6da280c 779snmp_prfProtoFn(variable_list * Var, snint *ErrP)
25c1b8b7 780{
d0e0c8d2 781 variable_list *Answer;
2ac76861 782 static StatCounters *f = NULL;
783 static StatCounters *l = NULL;
451b07c5 784 double x;
785 int minutes;
571c3b88 786
d0e0c8d2 787 debug(49, 5) ("snmp_prfProtoFn: Processing request with magic %d!\n", Var->name[8]);
571c3b88 788
d0e0c8d2 789 Answer = snmp_var_new(Var->name, Var->name_length);
790 *ErrP = SNMP_ERR_NOERROR;
571c3b88 791
2ac76861 792 switch (Var->name[9]) {
793 case PERF_PROTOSTAT_AGGR: /* cacheProtoAggregateStats */
d0e0c8d2 794 Answer->type = SMI_COUNTER32;
c6da280c 795 Answer->val_len = sizeof(snint);
d0e0c8d2 796 Answer->val.integer = xmalloc(Answer->val_len);
797 switch (Var->name[10]) {
798 case PERF_PROTOSTAT_AGGR_HTTP_REQ:
c6da280c 799 *(Answer->val.integer) = (snint) Counter.client_http.requests;
d0e0c8d2 800 break;
801 case PERF_PROTOSTAT_AGGR_HTTP_HITS:
c6da280c 802 *(Answer->val.integer) = (snint) Counter.client_http.hits;
d0e0c8d2 803 break;
804 case PERF_PROTOSTAT_AGGR_HTTP_ERRORS:
c6da280c 805 *(Answer->val.integer) = (snint) Counter.client_http.errors;
d0e0c8d2 806 break;
2ac76861 807 case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN:
c6da280c 808 *(Answer->val.integer) = (snint) Counter.client_http.kbytes_in.kb;
2ac76861 809 break;
810 case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT:
c6da280c 811 *(Answer->val.integer) = (snint) Counter.client_http.kbytes_out.kb;
2ac76861 812 break;
d0e0c8d2 813 case PERF_PROTOSTAT_AGGR_ICP_S:
c6da280c 814 *(Answer->val.integer) = (snint) Counter.icp.pkts_sent;
d0e0c8d2 815 break;
816 case PERF_PROTOSTAT_AGGR_ICP_R:
c6da280c 817 *(Answer->val.integer) = (snint) Counter.icp.pkts_recv;
d0e0c8d2 818 break;
819 case PERF_PROTOSTAT_AGGR_ICP_SKB:
c6da280c 820 *(Answer->val.integer) = (snint) Counter.icp.kbytes_sent.kb;
d0e0c8d2 821 break;
822 case PERF_PROTOSTAT_AGGR_ICP_RKB:
c6da280c 823 *(Answer->val.integer) = (snint) Counter.icp.kbytes_recv.kb;
2ac76861 824 break;
825 case PERF_PROTOSTAT_AGGR_REQ:
c6da280c 826 *(Answer->val.integer) = (snint) Counter.server.all.requests;
2ac76861 827 break;
828 case PERF_PROTOSTAT_AGGR_ERRORS:
c6da280c 829 *(Answer->val.integer) = (snint) Counter.server.all.errors;
2ac76861 830 break;
d0e0c8d2 831 case PERF_PROTOSTAT_AGGR_KBYTES_IN:
c6da280c 832 *(Answer->val.integer) = (snint) Counter.server.all.kbytes_in.kb;
d0e0c8d2 833 break;
834 case PERF_PROTOSTAT_AGGR_KBYTES_OUT:
c6da280c 835 *(Answer->val.integer) = (snint) Counter.server.all.kbytes_out.kb;
d0e0c8d2 836 break;
837 case PERF_PROTOSTAT_AGGR_CURSWAP:
c6da280c 838 *(Answer->val.integer) = (snint) store_swap_size;
d0e0c8d2 839 break;
d0e0c8d2 840 default:
d0e0c8d2 841 *ErrP = SNMP_ERR_NOSUCHNAME;
842 snmp_var_free(Answer);
843 return (NULL);
844 }
2ac76861 845 return Answer;
451b07c5 846 case PERF_PROTOSTAT_MEDIAN:
451b07c5 847
2ac76861 848 minutes = Var->name[12];
849
850 f = snmpStatGet(0);
851 l = snmpStatGet(minutes);
451b07c5 852
2ac76861 853 debug(49, 8) ("median: min= %d, %d l= %x , f = %x\n", minutes,
854 Var->name[11], l, f);
451b07c5 855 Answer->type = SMI_INTEGER;
c6da280c 856 Answer->val_len = sizeof(snint);
451b07c5 857 Answer->val.integer = xmalloc(Answer->val_len);
858
2ac76861 859 debug(49, 8) ("median: l= %x , f = %x\n", l, f);
451b07c5 860 switch (Var->name[11]) {
2ac76861 861 case PERF_MEDIAN_TIME:
862 x = minutes;
863 break;
864 case PERF_MEDIAN_HTTP_ALL:
865 x = statHistDeltaMedian(&l->client_http.all_svc_time,
866 &f->client_http.all_svc_time);
867 break;
868 case PERF_MEDIAN_HTTP_MISS:
869 x = statHistDeltaMedian(&l->client_http.miss_svc_time,
870 &f->client_http.miss_svc_time);
871 break;
872 case PERF_MEDIAN_HTTP_NM:
873 x = statHistDeltaMedian(&l->client_http.nm_svc_time,
874 &f->client_http.nm_svc_time);
875 break;
876 case PERF_MEDIAN_HTTP_HIT:
877 x = statHistDeltaMedian(&l->client_http.hit_svc_time,
878 &f->client_http.hit_svc_time);
879 break;
880 case PERF_MEDIAN_ICP_QUERY:
881 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
882 break;
883 case PERF_MEDIAN_ICP_REPLY:
884 x = statHistDeltaMedian(&l->icp.reply_svc_time, &f->icp.reply_svc_time);
885 break;
886 case PERF_MEDIAN_DNS:
887 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
888 break;
889 default:
2ac76861 890 *ErrP = SNMP_ERR_NOSUCHNAME;
891 snmp_var_free(Answer);
892 return (NULL);
451b07c5 893 }
c6da280c 894 *(Answer->val.integer) = (snint) x;
2ac76861 895 return Answer;
d0e0c8d2 896 }
451b07c5 897 *ErrP = SNMP_ERR_NOSUCHNAME;
898 snmp_var_free(Answer);
899 return (NULL);
25c1b8b7 900}
901
25c1b8b7 902
d0e0c8d2 903variable_list *
c6da280c 904snmp_dnsFn(variable_list * Var, snint *ErrP)
25c1b8b7 905{
d0e0c8d2 906 debug(49, 5) ("snmp_dnsFn: Processing request with magic %d!\n", Var->name[9]);
907 if (Var->name[9] == NET_DNS_IPCACHE)
908 return snmp_ipcacheFn(Var, ErrP);
909 if (Var->name[9] == NET_DNS_FQDNCACHE)
910 return snmp_fqdncacheFn(Var, ErrP);
7cb58016 911
d0e0c8d2 912 return NULL;
25c1b8b7 913}