]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/snmp_core.cc
Merged from parent (trunk r10600).
[thirdparty/squid.git] / src / snmp_core.cc
index ce951aee15cdad39b976ebf4756dc86bedf54045..74dce91e7eecb08db832b4f246ebda3aae6ffc02 100644 (file)
@@ -1,7 +1,4 @@
-
 /*
- * $Id: snmp_core.cc,v 1.68 2005/06/09 16:04:30 serassio Exp $
- *
  * DEBUG: section 49    SNMP support
  * AUTHOR: Glenn Chisholm
  *
  *  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.
  *
  */
 #include "squid.h"
-#include "comm.h"
+#include "acl/FilledChecklist.h"
 #include "cache_snmp.h"
-#include "ACLChecklist.h"
+#include "comm.h"
+#include "ipc/StartListening.h"
+#include "compat/strsep.h"
+#include "ip/Address.h"
 
 #define SNMP_REQUEST_SIZE 4096
 #define MAX_PROTOSTAT 5
 
+/// dials snmpConnectionOpened call
+class SnmpListeningStartedDialer: public CallDialer,
+        public Ipc::StartListeningCb
+{
+public:
+    typedef void (*Handler)(int fd, int errNo);
+    SnmpListeningStartedDialer(Handler aHandler): handler(aHandler) {}
+
+    virtual void print(std::ostream &os) const { startPrint(os) << ')'; }
+
+    virtual bool canDial(AsyncCall &) const { return true; }
+    virtual void dial(AsyncCall &) { (handler)(fd, errNo); }
+
+public:
+    Handler handler;
+};
+
+
+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
-{
+struct _mib_tree_entry {
     oid *name;
     int len;
     oid_ParseFn *parsefunction;
@@ -59,13 +78,14 @@ struct _mib_tree_entry
 mib_tree_entry *mib_tree_head;
 mib_tree_entry *mib_tree_last;
 
-#if STDC_HEADERS
+static void snmpIncomingConnectionOpened(int fd, int errNo);
+static void snmpOutgoingConnectionOpened(int fd, int errNo);
+
+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,...);
 static oid *snmpCreateOid(int length,...);
-#else
-static mib_tree_entry *snmpAddNode();
-static oid *snmpCreateOid();
-#endif
+mib_tree_entry * snmpLookupNodeStr(mib_tree_entry *entry, const char *str);
+int 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);
@@ -81,7 +101,6 @@ static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * curr
 static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current);
 static void snmpSnmplibDebug(int lvl, char *buf);
 
