/*
- * DEBUG: section 49 SNMP support
- * AUTHOR: Glenn Chisholm
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
*
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
*/
+
+/* DEBUG: section 49 SNMP support */
+
#include "squid.h"
#include "acl/FilledChecklist.h"
-#include "cache_snmp.h"
+#include "base/CbcPointer.h"
+#include "CachePeer.h"
+#include "client_db.h"
#include "comm.h"
-#include "compat/strsep.h"
+#include "comm/Connection.h"
+#include "comm/Loops.h"
+#include "comm/UdpOpenDialer.h"
+#include "fatal.h"
#include "ip/Address.h"
+#include "ip/tools.h"
+#include "snmp/Forwarder.h"
+#include "snmp_agent.h"
+#include "snmp_core.h"
+#include "SnmpRequest.h"
+#include "SquidConfig.h"
+#include "tools.h"
-#define SNMP_REQUEST_SIZE 4096
-#define MAX_PROTOSTAT 5
-
-Ip::Address theOutSNMPAddr;
-
-typedef struct _mib_tree_entry mib_tree_entry;
-typedef oid *(instance_Fn) (oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
-
-struct _mib_tree_entry {
- oid *name;
- int len;
- oid_ParseFn *parsefunction;
- instance_Fn *instancefunction;
- int children;
-
- struct _mib_tree_entry **leaves;
-
- struct _mib_tree_entry *parent;
-};
+static void snmpPortOpened(const Comm::ConnectionPointer &conn, int errNo);
mib_tree_entry *mib_tree_head;
mib_tree_entry *mib_tree_last;
-static mib_tree_entry * snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction);
-static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...);
+Comm::ConnectionPointer snmpIncomingConn;
+Comm::ConnectionPointer snmpOutgoingConn;
+
+static mib_tree_entry * snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType = atNone);
+static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType, int children,...);
static oid *snmpCreateOid(int length,...);
mib_tree_entry * snmpLookupNodeStr(mib_tree_entry *entry, const char *str);
-int snmpCreateOidFromStr(const char *str, oid **name, int *nl);
+bool snmpCreateOidFromStr(const char *str, oid **name, int *nl);
SQUIDCEXTERN void (*snmplib_debug_hook) (int, char *);
static oid *static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
static oid *time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
static oid *peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
static oid *client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
-static void snmpDecodePacket(snmp_request_t * rq);
-static void snmpConstructReponse(snmp_request_t * rq);
+static void snmpDecodePacket(SnmpRequest * rq);
+static void snmpConstructReponse(SnmpRequest * rq);
-static struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU);
static oid_ParseFn *snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen);
static oid_ParseFn *snmpTreeGet(oid * Current, snint CurrentLen);
static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * current);
static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current);
-static void snmpSnmplibDebug(int lvl, char *buf);
+extern "C" void snmpSnmplibDebug(int lvl, char *buf);
/*
* The functions used during startup:
* snmpInit
* snmpConnectionOpen
- * snmpConnectionShutdown
* snmpConnectionClose
*/
* without having a "search" function. A search function should be written
* to make this and the other code much less evil.
*/
- mib_tree_head = snmpAddNode(snmpCreateOid(1, 1), 1, NULL, NULL, 0);
+ mib_tree_head = snmpAddNode(snmpCreateOid(1, 1), 1, NULL, NULL, atNone, 0);
assert(mib_tree_head);
debugs(49, 5, "snmpInit: root is " << mib_tree_head);
/* SQ_SYS - 1.3.6.1.4.1.3495.1.1 */
snmpAddNodeStr("1.3.6.1.4.1.3495.1", 1, NULL, NULL);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSVMSIZ, snmp_sysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSSTOR, snmp_sysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYS_UPTIME, snmp_sysFn, static_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSVMSIZ, snmp_sysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSSTOR, snmp_sysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYS_UPTIME, snmp_sysFn, static_Inst, atMax);
/* SQ_CONF - 1.3.6.1.4.1.3495.1.2 */
snmpAddNodeStr("1.3.6.1.4.1.3495.1", 2, NULL, NULL);
/* SQ_CONF + CONF_STORAGE - 1.3.6.1.4.1.3495.1.5 */
snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_STORAGE, NULL, NULL);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_MMAXSZ, snmp_confFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWMAXSZ, snmp_confFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWHIWM, snmp_confFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWLOWM, snmp_confFn, static_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_MMAXSZ, snmp_confFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWMAXSZ, snmp_confFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWHIWM, snmp_confFn, static_Inst, atMin);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWLOWM, snmp_confFn, static_Inst, atMin);
snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_UNIQNAME, snmp_confFn, static_Inst);
/* PERF_SYS - 1.3.6.1.4.1.3495.1.3.1 */
snmpAddNodeStr("1.3.6.1.4.1.3495.1.3", PERF_SYS, NULL, NULL);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_PF, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMR, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MEMUSAGE, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUTIME, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUUSAGE, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MAXRESSZ, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMOBJCNT, snmp_prfSysFn, static_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_PF, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMR, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MEMUSAGE, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUTIME, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUUSAGE, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MAXRESSZ, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMOBJCNT, snmp_prfSysFn, static_Inst, atSum);
+ /*
+ Amos comments:
+ The meaning of LRU is "oldest timestamped object in cache, if LRU algorithm is
+ used"...
+ What this SMP support needs to do is aggregate via a special filter equivalent to
+ min() to retain the semantic oldest-object meaning. A special one is needed that
+ works as unsigned and ignores '0' values.
+ */
snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURLRUEXP, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNLREQ, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNUSED_FD, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURRESERVED_FD, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUSED_FD, snmp_prfSysFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURMAX_FD, snmp_prfSysFn, static_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNLREQ, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNUSED_FD, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURRESERVED_FD, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUSED_FD, snmp_prfSysFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURMAX_FD, snmp_prfSysFn, static_Inst, atMax);
/* PERF_PROTO - 1.3.6.1.4.1.3495.1.3.2 */
snmpAddNodeStr("1.3.6.1.4.1.3495.1.3", PERF_PROTO, NULL, NULL);
snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2", PERF_PROTOSTAT_AGGR, NULL, NULL);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_REQ, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_HITS, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_ERRORS, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_S, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_R, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_SKB, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_RKB, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_REQ, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ERRORS, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_IN, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_OUT, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CURSWAP, snmp_prfProtoFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CLIENTS, snmp_prfProtoFn, static_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_REQ, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_HITS, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_ERRORS, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_S, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_R, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_SKB, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_RKB, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_REQ, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ERRORS, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_IN, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_OUT, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CURSWAP, snmp_prfProtoFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CLIENTS, snmp_prfProtoFn, static_Inst, atSum);
/* Note this is time-series rather than 'static' */
/* cacheMedianSvcTable */
/* cacheMedianSvcEntry */
snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2", 1, NULL, NULL);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_TIME, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_ALL, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_MISS, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NM, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_HIT, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_QUERY, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_REPLY, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_DNS, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_RHR, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_BHR, snmp_prfProtoFn, time_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NH, snmp_prfProtoFn, time_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_TIME, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_ALL, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_MISS, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NM, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_HIT, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_QUERY, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_REPLY, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_DNS, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_RHR, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_BHR, snmp_prfProtoFn, time_Inst, atAverage);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NH, snmp_prfProtoFn, time_Inst, atAverage);
/* SQ_NET - 1.3.6.1.4.1.3495.1.4 */
snmpAddNodeStr("1.3.6.1.4.1.3495.1", 4, NULL, NULL);
snmpAddNodeStr("1.3.6.1.4.1.3495.1.4", NET_IP_CACHE, NULL, NULL);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_ENT, snmp_netIpFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_REQ, snmp_netIpFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_HITS, snmp_netIpFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_PENDHIT, snmp_netIpFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_NEGHIT, snmp_netIpFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_MISS, snmp_netIpFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_GHBN, snmp_netIpFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_LOC, snmp_netIpFn, static_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_ENT, snmp_netIpFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_REQ, snmp_netIpFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_HITS, snmp_netIpFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_PENDHIT, snmp_netIpFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_NEGHIT, snmp_netIpFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_MISS, snmp_netIpFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_GHBN, snmp_netIpFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_LOC, snmp_netIpFn, static_Inst, atSum);
snmpAddNodeStr("1.3.6.1.4.1.3495.1.4", NET_FQDN_CACHE, NULL, NULL);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_ENT, snmp_netFqdnFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_REQ, snmp_netFqdnFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_HITS, snmp_netFqdnFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_PENDHIT, snmp_netFqdnFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_NEGHIT, snmp_netFqdnFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_MISS, snmp_netFqdnFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_GHBN, snmp_netFqdnFn, static_Inst);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_ENT, snmp_netFqdnFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_REQ, snmp_netFqdnFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_HITS, snmp_netFqdnFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_PENDHIT, snmp_netFqdnFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_NEGHIT, snmp_netFqdnFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_MISS, snmp_netFqdnFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_GHBN, snmp_netFqdnFn, static_Inst, atSum);
snmpAddNodeStr("1.3.6.1.4.1.3495.1.4", NET_DNS_CACHE, NULL, NULL);
-#if USE_DNSSERVERS
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REQ, snmp_netDnsFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REP, snmp_netDnsFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_SERVERS, snmp_netDnsFn, static_Inst);
-#else
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REQ, snmp_netIdnsFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REP, snmp_netIdnsFn, static_Inst);
- snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_SERVERS, snmp_netIdnsFn, static_Inst);
-#endif
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REQ, snmp_netDnsFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REP, snmp_netDnsFn, static_Inst, atSum);
+ snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_SERVERS, snmp_netDnsFn, static_Inst, atSum);
/* SQ_MESH - 1.3.6.1.4.1.3495.1.5 */
snmpAddNodeStr("1.3.6.1.4.1.3495.1", 5, NULL, NULL);
}
void
-snmpConnectionOpen(void)
+snmpOpenPorts(void)
{
- struct addrinfo *xaddr = NULL;
- int x;
-
debugs(49, 5, "snmpConnectionOpen: Called");
- if (Config.Port.snmp > 0) {
- Config.Addrs.snmp_incoming.SetPort(Config.Port.snmp);
- enter_suid();
- theInSnmpConnection = comm_open_listener(SOCK_DGRAM,
- IPPROTO_UDP,
- Config.Addrs.snmp_incoming,
- COMM_NONBLOCKING,
- "SNMP Port");
- leave_suid();
-
- if (theInSnmpConnection < 0)
- fatal("Cannot open SNMP Port");
-
- commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
-
- debugs(1, 1, "Accepting SNMP messages on " << Config.Addrs.snmp_incoming << ", FD " << theInSnmpConnection << ".");
-
- if (!Config.Addrs.snmp_outgoing.IsNoAddr()) {
- Config.Addrs.snmp_outgoing.SetPort(Config.Port.snmp);
- enter_suid();
- theOutSnmpConnection = comm_open_listener(SOCK_DGRAM,
- IPPROTO_UDP,
- Config.Addrs.snmp_outgoing,
- COMM_NONBLOCKING,
- "SNMP Port");
- leave_suid();
+ if (Config.Port.snmp <= 0)
+ return;
- if (theOutSnmpConnection < 0)
- fatal("Cannot open Outgoing SNMP Port");
+ snmpIncomingConn = new Comm::Connection;
+ snmpIncomingConn->local = Config.Addrs.snmp_incoming;
+ snmpIncomingConn->local.port(Config.Port.snmp);
- commSetSelect(theOutSnmpConnection,
- COMM_SELECT_READ,
- snmpHandleUdp,
- NULL, 0);
+ if (!Ip::EnableIpv6 && !snmpIncomingConn->local.setIPv4()) {
+ debugs(49, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << snmpIncomingConn->local << " is not an IPv4 address.");
+ fatal("SNMP port cannot be opened.");
+ }
+ /* split-stack for now requires IPv4-only SNMP */
+ if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && snmpIncomingConn->local.isAnyAddr()) {
+ snmpIncomingConn->local.setIPv4();
+ }
- debugs(1, 1, "Outgoing SNMP messages on " << Config.Addrs.snmp_outgoing << ", FD " << theOutSnmpConnection << ".");
+ AsyncCall::Pointer call = asyncCall(49, 2, "snmpIncomingConnectionOpened",
+ Comm::UdpOpenDialer(&snmpPortOpened));
+ Ipc::StartListening(SOCK_DGRAM, IPPROTO_UDP, snmpIncomingConn, Ipc::fdnInSnmpSocket, call);
- fd_note(theOutSnmpConnection, "Outgoing SNMP socket");
+ if (!Config.Addrs.snmp_outgoing.isNoAddr()) {
+ snmpOutgoingConn = new Comm::Connection;
+ snmpOutgoingConn->local = Config.Addrs.snmp_outgoing;
+ snmpOutgoingConn->local.port(Config.Port.snmp);
- fd_note(theInSnmpConnection, "Incoming SNMP socket");
- } else {
- theOutSnmpConnection = theInSnmpConnection;
+ if (!Ip::EnableIpv6 && !snmpOutgoingConn->local.setIPv4()) {
+ debugs(49, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << snmpOutgoingConn->local << " is not an IPv4 address.");
+ fatal("SNMP port cannot be opened.");
}
-
- theOutSNMPAddr.SetEmpty();
-
- theOutSNMPAddr.InitAddrInfo(xaddr);
-
- x = getsockname(theOutSnmpConnection, xaddr->ai_addr, &xaddr->ai_addrlen);
-
- if (x < 0)
- debugs(51, 1, "theOutSnmpConnection FD " << theOutSnmpConnection << ": getsockname: " << xstrerror());
- else
- theOutSNMPAddr = *xaddr;
-
- theOutSNMPAddr.FreeAddrInfo(xaddr);
+ /* split-stack for now requires IPv4-only SNMP */
+ if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && snmpOutgoingConn->local.isAnyAddr()) {
+ snmpOutgoingConn->local.setIPv4();
+ }
+ AsyncCall::Pointer c = asyncCall(49, 2, "snmpOutgoingConnectionOpened",
+ Comm::UdpOpenDialer(&snmpPortOpened));
+ Ipc::StartListening(SOCK_DGRAM, IPPROTO_UDP, snmpOutgoingConn, Ipc::fdnOutSnmpSocket, c);
+ } else {
+ snmpOutgoingConn = snmpIncomingConn;
+ debugs(1, DBG_IMPORTANT, "Sending SNMP messages from " << snmpOutgoingConn->local);
}
}
-void
-snmpConnectionShutdown(void)
+static void
+snmpPortOpened(const Comm::ConnectionPointer &conn, int)
{
- if (theInSnmpConnection < 0)
- return;
+ if (!Comm::IsConnOpen(conn))
+ fatalf("Cannot open SNMP %s Port",(conn->fd == snmpIncomingConn->fd?"receiving":"sending"));
- if (theInSnmpConnection != theOutSnmpConnection) {
- debugs(49, 1, "FD " << theInSnmpConnection << " Closing SNMP socket");
- comm_close(theInSnmpConnection);
- }
+ Comm::SetSelect(conn->fd, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
- /*
- * Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'
- * and 'out' sockets might be just one FD. This prevents this
- * function from executing repeatedly. When we are really ready to
- * exit or restart, main will comm_close the 'out' descriptor.
- */
- theInSnmpConnection = -1;
-
- /*
- * Normally we only write to the outgoing SNMP socket, but we
- * also have a read handler there to catch messages sent to that
- * specific interface. During shutdown, we must disable reading
- * on the outgoing socket.
- */
- assert(theOutSnmpConnection > -1);
-
- commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
+ if (conn->fd == snmpIncomingConn->fd)
+ debugs(1, DBG_IMPORTANT, "Accepting SNMP messages on " << snmpIncomingConn->local);
+ else if (conn->fd == snmpOutgoingConn->fd)
+ debugs(1, DBG_IMPORTANT, "Sending SNMP messages from " << snmpOutgoingConn->local);
+ else
+ fatalf("Lost SNMP port (%d) on FD %d", (int)conn->local.port(), conn->fd);
}
void
-snmpConnectionClose(void)
+snmpClosePorts(void)
{
- snmpConnectionShutdown();
+ if (Comm::IsConnOpen(snmpIncomingConn)) {
+ debugs(49, DBG_IMPORTANT, "Closing SNMP receiving port " << snmpIncomingConn->local);
+ snmpIncomingConn->close();
+ }
+ snmpIncomingConn = NULL;
- if (theOutSnmpConnection > -1) {
- debugs(49, 1, "FD " << theOutSnmpConnection << " Closing SNMP socket");
- comm_close(theOutSnmpConnection);
- /* make sure the SNMP out connection is unset */
- theOutSnmpConnection = -1;
+ if (Comm::IsConnOpen(snmpOutgoingConn) && snmpIncomingConn != snmpOutgoingConn) {
+ // Perform OUT port closure so as not to step on IN port when sharing a conn.
+ debugs(49, DBG_IMPORTANT, "Closing SNMP sending port " << snmpOutgoingConn->local);
+ snmpOutgoingConn->close();
}
+ snmpOutgoingConn = NULL;
}
/*
* Accept the UDP packet
*/
void
-snmpHandleUdp(int sock, void *not_used)
+snmpHandleUdp(int sock, void *)
{
- LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
+ static char buf[SNMP_REQUEST_SIZE];
Ip::Address from;
- snmp_request_t *snmp_rq;
+ SnmpRequest *snmp_rq;
int len;
debugs(49, 5, "snmpHandleUdp: Called.");
- commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
+ Comm::SetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
- memset(buf, '\0', SNMP_REQUEST_SIZE);
+ memset(buf, '\0', sizeof(buf));
- len = comm_udp_recvfrom(sock,
- buf,
- SNMP_REQUEST_SIZE,
- 0,
- from);
+ len = comm_udp_recvfrom(sock, buf, sizeof(buf)-1, 0, from);
if (len > 0) {
- buf[len] = '\0';
debugs(49, 3, "snmpHandleUdp: FD " << sock << ": received " << len << " bytes from " << from << ".");
- snmp_rq = (snmp_request_t *)xcalloc(1, sizeof(snmp_request_t));
+ snmp_rq = (SnmpRequest *)xcalloc(1, sizeof(SnmpRequest));
snmp_rq->buf = (u_char *) buf;
snmp_rq->len = len;
snmp_rq->sock = sock;
xfree(snmp_rq->outbuf);
xfree(snmp_rq);
} else {
- debugs(49, 1, "snmpHandleUdp: FD " << sock << " recvfrom: " << xstrerror());
+ debugs(49, DBG_IMPORTANT, "snmpHandleUdp: FD " << sock << " recvfrom: " << xstrerror());
}
}
* Turn SNMP packet into a PDU, check available ACL's
*/
static void
-snmpDecodePacket(snmp_request_t * rq)
+snmpDecodePacket(SnmpRequest * rq)
{
struct snmp_pdu *PDU;
u_char *Community;
u_char *buf = rq->buf;
int len = rq->len;
- int allow = 0;
+ allow_t allow = ACCESS_DENIED;
+
+ if (!Config.accessList.snmp) {
+ debugs(49, DBG_IMPORTANT, "WARNING: snmp_access not configured. agent query DENIED from : " << rq->from);
+ return;
+ }
debugs(49, 5, HERE << "Called.");
PDU = snmp_pdu_create(0);
/* Check if we have explicit permission to access SNMP data.
* default (set above) is to deny all */
- if (Community && Config.accessList.snmp) {
+ if (Community) {
ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL);
checklist.src_addr = rq->from;
checklist.snmp_community = (char *) Community;
allow = checklist.fastCheck();
- }
- if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
- rq->community = Community;
- rq->PDU = PDU;
- debugs(49, 5, "snmpAgentParse: reqid=[" << PDU->reqid << "]");
- snmpConstructReponse(rq);
+ if (allow == ACCESS_ALLOWED && (snmp_coexist_V2toV1(PDU))) {
+ rq->community = Community;
+ rq->PDU = PDU;
+ debugs(49, 5, "snmpAgentParse: reqid=[" << PDU->reqid << "]");
+ snmpConstructReponse(rq);
+ } else {
+ debugs(49, DBG_IMPORTANT, "WARNING: SNMP agent query DENIED from : " << rq->from);
+ }
+ xfree(Community);
+
} else {
- debugs(49, 1, HERE << "Failed SNMP agent query from : " << rq->from);
+ debugs(49, DBG_IMPORTANT, "WARNING: Failed SNMP agent query from : " << rq->from);
snmp_free_pdu(PDU);
}
-
- if (Community)
- xfree(Community);
}
/*
* Packet OK, ACL Check OK, Create reponse.
*/
static void
-snmpConstructReponse(snmp_request_t * rq)
+snmpConstructReponse(SnmpRequest * rq)
{
struct snmp_pdu *RespPDU;
debugs(49, 5, "snmpConstructReponse: Called.");
+
+ if (UsingSmp() && IamWorkerProcess()) {
+ AsyncJob::Start(new Snmp::Forwarder(static_cast<Snmp::Pdu&>(*rq->PDU),
+ static_cast<Snmp::Session&>(rq->session), rq->sock, rq->from));
+ snmp_free_pdu(rq->PDU);
+ return;
+ }
+
RespPDU = snmpAgentResponse(rq->PDU);
snmp_free_pdu(rq->PDU);
* return the response to the requester.
*/
-static struct snmp_pdu *
+struct snmp_pdu *
snmpAgentResponse(struct snmp_pdu *PDU) {
struct snmp_pdu *Answer = NULL;
oid *NextOidName = NULL;
snint NextOidNameLen = 0;
- index++;
+ ++index;
if (get_next)
ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen);
mibTreeEntry = mib_tree_head;
if (Current[count] == mibTreeEntry->name[count]) {
- count++;
+ ++count;
while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
- count++;
+ ++count;
}
}
return (Fn);
}
+AggrType
+snmpAggrType(oid* Current, snint CurrentLen)
+{
+ debugs(49, 5, HERE);
+
+ mib_tree_entry* mibTreeEntry = mib_tree_head;
+ AggrType type = atNone;
+ int count = 0;
+
+ if (Current[count] == mibTreeEntry->name[count]) {
+ ++count;
+
+ while (mibTreeEntry != NULL && count < CurrentLen) {
+ mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
+ if (mibTreeEntry != NULL)
+ type = mibTreeEntry->aggrType;
+ ++count;
+ }
+ }
+
+ return type;
+}
+
static oid_ParseFn *
snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
{
oid_ParseFn *Fn = NULL;
- mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;
int count = 0;
debugs(49, 5, "snmpTreeNext: Called");
MemBuf tmp;
debugs(49, 6, "snmpTreeNext: Current : " << snmpDebugOid(Current, CurrentLen, tmp));
- mibTreeEntry = mib_tree_head;
+ mib_tree_entry *mibTreeEntry = mib_tree_head;
- if (Current[count] == mibTreeEntry->name[count]) {
- count++;
+ if (mibTreeEntry && Current[count] == mibTreeEntry->name[count]) {
+ ++count;
while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
mib_tree_entry *nextmibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
else
mibTreeEntry = nextmibTreeEntry;
- count++;
+ ++count;
}
debugs(49, 5, "snmpTreeNext: Recursed down to requested object");
} else {
if (mibTreeEntry == mib_tree_last)
return (Fn);
-
if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
*NextLen = CurrentLen;
*Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
if (*Next) {
- MemBuf tmp;
debugs(49, 6, "snmpTreeNext: Next : " << snmpDebugOid(*Next, *NextLen, tmp));
return (Fn);
}
}
if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
- count--;
- nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
+ --count;
+ mib_tree_entry *nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
if (nextoid) {
debugs(49, 5, "snmpTreeNext: Next OID found for sibling" << nextoid );
mibTreeEntry = nextoid;
- count++;
+ ++count;
} else {
debugs(49, 5, "snmpTreeNext: Attempting to recurse up for next object");
while (!nextoid) {
- count--;
+ --count;
if (mibTreeEntry->parent->parent) {
nextoid = mibTreeEntry->parent;
}
if (*Next) {
- MemBuf tmp;
debugs(49, 6, "snmpTreeNext: Next : " << snmpDebugOid(*Next, *NextLen, tmp));
return (Fn);
} else
{
oid *instance = NULL;
if (*len <= current->len) {
- instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
- xmemcpy(instance, name, (sizeof(name) * *len));
+ instance = (oid *)xmalloc(sizeof(*name) * (*len + 1));
+ memcpy(instance, name, sizeof(*name) * (*len));
instance[*len] = 0;
*len += 1;
}
int index[TIME_INDEX_LEN] = {TIME_INDEX};
if (*len <= current->len) {
- instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
- xmemcpy(instance, name, (sizeof(name) * *len));
+ instance = (oid *)xmalloc(sizeof(*name) * (*len + 1));
+ memcpy(instance, name, sizeof(*name) * (*len));
instance[*len] = *index;
*len += 1;
} else {
identifier = name[*len - 1];
while ((loop < TIME_INDEX_LEN) && (identifier != index[loop]))
- loop++;
+ ++loop;
if (loop < (TIME_INDEX_LEN - 1)) {
- instance = (oid *)xmalloc(sizeof(name) * (*len));
- xmemcpy(instance, name, (sizeof(name) * *len));
+ instance = (oid *)xmalloc(sizeof(*name) * (*len));
+ memcpy(instance, name, sizeof(*name) * (*len));
instance[*len - 1] = index[++loop];
}
}
return (instance);
}
-
static oid *
peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
{
oid *instance = NULL;
- peer *peers = Config.peers;
+ CachePeer *peers = Config.peers;
if (peers == NULL) {
debugs(49, 6, "snmp peer_Inst: No Peers.");
while ((current) && (!current->parsefunction))
current = current->leaves[0];
+ if (!current)
+ return (instance);
+
instance = client_Inst(current->name, len, current, Fn);
} else if (*len <= current->len) {
debugs(49, 6, "snmp peer_Inst: *len <= current->len ???");
- instance = (oid *)xmalloc(sizeof(name) * ( *len + 1));
- xmemcpy(instance, name, (sizeof(name) * *len));
+ instance = (oid *)xmalloc(sizeof(*name) * ( *len + 1));
+ memcpy(instance, name, sizeof(*name) * (*len));
instance[*len] = 1 ;
*len += 1;
} else {
int no = name[current->len] ;
int i;
// Note: This works because the Config.peers keeps its index according to its position.
- for ( i=0 ; peers && (i < no) ; peers = peers->next , i++ ) ;
+ for ( i=0 ; peers && (i < no) ; peers = peers->next , ++i ) ;
if (peers) {
debugs(49, 6, "snmp peer_Inst: Encode peer #" << i);
- instance = (oid *)xmalloc(sizeof(name) * (current->len + 1 ));
- xmemcpy(instance, name, (sizeof(name) * current->len ));
+ instance = (oid *)xmalloc(sizeof(*name) * (current->len + 1 ));
+ memcpy(instance, name, (sizeof(*name) * current->len ));
instance[current->len] = no + 1 ; // i.e. the next index on cache_peeer table.
} else {
debugs(49, 6, "snmp peer_Inst: We have " << i << " peers. Can't find #" << no);
if (aux)
laddr = *aux;
else
- laddr.SetAnyAddr();
+ laddr.setAnyAddr();
- if (laddr.IsIPv4())
+ if (laddr.isIPv4())
size = sizeof(in_addr);
-#if USE_IPV6
else
size = sizeof(in6_addr);
-#endif
debugs(49, 6, HERE << "len" << *len << ", current-len" << current->len << ", addr=" << laddr << ", size=" << size);
- instance = (oid *)xmalloc(sizeof(name) * (*len + size ));
- xmemcpy(instance, name, (sizeof(name) * (*len)));
+ instance = (oid *)xmalloc(sizeof(*name) * (*len + size ));
+ memcpy(instance, name, (sizeof(*name) * (*len)));
- if ( !laddr.IsAnyAddr() ) {
+ if ( !laddr.isAnyAddr() ) {
addr2oid(laddr, &instance[ *len]); // the addr
*len += size ;
}
if (aux)
laddr = *aux;
else
- laddr.SetAnyAddr();
+ laddr.setAnyAddr();
- if (!laddr.IsAnyAddr()) {
- if (laddr.IsIPv4())
+ if (!laddr.isAnyAddr()) {
+ if (laddr.isIPv4())
newshift = sizeof(in_addr);
-#if USE_IPV6
else
newshift = sizeof(in6_addr);
-#endif
debugs(49, 6, HERE << "len" << *len << ", current-len" << current->len << ", addr=" << laddr << ", newshift=" << newshift);
- instance = (oid *)xmalloc(sizeof(name) * (current->len + newshift));
- xmemcpy(instance, name, (sizeof(name) * (current->len)));
+ instance = (oid *)xmalloc(sizeof(*name) * (current->len + newshift));
+ memcpy(instance, name, (sizeof(*name) * (current->len)));
addr2oid(laddr, &instance[current->len]); // the addr.
*len = current->len + newshift ;
}
next = current->leaves[count];
}
- count++;
+ ++count;
}
/* Exactly the sibling on right */
next = current->leaves[count];
}
- count++;
+ ++count;
}
return (next);
entry->leaves = (mib_tree_entry **)xrealloc(entry->leaves, sizeof(mib_tree_entry *) * (entry->children + 1));
entry->leaves[entry->children] = child;
entry->leaves[entry->children]->parent = entry;
- entry->children++;
+ ++ entry->children;
}
mib_tree_entry *
}
int i, r = 1;
- while (r <= namelen) {
+ while (r < namelen) {
/* Find the child node which matches this */
- for (i = 0; i < e->children && e->leaves[i]->name[r] != name[r]; i++) ; // seek-loop
+ for (i = 0; i < e->children && e->leaves[i]->name[r] != name[r]; ++i) ; // seek-loop
/* Are we pointing to that node? */
if (i >= e->children)
/* Skip to that node! */
e = e->leaves[i];
- r++;
+ ++r;
}
xfree(name);
return e;
}
-int
+bool
snmpCreateOidFromStr(const char *str, oid **name, int *nl)
{
char const *delim = ".";
- char *p;
*name = NULL;
*nl = 0;
- char *s = xstrdup(str);
+ const char *s = str;
/* Parse the OID string into oid bits */
- while ( (p = strsep(&s, delim)) != NULL) {
+ while (size_t len = strcspn(s, delim)) {
*name = (oid*)xrealloc(*name, sizeof(oid) * ((*nl) + 1));
- (*name)[*nl] = atoi(p);
- (*nl)++;
+ (*name)[*nl] = atoi(s); // stops at the '.' delimiter
+ ++(*nl);
+ // exit with true when the last octet has been parsed
+ if (s[len] == '\0')
+ return true;
+ s += len+1;
}
- xfree(s);
- return 1;
+ // if we aborted before the lst octet was found, return false.
+ safe_free(name);
+ return false;
}
/*
* on failure.
*/
static mib_tree_entry *
-snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction)
+snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType)
{
mib_tree_entry *m, *b;
oid *n;
return NULL;
/* Create a node */
- m = snmpAddNode(n, nl, parsefunction, instancefunction, 0);
+ m = snmpAddNode(n, nl, parsefunction, instancefunction, aggrType, 0);
/* Link it into the existing tree */
snmpAddNodeChild(b, m);
return m;
}
-
/*
* Adds a node to the MIB tree structure and adds the appropriate children
*/
static mib_tree_entry *
-snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
+snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType, int children,...)
{
va_list args;
int loop;
entry->instancefunction = instancefunction;
entry->children = children;
entry->leaves = NULL;
+ entry->aggrType = aggrType;
if (children > 0) {
entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children);
- for (loop = 0; loop < children; loop++) {
+ for (loop = 0; loop < children; ++loop) {
entry->leaves[loop] = va_arg(args, mib_tree_entry *);
entry->leaves[loop]->parent = entry;
}
}
+ va_end(args);
return (entry);
}
/* End of tree utility functions */
new_oid = (oid *)xmalloc(sizeof(oid) * length);
if (length > 0) {
- for (loop = 0; loop < length; loop++) {
+ for (loop = 0; loop < length; ++loop) {
new_oid[loop] = va_arg(args, int);
}
}
+ va_end(args);
return (new_oid);
}
if (outbuf.isNull())
outbuf.init(16, MAX_IPSTRLEN);
- for (x = 0; x < Len; x++) {
+ for (x = 0; x < Len; ++x) {
size_t bytes = snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
outbuf.append(mbuf, bytes);
}
return outbuf.content();
}
-static void
+void
snmpSnmplibDebug(int lvl, char *buf)
{
debugs(49, lvl, buf);
}
-
-
/*
IPv4 address: 10.10.0.9 ==>
oid == 10.10.0.9
{
u_int i ;
u_char *cp = NULL;
- struct in_addr iaddr;
-#if USE_IPV6
+ struct in_addr i4addr;
struct in6_addr i6addr;
- oid code = addr.IsIPv6()? INETADDRESSTYPE_IPV6 : INETADDRESSTYPE_IPV4 ;
+ oid code = addr.isIPv6()? INETADDRESSTYPE_IPV6 : INETADDRESSTYPE_IPV4 ;
u_int size = (code == INETADDRESSTYPE_IPV4) ? sizeof(struct in_addr):sizeof(struct in6_addr);
-#else
- oid code = INETADDRESSTYPE_IPV4 ;
- u_int size = sizeof(struct in_addr) ;
-#endif /* USE_IPV6 */
// Dest[0] = code ;
if ( code == INETADDRESSTYPE_IPV4 ) {
- addr.GetInAddr(iaddr);
- cp = (u_char *) &(iaddr.s_addr);
- }
-#if USE_IPV6
- else {
- addr.GetInAddr(i6addr);
+ addr.getInAddr(i4addr);
+ cp = (u_char *) &(i4addr.s_addr);
+ } else {
+ addr.getInAddr(i6addr);
cp = (u_char *) &i6addr;
}
-#endif
- for ( i=0 ; i < size ; i++) {
+ for ( i=0 ; i < size ; ++i) {
// OID's are in network order
- Dest[i] = *cp++;
+ Dest[i] = *cp;
+ ++cp;
}
MemBuf tmp;
debugs(49, 7, "addr2oid: Dest : " << snmpDebugOid(Dest, size, tmp));
void
oid2addr(oid * id, Ip::Address &addr, u_int size)
{
- struct in_addr iaddr;
+ struct in_addr i4addr;
+ struct in6_addr i6addr;
u_int i;
u_char *cp;
-#if USE_IPV6
- struct in6_addr i6addr;
if ( size == sizeof(struct in_addr) )
-#endif /* USE_IPV6 */
- cp = (u_char *) &(iaddr.s_addr);
-#if USE_IPV6
+ cp = (u_char *) &(i4addr.s_addr);
else
cp = (u_char *) &(i6addr);
-#endif /* USE_IPV6 */
MemBuf tmp;
debugs(49, 7, "oid2addr: id : " << snmpDebugOid(id, size, tmp) );
- for (i=0 ; i<size; i++) {
+ for (i=0 ; i<size; ++i) {
cp[i] = id[i];
}
-#if USE_IPV6
if ( size == sizeof(struct in_addr) )
-#endif
- addr = iaddr;
-#if USE_IPV6
+ addr = i4addr;
else
addr = i6addr;
-#endif
-
}
/* SNMP checklists */
-#include "acl/Strategy.h"
#include "acl/Strategised.h"
+#include "acl/Strategy.h"
#include "acl/StringData.h"
class ACLSNMPCommunityStrategy : public ACLStrategy<char const *>
{
public:
- virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
+ virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
static ACLSNMPCommunityStrategy *Instance();
/* Not implemented to prevent copies of the instance. */
- /* Not private to prevent brain dead g+++ warnings about
+ /* Not private to prevent brain dead g++ warnings about
* private constructors with no friends */
ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &);
ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
int
-ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
+ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
{
return data->match (checklist->snmp_community);
}
}
ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_;
+