]> git.ipfire.org Git - thirdparty/squid.git/blame - src/snmp_core.cc
Fixed a bug and some confusion with ACLChecklist::fastCheck()
[thirdparty/squid.git] / src / snmp_core.cc
CommitLineData
b6a2f15e 1
d2afb1f2 2/*
108d65b2 3 * $Id: snmp_core.cc,v 1.71 2005/12/08 20:08:47 wessels Exp $
43d4303e 4 *
5 * DEBUG: section 49 SNMP support
dba79ac5 6 * AUTHOR: Glenn Chisholm
43d4303e 7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
43d4303e 10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
43d4303e 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
2b6662ba 24 *
43d4303e 25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
2b6662ba 29 *
43d4303e 30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
43d4303e 34 */
43d4303e 35#include "squid.h"
063dc1eb 36#include "comm.h"
43d4303e 37#include "cache_snmp.h"
4fb35c3c 38#include "ACLChecklist.h"
43d4303e 39
40#define SNMP_REQUEST_SIZE 4096
41#define MAX_PROTOSTAT 5
42
b6a2f15e 43typedef struct _mib_tree_entry mib_tree_entry;
44typedef oid *(instance_Fn) (oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
45
62e76326 46struct _mib_tree_entry
47{
c68e9c6b 48 oid *name;
49 int len;
50 oid_ParseFn *parsefunction;
b6a2f15e 51 instance_Fn *instancefunction;
c68e9c6b 52 int children;
62e76326 53
c68e9c6b 54 struct _mib_tree_entry **leaves;
62e76326 55
c68e9c6b 56 struct _mib_tree_entry *parent;
dba79ac5 57};
43d4303e 58
dba79ac5 59mib_tree_entry *mib_tree_head;
b6a2f15e 60mib_tree_entry *mib_tree_last;
43d4303e 61
6de2df60 62#if STDC_HEADERS
b6a2f15e 63static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...);
853dead1 64static oid *snmpCreateOid(int length,...);
8a6218c6 65#else
853dead1 66static mib_tree_entry *snmpAddNode();
67static oid *snmpCreateOid();
8a6218c6 68#endif
8fd63c35 69SQUIDCEXTERN void (*snmplib_debug_hook) (int, char *);
b6a2f15e 70static oid *static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
71static oid *time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
72static oid *peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
73static oid *client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
8a6218c6 74static void snmpDecodePacket(snmp_request_t * rq);
74c161ea 75static void snmpConstructReponse(snmp_request_t * rq);
62e76326 76
897029fd 77static struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU);
c68e9c6b 78static oid_ParseFn *snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen);
d439f213 79static oid_ParseFn *snmpTreeGet(oid * Current, snint CurrentLen);
c68e9c6b 80static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * current);
897029fd 81static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current);
dba79ac5 82static void snmpSnmplibDebug(int lvl, char *buf);
43d4303e 83
43d4303e 84
dba79ac5 85/*
86 * The functions used during startup:
87 * snmpInit
88 * snmpConnectionOpen
89 * snmpConnectionShutdown
90 * snmpConnectionClose
91 */
43d4303e 92
dba79ac5 93/*
c68e9c6b 94 * Turns the MIB into a Tree structure. Called during the startup process.
95 */
43d4303e 96void
97snmpInit(void)
98{
dba79ac5 99 debug(49, 5) ("snmpInit: Called.\n");
100
101 debug(49, 5) ("snmpInit: Building SNMP mib tree structure\n");
102
43d4303e 103 snmplib_debug_hook = snmpSnmplibDebug;
104
dba79ac5 105 mib_tree_head = snmpAddNode(snmpCreateOid(1, 1),
62e76326 106 1, NULL, NULL, 1,
107 snmpAddNode(snmpCreateOid(2, 1, 3),
108 2, NULL, NULL, 1,
109 snmpAddNode(snmpCreateOid(3, 1, 3, 6),
110 3, NULL, NULL, 1,
111 snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1),
112 4, NULL, NULL, 1,
113 snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4),
114 5, NULL, NULL, 1,
115 snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1),
116 6, NULL, NULL, 1,
117 snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495),
118 7, NULL, NULL, 1,
119 snmpAddNode(snmpCreateOid(LEN_SQUIDMIB, SQUIDMIB),
120 8, NULL, NULL, 5,
121 snmpAddNode(snmpCreateOid(LEN_SQ_SYS, SQ_SYS),
122 LEN_SQ_SYS, NULL, NULL, 3,
123 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYSVMSIZ),
124 LEN_SYS, snmp_sysFn, static_Inst, 0),
125 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYSSTOR),
126 LEN_SYS, snmp_sysFn, static_Inst, 0),
127 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYS_UPTIME),
128 LEN_SYS, snmp_sysFn, static_Inst, 0)),
129 snmpAddNode(snmpCreateOid(LEN_SQ_CONF, SQ_CONF),
130 LEN_SQ_CONF, NULL, NULL, 5,
131 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_ADMIN),
132 LEN_SYS, snmp_confFn, static_Inst, 0),
133 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_VERSION),
134 LEN_SYS, snmp_confFn, static_Inst, 0),
135 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_VERSION_ID),
136 LEN_SYS, snmp_confFn, static_Inst, 0),
137 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_LOG_FAC),
138 LEN_SYS, snmp_confFn, static_Inst, 0),
139 snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_STORAGE),
140 LEN_SYS, NULL, NULL, 4,
141 snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_MMAXSZ),
142 LEN_CONF_ST, snmp_confFn, static_Inst, 0),
143 snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWMAXSZ),
144 LEN_CONF_ST, snmp_confFn, static_Inst, 0),
145 snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWHIWM),
146 LEN_CONF_ST, snmp_confFn, static_Inst, 0),
147 snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWLOWM),
148 LEN_CONF_ST, snmp_confFn, static_Inst, 0))),
149 snmpAddNode(snmpCreateOid(LEN_SQ_PRF, SQ_PRF),
150 LEN_SQ_PRF, NULL, NULL, 2,
151 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_SYS),
152 LEN_SQ_PRF + 1, NULL, NULL, 11,
153 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 1),
154 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
155 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 2),
156 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
157 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 3),
158 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
159 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 4),
160 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
161 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 5),
162 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
163 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 6),
164 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
165 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 7),
166 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
167 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 8),
168 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
169 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 9),
170 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
171 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 10),
172 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
173 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 11),
174 LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0)),
175 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_PROTO),
176 LEN_SQ_PRF + 1, NULL, NULL, 2,
177 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 1),
178 LEN_SQ_PRF + 2, NULL, NULL, 15,
179 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 1),
180 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
181 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 2),
182 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
183 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 3),
184 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
185 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 4),
186 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
187 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 5),
188 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
189 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 6),
190 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
191 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 7),
192 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
193 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 8),
194 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
195 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 9),
196 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
197 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 10),
198 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
199 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 11),
200 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
201 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 12),
202 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
203 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 13),
204 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
205 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 14),
206 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
207 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 15),
208 LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0)),
209 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 2),
210 LEN_SQ_PRF + 2, NULL, NULL, 1,
211 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 2, 1),
212 LEN_SQ_PRF + 3, NULL, NULL, 10,
213 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 1),
214 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
215 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 2),
216 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
217 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 3),
218 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
219 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 4),
220 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
221 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 5),
222 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
223 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 6),
224 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
225 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 7),
226 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
227 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 8),
228 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
229 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 9),
230 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
231 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 10),
232 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0))))),
233 snmpAddNode(snmpCreateOid(LEN_SQ_NET, SQ_NET),
234 LEN_SQ_NET, NULL, NULL, 3,
235 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_IP_CACHE),
236 LEN_SQ_NET + 1, NULL, NULL, 8,
237 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_ENT),
238 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
239 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_REQ),
240 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
241 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_HITS),
242 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
243 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_PENDHIT),
244 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
245 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_NEGHIT),
246 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
247 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_MISS),
248 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
249 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_GHBN),
250 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
251 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_LOC),
252 LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0)),
253 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_FQDN_CACHE),
254 LEN_SQ_NET + 1, NULL, NULL, 7,
255 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_ENT),
256 LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
257 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_REQ),
258 LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
259 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_HITS),
260 LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
261 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_PENDHIT),
262 LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
263 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_NEGHIT),
264 LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
265 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_MISS),
266 LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
267 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_GHBN),
268 LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0)),
269 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_DNS_CACHE),
270 LEN_SQ_NET + 1, NULL, NULL, 3,
3c573763 271#if USE_DNSSERVERS
62e76326 272 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
273 LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
274 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
275 LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
276 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
277 LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0))),
3c573763 278#else
62e76326 279 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
280 LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
281 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
282 LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
283 snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
284 LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0))),
3c573763 285#endif
62e76326 286 snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH),
287 LEN_SQ_MESH, NULL, NULL, 2,
288 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 1),
289 LEN_SQ_MESH + 1, NULL, NULL, 1,
290 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1),
291 LEN_SQ_MESH + 2, NULL, NULL, 13,
292 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 1),
293 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
294 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 2),
295 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
296 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 3),
297 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
298 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 4),
299 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
300 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 5),
301 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
302 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 6),
303 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
304 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 7),
305 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
306 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 8),
307 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
308 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 9),
309 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
310 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 10),
311 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
312 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 11),
313 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
314 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 12),
315 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
316 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 13),
317 LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0))),
318 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 2),
319 LEN_SQ_MESH + 1, NULL, NULL, 1,
320 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 2, 1),
321 LEN_SQ_MESH + 2, NULL, NULL, 9,
322 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 1),
323 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
324 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 2),
325 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
326 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 3),
327 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
328 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 4),
329 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
330 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 5),
331 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
332 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 6),
333 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
334 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 7),
335 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
336 snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 8),
337 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
338 (mib_tree_last = snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 9),
339 LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0)))))
340 )
341 )
342 )
343 )
344 )
345 )
346 )
347 );
dba79ac5 348
349 debug(49, 9) ("snmpInit: Completed SNMP mib tree structure\n");
43d4303e 350}
351
352void
353snmpConnectionOpen(void)
354{
355 u_short port;
62e76326 356
43d4303e 357 struct sockaddr_in xaddr;
6637e3a5 358 socklen_t len;
43d4303e 359 int x;
360
c68e9c6b 361 debug(49, 5) ("snmpConnectionOpen: Called\n");
62e76326 362
43d4303e 363 if ((port = Config.Port.snmp) > (u_short) 0) {
62e76326 364 enter_suid();
365 theInSnmpConnection = comm_open(SOCK_DGRAM,
bdb741f4 366 IPPROTO_UDP,
62e76326 367 Config.Addrs.snmp_incoming,
368 port,
369 COMM_NONBLOCKING,
370 "SNMP Port");
371 leave_suid();
372
373 if (theInSnmpConnection < 0)
374 fatal("Cannot open snmp Port");
375
376 commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
377
378 debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",
379 (int) port, theInSnmpConnection);
380
381 if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) {
382 enter_suid();
383 theOutSnmpConnection = comm_open(SOCK_DGRAM,
bdb741f4 384 IPPROTO_UDP,
62e76326 385 Config.Addrs.snmp_outgoing,
386 port,
387 COMM_NONBLOCKING,
388 "SNMP Port");
389 leave_suid();
390
391 if (theOutSnmpConnection < 0)
392 fatal("Cannot open Outgoing SNMP Port");
393
394 commSetSelect(theOutSnmpConnection,
395 COMM_SELECT_READ,
396 snmpHandleUdp,
397 NULL, 0);
398
399 debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",
400 (int) port, theOutSnmpConnection);
401
402 fd_note(theOutSnmpConnection, "Outgoing SNMP socket");
403
404 fd_note(theInSnmpConnection, "Incoming SNMP socket");
405 } else {
406 theOutSnmpConnection = theInSnmpConnection;
407 }
408
ddfcbc22 409 memset(&theOutSNMPAddr, '\0', sizeof(struct IN_ADDR));
62e76326 410
411 len = sizeof(struct sockaddr_in);
412 memset(&xaddr, '\0', len);
413 x = getsockname(theOutSnmpConnection,
414
415 (struct sockaddr *) &xaddr, &len);
416
417 if (x < 0)
418 debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n",
419 theOutSnmpConnection, xstrerror());
420 else
421 theOutSNMPAddr = xaddr.sin_addr;
43d4303e 422 }
423}
424
43d4303e 425void
426snmpConnectionShutdown(void)
427{
428 if (theInSnmpConnection < 0)
62e76326 429 return;
430
43d4303e 431 if (theInSnmpConnection != theOutSnmpConnection) {
62e76326 432 debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection);
433 comm_close(theInSnmpConnection);
43d4303e 434 }
62e76326 435
43d4303e 436 /*
437 * Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'
438 * and 'out' sockets might be just one FD. This prevents this
439 * function from executing repeatedly. When we are really ready to
440 * exit or restart, main will comm_close the 'out' descriptor.
441 */ theInSnmpConnection = -1;
62e76326 442
dba79ac5 443 /*
43d4303e 444 * Normally we only write to the outgoing SNMP socket, but we
445 * also have a read handler there to catch messages sent to that
446 * specific interface. During shutdown, we must disable reading
447 * on the outgoing socket.
448 */
449 assert(theOutSnmpConnection > -1);
62e76326 450
43d4303e 451 commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
452}
453
454void
455snmpConnectionClose(void)
456{
457 snmpConnectionShutdown();
62e76326 458
43d4303e 459 if (theOutSnmpConnection > -1) {
62e76326 460 debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection);
461 comm_close(theOutSnmpConnection);
43d4303e 462 }
463}
464
dba79ac5 465/*
c68e9c6b 466 * Functions for handling the requests.
467 */
43d4303e 468
dba79ac5 469/*
470 * Accept the UDP packet
471 */
43d4303e 472void
dba79ac5 473snmpHandleUdp(int sock, void *not_used)
43d4303e 474{
dba79ac5 475 LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
62e76326 476
dba79ac5 477 struct sockaddr_in from;
478 socklen_t from_len;
479 snmp_request_t *snmp_rq;
480 int len;
481
482 debug(49, 5) ("snmpHandleUdp: Called.\n");
483
484 commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
62e76326 485
dba79ac5 486 from_len = sizeof(struct sockaddr_in);
487 memset(&from, '\0', from_len);
ec603b25 488 memset(buf, '\0', SNMP_REQUEST_SIZE);
dba79ac5 489
7d21986b 490 len = comm_udp_recvfrom(sock,
62e76326 491 buf,
492 SNMP_REQUEST_SIZE,
493 0,
494
495 (struct sockaddr *) &from,
496 &from_len);
dba79ac5 497
498 if (len > 0) {
62e76326 499 buf[len] = '\0';
500 debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
501 sock,
502 len,
503 inet_ntoa(from.sin_addr));
504
505 snmp_rq = (snmp_request_t *)xcalloc(1, sizeof(snmp_request_t));
506 snmp_rq->buf = (u_char *) buf;
507 snmp_rq->len = len;
508 snmp_rq->sock = sock;
509 snmp_rq->outbuf = (unsigned char *)xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);
510
511 xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));
512 snmpDecodePacket(snmp_rq);
513 xfree(snmp_rq->outbuf);
514 xfree(snmp_rq);
dba79ac5 515 } else {
62e76326 516 debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror());
dba79ac5 517 }
518}
43d4303e 519
dba79ac5 520/*
521 * Turn SNMP packet into a PDU, check available ACL's
522 */
9bc73deb 523static void
dba79ac5 524snmpDecodePacket(snmp_request_t * rq)
525{
62e76326 526
43d4303e 527 struct snmp_pdu *PDU;
62e76326 528
43d4303e 529 u_char *Community;
dba79ac5 530 u_char *buf = rq->buf;
531 int len = rq->len;
532 int allow = 0;
43d4303e 533
dba79ac5 534 debug(49, 5) ("snmpDecodePacket: Called.\n");
43d4303e 535 /* Now that we have the data, turn it into a PDU */
43d4303e 536 PDU = snmp_pdu_create(0);
0536fdfc 537 rq->session.Version = SNMP_VERSION_1;
538 Community = snmp_parse(&rq->session, PDU, buf, len);
dba79ac5 539 checklist.src_addr = rq->from.sin_addr;
f89fe82e 540 checklist.snmp_community = (char *) Community;
dba79ac5 541
506768d9 542 if (Community) {
108d65b2 543 ACLChecklist checklist;
506768d9 544 checklist.accessList = cbdataReference(Config.accessList.snmp);
108d65b2 545 /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
b448c119 546 allow = checklist.fastCheck();
506768d9 547 }
62e76326 548
dba79ac5 549 if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
62e76326 550 rq->community = Community;
551 rq->PDU = PDU;
552 debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid);
553 snmpConstructReponse(rq);
dba79ac5 554 } else {
62e76326 555 debug(49, 1) ("Failed SNMP agent query from : %s.\n",
556 inet_ntoa(rq->from.sin_addr));
557 snmp_free_pdu(PDU);
43d4303e 558 }
62e76326 559
5f0dc264 560 if (Community)
62e76326 561 xfree(Community);
dba79ac5 562}
43d4303e 563
dba79ac5 564/*
565 * Packet OK, ACL Check OK, Create reponse.
566 */
9bc73deb 567static void
74c161ea 568snmpConstructReponse(snmp_request_t * rq)
dba79ac5 569{
62e76326 570
dba79ac5 571 struct snmp_pdu *RespPDU;
74c161ea 572
dba79ac5 573 debug(49, 5) ("snmpConstructReponse: Called.\n");
dba79ac5 574 RespPDU = snmpAgentResponse(rq->PDU);
575 snmp_free_pdu(rq->PDU);
62e76326 576
ecd2a33f 577 if (RespPDU != NULL) {
0536fdfc 578 snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen);
62e76326 579 comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen);
580 snmp_free_pdu(RespPDU);
43d4303e 581 }
43d4303e 582}
583
dba79ac5 584/*
585 * Decide how to respond to the request, construct a response and
586 * return the response to the requester.
dba79ac5 587 */
62e76326 588
9bc73deb 589static struct snmp_pdu *
62e76326 590
591 snmpAgentResponse(struct snmp_pdu *PDU)
43d4303e 592{
62e76326 593
43d4303e 594 struct snmp_pdu *Answer = NULL;
43d4303e 595
dba79ac5 596 debug(49, 5) ("snmpAgentResponse: Called.\n");
43d4303e 597
62e76326 598 if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE)))
599 {
600 Answer->reqid = PDU->reqid;
601 Answer->errindex = 0;
602
0536fdfc 603 if (PDU->command == SNMP_PDU_GET || PDU->command == SNMP_PDU_GETNEXT) {
604 int get_next = (PDU->command == SNMP_PDU_GETNEXT);
605 variable_list *VarPtr_;
606 variable_list **RespVars = &(Answer->variables);
607 oid_ParseFn *ParseFn;
608 int index = 0;
62e76326 609 /* Loop through all variables */
610
0536fdfc 611 for (VarPtr_ = PDU->variables; VarPtr_; VarPtr_ = VarPtr_->next_variable) {
612 variable_list *VarPtr = VarPtr_;
613 variable_list *VarNew = NULL;
614 oid *NextOidName = NULL;
615 snint NextOidNameLen = 0;
62e76326 616
617 index++;
618
619 /* Find the parsing function for this variable */
0536fdfc 620
621 if (get_next)
622 ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen);
623 else
624 ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length);
62e76326 625
626 if (ParseFn == NULL) {
627 Answer->errstat = SNMP_ERR_NOSUCHNAME;
628 debug(49, 5) ("snmpAgentResponse: No such oid. ");
0536fdfc 629 } else {
630 if (get_next) {
631 VarPtr = snmp_var_new(NextOidName, NextOidNameLen);
632 xfree(NextOidName);
633 }
634
62e76326 635 VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat));
636
0536fdfc 637 if (get_next)
638 snmp_var_free(VarPtr);
639 }
640
62e76326 641 /* Was there an error? */
0536fdfc 642 if ((Answer->errstat != SNMP_ERR_NOERROR) || (VarNew == NULL)) {
62e76326 643 Answer->errindex = index;
0536fdfc 644 debug(49, 5) ("snmpAgentResponse: error.\n");
645
646 if (VarNew)
647 snmp_var_free(VarNew);
648
649 /* Free the already processed results, if any */
650 while ((VarPtr = Answer->variables) != NULL) {
651 Answer->variables = VarPtr->next_variable;
652 snmp_var_free(VarPtr);
653 }
654
655 /* Steal the original PDU list of variables for the error response */
656 Answer->variables = PDU->variables;
657
658 PDU->variables = NULL;
659
62e76326 660 return (Answer);
661 }
662
663 /* No error. Insert this var at the end, and move on to the next.
664 */
665 *RespVars = VarNew;
666
667 RespVars = &(VarNew->next_variable);
668 }
62e76326 669 }
dba79ac5 670 }
62e76326 671
dba79ac5 672 return (Answer);
673}
b644367b 674
9bc73deb 675static oid_ParseFn *
d439f213 676snmpTreeGet(oid * Current, snint CurrentLen)
677{
678 oid_ParseFn *Fn = NULL;
1810dde6 679 mib_tree_entry *mibTreeEntry = NULL;
d439f213 680 int count = 0;
681
682 debug(49, 5) ("snmpTreeGet: Called\n");
683
684 debug(49, 6) ("snmpTreeGet: Current : \n");
685 snmpDebugOid(6, Current, CurrentLen);
686
687 mibTreeEntry = mib_tree_head;
62e76326 688
d439f213 689 if (Current[count] == mibTreeEntry->name[count]) {
62e76326 690 count++;
691
692 while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
693 mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
694 count++;
695 }
d439f213 696 }
62e76326 697
ec603b25 698 if (mibTreeEntry && mibTreeEntry->parsefunction)
62e76326 699 Fn = mibTreeEntry->parsefunction;
700
d439f213 701 debug(49, 5) ("snmpTreeGet: return\n");
62e76326 702
d439f213 703 return (Fn);
704}
705
9bc73deb 706static oid_ParseFn *
dba79ac5 707snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
708{
709 oid_ParseFn *Fn = NULL;
897029fd 710 mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;
dba79ac5 711 int count = 0;
712
713 debug(49, 5) ("snmpTreeNext: Called\n");
714
715 debug(49, 6) ("snmpTreeNext: Current : \n");
716 snmpDebugOid(6, Current, CurrentLen);
b644367b 717
dba79ac5 718 mibTreeEntry = mib_tree_head;
62e76326 719
dba79ac5 720 if (Current[count] == mibTreeEntry->name[count]) {
62e76326 721 count++;
722
723 while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
aa6d85ce 724 mib_tree_entry *nextmibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
725
726 if (!nextmibTreeEntry)
727 break;
728 else
729 mibTreeEntry = nextmibTreeEntry;
730
62e76326 731 count++;
732 }
733
734 debug(49, 5) ("snmpTreeNext: Recursed down to requested object\n");
b6a2f15e 735 } else {
62e76326 736 return NULL;
b6a2f15e 737 }
62e76326 738
b6a2f15e 739 if (mibTreeEntry == mib_tree_last)
62e76326 740 return (Fn);
741
b6a2f15e 742 if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
62e76326 743 *NextLen = CurrentLen;
744 *Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
745
746 if (*Next)
747 return (Fn);
b6a2f15e 748 }
62e76326 749
b6a2f15e 750 if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
62e76326 751 count--;
752 nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
753
754 if (nextoid) {
755 debug(49, 5) ("snmpTreeNext: Next OID found for sibling\n");
756 mibTreeEntry = nextoid;
757 count++;
758 } else {
759 debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next object\n");
760
761 while (!nextoid) {
762 count--;
763
764 if (mibTreeEntry->parent->parent) {
765 nextoid = mibTreeEntry->parent;
766 mibTreeEntry = snmpTreeEntry(Current[count] + 1, count, nextoid->parent);
767
768 if (!mibTreeEntry) {
769 mibTreeEntry = nextoid;
770 nextoid = NULL;
771 }
772 } else {
773 nextoid = mibTreeEntry;
774 mibTreeEntry = NULL;
775 }
776 }
777 }
b6a2f15e 778 }
62e76326 779
b6a2f15e 780 while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) {
62e76326 781 mibTreeEntry = mibTreeEntry->leaves[0];
dba79ac5 782 }
62e76326 783
c68e9c6b 784 if (mibTreeEntry) {
62e76326 785 *NextLen = mibTreeEntry->len;
786 *Next = (*mibTreeEntry->instancefunction) (mibTreeEntry->name, NextLen, mibTreeEntry, &Fn);
dba79ac5 787 }
62e76326 788
96ca8fa1 789 if (*Next)
62e76326 790 return (Fn);
96ca8fa1 791 else
62e76326 792 return NULL;
43d4303e 793}
794
9bc73deb 795static oid *
b6a2f15e 796static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
797{
798 oid *instance = NULL;
799
800 if (*len <= current->len) {
62e76326 801 instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
802 xmemcpy(instance, name, (sizeof(name) * *len));
803 instance[*len] = 0;
804 *len += 1;
b6a2f15e 805 }
62e76326 806
b6a2f15e 807 *Fn = current->parsefunction;
808 return (instance);
809}
810
9bc73deb 811static oid *
b6a2f15e 812time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
813{
814 oid *instance = NULL;
815 int identifier = 0, loop = 0;
816 int index[TIME_INDEX_LEN] =
62e76326 817 {TIME_INDEX};
b6a2f15e 818
819 if (*len <= current->len) {
62e76326 820 instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
821 xmemcpy(instance, name, (sizeof(name) * *len));
822 instance[*len] = *index;
823 *len += 1;
b6a2f15e 824 } else {
62e76326 825 identifier = name[*len - 1];
826
827 while ((identifier != index[loop]) && (loop < TIME_INDEX_LEN))
828 loop++;
829
830 if (loop < TIME_INDEX_LEN - 1) {
831 instance = (oid *)xmalloc(sizeof(name) * (*len));
832 xmemcpy(instance, name, (sizeof(name) * *len));
833 instance[*len - 1] = index[++loop];
834 }
b6a2f15e 835 }
62e76326 836
b6a2f15e 837 *Fn = current->parsefunction;
838 return (instance);
839}
840
9bc73deb 841static oid *
b6a2f15e 842peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
843{
844 oid *instance = NULL;
845 u_char *cp = NULL;
846 peer *peers = Config.peers;
62e76326 847
ddfcbc22 848 struct IN_ADDR *laddr = NULL;
b6a2f15e 849 char *host_addr = NULL, *current_addr = NULL, *last_addr = NULL;
850
851 if (peers == NULL) {
62e76326 852 current = current->parent->parent->parent->leaves[1];
853
854 while ((current) && (!current->parsefunction))
855 current = current->leaves[0];
856
857 instance = client_Inst(current->name, len, current, Fn);
b6a2f15e 858 } else if (*len <= current->len) {
62e76326 859 instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
860 xmemcpy(instance, name, (sizeof(name) * *len));
861 cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
862 instance[*len] = *cp++;
863 instance[*len + 1] = *cp++;
864 instance[*len + 2] = *cp++;
865 instance[*len + 3] = *cp++;
866 *len += 4;
b6a2f15e 867 } else {
62e76326 868 laddr = oid2addr(&name[*len - 4]);
869 host_addr = inet_ntoa(*laddr);
870 last_addr = (char *)xmalloc(strlen(host_addr));
871 strncpy(last_addr, host_addr, strlen(host_addr));
872 current_addr = inet_ntoa(peers->in_addr.sin_addr);
873
874 while ((peers) && (strncmp(last_addr, current_addr, strlen(current_addr)))) {
875 if (peers->next) {
876 peers = peers->next;
877 current_addr = inet_ntoa(peers->in_addr.sin_addr);
878 } else {
879 peers = NULL;
880 }
881 }
882
883 xfree(last_addr);
884
885 if (peers) {
886 if (peers->next) {
887 peers = peers->next;
888 instance = (oid *)xmalloc(sizeof(name) * (*len));
889 xmemcpy(instance, name, (sizeof(name) * *len));
890 cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
891 instance[*len - 4] = *cp++;
892 instance[*len - 3] = *cp++;
893 instance[*len - 2] = *cp++;
894 instance[*len - 1] = *cp++;
895 } else {
896 return (instance);
897 }
898 } else {
899 return (instance);
900 }
b6a2f15e 901 }
62e76326 902
b6a2f15e 903 *Fn = current->parsefunction;
904 return (instance);
905}
906
9bc73deb 907static oid *
b6a2f15e 908client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
909{
910 oid *instance = NULL;
911 u_char *cp = NULL;
62e76326 912
ddfcbc22 913 struct IN_ADDR *laddr = NULL;
b6a2f15e 914
915 if (*len <= current->len) {
62e76326 916 instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
917 xmemcpy(instance, name, (sizeof(name) * *len));
918 laddr = client_entry(NULL);
919
920 if (laddr) {
921 cp = (u_char *) & (laddr->s_addr);
922 instance[*len] = *cp++;
923 instance[*len + 1] = *cp++;
924 instance[*len + 2] = *cp++;
925 instance[*len + 3] = *cp++;
926 *len += 4;
927 }
b6a2f15e 928 } else {
62e76326 929 laddr = oid2addr(&name[*len - 4]);
930 laddr = client_entry(laddr);
931
932 if (laddr) {
933 instance = (oid *)xmalloc(sizeof(name) * (*len));
934 xmemcpy(instance, name, (sizeof(name) * *len));
935 cp = (u_char *) & (laddr->s_addr);
936 instance[*len - 4] = *cp++;
937 instance[*len - 3] = *cp++;
938 instance[*len - 2] = *cp++;
939 instance[*len - 1] = *cp++;
940 }
b6a2f15e 941 }
62e76326 942
b6a2f15e 943 *Fn = current->parsefunction;
944 return (instance);
945}
946
947
948/*
949 * Utility functions
950 */
951
952/*
953 * Tree utility functions.
954 */
955
62e76326 956/*
b6a2f15e 957 * Returns a the sibling object in the tree
958 */
9bc73deb 959static mib_tree_entry *
897029fd 960snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
43d4303e 961{
dba79ac5 962 mib_tree_entry *next = NULL;
963 int count = 0;
8a6218c6 964
897029fd 965 while ((!next) && (count < current->children)) {
62e76326 966 if (current->leaves[count]->name[len] == entry) {
967 next = current->leaves[count];
968 }
969
970 count++;
897029fd 971 }
62e76326 972
8a6218c6 973 if (count < current->children) {
62e76326 974 next = current->leaves[count];
8a6218c6 975 } else {
62e76326 976 next = NULL;
897029fd 977 }
62e76326 978
897029fd 979 return (next);
980}
665bc266 981
62e76326 982/*
b6a2f15e 983 * Returns the requested child object or NULL if it does not exist
984 */
9bc73deb 985static mib_tree_entry *
897029fd 986snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
987{
988 mib_tree_entry *next = NULL;
989 int count = 0;
43d4303e 990
dba79ac5 991 while ((!next) && (count < current->children)) {
62e76326 992 if (current->leaves[count]->name[len] == entry) {
993 next = current->leaves[count];
994 }
995
996 count++;
43d4303e 997 }
62e76326 998
dba79ac5 999 return (next);
1000}
43d4303e 1001
d439f213 1002/*
1003 * Adds a node to the MIB tree structure and adds the appropriate children
1004 */
9bc73deb 1005static mib_tree_entry *
1952717f 1006#if STDC_HEADERS
b6a2f15e 1007snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
1952717f 1008#else
1009snmpAddNode(va_alist)
62e76326 1010va_dcl
fa86210b 1011#endif
d439f213 1012{
1952717f 1013#if STDC_HEADERS
d439f213 1014 va_list args;
1015 int loop;
1016 mib_tree_entry *entry = NULL;
b6a2f15e 1017 va_start(args, children);
853dead1 1018#else
62e76326 1019
853dead1 1020 va_list args;
1021 oid *name = NULL;
1022 int len = 0, children = 0, loop;
1023 oid_ParseFn *parsefunction = NULL;
b6a2f15e 1024 instance_Fn *instancefunction = NULL;
853dead1 1025 mib_tree_entry *entry = NULL;
b6a2f15e 1026 va_start(args);
1027 name = va_arg(args, oid *);
1028 len = va_arg(args, int);
1029 parsefunction = va_arg(args, oid_ParseFn *);
1030 instancefunction = va_arg(args, instance_Fn *);
1031 children = va_arg(args, int);
853dead1 1032#endif
d439f213 1033
b6a2f15e 1034 debug(49, 6) ("snmpAddNode: Children : %d, Oid : \n", children);
1035 snmpDebugOid(6, name, len);
d439f213 1036
b6a2f15e 1037 va_start(args, children);
e6ccf245 1038 entry = (mib_tree_entry *)xmalloc(sizeof(mib_tree_entry));
6ccbae85 1039 entry->name = name;
b6a2f15e 1040 entry->len = len;
1041 entry->parsefunction = parsefunction;
1042 entry->instancefunction = instancefunction;
1043 entry->children = children;
d439f213 1044
62e76326 1045 if (children > 0)
1046 {
1047 entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children);
1048
1049 for (loop = 0; loop < children; loop++) {
1050 entry->leaves[loop] = va_arg(args, mib_tree_entry *);
1051 entry->leaves[loop]->parent = entry;
1052 }
d439f213 1053 }
62e76326 1054
d439f213 1055 return (entry);
1056}
1057/* End of tree utility functions */
1058
62e76326 1059/*
61d53e64 1060 * Returns the list of parameters in an oid
c68e9c6b 1061 */
9bc73deb 1062static oid *
1952717f 1063#if STDC_HEADERS
c68e9c6b 1064snmpCreateOid(int length,...)
1952717f 1065#else
1066snmpCreateOid(va_alist)
62e76326 1067va_dcl
1952717f 1068#endif
dba79ac5 1069{
1952717f 1070#if STDC_HEADERS
c68e9c6b 1071 va_list args;
1072 oid *new_oid;
1073 int loop;
c68e9c6b 1074 va_start(args, length);
853dead1 1075#else
62e76326 1076
853dead1 1077 va_list args;
1078 int length = 0, loop;
1079 oid *new_oid;
853dead1 1080 va_start(args);
1081 length va_arg(args, int);
1082#endif
8a6218c6 1083
e6ccf245 1084 new_oid = (oid *)xmalloc(sizeof(oid) * length);
c68e9c6b 1085
62e76326 1086 if (length > 0)
1087 {
1088 for (loop = 0; loop < length; loop++) {
1089 new_oid[loop] = va_arg(args, int);
1090 }
c68e9c6b 1091 }
62e76326 1092
c68e9c6b 1093 return (new_oid);
43d4303e 1094}
1095
7b01964d 1096#if UNUSED_CODE
dba79ac5 1097/*
5898ce23 1098 * Allocate space for, and copy, an OID. Returns new oid.
43d4303e 1099 */
9bc73deb 1100static oid *
dba79ac5 1101snmpOidDup(oid * A, snint ALen)
43d4303e 1102{
5898ce23 1103 oid *Ans = xmalloc(sizeof(oid) * ALen);
1104 xmemcpy(Ans, A, (sizeof(oid) * ALen));
1105 return Ans;
43d4303e 1106}
62e76326 1107
7b01964d 1108#endif
43d4303e 1109
dba79ac5 1110/*
c68e9c6b 1111 * Debug calls, prints out the OID for debugging purposes.
1112 */
dba79ac5 1113void
1114snmpDebugOid(int lvl, oid * Name, snint Len)
c68e9c6b 1115{
dba79ac5 1116 char mbuf[16], objid[1024];
1117 int x;
1118 objid[0] = '\0';
43d4303e 1119
dba79ac5 1120 for (x = 0; x < Len; x++) {
62e76326 1121 snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
1122 strncat(objid, mbuf, sizeof(objid));
43d4303e 1123 }
c68e9c6b 1124
dba79ac5 1125 debug(49, lvl) (" oid = %s\n", objid);
43d4303e 1126}
b644367b 1127
c68e9c6b 1128static void
dba79ac5 1129snmpSnmplibDebug(int lvl, char *buf)
c68e9c6b 1130{
dba79ac5 1131 debug(49, lvl) ("%s", buf);
c68e9c6b 1132}
b6a2f15e 1133
1134void
62e76326 1135
ddfcbc22 1136addr2oid(struct IN_ADDR addr, oid * Dest)
b6a2f15e 1137{
1138 u_char *cp;
1139 cp = (u_char *) & (addr.s_addr);
1140 Dest[0] = *cp++;
1141 Dest[1] = *cp++;
1142 Dest[2] = *cp++;
1143 Dest[3] = *cp++;
1144}
1145
ddfcbc22 1146struct IN_ADDR
62e76326 1147 *
1148 oid2addr(oid * id)
b6a2f15e 1149{
62e76326 1150
ddfcbc22 1151 static struct IN_ADDR laddr;
b6a2f15e 1152 u_char *cp = (u_char *) & (laddr.s_addr);
1153 cp[0] = id[0];
1154 cp[1] = id[1];
1155 cp[2] = id[2];
1156 cp[3] = id[3];
1157 return &laddr;
1158}
b0dd28ba 1159
1160/* SNMP checklists */
1161#include "ACLStrategy.h"
1162#include "ACLStrategised.h"
1163#include "ACLStringData.h"
1164
1165class ACLSNMPCommunityStrategy : public ACLStrategy<char const *>
1166{
1167
1168public:
1169 virtual int match (ACLData<MatchType> * &, ACLChecklist *);
1170 static ACLSNMPCommunityStrategy *Instance();
1171 /* Not implemented to prevent copies of the instance. */
1172 /* Not private to prevent brain dead g+++ warnings about
1173 * private constructors with no friends */
1174 ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &);
1175
1176private:
1177 static ACLSNMPCommunityStrategy Instance_;
1178 ACLSNMPCommunityStrategy(){}
1179
1180 ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &);
1181};
1182
1183class ACLSNMPCommunity
1184{
1185
1186private:
1187 static ACL::Prototype RegistryProtoype;
1188 static ACLStrategised<char const *> RegistryEntry_;
1189};
1190
1191ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community");
1192ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
1193
1194int
1195ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
1196{
1197 return data->match (checklist->snmp_community);
b0dd28ba 1198}
1199
1200ACLSNMPCommunityStrategy *
1201ACLSNMPCommunityStrategy::Instance()
1202{
1203 return &Instance_;
1204}
1205
1206ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_;