-
 /*
  * The functions used during startup:
  * snmpInit
@@ -96,329 +115,270 @@ static void snmpSnmplibDebug(int lvl, char *buf);
 void
 snmpInit(void)
 {
-    debug(49, 5) ("snmpInit: Called.\n");
-
-    debug(49, 5) ("snmpInit: Building SNMP mib tree structure\n");
+    debugs(49, 5, "snmpInit: Building SNMP mib tree structure");
 
     snmplib_debug_hook = snmpSnmplibDebug;
 
-    mib_tree_head = snmpAddNode(snmpCreateOid(1, 1),
-                                1, NULL, NULL, 1,
-                                snmpAddNode(snmpCreateOid(2, 1, 3),
-                                            2, NULL, NULL, 1,
-                                            snmpAddNode(snmpCreateOid(3, 1, 3, 6),
-                                                        3, NULL, NULL, 1,
-                                                        snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1),
-                                                                    4, NULL, NULL, 1,
-                                                                    snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4),
-                                                                                5, NULL, NULL, 1,
-                                                                                snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1),
-                                                                                            6, NULL, NULL, 1,
-                                                                                            snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495),
-                                                                                                        7, NULL, NULL, 1,
-                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQUIDMIB, SQUIDMIB),
-                                                                                                                    8, NULL, NULL, 5,
-                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_SYS, SQ_SYS),
-                                                                                                                                LEN_SQ_SYS, NULL, NULL, 3,
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYSVMSIZ),
-                                                                                                                                            LEN_SYS, snmp_sysFn, static_Inst, 0),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYSSTOR),
-                                                                                                                                            LEN_SYS, snmp_sysFn, static_Inst, 0),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYS_UPTIME),
-                                                                                                                                            LEN_SYS, snmp_sysFn, static_Inst, 0)),
-                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_CONF, SQ_CONF),
-                                                                                                                                LEN_SQ_CONF, NULL, NULL, 5,
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_ADMIN),
-                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_VERSION),
-                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_VERSION_ID),
-                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_LOG_FAC),
-                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_STORAGE),
-                                                                                                                                            LEN_SYS, NULL, NULL, 4,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_MMAXSZ),
-                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWMAXSZ),
-                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWHIWM),
-                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWLOWM),
-                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0))),
-                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF, SQ_PRF),
-                                                                                                                                LEN_SQ_PRF, NULL, NULL, 2,
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_SYS),
-                                                                                                                                            LEN_SQ_PRF + 1, NULL, NULL, 11,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 1),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 2),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 3),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 4),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 5),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 6),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 7),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 8),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 9),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 10),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 11),
-                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0)),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_PROTO),
-                                                                                                                                            LEN_SQ_PRF + 1, NULL, NULL, 2,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 1),
-                                                                                                                                                        LEN_SQ_PRF + 2, NULL, NULL, 15,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 1),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 2),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 3),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 4),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 5),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 6),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 7),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 8),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 9),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 10),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 11),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 12),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 13),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 14),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 15),
-                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0)),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 2),
-                                                                                                                                                        LEN_SQ_PRF + 2, NULL, NULL, 1,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 2, 1),
-                                                                                                                                                                    LEN_SQ_PRF + 3, NULL, NULL, 10,
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 1),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 2),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 3),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 4),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 5),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 6),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 7),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 8),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 9),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 10),
-                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0))))),
-                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_NET, SQ_NET),
-                                                                                                                                LEN_SQ_NET, NULL, NULL, 3,
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_IP_CACHE),
-                                                                                                                                            LEN_SQ_NET + 1, NULL, NULL, 8,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_ENT),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_REQ),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_HITS),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_PENDHIT),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_NEGHIT),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_MISS),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_GHBN),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_LOC),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0)),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_FQDN_CACHE),
-                                                                                                                                            LEN_SQ_NET + 1, NULL, NULL, 7,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_ENT),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_REQ),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_HITS),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_PENDHIT),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_NEGHIT),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_MISS),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_GHBN),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0)),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_DNS_CACHE),
-                                                                                                                                            LEN_SQ_NET + 1, NULL, NULL, 3,
+    /*
+     * This following bit of evil is to get the final node in the "squid" mib
+     * 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);
+
+    assert(mib_tree_head);
+    debugs(49, 5, "snmpInit: root is " << mib_tree_head);
+    snmpAddNodeStr("1", 3, NULL, NULL);
+
+    snmpAddNodeStr("1.3", 6, NULL, NULL);
+
+    snmpAddNodeStr("1.3.6", 1, NULL, NULL);
+    snmpAddNodeStr("1.3.6.1", 4, NULL, NULL);
+    snmpAddNodeStr("1.3.6.1.4", 1, NULL, NULL);
+    snmpAddNodeStr("1.3.6.1.4.1", 3495, NULL, NULL);
+    mib_tree_entry *m2 = snmpAddNodeStr("1.3.6.1.4.1.3495", 1, NULL, NULL);
+
+    mib_tree_entry *n = snmpLookupNodeStr(NULL, "1.3.6.1.4.1.3495.1");
+    assert(m2 == n);
+
+    /* 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);
+
+    /* SQ_CONF - 1.3.6.1.4.1.3495.1.2 */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1", 2, NULL, NULL);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_ADMIN, snmp_confFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_VERSION, snmp_confFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_VERSION_ID, snmp_confFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_LOG_FAC, snmp_confFn, static_Inst);
+
+    /* 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", CONF_UNIQNAME, snmp_confFn, static_Inst);
+
+    /* SQ_PRF - 1.3.6.1.4.1.3495.1.3 */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1", 3, NULL, NULL);                    /* SQ_PRF */
+
+    /* 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_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);
+
+    /* 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);
+
+    /* Note this is time-series rather than 'static' */
+    /* cacheMedianSvcTable */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2", PERF_PROTOSTAT_MEDIAN, NULL, NULL);
+
+    /* 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);
+
+    /* 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", 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", NET_DNS_CACHE, NULL, NULL);
 #if USE_DNSSERVERS
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0))),
+    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
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
-                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0))),
+    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
-                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH),
-                                                                                                                                LEN_SQ_MESH, NULL, NULL, 2,
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 1),
-                                                                                                                                            LEN_SQ_MESH + 1, NULL, NULL, 1,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1),
-                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 13,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 1),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 2),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 3),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 4),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 5),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 6),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 7),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 8),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 9),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 10),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 11),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 12),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 13),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0))),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 2),
-                                                                                                                                            LEN_SQ_MESH + 1, NULL, NULL, 1,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 2, 1),
-                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 9,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 1),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 2),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 3),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 4),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 5),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 6),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 7),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 8),
-                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        (mib_tree_last = snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 9),
-                                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0)))))
-                                                                                                                   )
-                                                                                                       )
-                                                                                           )
-                                                                               )
-                                                                   )
-                                                       )
-                                           )
-                               );
-
-    debug(49, 9) ("snmpInit: Completed SNMP mib tree structure\n");
+
+    /* SQ_MESH - 1.3.6.1.4.1.3495.1.5 */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1", 5, NULL, NULL);
+
+    /* cachePeerTable - 1.3.6.1.4.1.3495.1.5.1 */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5", MESH_PTBL, NULL, NULL);
+
+    /* CachePeerTableEntry (version 3) - 1.3.6.1.4.1.3495.1.5.1.3 */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1", 3, NULL, NULL);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_INDEX, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_NAME, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_ADDR_TYPE, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_ADDR, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_HTTP, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_ICP, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_TYPE, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_STATE, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_SENT, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_PACKED, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_FETCHES, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_RTT, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_IGN, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_KEEPAL_S, snmp_meshPtblFn, peer_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.1.3", MESH_PTBL_KEEPAL_R, snmp_meshPtblFn, peer_Inst);
+
+    /* cacheClientTable - 1.3.6.1.4.1.3495.1.5.2 */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5", MESH_CTBL, NULL, NULL);
+
+    /* BUG 2811: we NEED to create a reliable index for the client DB and make version 3 of the table. */
+    /* for now we have version 2 table with OID capable of mixed IPv4 / IPv6 clients and upgraded address text format. */
+
+    /* cacheClientEntry - 1.3.6.1.4.1.3495.1.5.2.2 */
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2", 2, NULL, NULL);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_ADDR_TYPE, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_ADDR, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_HTREQ, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_HTBYTES, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_HTHITS, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_HTHITBYTES, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_ICPREQ, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_ICPBYTES, snmp_meshCtblFn, client_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_ICPHITS, snmp_meshCtblFn, client_Inst);
+    mib_tree_last = snmpAddNodeStr("1.3.6.1.4.1.3495.1.5.2.2", MESH_CTBL_ICPHITBYTES, snmp_meshCtblFn, client_Inst);
+
+    debugs(49, 9, "snmpInit: Completed SNMP mib tree structure");
 }
 
 void
 snmpConnectionOpen(void)
 {
-    u_short port;
+    debugs(49, 5, "snmpConnectionOpen: Called");
 
-    struct sockaddr_in xaddr;
-    socklen_t len;
-    int x;
+    if (Config.Port.snmp > 0) {
+        Config.Addrs.snmp_incoming.SetPort(Config.Port.snmp);
+
+        AsyncCall::Pointer call = asyncCall(49, 2,
+                                            "snmpIncomingConnectionOpened",
+                                            SnmpListeningStartedDialer(&snmpIncomingConnectionOpened));
+
+        Ipc::StartListening(SOCK_DGRAM,
+                            IPPROTO_UDP,
+                            Config.Addrs.snmp_incoming,
+                            COMM_NONBLOCKING,
+                            Ipc::fdnInSnmpSocket, call);
 
-    debug(49, 5) ("snmpConnectionOpen: Called\n");
+        if (!Config.Addrs.snmp_outgoing.IsNoAddr()) {
+            Config.Addrs.snmp_outgoing.SetPort(Config.Port.snmp);
 
-    if ((port = Config.Port.snmp) > (u_short) 0) {
-        enter_suid();
-        theInSnmpConnection = comm_open(SOCK_DGRAM,
-                                        IPPROTO_UDP,
-                                        Config.Addrs.snmp_incoming,
-                                        port,
-                                        COMM_NONBLOCKING,
-                                        "SNMP Port");
-        leave_suid();
+            AsyncCall::Pointer call = asyncCall(49, 2,
+                                                "snmpOutgoingConnectionOpened",
+                                                SnmpListeningStartedDialer(&snmpOutgoingConnectionOpened));
 
-        if (theInSnmpConnection < 0)
-            fatal("Cannot open snmp Port");
+            Ipc::StartListening(SOCK_DGRAM,
+                                IPPROTO_UDP,
+                                Config.Addrs.snmp_outgoing,
+                                COMM_NONBLOCKING,
+                                Ipc::fdnOutSnmpSocket, call);
+        }
+    }
+}
+
+static void
+snmpIncomingConnectionOpened(int fd, int errNo)
+{
+    theInSnmpConnection = fd;
+    if (theInSnmpConnection < 0)
+        fatal("Cannot open Incoming SNMP Port");
 
-        commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
+    commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL,
+                  0);
 
-        debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",
-                     (int) port, theInSnmpConnection);
+    debugs(1, 1, "Accepting SNMP messages on " << Config.Addrs.snmp_incoming <<
+           ", FD " << theInSnmpConnection << ".");
 
