From dba79ac56de7e563b80a5cac8678ee41ffa0d4a6 Mon Sep 17 00:00:00 2001 From: glenn <> Date: Thu, 12 Nov 1998 03:04:09 +0000 Subject: [PATCH] Squid SNMP code rewrite --- src/Makefile.in | 7 +- src/acl.cc | 60 +- src/cache_cf.cc | 76 +-- src/cf.data.pre | 89 +-- src/cf_gen.cc | 6 +- src/client_side.cc | 3 +- src/enums.h | 4 +- src/main.cc | 3 +- src/protos.h | 22 +- src/snmp_agent.cc | 10 +- src/snmp_core.cc | 1353 ++++++++++++++++++++++---------------------- src/structs.h | 47 +- src/typedefs.h | 6 +- 13 files changed, 758 insertions(+), 928 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index 77780e4f08..fb73603309 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.161 1998/10/10 14:57:36 wessels Exp $ +# $Id: Makefile.in,v 1.162 1998/11/11 20:04:09 glenn Exp $ # # Uncomment and customize the following to suit your needs: # @@ -173,10 +173,7 @@ OBJS = \ SNMP_OBJS = \ snmp_core.o \ - snmp_oidlist.o \ - snmp_agent.o \ - snmp_config.o \ - snmp_auth.o + snmp_agent.o HTCP_OBJS = htcp.o diff --git a/src/acl.cc b/src/acl.cc index 6a4743b799..002240c757 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,6 +1,6 @@ /* - * $Id: acl.cc,v 1.185 1998/10/13 23:33:29 wessels Exp $ + * $Id: acl.cc,v 1.186 1998/11/11 20:04:10 glenn Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -46,7 +46,6 @@ static void aclParseWordList(void *curlist); static void aclParseProtoList(void *curlist); static void aclParseMethodList(void *curlist); static void aclParseTimeSpec(void *curlist); -static void aclParseSnmpComm(void *curlist); static void aclParseIntRange(void *curlist); static char *strtokFile(void); static void aclDestroyAclList(acl_list * list); @@ -61,6 +60,7 @@ static int aclMatchIdent(wordlist * data, const char *ident); static int aclMatchIp(void *dataptr, struct in_addr c); static int aclMatchDomainList(void *dataptr, const char *); static int aclMatchIntegerRange(intrange * data, int i); +static int aclMatchWordList(wordlist *, const char *); static squid_acl aclStrToType(const char *s); static int decode_addr(const char *, struct in_addr *, struct in_addr *); static void aclCheck(aclCheck_t * checklist); @@ -174,8 +174,10 @@ aclStrToType(const char *s) return ACL_SRC_ASN; if (!strcmp(s, "dst_as")) return ACL_DST_ASN; +#if SQUID_SNMP if (!strcmp(s, "snmp_community")) - return ACL_SNMP_COMM; + return ACL_SNMP_COMMUNITY; +#endif if (!strcmp(s, "src_rtt")) return ACL_NETDB_SRC_RTT; #if USE_ARP_ACL @@ -222,8 +224,10 @@ aclTypeToStr(squid_acl type) return "src_as"; if (type == ACL_DST_ASN) return "dst_as"; - if (type == ACL_SNMP_COMM) +#if SQUID_SNMP + if (type == ACL_SNMP_COMMUNITY) return "snmp_community"; +#endif if (type == ACL_NETDB_SRC_RTT) return "src_rtt"; #if USE_ARP_ACL @@ -639,23 +643,6 @@ aclParseProxyAuth(void *data) return; } -static void -aclParseSnmpComm(void *data) -{ - acl_snmp_comm **q = data; - acl_snmp_comm *p; - char *t; - t = strtok(NULL, w_space); - if (t) { - p = xcalloc(1, sizeof(acl_snmp_comm)); - p->name = xstrdup(t); - p->community = NULL; - *q = p; - } - t = strtok(NULL, w_space); - return; -} - void aclParseAclLine(acl ** head) { @@ -744,9 +731,11 @@ aclParseAclLine(acl ** head) case ACL_PROXY_AUTH: aclParseProxyAuth(&A->data); break; - case ACL_SNMP_COMM: - aclParseSnmpComm(&A->data); +#if SQUID_SNMP + case ACL_SNMP_COMMUNITY: + aclParseWordList(&A->data); break; +#endif #if USE_ARP_ACL case ACL_SRC_ARP: aclParseArpList(&A->data); @@ -1150,6 +1139,19 @@ aclMatchTime(acl_time_data * data, time_t when) return data->weekbits & (1 << tm.tm_wday) ? 1 : 0; } +static int +aclMatchWordList(wordlist * w, const char *community) +{ + debug(28, 3) ("aclMatchWordList: looking for '%s'\n", community); + while (w != NULL) { + debug(28, 3) ("aclMatchWordList: checking '%s'\n", w->key); + if (!strcmp(w->key, community)) + return 1; + w = w->next; + } + return 0; +} + static int aclMatchAcl(acl * ae, aclCheck_t * checklist) { @@ -1283,8 +1285,10 @@ aclMatchAcl(acl * ae, aclCheck_t * checklist) return 0; } /* NOTREACHED */ - case ACL_SNMP_COMM: - return asnMatchIp(ae->data, checklist->src_addr); +#if SQUID_SNMP + case ACL_SNMP_COMMUNITY: + return aclMatchWordList(ae->data, checklist->snmp_community); +#endif case ACL_SRC_ASN: return asnMatchIp(ae->data, checklist->src_addr); case ACL_DST_ASN: @@ -1614,6 +1618,9 @@ aclDestroyAcls(acl ** head) splay_destroy(a->data, xfree); break; case ACL_USER: +#if SQUID_SNMP + case ACL_SNMP_COMMUNITY: +#endif wordlistDestroy((wordlist **) & a->data); break; case ACL_TIME: @@ -1985,6 +1992,9 @@ aclDumpGeneric(const acl * a) case ACL_SRC_DOMAIN: case ACL_DST_DOMAIN: case ACL_USER: +#if SQUID_SNMP + case ACL_SNMP_COMMUNITY: +#endif return aclDumpDomainList(a->data); break; case ACL_TIME: diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 1c8a6cfbb9..5fc75fdad5 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,6 +1,6 @@ /* - * $Id: cache_cf.cc,v 1.308 1998/10/14 21:11:55 wessels Exp $ + * $Id: cache_cf.cc,v 1.309 1998/11/11 20:04:12 glenn Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -64,10 +64,6 @@ static int parseTimeUnits(const char *unit); static void parseTimeLine(time_t * tptr, const char *units); static void parse_string(char **); static void parse_wordlist(wordlist **); -#if SQUID_SNMP -/* sigh, stringlist is only used for SNMP stuff now */ -static void parse_stringlist(wordlist **); -#endif static void default_all(void); static void defaults_if_none(void); static int parse_line(char *); @@ -447,31 +443,6 @@ free_acl(acl ** ae) aclDestroyAcls(ae); } -#if SQUID_SNMP - -static void -dump_snmp_access(StoreEntry * entry, const char *name, communityEntry * Head) -{ - acl_list *l; - communityEntry *cp; - acl_access *head; - - for (cp = Head; cp; cp = cp->next) { - head = cp->acls; - while (head != NULL) { - for (l = head->acl_list; l != NULL; l = l->next) { - storeAppendPrintf(entry, "%s %s %s %s%s\n", - name, cp->name, - head->allow ? "Allow" : "Deny", - l->op ? null_string : "!", - l->acl->name); - } - head = head->next; - } - } -} -#endif - static void dump_acl_access(StoreEntry * entry, const char *name, acl_access * head) { @@ -490,39 +461,6 @@ dump_acl_access(StoreEntry * entry, const char *name, acl_access * head) } } -#if SQUID_SNMP - -static void -parse_snmp_access(communityEntry ** head) -{ - char *t = NULL; - communityEntry *cp; -/* This is tricky: we need to define the communities here, assuming that - * communities and the MIB have already been defined */ - - if (!snmpInitConfig()) { - debug(15, 0) ("parse_snmp_access: Access lists NOT defined.\n"); - return; - } - t = strtok(NULL, w_space); - for (cp = *head; cp; cp = cp->next) - if (!strcmp(t, cp->name)) { - aclParseAccessLine(&cp->acls); - return; - } - debug(15, 0) ("parse_snmp_access: Unknown community %s!\n", t); -} - -static void -free_snmp_access(communityEntry ** Head) -{ - communityEntry *cp; - - for (cp = *Head; cp; cp = cp->next) - aclDestroyAccessList(&cp->acls); -} -#endif - static void parse_acl_access(acl_access ** head) { @@ -1393,18 +1331,6 @@ check_null_wordlist(wordlist * w) return w == NULL; } -#if SQUID_SNMP -static void -parse_stringlist(wordlist ** list) -{ - char *token; - while ((token = strtok(NULL, null_string))) - wordlistAdd(list, token); -} -#define free_stringlist free_wordlist -#define dump_stringlist dump_wordlist -#endif /* SQUID_SNMP */ - #define free_wordlist wordlistDestroy #define free_uri_whitespace free_int diff --git a/src/cf.data.pre b/src/cf.data.pre index 07b6b8af0f..ba0a6e1d34 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.122 1998/10/14 21:11:57 wessels Exp $ +# $Id: cf.data.pre,v 1.123 1998/11/11 20:04:12 glenn Exp $ # # # SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -1393,6 +1393,11 @@ DOC_START # needed during ACL checking the username is NOT logged # in access.log. + acl aclname snmp_community string ... + # Example: + # + # acl snmppublic snmp_community public + acl manager proto cache_object acl localhost src 127.0.0.1/255.255.255.255 acl all src 0.0.0.0/0.0.0.0 @@ -2283,19 +2288,6 @@ DOC_START snmp_port 3401 DOC_END -NAME: snmp_do_queueing -TYPE: onoff -LOC: Config.Snmp.do_queueing -DEFAULT: on -IFDEF: SQUID_SNMP -DOC_START - If disabled, snmp packets will not be queued but delivered - immediately. This could be useful when you want to monitor a - cache in trouble, but this could also make Squid block, slowing - connections and possibly worsening the cache status. -snmp_do_queueing on -DOC_END - NAME: forward_snmpd_port TYPE: ushort LOC: Config.Snmp.localPort @@ -2317,73 +2309,16 @@ DOC_START forward_snmpd_port 0 DOC_END -NAME: snmp_mib_path -TYPE: string -LOC: Config.Snmp.mibPath -DEFAULT: @DEFAULT_MIB_PATH@ -IFDEF: SQUID_SNMP -DOC_START - The location of Squid's mib. -snmp_mib_path @DEFAULT_MIB_PATH@ -DOC_END - -NAME: trap_sink -TYPE: string -LOC: Config.Snmp.trap_sink -DEFAULT: 127.0.0.1 -IFDEF: SQUID_SNMP -DOC_START - Hostname or ip address of trap sink for snmp -trap_sink 127.0.0.1 -DOC_END - -NAME: snmp_trap_community -TYPE: string -LOC: Config.Snmp.trap_community -DEFAULT: public -IFDEF: SQUID_SNMP -DOC_START - Community name for traps. -snmp_trap_community public -DOC_END - -NAME: snmp_enable_authen_traps -TYPE: onoff -LOC: Config.Snmp.conf_authtraps -DEFAULT: off -IFDEF: SQUID_SNMP -DOC_START - Enable SNMP authenticated traps. Set to 'off' or 'on'. -snmp_enable_authen_traps off -DOC_END - -NAME: snmp_agent_conf -TYPE: stringlist -LOC: Config.Snmp.snmpconf +NAME: snmp_access +TYPE: acl_access +LOC: Config.accessList.snmp DEFAULT: none IFDEF: SQUID_SNMP DOC_START - Define snmp views, users and communities - Example: - snmp_agent_conf view all .1.3.6 included - snmp_agent_conf view squid .1.3.6 included - snmp_agent_conf user squid - all all public - snmp_agent_conf user all all all all squid - snmp_agent_conf community public squid squid - snmp_agent_conf community readwrite all all -DOC_END + Allowing or denying access to the SNMP port. + usage: -NAME: snmp_acl -TYPE: snmp_access -LOC: Config.Snmp.communities -DEFAULT: none -IFDEF: SQUID_SNMP -DOC_START - Define access controls per community: - snmp_access communityname allow|deny [!]aclname ... - Example: - snmp_acl public allow adminsubnet - snmp_acl public deny all + snmp_access allow|deny [!]aclname ... DOC_END NAME: snmp_incoming_address diff --git a/src/cf_gen.cc b/src/cf_gen.cc index 0844ce3175..21c54696c5 100644 --- a/src/cf_gen.cc +++ b/src/cf_gen.cc @@ -1,5 +1,5 @@ /* - * $Id: cf_gen.cc,v 1.27 1998/08/21 09:15:43 wessels Exp $ + * $Id: cf_gen.cc,v 1.28 1998/11/11 20:04:13 glenn Exp $ * * DEBUG: none * AUTHOR: Max Okumoto @@ -65,10 +65,6 @@ #include #endif -#if SQUID_SNMP -#include "snmp.h" -#endif - #define MAX_LINE 1024 /* longest configuration line */ #define _PATH_PARSER "cf_parser.c" #define _PATH_SQUID_CONF "squid.conf" diff --git a/src/client_side.cc b/src/client_side.cc index dc148399dd..772b1f785c 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.420 1998/10/19 06:15:29 rousskov Exp $ + * $Id: client_side.cc,v 1.421 1998/11/11 20:04:14 glenn Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -1950,6 +1950,7 @@ parseHttpRequest(ConnStateData * conn, method_t * method_p, int *status, return parseHttpRequestAbort(conn, "error:missing-http-ident"); #endif } else { +debug(0, 0) ("parseHttpRequest: VER is {%s}\n", token); http_ver = (float) atof(token + 5); } diff --git a/src/enums.h b/src/enums.h index fcbe91c7c1..4470f4f31c 100644 --- a/src/enums.h +++ b/src/enums.h @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.135 1998/10/12 21:40:57 wessels Exp $ + * $Id: enums.h,v 1.136 1998/11/11 20:04:15 glenn Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -105,7 +105,7 @@ typedef enum { ACL_SRC_ASN, ACL_DST_ASN, ACL_SRC_ARP, - ACL_SNMP_COMM, + ACL_SNMP_COMMUNITY, ACL_NETDB_SRC_RTT, ACL_ENUM_MAX } squid_acl; diff --git a/src/main.cc b/src/main.cc index 3452e85ad1..078b0ceb08 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.274 1998/10/21 06:54:19 wessels Exp $ + * $Id: main.cc,v 1.275 1998/11/11 20:04:16 glenn Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -416,6 +416,7 @@ mainInitialize(void) #ifdef SQUID_SNMP snmpInit(); #endif + #if MALLOC_DBG malloc_debug(0, malloc_debug_level); diff --git a/src/protos.h b/src/protos.h index f348520118..c13f9e9003 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.283 1998/10/23 21:53:32 glenn Exp $ + * $Id: protos.h,v 1.284 1998/11/11 20:04:17 glenn Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -478,15 +478,23 @@ extern PF httpAccept; #ifdef SQUID_SNMP extern PF snmpHandleUdp; extern void snmpInit(void); -extern int snmpInitConfig(void); extern void snmpConnectionOpen(void); extern void snmpConnectionShutdown(void); extern void snmpConnectionClose(void); -extern int snmpCreateView(char **); -extern int snmpCreateUser(char **); -extern int snmpCreateCommunity(char **); -extern void snmpTokenize(char *, char **, int); -extern int snmpCompare(oid * name1, int len1, oid * name2, int len2); +extern void snmpDebugOid(int lvl, oid * Name, snint Len); +extern void addr2oid(struct in_addr addr, oid * Dest); +extern struct in_addr* oid2addr(oid * id); +variable_list *snmp_basicFn(variable_list *, snint *); +variable_list *snmp_confFn(variable_list *, snint *); +variable_list *snmp_sysFn(variable_list *, snint *); +variable_list *snmp_prfSysFn(variable_list *, snint *); +variable_list *snmp_prfProtoFn(variable_list *, snint *); +variable_list *snmp_prfPeerFn(variable_list *, snint *); +variable_list *snmp_netIpFn(variable_list *, snint *); +variable_list *snmp_netFqdnFn(variable_list *, snint *); +variable_list *snmp_netDnsFn(variable_list *, snint *); +variable_list *snmp_meshPtblFn(variable_list *, snint *); +variable_list *snmp_meshCtblFn(variable_list *, snint *); #endif /* SQUID_SNMP */ extern void icpHandleIcpV3(int, struct sockaddr_in, char *, int); diff --git a/src/snmp_agent.cc b/src/snmp_agent.cc index 9b9d87a8a3..e7cf55dbdb 100644 --- a/src/snmp_agent.cc +++ b/src/snmp_agent.cc @@ -1,6 +1,6 @@ /* - * $Id: snmp_agent.cc,v 1.58 1998/09/29 16:33:49 wessels Exp $ + * $Id: snmp_agent.cc,v 1.59 1998/11/11 20:04:18 glenn Exp $ * * DEBUG: section 49 SNMP Interface * AUTHOR: Kostas Anagnostakis @@ -35,18 +35,10 @@ #include "squid.h" - -#include "snmp.h" -#include "snmp_impl.h" -#include "asn1.h" -#include "snmp_api.h" -#include "snmp_vars.h" -#include "snmp_oidlist.h" #include "cache_snmp.h" extern StatCounters *snmpStatGet(int); - /************************************************************************ SQUID MIB Implementation diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 084c1b84b4..8dd09f1fcf 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -1,8 +1,8 @@ /* - * $Id: snmp_core.cc,v 1.12 1998/09/29 16:33:51 wessels Exp $ + * $Id: snmp_core.cc,v 1.13 1998/11/11 20:04:19 glenn Exp $ * * DEBUG: section 49 SNMP support - * AUTHOR: Kostas Anagnostakis + * AUTHOR: Glenn Chisholm * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- @@ -20,463 +20,392 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */ - -/********************************************************************** - * - * Copyright 1996 by Carnegie Mellon University - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of CMU not be - * used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHAL - * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * Author: Ryan Troll - * - **********************************************************************/ - - #include "squid.h" - #include "cache_snmp.h" -#include "squid_mib.h" #define SNMP_REQUEST_SIZE 4096 #define MAX_PROTOSTAT 5 -int snmp_dump_packet; -void *users, *communities; - -static struct sockaddr_in local_snmpd; -static int snmp_init_config = 0; -struct snmp_session *Session; -struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU); - -void snmpFwd_insertPending(struct sockaddr_in *, long); -int snmpFwd_removePending(struct sockaddr_in *, long); - -extern void (*snmplib_debug_hook) (int, char *); -static void snmpSnmplibDebug(int lvl, char *buf); +struct _mib_tree_entry { + oid *name; + int len; + oid_ParseFn *parsefunction; + int children; + struct _mib_tree_entry **leaves; + struct _mib_tree_entry *parent; +}; -struct snmpUdpData { +struct _snmpUdpData { struct sockaddr_in address; void *msg; int len; - struct snmpUdpData *next; + struct _snmpUdpData *next; }; -typedef struct snmpUdpData snmpUdpData; - -struct snmpFwdQueue { - struct sockaddr_in addr; - long req_id; - time_t req_time; - struct snmpFwdQueue *next; -}; +typedef struct _snmpUdpData snmpUdpData; +typedef struct _mib_tree_entry mib_tree_entry; -struct snmpFwdQueue *snmpHead = NULL; +mib_tree_entry *mib_tree_head; +snmpUdpData *snmpUdpHead = NULL; +snmpUdpData *snmpUdpTail = NULL; -struct snmpUdpData *snmpUdpHead = NULL; -struct snmpUdpData *snmpUdpTail = NULL; +extern void (*snmplib_debug_hook) (int, char *); -void snmpUdpReply(int, void *); -void snmpAppendUdp(snmpUdpData *); -void snmpUdpSend(int, const struct sockaddr_in *, void *, int); +static void snmpDecodePacket(snmp_request_t * rq); +static void snmpConstructReponse(snmp_request_t * rq, struct snmp_session *Session); +static struct snmp_pdu* snmpAgentResponse(struct snmp_pdu *PDU); -/* now include mib location definitions - * and magic numbers */ +static void snmpUdpSend(int, const struct sockaddr_in *, void *, int); +static void snmpUdpReply(int, void *); +static void snmpAppendUdp(snmpUdpData *); -#include "cache_snmp.h" +static mib_tree_entry* snmpAddNode(oid *name, int len, oid_ParseFn *parsefunction, int children, ...); +static oid_ParseFn *snmpTreeNext(oid *Current, snint CurrentLen, oid **Next, snint *NextLen); +static mib_tree_entry* snmpTreeEntry(oid entry, snint len, mib_tree_entry *current); -static void -snmpSnmplibDebug(int lvl, char *buf) -{ - debug(49, lvl) ("%s", buf); -} +static oid* snmpCreateOid(int length, ...); +static oid* snmpOidDup(oid * A, snint ALen); +static void snmpSnmplibDebug(int lvl, char *buf); -void -snmpHandleUdp(int sock, void *not_used) -{ - struct sockaddr_in from; - socklen_t from_len; - LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE); - LOCAL_ARRAY(char, deb_line, 4096); - int len; - snmp_request_t *snmp_rq; - debug(49, 5) ("snmpHandleUdp: Called.\n"); - commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0); - from_len = sizeof(struct sockaddr_in); - memset(&from, '\0', from_len); - Counter.syscalls.sock.recvfroms++; - len = recvfrom(sock, - buf, - SNMP_REQUEST_SIZE, - 0, - (struct sockaddr *) &from, - &from_len); - if (len < 0) { -#ifdef _SQUID_LINUX_ - /* Some Linux systems seem to set the FD for reading and then - * return ECONNREFUSED when sendto() fails and generates an ICMP - * port unreachable message. */ - /* or maybe an EHOSTUNREACH "No route to host" message */ - if (errno != ECONNREFUSED && errno != EHOSTUNREACH) -#endif - debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", - sock, xstrerror()); - return; - } - if (snmp_dump_packet) { - int count; - debug(49, 6) ("received %d bytes from %s:\n", (int) len, - inet_ntoa(from.sin_addr)); - for (count = 0; count < len; count++) { - snprintf(deb_line, 4096, "%s %02X ", deb_line, (u_char) buf[count]); - if ((count % 16) == 15 || count == (len - 1)) { - debug(49, 8) ("snmp in: %s\n", deb_line); - deb_line[0] = '\0'; - } - } - } - buf[len] = '\0'; - debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n", - sock, - len, - inet_ntoa(from.sin_addr)); - - snmp_rq = xcalloc(1, sizeof(snmp_request_t)); - snmp_rq->buf = (u_char *) buf; - snmp_rq->len = len; - snmp_rq->sock = sock; - snmp_rq->outbuf = xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE); - memcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in)); - snmpAgentParse(snmp_rq); -} - -void -snmpAgentParseDone(int errstat, void *data) -{ - snmp_request_t *snmp_rq = (snmp_request_t *) data; - LOCAL_ARRAY(char, deb_line, 4096); - int sock = snmp_rq->sock; - long this_reqid = snmp_rq->reqid; - debug(49, 2) ("snmpAgentParseDone: errstat=%d, reqid=%d _t=%x\n", - errstat, this_reqid, snmp_rq); - - if (memcmp(&snmp_rq->from, &local_snmpd, sizeof(struct sockaddr_in)) == 0) { - /* look it up */ - if (snmpFwd_removePending(&snmp_rq->from, this_reqid)) { /* failed */ - debug(49, 2) ("snmp: bogus response from %s.\n", - inet_ntoa(snmp_rq->from.sin_addr)); - if (snmp_rq->community) - xfree(snmp_rq->community); - xfree(snmp_rq->outbuf); - xfree(snmp_rq); - return; - } - } - switch (errstat) { - case 2: /* we might have to forward */ - if (Config.Snmp.localPort != 0) { - snmpFwd_insertPending(&snmp_rq->from, this_reqid); - snmpUdpSend(sock, &local_snmpd, snmp_rq->outbuf, snmp_rq->outlen); - break; - } - debug(49, 4) ("snmp: can't forward.\n"); - break; - case 1: /* everything is ok */ - debug(49, 5) ("snmp: parsed.\n"); - if (snmp_dump_packet) { - int count = 0; - debug(49, 5) ("snmp: sent %d bytes to %s\n", (int) snmp_rq->outlen, - inet_ntoa(snmp_rq->from.sin_addr)); - for (count = 0; count < snmp_rq->outlen; count++) { - snprintf(deb_line, 4096, "%s %02X ", deb_line, - (u_char) snmp_rq->outbuf[count]); - if ((count % 16) == 15 || count == (snmp_rq->len - 1)) { - debug(49, 7) ("snmp out: %s\n", deb_line); - deb_line[0] = '\0'; - } - } - } - snmpUdpSend(snmp_rq->sock, &snmp_rq->from, snmp_rq->outbuf, snmp_rq->outlen); - break; - case 0: - debug(49, 5) ("snmpagentparsedone failed\n"); - if (snmp_rq->outbuf) - xfree(snmp_rq->outbuf); - break; - } - if (snmp_rq->community) - xfree(snmp_rq->community); - cbdataFree(snmp_rq); - return; -} +/* + * The functions used during startup: + * snmpInit + * snmpConnectionOpen + * snmpConnectionShutdown + * snmpConnectionClose + */ +/* + Turns the MIB into a Tree structure. Called during the startup process. +*/ void snmpInit(void) { - assert(NULL != Config.Snmp.mibPath); - if (!snmpInitConfig()) - debug(49, 0) ("snmpInit: snmpInitConfig() failed.\n"); + debug(49, 5) ("snmpInit: Called.\n"); + + debug(49, 5) ("snmpInit: Building SNMP mib tree structure\n"); + snmplib_debug_hook = snmpSnmplibDebug; -} -int -snmpInitConfig() -{ - wordlist *w; - char *buf; - char *tokens[10]; - - if (snmp_init_config) - return 1; - - snmp_init_config = 1; - assert(NULL != Config.Snmp.mibPath); - if (Mib == NULL) { - debug(49, 3) ("init_mib: calling with %s\n", Config.Snmp.mibPath); - init_mib(Config.Snmp.mibPath); - } - if (Mib == NULL) { - debug(49, 0) ("WARNING: Failed to open MIB '%s'\n", - Config.Snmp.mibPath); - return 0; - } - /* - * Process 'snmp_agent_conf' lines - */ - for (w = Config.Snmp.snmpconf; w != NULL; w = w->next) { - buf = xstrdup(w->key); - snmpTokenize(buf, tokens, 10); - if (0 == strcmp("view", tokens[0])) { - if (snmpCreateView(tokens) < 0) { - debug(49, 1) ("snmpInit: error parsing '%s'\n", w->key); - safe_free(buf); - return 0; - } - } else if (0 == strcmp("user", tokens[0])) { - if (snmpCreateUser(tokens) < 0) { - debug(49, 1) ("snmpInit: error parsing '%s'\n", w->key); - safe_free(buf); - return 0; - } - } else if (0 == strcmp("community", tokens[0])) { - if (snmpCreateCommunity(tokens) < 0) - debug(49, 1) ("snmpInit: error parsing '%s'\n", w->key); - } else { - debug(49, 1) ("snmpInit: error parsing '%s'\n", w->key); - safe_free(buf); - return 0; - } - safe_free(buf); - } - if (!Config.Snmp.communities) { - debug(49, 2) ("snmpInit: WARNING: communities not defined.\n"); - } else - debug(49, 5) ("snmpInit: communities defined.\n"); - snmpInitAgentAuth(); - assert(0 <= snmpDefaultAuth()); - return 1; + mib_tree_head = snmpAddNode(snmpCreateOid(1, 1), + 1, NULL, 1, + snmpAddNode(snmpCreateOid(2, 1, 3), + 2, NULL, 1, + snmpAddNode(snmpCreateOid(3, 1, 3, 6), + 3, NULL, 1, + snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1), + 4, NULL, 1, + snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4), + 5, NULL, 1, + snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1), + 6, NULL, 1, + snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495), + 7, NULL, 1, + snmpAddNode(snmpCreateOid(LEN_SQUIDMIB, SQUIDMIB), + 8, NULL, 5, + snmpAddNode(snmpCreateOid(LEN_SQ_SYS, SQ_SYS), + LEN_SQ_SYS, NULL, 3, + snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 1, SQ_SYS, 1), + LEN_SQ_SYS + 1, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 1, SQ_SYS, 2), + LEN_SQ_SYS + 1, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 1, SQ_SYS, 3), + LEN_SQ_SYS + 1, snmp_sysFn, 0)), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF, SQ_CONF), + LEN_SQ_CONF, NULL, 5, + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 1), + LEN_SQ_CONF + 1, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 2), + LEN_SQ_CONF + 1, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 3), + LEN_SQ_CONF + 1, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 4), + LEN_SQ_CONF + 1, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 5), + LEN_SQ_CONF + 1, NULL, 6, + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 1), + LEN_SQ_CONF + 2, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 2), + LEN_SQ_CONF + 2, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 3), + LEN_SQ_CONF + 2, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 4), + LEN_SQ_CONF + 2, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 5), + LEN_SQ_CONF + 2, snmp_confFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 6), + LEN_SQ_CONF + 2, snmp_confFn, 0))), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF, SQ_PRF), + LEN_SQ_PRF, snmp_confFn, 2, + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, 1), + LEN_SQ_PRF + 1, snmp_sysFn, 11, + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 1), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 2), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 3), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 4), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 5), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 6), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 7), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 8), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 9), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 10), + LEN_SQ_PRF + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 11), + LEN_SQ_PRF + 2, snmp_sysFn, 0)), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, 2), + LEN_SQ_PRF + 1, snmp_sysFn, 2, + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 2, 1), + LEN_SQ_PRF + 2, snmp_sysFn, 14, + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 1), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 2), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 3), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 4), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 5), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 6), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 7), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 8), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 9), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 10), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 11), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 12), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 13), + LEN_SQ_PRF + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 14), + LEN_SQ_PRF + 3, snmp_sysFn, 0)), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 2, 2), + LEN_SQ_PRF + 2, snmp_sysFn, 1, + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 2, 1), + LEN_SQ_PRF + 3, snmp_sysFn, 8, + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 1), + LEN_SQ_PRF + 4, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 2), + LEN_SQ_PRF + 4, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 3), + LEN_SQ_PRF + 4, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 4), + LEN_SQ_PRF + 4, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 5), + LEN_SQ_PRF + 4, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 6), + LEN_SQ_PRF + 4, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 7), + LEN_SQ_PRF + 4, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 8), + LEN_SQ_PRF + 4, snmp_sysFn, 0))))), + snmpAddNode(snmpCreateOid(LEN_SQ_NET, SQ_NET), + LEN_SQ_NET, snmp_confFn, 3, + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, 1), + LEN_SQ_NET + 1, snmp_sysFn, 9, + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 1), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 2), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 3), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 4), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 5), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 6), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 7), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 8), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 9), + LEN_SQ_NET + 2, snmp_sysFn, 0)), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, 2), + LEN_SQ_NET + 1, snmp_sysFn, 8, + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 1), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 2), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 3), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 4), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 5), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 6), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 7), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 8), + LEN_SQ_NET + 2, snmp_sysFn, 0)), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, 3), + LEN_SQ_NET + 1, snmp_sysFn, 3, + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 3, 1), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 3, 2), + LEN_SQ_NET + 2, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 3, 3), + LEN_SQ_NET + 2, snmp_sysFn, 0))), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH), + LEN_SQ_MESH, snmp_confFn, 2, + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 1), + LEN_SQ_MESH + 1, snmp_sysFn, 1, + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1), + LEN_SQ_MESH + 2, snmp_sysFn, 13, + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 1), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 2), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 3), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 4), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 5), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 6), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 7), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 8), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 9), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 10), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 11), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 12), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 13), + LEN_SQ_MESH + 3, snmp_sysFn, 0))), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 2), + LEN_SQ_MESH + 1, snmp_sysFn, 1, + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 2, 1), + LEN_SQ_MESH + 2, snmp_sysFn, 9, + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 1), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 2), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 3), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 4), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 5), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 6), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 7), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 8), + LEN_SQ_MESH + 3, snmp_sysFn, 0), + snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 9), + LEN_SQ_MESH + 3, snmp_sysFn, 0)))) + ) + ) + ) + ) + ) + ) + ) + ); + + debug(49, 9) ("snmpInit: Completed SNMP mib tree structure\n"); } void snmpConnectionOpen(void) { u_short port; - struct in_addr addr; struct sockaddr_in xaddr; socklen_t len; int x; + debug(49, 5) ("snmpConnectionOpen: Called\n"); if ((port = Config.Port.snmp) > (u_short) 0) { - enter_suid(); - theInSnmpConnection = comm_open(SOCK_DGRAM, - 0, - Config.Addrs.snmp_incoming, - port, - COMM_NONBLOCKING, - "SNMP Port"); - leave_suid(); - if (theInSnmpConnection < 0) - fatal("Cannot open snmp Port"); - commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0); - debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n", - (int) port, theInSnmpConnection); - if ((addr = Config.Addrs.snmp_outgoing).s_addr != no_addr.s_addr) { - enter_suid(); - theOutSnmpConnection = comm_open(SOCK_DGRAM, - 0, - addr, - port, - COMM_NONBLOCKING, - "SNMP Port"); - leave_suid(); - if (theOutSnmpConnection < 0) - fatal("Cannot open Outgoing SNMP Port"); - commSetSelect(theOutSnmpConnection, - COMM_SELECT_READ, - snmpHandleUdp, - NULL, 0); - debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n", - (int) port, theOutSnmpConnection); - fd_note(theOutSnmpConnection, "Outgoing SNMP socket"); - fd_note(theInSnmpConnection, "Incoming SNMP socket"); - } else { - theOutSnmpConnection = theInSnmpConnection; - } - memset(&theOutSNMPAddr, '\0', sizeof(struct in_addr)); - len = sizeof(struct sockaddr_in); - memset(&xaddr, '\0', len); - x = getsockname(theOutSnmpConnection, - (struct sockaddr *) &xaddr, &len); - if (x < 0) - debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n", - theOutSnmpConnection, xstrerror()); - else { - theOutSNMPAddr = xaddr.sin_addr; - if (Config.Snmp.localPort != 0) { - local_snmpd.sin_addr = xaddr.sin_addr; - local_snmpd.sin_port = Config.Snmp.localPort; - } - } + enter_suid(); + theInSnmpConnection = comm_open(SOCK_DGRAM, + 0, + Config.Addrs.snmp_incoming, + port, + COMM_NONBLOCKING, + "SNMP Port"); + leave_suid(); + if (theInSnmpConnection < 0) + fatal("Cannot open snmp Port"); + commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0); + debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n", + (int) port, theInSnmpConnection); + if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) { + enter_suid(); + theOutSnmpConnection = comm_open(SOCK_DGRAM, + 0, + Config.Addrs.snmp_outgoing, + port, + COMM_NONBLOCKING, + "SNMP Port"); + leave_suid(); + if (theOutSnmpConnection < 0) + fatal("Cannot open Outgoing SNMP Port"); + commSetSelect(theOutSnmpConnection, + COMM_SELECT_READ, + snmpHandleUdp, + NULL, 0); + debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n", + (int) port, theOutSnmpConnection); + fd_note(theOutSnmpConnection, "Outgoing SNMP socket"); + fd_note(theInSnmpConnection, "Incoming SNMP socket"); + } else { + theOutSnmpConnection = theInSnmpConnection; + } + memset(&theOutSNMPAddr, '\0', sizeof(struct in_addr)); + len = sizeof(struct sockaddr_in); + memset(&xaddr, '\0', len); + x = getsockname(theOutSnmpConnection, + (struct sockaddr *) &xaddr, &len); + if (x < 0) + debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n", + theOutSnmpConnection, xstrerror()); + else + theOutSNMPAddr = xaddr.sin_addr; } } -void -snmpFwd_insertPending(struct sockaddr_in *ad, long reqid) -{ - struct snmpFwdQueue *new; - - new = (struct snmpFwdQueue *) xcalloc(1, sizeof(struct snmpFwdQueue)); - xmemcpy(&new->addr, ad, sizeof(struct sockaddr_in)); - new->req_id = reqid; - new->req_time = squid_curtime; - if (snmpHead == NULL) { - new->next = NULL; - snmpHead = new; - } - new->next = snmpHead; - snmpHead = new; -} - -int -snmpFwd_removePending(struct sockaddr_in *fr, long reqid) -{ - struct snmpFwdQueue *p, *prev = NULL; - for (p = snmpHead; p != NULL; p = p->next, prev = p) - if (reqid == p->req_id) { - xmemcpy(fr, &p->addr, sizeof(struct sockaddr_in)); - if (p == snmpHead) - snmpHead = p->next; - else if (p->next == NULL) - prev->next = NULL; - debug(49, 3) ("snmpFwd_removePending: freeing %p\n", p); - xfree(p); - return 0; - } - return 1; -} - -void -snmpUdpSend(int fd, - const struct sockaddr_in *to, - void *msg, int len) -{ - snmpUdpData *data = xcalloc(1, sizeof(snmpUdpData)); - debug(49, 5) ("snmpUdpSend: Queueing response for %s\n", - inet_ntoa(to->sin_addr)); - data->address = *to; - data->msg = msg; - data->len = len; - snmpAppendUdp(data); - commSetSelect(fd, COMM_SELECT_WRITE, snmpUdpReply, snmpUdpHead, 0); - -} -void -snmpUdpReply(int fd, void *data) -{ - snmpUdpData *queue = data; - int x; - /* Disable handler, in case of errors. */ - commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); - while ((queue = snmpUdpHead) != NULL) { - debug(49, 5) ("snmpUdpReply: FD %d sending %d bytes to %s port %d\n", - fd, - queue->len, - inet_ntoa(queue->address.sin_addr), - ntohs(queue->address.sin_port)); - x = comm_udp_sendto(fd, - &queue->address, - sizeof(struct sockaddr_in), - queue->msg, - queue->len); - if (x < 0) { - if (ignoreErrno(errno)) - break; /* don't de-queue */ - } - snmpUdpHead = queue->next; - debug(49, 3) ("snmpUdpReply: freeing %p\n", queue->msg); - safe_free(queue->msg); - debug(49, 3) ("snmpUdpReply: freeing %p\n", queue); - safe_free(queue); - } - /* Reinstate handler if needed */ - if (snmpUdpHead) { - commSetSelect(fd, COMM_SELECT_WRITE, snmpUdpReply, snmpUdpHead, 0); - } -} - -void -snmpAppendUdp(snmpUdpData * item) -{ - item->next = NULL; - if (snmpUdpHead == NULL) { - snmpUdpHead = item; - snmpUdpTail = item; - } else if (snmpUdpTail == snmpUdpHead) { - snmpUdpTail = item; - snmpUdpHead->next = item; - } else { - snmpUdpTail->next = item; - snmpUdpTail = item; - } - -} - void snmpConnectionShutdown(void) { if (theInSnmpConnection < 0) - return; + return; if (theInSnmpConnection != theOutSnmpConnection) { - debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection); - comm_close(theInSnmpConnection); + debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection); + comm_close(theInSnmpConnection); } /* * Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in' @@ -484,7 +413,7 @@ snmpConnectionShutdown(void) * function from executing repeatedly. When we are really ready to * exit or restart, main will comm_close the 'out' descriptor. */ theInSnmpConnection = -1; - /* + /* * Normally we only write to the outgoing SNMP socket, but we * also have a read handler there to catch messages sent to that * specific interface. During shutdown, we must disable reading @@ -499,351 +428,421 @@ snmpConnectionClose(void) { snmpConnectionShutdown(); if (theOutSnmpConnection > -1) { - debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection); - comm_close(theOutSnmpConnection); + debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection); + comm_close(theOutSnmpConnection); } } -/* returns: - * 2: no such object in this mib - * 1: ok - * 0: failed */ +/* + Functions for handling the requests. +*/ +/* + * Accept the UDP packet + */ void -snmpAgentParse(void *data) +snmpHandleUdp(int sock, void *not_used) { - snmp_request_t *rq = (snmp_request_t *) data; - u_char *buf = rq->buf; - int len = rq->len; + LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE); + struct sockaddr_in from; + socklen_t from_len; + snmp_request_t *snmp_rq; + int len; + + debug(49, 5) ("snmpHandleUdp: Called.\n"); + + commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0); + from_len = sizeof(struct sockaddr_in); + memset(&from, '\0', from_len); + + Counter.syscalls.sock.recvfroms++; + + len = recvfrom(sock, + buf, + SNMP_REQUEST_SIZE, + 0, + (struct sockaddr *) &from, + &from_len); + + 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)); + + snmp_rq = xcalloc(1, sizeof(snmp_request_t)); + snmp_rq->buf = (u_char *) buf; + snmp_rq->len = len; + snmp_rq->sock = sock; + snmp_rq->outbuf = xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE); + memcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in)); + snmpDecodePacket(snmp_rq); + } else { + debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror()); + } +} +/* + * Turn SNMP packet into a PDU, check available ACL's + */ +void +snmpDecodePacket(snmp_request_t * rq) +{ struct snmp_pdu *PDU; + struct snmp_session *Session; + aclCheck_t checklist; 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 */ + Session = (struct snmp_session *) xmalloc(sizeof(struct snmp_session)); + Session->Version = SNMP_VERSION_1; + Session->authenticator = NULL; + Session->community = (u_char *) xstrdup("public"); + Session->community_len = 6; cbdataAdd(rq, MEM_NONE); PDU = snmp_pdu_create(0); Community = snmp_parse(Session, PDU, buf, len); - if (!snmp_coexist_V2toV1(PDU)) { /* incompatibility */ - debug(49, 3) ("snmpAgentParse: Incompatible V2 packet.\n"); + checklist.src_addr = rq->from.sin_addr; + checklist.snmp_community = Community; + + allow = aclCheckFast(Config.accessList.snmp, &checklist); + if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) { + rq->community = Community; + rq->PDU = PDU; + debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid); + snmpConstructReponse(rq, Session); + } else { snmp_free_pdu(PDU); - snmpAgentParseDone(0, rq); - return; } - rq->community = Community; - rq->PDU = PDU; - debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid); +} - if (!Community) { - debug(49, 2) ("snmpAgentParse: WARNING: Could not parse community\n"); +/* + * Packet OK, ACL Check OK, Create reponse. + */ +void +snmpConstructReponse(snmp_request_t * rq, struct snmp_session *Session) +{ + struct snmp_pdu *RespPDU; + int ret; - snmp_free_pdu(PDU); - snmpAgentParseDone(0, rq); - return; + debug(49, 5) ("snmpConstructReponse: Called.\n"); + + Session->community = rq->community; + Session->community_len = strlen((char *) rq->community); + + RespPDU = snmpAgentResponse(rq->PDU); + snmp_free_pdu(rq->PDU); + xfree(Session); + if (RespPDU == NULL) { + } else { + ret = snmp_build(Session, RespPDU, rq->outbuf, &rq->outlen); + snmpUdpSend(rq->sock, &rq->from, rq->outbuf, rq->outlen); + snmp_free_pdu(RespPDU); } - snmpAclCheckStart(rq); } +/* + * Decide how to respond to the request, construct a response and + * return the response to the requester. + * + * If configured forward any reponses which are not for this agent. + */ struct snmp_pdu * snmpAgentResponse(struct snmp_pdu *PDU) { struct snmp_pdu *Answer = NULL; - variable_list *VarPtr, *VarNew = NULL; - variable_list **VarPtrP, **RespVars; - int index = 0; - oid_ParseFn *ParseFn; - - debug(49, 9) ("snmpAgentResponse: Received a %d PDU\n", PDU->command); + oid_ParseFn *ParseFn = NULL; + variable_list *VarNew = NULL; - /* Create a response */ - Answer = snmp_pdu_create(SNMP_PDU_RESPONSE); - if (Answer == NULL) - return (NULL); - Answer->reqid = PDU->reqid; - Answer->errindex = 0; + debug(49, 5) ("snmpAgentResponse: Called.\n"); - if (PDU->command == SNMP_PDU_GET) { + if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE))) { + Answer->reqid = PDU->reqid; + Answer->errindex = 0; + if (PDU->command == SNMP_PDU_GET) { - RespVars = &(Answer->variables); - /* Loop through all variables */ - for (VarPtrP = &(PDU->variables); - *VarPtrP; - VarPtrP = &((*VarPtrP)->next_variable)) { - VarPtr = *VarPtrP; + } else if (PDU->command == SNMP_PDU_GETNEXT) { + oid *NextOidName = NULL; + int NextOidNameLen = 0; - index++; - - /* Find the parsing function for this variable */ - ParseFn = oidlist_Find(VarPtr->name, VarPtr->name_length); + ParseFn = snmpTreeNext(PDU->variables->name, PDU->variables->name_length, + &(NextOidName), (snint *) &NextOidNameLen); if (ParseFn == NULL) { Answer->errstat = SNMP_ERR_NOSUCHNAME; - debug(49, 5) ("snmpAgentResponse: No such oid. "); - } else - VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat)); + debug(49, 5) ("snmpAgentResponse: No such oid: "); + snmpDebugOid(5, PDU->variables->name, PDU->variables->name_length); + } else { + xfree(PDU->variables->name); + PDU->variables->name = NextOidName; + PDU->variables->name_length = NextOidNameLen; + VarNew = (*ParseFn) (PDU->variables, (snint *) &Answer->errstat); + } /* Was there an error? */ - if ((Answer->errstat != SNMP_ERR_NOERROR) || - (VarNew == NULL)) { - Answer->errindex = index; - debug(49, 5) ("snmpAgentParse: successful.\n"); - /* Just copy the rest of the variables. Quickly. */ - *RespVars = VarPtr; - *VarPtrP = NULL; - return (Answer); + if (Answer->errstat != SNMP_ERR_NOERROR) { + Answer->errindex = 1; + + /* Just copy this variable */ + Answer->variables = PDU->variables; + PDU->variables = NULL; + } else { + Answer->variables = VarNew; } - /* No error. Insert this var at the end, and move on to the next. - */ - *RespVars = VarNew; - RespVars = &(VarNew->next_variable); - } - return (Answer); - } else if (PDU->command == SNMP_PDU_GETNEXT) { - oid *TmpOidName; - int TmpOidNameLen = 0; - - /* Find the next OID. */ - VarPtr = PDU->variables; - - ParseFn = oidlist_Next(VarPtr->name, VarPtr->name_length, - &(TmpOidName), (snint *) & (TmpOidNameLen)); - - if (ParseFn == NULL) { - Answer->errstat = SNMP_ERR_NOSUCHNAME; - debug(49, 5) ("snmpAgentResponse: No such oid: "); - snmpDebugOid(5, VarPtr->name, VarPtr->name_length); - } else { - xfree(VarPtr->name); - VarPtr->name = TmpOidName; - VarPtr->name_length = TmpOidNameLen; - VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat)); + + }else{ + snmp_free_pdu(Answer); + Answer = NULL; } + } + return (Answer); +} - /* Was there an error? */ - if (Answer->errstat != SNMP_ERR_NOERROR) { - Answer->errindex = 1; +oid_ParseFn * +snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen) +{ + oid_ParseFn *Fn = NULL; + mib_tree_entry *mibTreeEntry = NULL, *new_oid = NULL; + int count = 0; + + debug(49, 5) ("snmpTreeNext: Called\n"); + + debug(49, 6) ("snmpTreeNext: Current : \n"); + snmpDebugOid(6, Current, CurrentLen); - /* Just copy this variable */ - Answer->variables = VarPtr; - PDU->variables = NULL; - } else { - Answer->variables = VarNew; + mibTreeEntry = mib_tree_head; + if (Current[count] == mibTreeEntry->name[count]) { + count++; + while ((mibTreeEntry) && (count < CurrentLen)) { + mibTreeEntry = snmpTreeEntry(Current[count], count , mibTreeEntry); + count++; } + debug(49, 5) ("snmpTreeNext: Past first\n"); + + if (mibTreeEntry->parsefunction) { + while(!new_oid){ + new_oid = snmpTreeEntry(Current[count]+1, count , mibTreeEntry->parent); + if(!new_oid){ + mibTreeEntry = mibTreeEntry->parent; + count--; + } + } + } + debug(49, 5) ("snmpTreeNext: Past Second\n"); - /* Done. Return this PDU */ - return (Answer); - } /* end SNMP_PDU_GETNEXT */ - debug(49, 5) ("snmpAgentResponse: Ignoring PDU %d unknown command\n", PDU->command); - snmp_free_pdu(Answer); - return (NULL); + if ((!mibTreeEntry->parsefunction) && (mibTreeEntry)) { + while (!mibTreeEntry->parsefunction) { + mibTreeEntry = snmpTreeEntry(1, count , mibTreeEntry); + count++; + } + } + debug(49, 5) ("snmpTreeNext: Past Third\n"); + } + if(mibTreeEntry){ + *Next = snmpOidDup(mibTreeEntry->name, mibTreeEntry->len); + *NextLen = mibTreeEntry->len; + Fn = mibTreeEntry->parsefunction; + } + debug(49, 5) ("snmpTreeNext: return\n"); + return (Fn); } -void -snmpDebugOid(int lvl, oid * Name, snint Len) +mib_tree_entry * +snmpTreeEntry(oid entry, snint len, mib_tree_entry * current) { - char mbuf[16], objid[1024]; - int x; - objid[0] = '\0'; + mib_tree_entry *next = NULL; + int count = 0; - for (x = 0; x < Len; x++) { - snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]); - strncat(objid, mbuf, sizeof(objid)); - } + debug(49, 5) ("snmpTreeEntry: Called\n"); - debug(49, lvl) (" oid = %s\n", objid); -} + debug(49, 6) ("snmpTreeEntry: Oid: %d, Len: %d, Current : \n",entry, len); + snmpDebugOid(6, current->name, current->len); -int -oidcmp(oid * A, snint ALen, oid * B, snint BLen) -{ - oid *aptr = A; - oid *bptr = B; - snint m = MIN(ALen, BLen); - - /* Compare the first M bytes. */ - while (m) { - if (*aptr < *bptr) - return (-1); - if (*aptr++ > *bptr++) - return (1); - m--; + while ((!next) && (count < current->children)) { + debug(49, 6) ("snmpTreeEntry: While loop count: %d, children: %d \n", count, current->children); + snmpDebugOid(6, current->leaves[count]->name, current->leaves[count]->len); + if (current->leaves[count]->name[len] == entry) { + next = current->leaves[count]; + } + count++; } + if(next){ + debug(49, 6) ("snmpTreeEntry: Returned : \n"); + snmpDebugOid(6, next->name, next->len); + } + return (next); +} - /* The first M bytes were identical. So, they share the same - * root. The shorter one must come first. - */ - if (ALen < BLen) - return (-1); +/* + Send the UDP reply. +*/ +void +snmpUdpSend(int fd, const struct sockaddr_in *to, void *msg, int len) +{ + snmpUdpData *data = xcalloc(1, sizeof(snmpUdpData)); + debug(49, 5) ("snmpUdpSend: Queueing response for %s\n", + inet_ntoa(to->sin_addr)); + data->address = *to; + data->msg = msg; + data->len = len; + snmpAppendUdp(data); + commSetSelect(fd, COMM_SELECT_WRITE, snmpUdpReply, snmpUdpHead, 0); - if (ALen > BLen) - return (1); +} - /* Same length, all bytes identical. Must be the same OID. */ - return (0); +void +snmpUdpReply(int fd, void *data) +{ + snmpUdpData *queue = data; + int x; + /* Disable handler, in case of errors. */ + commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0); + while ((queue = snmpUdpHead) != NULL) { + debug(49, 5) ("snmpUdpReply: FD %d sending %d bytes to %s port %d\n", + fd, + queue->len, + inet_ntoa(queue->address.sin_addr), + ntohs(queue->address.sin_port)); + x = comm_udp_sendto(fd, + &queue->address, + sizeof(struct sockaddr_in), + queue->msg, + queue->len); + if (x < 0) { + if (ignoreErrno(errno)) + break; /* don't de-queue */ + } + snmpUdpHead = queue->next; + debug(49, 3) ("snmpUdpReply: freeing %p\n", queue->msg); + safe_free(queue->msg); + debug(49, 3) ("snmpUdpReply: freeing %p\n", queue); + safe_free(queue); + } + /* Reinstate handler if needed */ + if (snmpUdpHead) { + commSetSelect(fd, COMM_SELECT_WRITE, snmpUdpReply, snmpUdpHead, 0); + } } -int -oidncmp(oid * A, snint ALen, oid * B, snint BLen, snint CompLen) +void +snmpAppendUdp(snmpUdpData * item) { - oid *aptr = A; - oid *bptr = B; - snint m = MIN(MIN(ALen, BLen), CompLen); - snint count = 0; - - /* Compare the first M bytes. */ - while (count != m) { - if (*aptr < *bptr) - return (-1); - if (*aptr++ > *bptr++) - return (1); - count++; + item->next = NULL; + if (snmpUdpHead == NULL) { + snmpUdpHead = item; + snmpUdpTail = item; + } else if (snmpUdpTail == snmpUdpHead) { + snmpUdpTail = item; + snmpUdpHead->next = item; + } else { + snmpUdpTail->next = item; + snmpUdpTail = item; } - if (m == CompLen) - return (0); +} +/* + Utility functions +*/ - if (ALen < BLen) - return (-1); +/* + Tree utility functions. +*/ - if (ALen > BLen) - return (1); +/* + Adds a node to the MIB tree structure and adds the appropriate children +*/ +mib_tree_entry* +snmpAddNode(oid *name, int len, oid_ParseFn *parsefunction, int children, ...) +{ + va_list args; + int loop; + mib_tree_entry *entry = NULL; + + debug(49, 6) ("snmpAddNode: Children : %d, Oid : \n", children); + snmpDebugOid(6, name, len); + + va_start(args, children); + entry = xmalloc(sizeof(mib_tree_entry)); + entry->name = snmpOidDup(name, len); + entry->len = len; + entry->parsefunction = parsefunction; + entry->children = children; + + if(children > 0){ + entry->leaves = xmalloc(sizeof(mib_tree_entry*)*children); + for(loop = 0;loop < children;loop++){ + entry->leaves[loop] = va_arg(args, mib_tree_entry*); + entry->leaves[loop]->parent = entry; + } + } + return(entry); +} +/* End of tree utility functions */ - /* Same length, all bytes identical. Must be the same OID. */ - return (0); +/* + Returns the list of parameters in an oid[] +*/ +oid* +snmpCreateOid(int length, ...) +{ + va_list args; + oid *new_oid; + int loop; + + va_start(args, length); + new_oid = xmalloc(sizeof(oid)*length); + + if(length > 0){ + for(loop = 0;loop < length;loop++){ + new_oid[loop] = va_arg(args, int); + } + } + return(new_oid); } -/* Allocate space for, and copy, an OID. Returns new oid, or NULL. +/* + Allocate space for, and copy, an OID. Returns new oid, or NULL. */ oid * -oiddup(oid * A, snint ALen) +snmpOidDup(oid * A, snint ALen) { oid *Ans; - - Ans = (oid *) xmalloc(sizeof(oid) * ALen); + + Ans = (oid *) xmalloc(sizeof(oid) * ALen); if (Ans) - memcpy(Ans, A, (sizeof(oid) * ALen)); + memcpy(Ans, A, (sizeof(oid) * ALen)); return (Ans); } +/* + Debug calls, prints out the OID for debugging purposes. +*/ +void +snmpDebugOid(int lvl, oid * Name, snint Len) +{ + char mbuf[16], objid[1024]; + int x; + objid[0] = '\0'; -/********************************************************************** - * OIDLIST FUNCTIONS - * - * Find the parsing function for OIDs registered in this agent. - **********************************************************************/ - -oid_ParseFn * -oidlist_Find(oid * Src, snint SrcLen) -{ - struct MIBListEntry *Ptr; - int ret; - - debug(49, 7) ("oidlist_Find: Called.\n "); - snmpDebugOid(7, Src, SrcLen); - - for (Ptr = squidMIBList; Ptr->GetFn; Ptr++) { - - ret = oidncmp(Src, SrcLen, Ptr->Name, Ptr->NameLen, Ptr->NameLen); - - if (!ret) { - - /* Cool. We found the mib it's in. Let it find the function. - */ - debug(49, 7) ("oidlist_Find: found, returning GetFn Ptr! \n"); - - return ((*Ptr->GetFn) (Src, SrcLen)); - } - if (ret < 0) { - debug(49, 7) ("oidlist_Find: We just passed it, so it doesn't exist.\n "); - /* We just passed it, so it doesn't exist. */ - return (NULL); - } + for (x = 0; x < Len; x++) { + snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]); + strncat(objid, mbuf, sizeof(objid)); } - - debug(49, 5) ("oidlist_Find: the request was past the end. It doesn't exist.\n"); - /* We get here if the request was past the end. It doesn't exist. */ - return (NULL); + + debug(49, lvl) (" oid = %s\n", objid); } -/* Find the next item. For SNMP_PDU_GETNEXT requests. - * - * Returns a pointer to the parser function, and copies the oid to dest. - * - * This is just plain ugly and needs a total rewrite, these changes are - * to make it work, nothing else! - * - */ -oid_ParseFn * -oidlist_Next(oid * Src, snint SrcLen, oid ** DestP, snint * DestLenP) -{ - struct MIBListEntry *Ptr; - int ret; - oid_ParseFn *Fn = NULL; - - debug(49, 7) ("oidlist_Next: Looking for next of:\n"); - snmpDebugOid(7, Src, SrcLen); - - for (Ptr = squidMIBList; Ptr->GetNextFn; Ptr++) { - - /* Only look at as much as we have stored */ - ret = oidncmp(Src, SrcLen, Ptr->Name, Ptr->NameLen, Ptr->NameLen); - if (!ret) { - debug(49, 6) ("oidlist_Next: Checking MIB\n"); - - /* Cool. We found the mib it's in. Ask it. - */ - while (Ptr != NULL && Ptr->GetNextFn) { - Fn = ((*Ptr->GetNextFn) (Src, SrcLen, DestP, DestLenP)); - if (Fn == NULL) { - /* If this returned NULL, we're looking for the first - * in the next MIB. - */ - debug(49, 6) ("oidlist_Next: Not in this entry. Trying next.\n"); - Ptr++; - continue; - } - return Fn; - } - /* Return what we found. NULL if it wasn't in the MIB, and there - * were no more MIBs. - */ - debug(49, 3) ("oidlist_Next: No next mib.\n"); - return NULL; - } - if (ret < 0) { - /* We just passed the mib it would be in. Return - * the next in this MIB. - */ - debug(49, 3) ("oidlist_Next: Passed mib. Checking this one.\n"); - while (Ptr != NULL && Ptr->GetNextFn) { - Fn = ((*Ptr->GetNextFn) (Src, SrcLen, DestP, DestLenP)); - if (Fn == NULL && oidncmp(Src, SrcLen, Ptr->Name, Ptr->NameLen, Ptr->NameLen) < 0) { - debug(49, 6) ("oidlist_Next: Not in this entry. Trying next.\n"); - Ptr++; - continue; - } else { - return Fn; - } - } - debug(49, 3) ("oidlist_Next: No next mib.\n"); - return NULL; - } - } +static void +snmpSnmplibDebug(int lvl, char *buf) +{ + debug(49, lvl) ("%s", buf); +} - /* We get here if the request was past the end. It doesn't exist. */ - debug(49, 7) ("oidlist_Next: Found nothing.\n"); - return (NULL); -} -struct in_addr * -gen_getMax() -{ - static struct in_addr maddr; -#if USE_ICMP - safe_inet_addr("255.255.255.255", &maddr); -#else - safe_inet_addr("0.0.0.0", &maddr); -#endif - return &maddr; -} diff --git a/src/structs.h b/src/structs.h index 2a302cf924..6ace70f3b9 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,7 +1,7 @@ /* - * $Id: structs.h,v 1.245 1998/10/19 22:37:05 wessels Exp $ + * $Id: structs.h,v 1.246 1998/11/11 20:04:20 glenn Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -109,36 +109,6 @@ struct _snmp_request_t { u_char *community; }; -struct _viewEntry { - char viewName[32]; - int viewIndex; - int viewType; - int viewSubtreeLen; - oid viewSubtree[32]; - struct _viewEntry *next; -}; - -struct _communityEntry { - char name[64]; - int readView; - int writeView; - acl_access *acls; - communityEntry *next; -}; - -struct _usecEntry { - u_char userName[32]; - int userLen; - int qoS; - u_char authKey[16]; - u_char privKey[16]; - int noauthReadView; - int noauthWriteView; - int authReadView; - int authWriteView; - usecEntry *next; -}; - #endif struct _acl { @@ -171,6 +141,9 @@ struct _aclCheck_t { char browser[BROWSERNAMELEN]; acl_proxy_auth_user *auth_user; acl_lookup_state state[ACL_ENUM_MAX]; +#if SQUID_SNMP + char *snmp_community; +#endif PF *callback; void *callback_data; }; @@ -261,16 +234,7 @@ struct _SquidConfig { struct { char *configFile; char *agentInfo; - char *mibPath; - char *trap_community; - char *trap_sink; u_short localPort; - int do_queueing; - int conf_authtraps; - wordlist *snmpconf; - viewEntry *views; - usecEntry *users; - communityEntry *communities; } Snmp; #endif char *as_whois_server; @@ -387,6 +351,9 @@ struct _SquidConfig { acl_access *AlwaysDirect; acl_access *ASlists; acl_access *noCache; +#if SQUID_SNMP + acl_access *snmp; +#endif } accessList; acl_deny_info_list *denyInfoList; char *proxyAuthRealm; diff --git a/src/typedefs.h b/src/typedefs.h index 14cbd972f3..3d98d5d30c 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.80 1998/10/15 17:34:34 wessels Exp $ + * $Id: typedefs.h,v 1.81 1998/11/11 20:04:21 glenn Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -163,10 +163,8 @@ typedef struct _helper_request helper_request; typedef struct _generic_cbdata generic_cbdata; #if SQUID_SNMP +typedef variable_list *(oid_ParseFn) (variable_list *, snint *); typedef struct _snmp_request_t snmp_request_t; -typedef struct _viewEntry viewEntry; -typedef struct _communityEntry communityEntry; -typedef struct _usecEntry usecEntry; #endif /* define AIOCB even without USE_ASYNC_IO */ -- 2.47.2