snmp_agent.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:15k
源码类别:

代理服务器

开发平台:

Unix_Linux

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