-        if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) {
-            enter_suid();
-            theOutSnmpConnection = comm_open(SOCK_DGRAM,
-                                             IPPROTO_UDP,
-                                             Config.Addrs.snmp_outgoing,
-                                             port,
-                                             COMM_NONBLOCKING,
-                                             "SNMP Port");
-            leave_suid();
+    if (Config.Addrs.snmp_outgoing.IsNoAddr())
+        theOutSnmpConnection = theInSnmpConnection;
+}
 
-            if (theOutSnmpConnection < 0)
-                fatal("Cannot open Outgoing SNMP Port");
+static void
+snmpOutgoingConnectionOpened(int fd, int errNo)
+{
+    theOutSnmpConnection = fd;
+    if (theOutSnmpConnection < 0)
+        fatal("Cannot open Outgoing SNMP Port");
 
-            commSetSelect(theOutSnmpConnection,
-                          COMM_SELECT_READ,
-                          snmpHandleUdp,
-                          NULL, 0);
+    commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL,
+                  0);
 
-            debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",
-                         (int) port, theOutSnmpConnection);
+    debugs(1, 1, "Outgoing SNMP messages on " << Config.Addrs.snmp_outgoing <<
+           ", FD " << theOutSnmpConnection << ".");
 
-            fd_note(theOutSnmpConnection, "Outgoing SNMP socket");
+    {
+        struct addrinfo *xaddr = NULL;
+        int x;
 
-            fd_note(theInSnmpConnection, "Incoming SNMP socket");
-        } else {
-            theOutSnmpConnection = theInSnmpConnection;
-        }
 
-        memset(&theOutSNMPAddr, '\0', sizeof(struct IN_ADDR));
+        theOutSNMPAddr.SetEmpty();
 
-        len = sizeof(struct sockaddr_in);
-        memset(&xaddr, '\0', len);
-        x = getsockname(theOutSnmpConnection,
+        theOutSNMPAddr.InitAddrInfo(xaddr);
 
-                        (struct sockaddr *) &xaddr, &len);
+        x = getsockname(theOutSnmpConnection, xaddr->ai_addr, &xaddr->ai_addrlen);
 
         if (x < 0)
-            debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n",
-                          theOutSnmpConnection, xstrerror());
+            debugs(51, 1, "theOutSnmpConnection FD " << theOutSnmpConnection << ": getsockname: " << xstrerror());
         else
-            theOutSNMPAddr = xaddr.sin_addr;
+            theOutSNMPAddr = *xaddr;
+
+        theOutSNMPAddr.FreeAddrInfo(xaddr);
     }
 }
 
@@ -429,7 +389,7 @@ snmpConnectionShutdown(void)
         return;
 
     if (theInSnmpConnection != theOutSnmpConnection) {
-        debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection);
+        debugs(49, 1, "FD " << theInSnmpConnection << " Closing SNMP socket");
         comm_close(theInSnmpConnection);
     }
 
@@ -438,7 +398,8 @@ snmpConnectionShutdown(void)
      * 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;
+     */
+    theInSnmpConnection = -1;
 
     /*
      * Normally we only write to the outgoing SNMP socket, but we
@@ -457,8 +418,10 @@ snmpConnectionClose(void)
     snmpConnectionShutdown();
 
     if (theOutSnmpConnection > -1) {
-        debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection);
+        debugs(49, 1, "FD " << theOutSnmpConnection << " Closing SNMP socket");
         comm_close(theOutSnmpConnection);
+        /* make sure the SNMP out connection is unset */
+        theOutSnmpConnection = -1;
     }
 }
 
@@ -473,47 +436,37 @@ void
 snmpHandleUdp(int sock, void *not_used)
 {
     LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
-
-    struct sockaddr_in from;
-    socklen_t from_len;
+    Ip::Address from;
     snmp_request_t *snmp_rq;
     int len;
 
-    debug(49, 5) ("snmpHandleUdp: Called.\n");
+    debugs(49, 5, "snmpHandleUdp: Called.");
 
     commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
-    from_len = sizeof(struct sockaddr_in);
-    memset(&from, '\0', from_len);
     memset(buf, '\0', SNMP_REQUEST_SIZE);
 
     len = comm_udp_recvfrom(sock,
                             buf,
                             SNMP_REQUEST_SIZE,
                             0,
-
-                            (struct sockaddr *) &from,
-                            &from_len);
+                            from);
 
     if (len > 0) {
         buf[len] = '\0';
-        debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
-                      sock,
-                      len,
-                      inet_ntoa(from.sin_addr));
+        debugs(49, 3, "snmpHandleUdp: FD " << sock << ": received " << len << " bytes from " << from << ".");
 
         snmp_rq = (snmp_request_t *)xcalloc(1, sizeof(snmp_request_t));
         snmp_rq->buf = (u_char *) buf;
         snmp_rq->len = len;
         snmp_rq->sock = sock;
         snmp_rq->outbuf = (unsigned char *)xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);
-
-        xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));
+        snmp_rq->from = from;
         snmpDecodePacket(snmp_rq);
         xfree(snmp_rq->outbuf);
         xfree(snmp_rq);
     } else {
-        debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror());
+        debugs(49, 1, "snmpHandleUdp: FD " << sock << " recvfrom: " << xstrerror());
     }
 }
 
@@ -523,37 +476,34 @@ snmpHandleUdp(int sock, void *not_used)
 static void
 snmpDecodePacket(snmp_request_t * rq)
 {
-
     struct snmp_pdu *PDU;
-
     u_char *Community;
     u_char *buf = rq->buf;
     int len = rq->len;
     int allow = 0;
 
-    debug(49, 5) ("snmpDecodePacket: Called.\n");
-    /* Now that we have the data, turn it into a PDU */
+    debugs(49, 5, HERE << "Called.");
     PDU = snmp_pdu_create(0);
+    /* Allways answer on SNMPv1 */
     rq->session.Version = SNMP_VERSION_1;
     Community = snmp_parse(&rq->session, PDU, buf, len);
-    ACLChecklist checklist;
-    checklist.src_addr = rq->from.sin_addr;
-    checklist.snmp_community = (char *) Community;
 
-    if (Community) {
-        checklist.accessList = cbdataReference(Config.accessList.snmp);
+    /* Check if we have explicit permission to access SNMP data.
+     * default (set above) is to deny all */
+    if (Community && Config.accessList.snmp) {
+        ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL);
+        checklist.src_addr = rq->from;
+        checklist.snmp_community = (char *) Community;
         allow = checklist.fastCheck();
-        checklist.accessList = NULL;
     }
 
     if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
         rq->community = Community;
         rq->PDU = PDU;
-        debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid);
+        debugs(49, 5, "snmpAgentParse: reqid=[" << PDU->reqid << "]");
         snmpConstructReponse(rq);
     } else {
-        debug(49, 1) ("Failed SNMP agent query from : %s.\n",
-                      inet_ntoa(rq->from.sin_addr));
+        debugs(49, 1, HERE << "Failed SNMP agent query from : " << rq->from);
         snmp_free_pdu(PDU);
     }
 
@@ -570,13 +520,13 @@ snmpConstructReponse(snmp_request_t * rq)
 
     struct snmp_pdu *RespPDU;
 
-    debug(49, 5) ("snmpConstructReponse: Called.\n");
+    debugs(49, 5, "snmpConstructReponse: Called.");
     RespPDU = snmpAgentResponse(rq->PDU);
     snmp_free_pdu(rq->PDU);
 
     if (RespPDU != NULL) {
         snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen);
-        comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen);
+        comm_udp_sendto(rq->sock, rq->from, rq->outbuf, rq->outlen);
         snmp_free_pdu(RespPDU);
     }
 }
@@ -587,20 +537,18 @@ snmpConstructReponse(snmp_request_t * rq)
  */
 
 static struct snmp_pdu *
-
-            snmpAgentResponse(struct snmp_pdu *PDU)
-{
+snmpAgentResponse(struct snmp_pdu *PDU) {
 
     struct snmp_pdu *Answer = NULL;
 
-    debug(49, 5) ("snmpAgentResponse: Called.\n");
+    debugs(49, 5, "snmpAgentResponse: Called.");
 
-    if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE)))
-    {
+    if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE))) {
         Answer->reqid = PDU->reqid;
         Answer->errindex = 0;
 
         if (PDU->command == SNMP_PDU_GET || PDU->command == SNMP_PDU_GETNEXT) {
+            /* Indirect way */
             int get_next = (PDU->command == SNMP_PDU_GETNEXT);
             variable_list *VarPtr_;
             variable_list **RespVars = &(Answer->variables);
@@ -616,8 +564,6 @@ static struct snmp_pdu *
 
                 index++;
 
-                /* Find the parsing function for this variable */
-
                 if (get_next)
                     ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen);
                 else
@@ -625,28 +571,28 @@ static struct snmp_pdu *
 
                 if (ParseFn == NULL) {
                     Answer->errstat = SNMP_ERR_NOSUCHNAME;
-                    debug(49, 5) ("snmpAgentResponse: No such oid. ");
+                    debugs(49, 5, "snmpAgentResponse: No such oid. ");
                 } else {
                     if (get_next) {
                         VarPtr = snmp_var_new(NextOidName, NextOidNameLen);
                         xfree(NextOidName);
                     }
 
-                    VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat));
+                    int * errstatTmp =  &(Answer->errstat);
+
+                    VarNew = (*ParseFn) (VarPtr, (snint *) errstatTmp);
 
                     if (get_next)
                         snmp_var_free(VarPtr);
                 }
 
-                /* Was there an error? */
                 if ((Answer->errstat != SNMP_ERR_NOERROR) || (VarNew == NULL)) {
                     Answer->errindex = index;
-                    debug(49, 5) ("snmpAgentResponse: error.\n");
+                    debugs(49, 5, "snmpAgentResponse: error.");
 
                     if (VarNew)
                         snmp_var_free(VarNew);
 
-                    /* Free the already processed results, if any */
                     while ((VarPtr = Answer->variables) != NULL) {
                         Answer->variables = VarPtr->next_variable;
                         snmp_var_free(VarPtr);
@@ -679,10 +625,10 @@ snmpTreeGet(oid * Current, snint CurrentLen)
     mib_tree_entry *mibTreeEntry = NULL;
     int count = 0;
 
-    debug(49, 5) ("snmpTreeGet: Called\n");
+    debugs(49, 5, "snmpTreeGet: Called");
 
-    debug(49, 6) ("snmpTreeGet: Current : \n");
-    snmpDebugOid(6, Current, CurrentLen);
+    MemBuf tmp;
+    debugs(49, 6, "snmpTreeGet: Current : " << snmpDebugOid(Current, CurrentLen, tmp) );
 
     mibTreeEntry = mib_tree_head;
 
@@ -698,7 +644,7 @@ snmpTreeGet(oid * Current, snint CurrentLen)
     if (mibTreeEntry && mibTreeEntry->parsefunction)
         Fn = mibTreeEntry->parsefunction;
 
-    debug(49, 5) ("snmpTreeGet: return\n");
+    debugs(49, 5, "snmpTreeGet: return");
 
     return (Fn);
 }
@@ -710,10 +656,10 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
     mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;
     int count = 0;
 
-    debug(49, 5) ("snmpTreeNext: Called\n");
+    debugs(49, 5, "snmpTreeNext: Called");
 
-    debug(49, 6) ("snmpTreeNext: Current : \n");
-    snmpDebugOid(6, Current, CurrentLen);
+    MemBuf tmp;
+    debugs(49, 6, "snmpTreeNext: Current : " << snmpDebugOid(Current, CurrentLen, tmp));
 
     mibTreeEntry = mib_tree_head;
 
@@ -721,11 +667,16 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
         count++;
 
         while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
-            mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
+            mib_tree_entry *nextmibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
+
+            if (!nextmibTreeEntry)
+                break;
+            else
+                mibTreeEntry = nextmibTreeEntry;
+
             count++;
         }
-
-        debug(49, 5) ("snmpTreeNext: Recursed down to requested object\n");
+        debugs(49, 5, "snmpTreeNext: Recursed down to requested object");
     } else {
         return NULL;
     }
@@ -733,24 +684,26 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
     if (mibTreeEntry == mib_tree_last)
         return (Fn);
 
+
     if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
         *NextLen = CurrentLen;
         *Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
-
-        if (*Next)
+        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);
-
         if (nextoid) {
-            debug(49, 5) ("snmpTreeNext: Next OID found for sibling\n");
+            debugs(49, 5, "snmpTreeNext: Next OID found for sibling" << nextoid );
             mibTreeEntry = nextoid;
             count++;
         } else {
-            debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next object\n");
+            debugs(49, 5, "snmpTreeNext: Attempting to recurse up for next object");
 
             while (!nextoid) {
                 count--;
@@ -770,7 +723,6 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
             }
         }
     }
-
     while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) {
         mibTreeEntry = mibTreeEntry->leaves[0];
     }
@@ -780,9 +732,11 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
         *Next = (*mibTreeEntry->instancefunction) (mibTreeEntry->name, NextLen, mibTreeEntry, &Fn);
     }
 
-    if (*Next)
+    if (*Next) {
+        MemBuf tmp;
+        debugs(49, 6, "snmpTreeNext: Next : " << snmpDebugOid(*Next, *NextLen, tmp));
         return (Fn);
-    else
+    else
         return NULL;
 }
 
@@ -790,14 +744,12 @@ static oid *
 static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
-
     if (*len <= current->len) {
         instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
         xmemcpy(instance, name, (sizeof(name) * *len));
         instance[*len] = 0;
         *len += 1;
     }
-
     *Fn = current->parsefunction;
     return (instance);
 }
@@ -807,8 +759,7 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
     int identifier = 0, loop = 0;
-    int index[TIME_INDEX_LEN] =
-        {TIME_INDEX};
+    int index[TIME_INDEX_LEN] = {TIME_INDEX};
 
     if (*len <= current->len) {
         instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
@@ -818,10 +769,10 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
     } else {
         identifier = name[*len - 1];
 
-        while ((identifier != index[loop]) && (loop < TIME_INDEX_LEN))
+        while ((loop < TIME_INDEX_LEN) && (identifier != index[loop]))
             loop++;
 
-        if (loop < TIME_INDEX_LEN - 1) {
+        if (loop < (TIME_INDEX_LEN - 1)) {
             instance = (oid *)xmalloc(sizeof(name) * (*len));
             xmemcpy(instance, name, (sizeof(name) * *len));
             instance[*len - 1] = index[++loop];
@@ -832,68 +783,42 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
     return (instance);
 }
 
+
 static oid *
 peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
-    u_char *cp = NULL;
     peer *peers = Config.peers;
 
-    struct IN_ADDR *laddr = NULL;
-    char *host_addr = NULL, *current_addr = NULL, *last_addr = NULL;
-
     if (peers == NULL) {
+        debugs(49, 6, "snmp peer_Inst: No Peers.");
         current = current->parent->parent->parent->leaves[1];
-
         while ((current) && (!current->parsefunction))
             current = current->leaves[0];
 
         instance = client_Inst(current->name, len, current, Fn);
     } else if (*len <= current->len) {
-        instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
+        debugs(49, 6, "snmp peer_Inst: *len <= current->len ???");
+        instance = (oid *)xmalloc(sizeof(name) * ( *len + 1));
         xmemcpy(instance, name, (sizeof(name) * *len));
-        cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
-        instance[*len] = *cp++;
-        instance[*len + 1] = *cp++;
-        instance[*len + 2] = *cp++;
-        instance[*len + 3] = *cp++;
-        *len += 4;
+        instance[*len] = 1 ;
+        *len += 1;
     } else {
-        laddr = oid2addr(&name[*len - 4]);
-        host_addr = inet_ntoa(*laddr);
-        last_addr = (char *)xmalloc(strlen(host_addr));
-        strncpy(last_addr, host_addr, strlen(host_addr));
-        current_addr = inet_ntoa(peers->in_addr.sin_addr);
-
-        while ((peers) && (strncmp(last_addr, current_addr, strlen(current_addr)))) {
-            if (peers->next) {
-                peers = peers->next;
-                current_addr = inet_ntoa(peers->in_addr.sin_addr);
-            } else {
-                peers = NULL;
-            }
-        }
-
-        xfree(last_addr);
+        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++ ) ;
 
         if (peers) {
-            if (peers->next) {
-                peers = peers->next;
-                instance = (oid *)xmalloc(sizeof(name) * (*len));
-                xmemcpy(instance, name, (sizeof(name) * *len));
-                cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
-                instance[*len - 4] = *cp++;
-                instance[*len - 3] = *cp++;
-                instance[*len - 2] = *cp++;
-                instance[*len - 1] = *cp++;
-            } else {
-                return (instance);
-            }
+            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[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);
             return (instance);
         }
     }
-
     *Fn = current->parsefunction;
     return (instance);
 }
@@ -902,35 +827,57 @@ static oid *
 client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
-    u_char *cp = NULL;
-
-    struct IN_ADDR *laddr = NULL;
+    Ip::Address laddr;
+    Ip::Address *aux;
+    int size = 0;
+    int newshift = 0;
 
     if (*len <= current->len) {
-        instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
-        xmemcpy(instance, name, (sizeof(name) * *len));
-        laddr = client_entry(NULL);
-
-        if (laddr) {
-            cp = (u_char *) & (laddr->s_addr);
-            instance[*len] = *cp++;
-            instance[*len + 1] = *cp++;
-            instance[*len + 2] = *cp++;
-            instance[*len + 3] = *cp++;
-            *len += 4;
+        aux  = client_entry(NULL);
+        if (aux)
+            laddr = *aux;
+        else
+            laddr.SetAnyAddr();
+
+        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)));
+
+        if ( !laddr.IsAnyAddr() ) {
+            addr2oid(laddr, &instance[ *len]);  // the addr
+            *len += size ;
         }
     } else {
-        laddr = oid2addr(&name[*len - 4]);
-        laddr = client_entry(laddr);
+        int shift = *len - current->len ; // i.e 4 or 16
+        oid2addr(&name[*len - shift], laddr,shift);
+        aux = client_entry(&laddr);
+        if (aux)
+            laddr = *aux;
+        else
+            laddr.SetAnyAddr();
+
+        if (!laddr.IsAnyAddr()) {
+            if (laddr.IsIPv4())
+                newshift = sizeof(in_addr);
+#if USE_IPV6
+            else
+                newshift = sizeof(in6_addr);
+#endif
 
-        if (laddr) {
-            instance = (oid *)xmalloc(sizeof(name) * (*len));
-            xmemcpy(instance, name, (sizeof(name) * *len));
-            cp = (u_char *) & (laddr->s_addr);
-            instance[*len - 4] = *cp++;
-            instance[*len - 3] = *cp++;
-            instance[*len - 2] = *cp++;
-            instance[*len - 1] = *cp++;
+            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)));
+            addr2oid(laddr, &instance[current->len]);  // the addr.
+            *len = current->len + newshift ;
         }
     }
 
@@ -938,17 +885,17 @@ client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn
     return (instance);
 }
 
-
 /*
  * Utility functions
  */
 
 /*
- * Tree utility functions. 
+ * Tree utility functions.
  */
 
 /*
- * Returns a the sibling object in the tree
+ * Returns a sibling object for the requested child object or NULL
+ * if it does not exit
  */
 static mib_tree_entry *
 snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
@@ -964,6 +911,7 @@ snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
         count++;
     }
 
+    /* Exactly the sibling on right */
     if (count < current->children) {
         next = current->leaves[count];
     } else {
@@ -982,7 +930,7 @@ snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
     mib_tree_entry *next = NULL;
     int count = 0;
 
-    while ((!next) && (count < current->children)) {
+    while ((!next) && current && (count < current->children)) {
         if (current->leaves[count]->name[len] == entry) {
             next = current->leaves[count];
         }
@@ -993,40 +941,127 @@ snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
     return (next);
 }
 
+void
+snmpAddNodeChild(mib_tree_entry *entry, mib_tree_entry *child)
+{
+    debugs(49, 5, "snmpAddNodeChild: assigning " << child << " to parent " << entry);
+    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++;
+}
+
+mib_tree_entry *
+snmpLookupNodeStr(mib_tree_entry *root, const char *str)
+{
+    oid *name;
+    int namelen;
+    mib_tree_entry *e;
+
+    if (root)
+        e = root;
+    else
+        e = mib_tree_head;
+
+    if (! snmpCreateOidFromStr(str, &name, &namelen))
+        return NULL;
+
+    /* I wish there were some kind of sensible existing tree traversal
+     * routine to use. I'll worry about that later */
+    if (namelen <= 1) {
+        xfree(name);
+        return e;       /* XXX it should only be this? */
+    }
+
+    int i, r = 1;
+    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
+
+        /* Are we pointing to that node? */
+        if (i >= e->children)
+            break;
+        assert(e->leaves[i]->name[r] == name[r]);
+
+        /* Skip to that node! */
+        e = e->leaves[i];
+        r++;
+    }
+
+    xfree(name);
+    return e;
+}
+
+int
+snmpCreateOidFromStr(const char *str, oid **name, int *nl)
+{
+    char const *delim = ".";
+    char *p;
+
+    *name = NULL;
+    *nl = 0;
+    char *s = xstrdup(str);
+    char *s_ = s;
+
+    /* Parse the OID string into oid bits */
+    while ( (p = strsep(&s_, delim)) != NULL) {
+        *name = (oid*)xrealloc(*name, sizeof(oid) * ((*nl) + 1));
+        (*name)[*nl] = atoi(p);
+        (*nl)++;
+    }
+
+    xfree(s);
+    return 1;
+}
+
+/*
+ * Create an entry. Return a pointer to the newly created node, or NULL
+ * on failure.
+ */
+static mib_tree_entry *
+snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction)
+{
+    mib_tree_entry *m, *b;
+    oid *n;
+    int nl;
+    char s[1024];
+
+    /* Find base node */
+    b = snmpLookupNodeStr(mib_tree_head, base_str);
+    if (! b)
+        return NULL;
+    debugs(49, 5, "snmpAddNodeStr: " << base_str << ": -> " << b);
+
+    /* Create OID string for new entry */
+    snprintf(s, 1024, "%s.%d", base_str, o);
+    if (! snmpCreateOidFromStr(s, &n, &nl))
+        return NULL;
+
+    /* Create a node */
+    m = snmpAddNode(n, nl, parsefunction, instancefunction, 0);
+
+    /* Link it into the existing tree */
+    snmpAddNodeChild(b, m);
+
+    /* Return the node */
+    return m;
+}
+
+
 /*
  * Adds a node to the MIB tree structure and adds the appropriate children
  */
 static mib_tree_entry *
-#if STDC_HEADERS
 snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
-#else
-snmpAddNode(va_alist)
-va_dcl
-#endif
 {
-#if STDC_HEADERS
     va_list args;
     int loop;
     mib_tree_entry *entry = NULL;
     va_start(args, children);
-#else
-
-    va_list args;
-    oid *name = NULL;
-    int len = 0, children = 0, loop;
-    oid_ParseFn *parsefunction = NULL;
-    instance_Fn *instancefunction = NULL;
-    mib_tree_entry *entry = NULL;
-    va_start(args);
-    name = va_arg(args, oid *);
-    len = va_arg(args, int);
-    parsefunction = va_arg(args, oid_ParseFn *);
-    instancefunction = va_arg(args, instance_Fn *);
-    children = va_arg(args, int);
-#endif
 
-    debug(49, 6) ("snmpAddNode: Children : %d, Oid : \n", children);
-    snmpDebugOid(6, name, len);
+    MemBuf tmp;
+    debugs(49, 6, "snmpAddNode: Children : " << children << ", Oid : " << snmpDebugOid(name, len, tmp));
 
     va_start(args, children);
     entry = (mib_tree_entry *)xmalloc(sizeof(mib_tree_entry));
@@ -1035,9 +1070,9 @@ va_dcl
     entry->parsefunction = parsefunction;
     entry->instancefunction = instancefunction;
     entry->children = children;
+    entry->leaves = NULL;
 
-    if (children > 0)
-    {
+    if (children > 0) {
         entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children);
 
         for (loop = 0; loop < children; loop++) {
@@ -1054,31 +1089,16 @@ va_dcl
  * Returns the list of parameters in an oid
  */
 static oid *
-#if STDC_HEADERS
 snmpCreateOid(int length,...)
-#else
-snmpCreateOid(va_alist)
-va_dcl
-#endif
 {
-#if STDC_HEADERS
     va_list args;
     oid *new_oid;
     int loop;
     va_start(args, length);
-#else
-
-    va_list args;
-    int length = 0, loop;
-    oid *new_oid;
-    va_start(args);
-    length va_arg(args, int);
-#endif
 
     new_oid = (oid *)xmalloc(sizeof(oid) * length);
 
-    if (length > 0)
-    {
+    if (length > 0) {
         for (loop = 0; loop < length; loop++) {
             new_oid[loop] = va_arg(args, int);
         }
@@ -1087,80 +1107,118 @@ va_dcl
     return (new_oid);
 }
 
-#if UNUSED_CODE
-/*
- * Allocate space for, and copy, an OID.  Returns new oid.
- */
-static oid *
-snmpOidDup(oid * A, snint ALen)
-{
-    oid *Ans = xmalloc(sizeof(oid) * ALen);
-    xmemcpy(Ans, A, (sizeof(oid) * ALen));
-    return Ans;
-}
-
-#endif
-
 /*
  * Debug calls, prints out the OID for debugging purposes.
  */
-void
-snmpDebugOid(int lvl, oid * Name, snint Len)
+const char *
+snmpDebugOid(oid * Name, snint Len, MemBuf &outbuf)
 {
-    char mbuf[16], objid[1024];
+    char mbuf[16];
     int x;
-    objid[0] = '\0';
+    if (outbuf.isNull())
+        outbuf.init(16, MAX_IPSTRLEN);
 
     for (x = 0; x < Len; x++) {
-        snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
-        strncat(objid, mbuf, sizeof(objid));
+        size_t bytes = snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
+        outbuf.append(mbuf, bytes);
     }
-
-    debug(49, lvl) ("   oid = %s\n", objid);
+    return outbuf.content();
 }
 
 static void
 snmpSnmplibDebug(int lvl, char *buf)
 {
-    debug(49, lvl) ("%s", buf);
+    debugs(49, lvl, buf);
 }
 
-void
 
-addr2oid(struct IN_ADDR addr, oid * Dest)
+
+/*
+   IPv4 address: 10.10.0.9  ==>
+   oid == 10.10.0.9
+   IPv6 adress : 20:01:32:ef:a2:21:fb:32:00:00:00:00:00:00:00:00:OO:01 ==>
+   oid == 32.1.50.239.162.33.251.20.50.0.0.0.0.0.0.0.0.0.1
+*/
+void
+addr2oid(Ip::Address &addr, oid * Dest)
 {
-    u_char *cp;
-    cp = (u_char *) & (addr.s_addr);
-    Dest[0] = *cp++;
-    Dest[1] = *cp++;
-    Dest[2] = *cp++;
-    Dest[3] = *cp++;
+    u_int i ;
+    u_char *cp = NULL;
+    struct in_addr iaddr;
+#if USE_IPV6
+    struct in6_addr i6addr;
+    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);
+        cp = (u_char *) &i6addr;
+    }
+#endif
+    for ( i=0 ; i < size ; i++) {
+        // OID's are in network order
+        Dest[i] = *cp++;
+    }
+    MemBuf tmp;
+    debugs(49, 7, "addr2oid: Dest : " << snmpDebugOid(Dest, size, tmp));
 }
 
-struct IN_ADDR
-            *
-            oid2addr(oid * id)
+/*
+   oid == 10.10.0.9 ==>
+   IPv4 address: 10.10.0.9
+   oid == 32.1.50.239.162.33.251.20.50.0.0.0.0.0.0.0.0.0.1 ==>
+   IPv6 adress : 20:01:32:ef:a2:21:fb:32:00:00:00:00:00:00:00:00:OO:01
+*/
+void
+oid2addr(oid * id, Ip::Address &addr, u_int size)
 {
+    struct in_addr iaddr;
+    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
+    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++) {
+        cp[i] = id[i];
+    }
+#if USE_IPV6
+    if ( size == sizeof(struct in_addr) )
+#endif
+        addr = iaddr;
+#if USE_IPV6
+    else
+        addr = i6addr;
+#endif
 
-    static struct IN_ADDR laddr;
-    u_char *cp = (u_char *) & (laddr.s_addr);
-    cp[0] = id[0];
-    cp[1] = id[1];
-    cp[2] = id[2];
-    cp[3] = id[3];
-    return &laddr;
 }
 
 /* SNMP checklists */
-#include "ACLStrategy.h"
-#include "ACLStrategised.h"
-#include "ACLStringData.h"
+#include "acl/Strategy.h"
+#include "acl/Strategised.h"
+#include "acl/StringData.h"
 
 class ACLSNMPCommunityStrategy : public ACLStrategy<char const *>
 {
 
 public:
-    virtual int match (ACLData<MatchType> * &, ACLChecklist *);
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *);
     static ACLSNMPCommunityStrategy *Instance();
     /* Not implemented to prevent copies of the instance. */
     /* Not private to prevent brain dead g+++ warnings about
@@ -1169,7 +1227,7 @@ public:
 
 private:
     static ACLSNMPCommunityStrategy Instance_;
-    ACLSNMPCommunityStrategy(){}
+    ACLSNMPCommunityStrategy() {}
 
     ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &);
 };
@@ -1186,10 +1244,9 @@ ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEnt
 ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
 
 int
-ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
+ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist)
 {
     return data->match (checklist->snmp_community);
-    ;
 }
 
 ACLSNMPCommunityStrategy *