]> git.ipfire.org Git - thirdparty/squid.git/blame - src/snmp_core.cc
Bug #1267: Cosmetic change to DISKD statistics
[thirdparty/squid.git] / src / snmp_core.cc
CommitLineData
b6a2f15e 1
d2afb1f2 2/*
ddfcbc22 3 * $Id: snmp_core.cc,v 1.66 2005/04/18 21:52:43 hno 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
74c161ea 529 struct snmp_session Session;
43d4303e 530 u_char *Community;
dba79ac5 531 u_char *buf = rq->buf;
532 int len = rq->len;
533 int allow = 0;
43d4303e 534
dba79ac5 535 debug(49, 5) ("snmpDecodePacket: Called.\n");
43d4303e 536 /* Now that we have the data, turn it into a PDU */
43d4303e 537 PDU = snmp_pdu_create(0);
227e68b6 538 Session.Version = SNMP_VERSION_1;
74c161ea 539 Community = snmp_parse(&Session, PDU, buf, len);
4fb35c3c 540 ACLChecklist checklist;
dba79ac5 541 checklist.src_addr = rq->from.sin_addr;
f89fe82e 542 checklist.snmp_community = (char *) Community;
b448c119 543 checklist.accessList = Config.accessList.snmp;
dba79ac5 544
ec18aedf 545 if (Community)
b448c119 546 allow = checklist.fastCheck();
547
548 checklist.accessList = NULL;
62e76326 549
dba79ac5 550 if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
62e76326 551 rq->community = Community;
552 rq->PDU = PDU;
553 debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid);
554 snmpConstructReponse(rq);
dba79ac5 555 } else {
62e76326 556 debug(49, 1) ("Failed SNMP agent query from : %s.\n",
557 inet_ntoa(rq->from.sin_addr));
558 snmp_free_pdu(PDU);
43d4303e 559 }
62e76326 560
5f0dc264 561 if (Community)
62e76326 562 xfree(Community);
dba79ac5 563}
43d4303e 564
dba79ac5 565/*
566 * Packet OK, ACL Check OK, Create reponse.
567 */
9bc73deb 568static void
74c161ea 569snmpConstructReponse(snmp_request_t * rq)
dba79ac5 570{
62e76326 571
74c161ea 572 struct snmp_session Session;
62e76326 573
dba79ac5 574 struct snmp_pdu *RespPDU;
74c161ea 575
dba79ac5 576 debug(49, 5) ("snmpConstructReponse: Called.\n");
dba79ac5 577 RespPDU = snmpAgentResponse(rq->PDU);
578 snmp_free_pdu(rq->PDU);
62e76326 579
ecd2a33f 580 if (RespPDU != NULL) {
62e76326 581 Session.Version = SNMP_VERSION_1;
582 Session.community = rq->community;
583 Session.community_len = strlen((char *) rq->community);
584 snmp_build(&Session, RespPDU, rq->outbuf, &rq->outlen);
585 comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen);
586 snmp_free_pdu(RespPDU);
43d4303e 587 }
43d4303e 588}
589
dba79ac5 590/*
591 * Decide how to respond to the request, construct a response and
592 * return the response to the requester.
dba79ac5 593 */
62e76326 594
9bc73deb 595static struct snmp_pdu *
62e76326 596
597 snmpAgentResponse(struct snmp_pdu *PDU)
43d4303e 598{
62e76326 599
43d4303e 600 struct snmp_pdu *Answer = NULL;
dba79ac5 601 oid_ParseFn *ParseFn = NULL;
d439f213 602
603 variable_list *VarPtr, *VarNew = NULL, **VarPtrP;
604 int index = 0;
43d4303e 605
dba79ac5 606 debug(49, 5) ("snmpAgentResponse: Called.\n");
43d4303e 607
62e76326 608 if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE)))
609 {
610 Answer->reqid = PDU->reqid;
611 Answer->errindex = 0;
612
613 if (PDU->command == SNMP_PDU_GET) {
614 variable_list **RespVars;
615
616 RespVars = &(Answer->variables);
617 /* Loop through all variables */
618
619 for (VarPtrP = &(PDU->variables);
620 *VarPtrP;
621 VarPtrP = &((*VarPtrP)->next_variable)) {
622 VarPtr = *VarPtrP;
623
624 index++;
625
626 /* Find the parsing function for this variable */
627 ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length);
628
629 if (ParseFn == NULL) {
630 Answer->errstat = SNMP_ERR_NOSUCHNAME;
631 debug(49, 5) ("snmpAgentResponse: No such oid. ");
632 } else
633 VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat));
634
635 /* Was there an error? */
636 if ((Answer->errstat != SNMP_ERR_NOERROR) ||
637 (VarNew == NULL)) {
638 Answer->errindex = index;
639 debug(49, 5) ("snmpAgentParse: successful.\n");
640 /* Just copy the rest of the variables. Quickly. */
641 *RespVars = VarPtr;
642 *VarPtrP = NULL;
643 return (Answer);
644 }
645
646 /* No error. Insert this var at the end, and move on to the next.
647 */
648 *RespVars = VarNew;
649
650 RespVars = &(VarNew->next_variable);
651 }
652
653 return (Answer);
654 } else if (PDU->command == SNMP_PDU_GETNEXT) {
655 oid *NextOidName = NULL;
656 int NextOidNameLen = 0;
657
658 ParseFn = snmpTreeNext(PDU->variables->name, PDU->variables->name_length,
659 &(NextOidName), (snint *) & NextOidNameLen);
660
661 if (ParseFn == NULL) {
662 Answer->errstat = SNMP_ERR_NOSUCHNAME;
663 debug(49, 5) ("snmpAgentResponse: No such oid: ");
664 snmpDebugOid(5, PDU->variables->name, PDU->variables->name_length);
665 } else {
666 xfree(PDU->variables->name);
667 PDU->variables->name = NextOidName;
668 PDU->variables->name_length = NextOidNameLen;
669 VarNew = (*ParseFn) (PDU->variables, (snint *) & Answer->errstat);
670 }
671
672 /* Was there an error? */
673 if (Answer->errstat != SNMP_ERR_NOERROR) {
674 Answer->errindex = 1;
675 Answer->variables = PDU->variables;
676 PDU->variables = NULL;
677 } else {
678 Answer->variables = VarNew;
679 }
680
681 } else {
682 snmp_free_pdu(Answer);
683 Answer = NULL;
684 }
dba79ac5 685 }
62e76326 686
dba79ac5 687 return (Answer);
688}
b644367b 689
9bc73deb 690static oid_ParseFn *
d439f213 691snmpTreeGet(oid * Current, snint CurrentLen)
692{
693 oid_ParseFn *Fn = NULL;
1810dde6 694 mib_tree_entry *mibTreeEntry = NULL;
d439f213 695 int count = 0;
696
697 debug(49, 5) ("snmpTreeGet: Called\n");
698
699 debug(49, 6) ("snmpTreeGet: Current : \n");
700 snmpDebugOid(6, Current, CurrentLen);
701
702 mibTreeEntry = mib_tree_head;
62e76326 703
d439f213 704 if (Current[count] == mibTreeEntry->name[count]) {
62e76326 705 count++;
706
707 while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
708 mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
709 count++;
710 }
d439f213 711 }
62e76326 712
ec603b25 713 if (mibTreeEntry && mibTreeEntry->parsefunction)
62e76326 714 Fn = mibTreeEntry->parsefunction;
715
d439f213 716 debug(49, 5) ("snmpTreeGet: return\n");
62e76326 717
d439f213 718 return (Fn);
719}
720
9bc73deb 721static oid_ParseFn *
dba79ac5 722snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
723{
724 oid_ParseFn *Fn = NULL;
897029fd 725 mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;
dba79ac5 726 int count = 0;
727
728 debug(49, 5) ("snmpTreeNext: Called\n");
729
730 debug(49, 6) ("snmpTreeNext: Current : \n");
731 snmpDebugOid(6, Current, CurrentLen);
b644367b 732
dba79ac5 733 mibTreeEntry = mib_tree_head;
62e76326 734
dba79ac5 735 if (Current[count] == mibTreeEntry->name[count]) {
62e76326 736 count++;
737
738 while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
739 mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
740 count++;
741 }
742
743 debug(49, 5) ("snmpTreeNext: Recursed down to requested object\n");
b6a2f15e 744 } else {
62e76326 745 return NULL;
b6a2f15e 746 }
62e76326 747
b6a2f15e 748 if (mibTreeEntry == mib_tree_last)
62e76326 749 return (Fn);
750
b6a2f15e 751 if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
62e76326 752 *NextLen = CurrentLen;
753 *Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
754
755 if (*Next)
756 return (Fn);
b6a2f15e 757 }
62e76326 758
b6a2f15e 759 if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
62e76326 760 count--;
761 nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
762
763 if (nextoid) {
764 debug(49, 5) ("snmpTreeNext: Next OID found for sibling\n");
765 mibTreeEntry = nextoid;
766 count++;
767 } else {
768 debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next object\n");
769
770 while (!nextoid) {
771 count--;
772
773 if (mibTreeEntry->parent->parent) {
774 nextoid = mibTreeEntry->parent;
775 mibTreeEntry = snmpTreeEntry(Current[count] + 1, count, nextoid->parent);
776
777 if (!mibTreeEntry) {
778 mibTreeEntry = nextoid;
779 nextoid = NULL;
780 }
781 } else {
782 nextoid = mibTreeEntry;
783 mibTreeEntry = NULL;
784 }
785 }
786 }
b6a2f15e 787 }
62e76326 788
b6a2f15e 789 while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) {
62e76326 790 mibTreeEntry = mibTreeEntry->leaves[0];
dba79ac5 791 }
62e76326 792
c68e9c6b 793 if (mibTreeEntry) {
62e76326 794 *NextLen = mibTreeEntry->len;
795 *Next = (*mibTreeEntry->instancefunction) (mibTreeEntry->name, NextLen, mibTreeEntry, &Fn);
dba79ac5 796 }
62e76326 797
96ca8fa1 798 if (*Next)
62e76326 799 return (Fn);
96ca8fa1 800 else
62e76326 801 return NULL;
43d4303e 802}
803
9bc73deb 804static oid *
b6a2f15e 805static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
806{
807 oid *instance = NULL;
808
809 if (*len <= current->len) {
62e76326 810 instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
811 xmemcpy(instance, name, (sizeof(name) * *len));
812 instance[*len] = 0;
813 *len += 1;
b6a2f15e 814 }
62e76326 815
b6a2f15e 816 *Fn = current->parsefunction;
817 return (instance);
818}
819
9bc73deb 820static oid *
b6a2f15e 821time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
822{
823 oid *instance = NULL;
824 int identifier = 0, loop = 0;
825 int index[TIME_INDEX_LEN] =
62e76326 826 {TIME_INDEX};
b6a2f15e 827
828 if (*len <= current->len) {
62e76326 829 instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
830 xmemcpy(instance, name, (sizeof(name) * *len));
831 instance[*len] = *index;
832 *len += 1;
b6a2f15e 833 } else {
62e76326 834 identifier = name[*len - 1];
835
836 while ((identifier != index[loop]) && (loop < TIME_INDEX_LEN))
837 loop++;
838
839 if (loop < TIME_INDEX_LEN - 1) {
840 instance = (oid *)xmalloc(sizeof(name) * (*len));
841 xmemcpy(instance, name, (sizeof(name) * *len));
842 instance[*len - 1] = index[++loop];
843 }
b6a2f15e 844 }
62e76326 845
b6a2f15e 846 *Fn = current->parsefunction;
847 return (instance);
848}
849
9bc73deb 850static oid *
b6a2f15e 851peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
852{
853 oid *instance = NULL;
854 u_char *cp = NULL;
855 peer *peers = Config.peers;
62e76326 856
ddfcbc22 857 struct IN_ADDR *laddr = NULL;
b6a2f15e 858 char *host_addr = NULL, *current_addr = NULL, *last_addr = NULL;
859
860 if (peers == NULL) {
62e76326 861 current = current->parent->parent->parent->leaves[1];
862
863 while ((current) && (!current->parsefunction))
864 current = current->leaves[0];
865
866 instance = client_Inst(current->name, len, current, Fn);
b6a2f15e 867 } else if (*len <= current->len) {
62e76326 868 instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
869 xmemcpy(instance, name, (sizeof(name) * *len));
870 cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
871 instance[*len] = *cp++;
872 instance[*len + 1] = *cp++;
873 instance[*len + 2] = *cp++;
874 instance[*len + 3] = *cp++;
875 *len += 4;
b6a2f15e 876 } else {
62e76326 877 laddr = oid2addr(&name[*len - 4]);
878 host_addr = inet_ntoa(*laddr);
879 last_addr = (char *)xmalloc(strlen(host_addr));
880 strncpy(last_addr, host_addr, strlen(host_addr));
881 current_addr = inet_ntoa(peers->in_addr.sin_addr);
882
883 while ((peers) && (strncmp(last_addr, current_addr, strlen(current_addr)))) {
884 if (peers->next) {
885 peers = peers->next;
886 current_addr = inet_ntoa(peers->in_addr.sin_addr);
887 } else {
888 peers = NULL;
889 }
890 }
891
892 xfree(last_addr);
893
894 if (peers) {
895 if (peers->next) {
896 peers = peers->next;
897 instance = (oid *)xmalloc(sizeof(name) * (*len));
898 xmemcpy(instance, name, (sizeof(name) * *len));
899 cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
900 instance[*len - 4] = *cp++;
901 instance[*len - 3] = *cp++;
902 instance[*len - 2] = *cp++;
903 instance[*len - 1] = *cp++;
904 } else {
905 return (instance);
906 }
907 } else {
908 return (instance);
909 }
b6a2f15e 910 }
62e76326 911
b6a2f15e 912 *Fn = current->parsefunction;
913 return (instance);
914}
915
9bc73deb 916static oid *
b6a2f15e 917client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
918{
919 oid *instance = NULL;
920 u_char *cp = NULL;
62e76326 921
ddfcbc22 922 struct IN_ADDR *laddr = NULL;
b6a2f15e 923
924 if (*len <= current->len) {
62e76326 925 instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
926 xmemcpy(instance, name, (sizeof(name) * *len));
927 laddr = client_entry(NULL);
928
929 if (laddr) {
930 cp = (u_char *) & (laddr->s_addr);
931 instance[*len] = *cp++;
932 instance[*len + 1] = *cp++;
933 instance[*len + 2] = *cp++;
934 instance[*len + 3] = *cp++;
935 *len += 4;
936 }
b6a2f15e 937 } else {
62e76326 938 laddr = oid2addr(&name[*len - 4]);
939 laddr = client_entry(laddr);
940
941 if (laddr) {
942 instance = (oid *)xmalloc(sizeof(name) * (*len));
943 xmemcpy(instance, name, (sizeof(name) * *len));
944 cp = (u_char *) & (laddr->s_addr);
945 instance[*len - 4] = *cp++;
946 instance[*len - 3] = *cp++;
947 instance[*len - 2] = *cp++;
948 instance[*len - 1] = *cp++;
949 }
b6a2f15e 950 }
62e76326 951
b6a2f15e 952 *Fn = current->parsefunction;
953 return (instance);
954}
955
956
957/*
958 * Utility functions
959 */
960
961/*
962 * Tree utility functions.
963 */
964
62e76326 965/*
b6a2f15e 966 * Returns a the sibling object in the tree
967 */
9bc73deb 968static mib_tree_entry *
897029fd 969snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
43d4303e 970{
dba79ac5 971 mib_tree_entry *next = NULL;
972 int count = 0;
8a6218c6 973
897029fd 974 while ((!next) && (count < current->children)) {
62e76326 975 if (current->leaves[count]->name[len] == entry) {
976 next = current->leaves[count];
977 }
978
979 count++;
897029fd 980 }
62e76326 981
8a6218c6 982 if (count < current->children) {
62e76326 983 next = current->leaves[count];
8a6218c6 984 } else {
62e76326 985 next = NULL;
897029fd 986 }
62e76326 987
897029fd 988 return (next);
989}
665bc266 990
62e76326 991/*
b6a2f15e 992 * Returns the requested child object or NULL if it does not exist
993 */
9bc73deb 994static mib_tree_entry *
897029fd 995snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
996{
997 mib_tree_entry *next = NULL;
998 int count = 0;
43d4303e 999
dba79ac5 1000 while ((!next) && (count < current->children)) {
62e76326 1001 if (current->leaves[count]->name[len] == entry) {
1002 next = current->leaves[count];
1003 }
1004
1005 count++;
43d4303e 1006 }
62e76326 1007
dba79ac5 1008 return (next);
1009}
43d4303e 1010
d439f213 1011/*
1012 * Adds a node to the MIB tree structure and adds the appropriate children
1013 */
9bc73deb 1014static mib_tree_entry *
1952717f 1015#if STDC_HEADERS
b6a2f15e 1016snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
1952717f 1017#else
1018snmpAddNode(va_alist)
62e76326 1019va_dcl
fa86210b 1020#endif
d439f213 1021{
1952717f 1022#if STDC_HEADERS
d439f213 1023 va_list args;
1024 int loop;
1025 mib_tree_entry *entry = NULL;
b6a2f15e 1026 va_start(args, children);
853dead1 1027#else
62e76326 1028
853dead1 1029 va_list args;
1030 oid *name = NULL;
1031 int len = 0, children = 0, loop;
1032 oid_ParseFn *parsefunction = NULL;
b6a2f15e 1033 instance_Fn *instancefunction = NULL;
853dead1 1034 mib_tree_entry *entry = NULL;
b6a2f15e 1035 va_start(args);
1036 name = va_arg(args, oid *);
1037 len = va_arg(args, int);
1038 parsefunction = va_arg(args, oid_ParseFn *);
1039 instancefunction = va_arg(args, instance_Fn *);
1040 children = va_arg(args, int);
853dead1 1041#endif
d439f213 1042
b6a2f15e 1043 debug(49, 6) ("snmpAddNode: Children : %d, Oid : \n", children);
1044 snmpDebugOid(6, name, len);
d439f213 1045
b6a2f15e 1046 va_start(args, children);
e6ccf245 1047 entry = (mib_tree_entry *)xmalloc(sizeof(mib_tree_entry));
6ccbae85 1048 entry->name = name;
b6a2f15e 1049 entry->len = len;
1050 entry->parsefunction = parsefunction;
1051 entry->instancefunction = instancefunction;
1052 entry->children = children;
d439f213 1053
62e76326 1054 if (children > 0)
1055 {
1056 entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children);
1057
1058 for (loop = 0; loop < children; loop++) {
1059 entry->leaves[loop] = va_arg(args, mib_tree_entry *);
1060 entry->leaves[loop]->parent = entry;
1061 }
d439f213 1062 }
62e76326 1063
d439f213 1064 return (entry);
1065}
1066/* End of tree utility functions */
1067
62e76326 1068/*
61d53e64 1069 * Returns the list of parameters in an oid
c68e9c6b 1070 */
9bc73deb 1071static oid *
1952717f 1072#if STDC_HEADERS
c68e9c6b 1073snmpCreateOid(int length,...)
1952717f 1074#else
1075snmpCreateOid(va_alist)
62e76326 1076va_dcl
1952717f 1077#endif
dba79ac5 1078{
1952717f 1079#if STDC_HEADERS
c68e9c6b 1080 va_list args;
1081 oid *new_oid;
1082 int loop;
c68e9c6b 1083 va_start(args, length);
853dead1 1084#else
62e76326 1085
853dead1 1086 va_list args;
1087 int length = 0, loop;
1088 oid *new_oid;
853dead1 1089 va_start(args);
1090 length va_arg(args, int);
1091#endif
8a6218c6 1092
e6ccf245 1093 new_oid = (oid *)xmalloc(sizeof(oid) * length);
c68e9c6b 1094
62e76326 1095 if (length > 0)
1096 {
1097 for (loop = 0; loop < length; loop++) {
1098 new_oid[loop] = va_arg(args, int);
1099 }
c68e9c6b 1100 }
62e76326 1101
c68e9c6b 1102 return (new_oid);
43d4303e 1103}
1104
7b01964d 1105#if UNUSED_CODE
dba79ac5 1106/*
5898ce23 1107 * Allocate space for, and copy, an OID. Returns new oid.
43d4303e 1108 */
9bc73deb 1109static oid *
dba79ac5 1110snmpOidDup(oid * A, snint ALen)
43d4303e 1111{
5898ce23 1112 oid *Ans = xmalloc(sizeof(oid) * ALen);
1113 xmemcpy(Ans, A, (sizeof(oid) * ALen));
1114 return Ans;
43d4303e 1115}
62e76326 1116
7b01964d 1117#endif
43d4303e 1118
dba79ac5 1119/*
c68e9c6b 1120 * Debug calls, prints out the OID for debugging purposes.
1121 */
dba79ac5 1122void
1123snmpDebugOid(int lvl, oid * Name, snint Len)
c68e9c6b 1124{
dba79ac5 1125 char mbuf[16], objid[1024];
1126 int x;
1127 objid[0] = '\0';
43d4303e 1128
dba79ac5 1129 for (x = 0; x < Len; x++) {
62e76326 1130 snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
1131 strncat(objid, mbuf, sizeof(objid));
43d4303e 1132 }
c68e9c6b 1133
dba79ac5 1134 debug(49, lvl) (" oid = %s\n", objid);
43d4303e 1135}
b644367b 1136
c68e9c6b 1137static void
dba79ac5 1138snmpSnmplibDebug(int lvl, char *buf)
c68e9c6b 1139{
dba79ac5 1140 debug(49, lvl) ("%s", buf);
c68e9c6b 1141}
b6a2f15e 1142
1143void
62e76326 1144
ddfcbc22 1145addr2oid(struct IN_ADDR addr, oid * Dest)
b6a2f15e 1146{
1147 u_char *cp;
1148 cp = (u_char *) & (addr.s_addr);
1149 Dest[0] = *cp++;
1150 Dest[1] = *cp++;
1151 Dest[2] = *cp++;
1152 Dest[3] = *cp++;
1153}
1154
ddfcbc22 1155struct IN_ADDR
62e76326 1156 *
1157 oid2addr(oid * id)
b6a2f15e 1158{
62e76326 1159
ddfcbc22 1160 static struct IN_ADDR laddr;
b6a2f15e 1161 u_char *cp = (u_char *) & (laddr.s_addr);
1162 cp[0] = id[0];
1163 cp[1] = id[1];
1164 cp[2] = id[2];
1165 cp[3] = id[3];
1166 return &laddr;
1167}
b0dd28ba 1168
1169/* SNMP checklists */
1170#include "ACLStrategy.h"
1171#include "ACLStrategised.h"
1172#include "ACLStringData.h"
1173
1174class ACLSNMPCommunityStrategy : public ACLStrategy<char const *>
1175{
1176
1177public:
1178 virtual int match (ACLData<MatchType> * &, ACLChecklist *);
1179 static ACLSNMPCommunityStrategy *Instance();
1180 /* Not implemented to prevent copies of the instance. */
1181 /* Not private to prevent brain dead g+++ warnings about
1182 * private constructors with no friends */
1183 ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &);
1184
1185private:
1186 static ACLSNMPCommunityStrategy Instance_;
1187 ACLSNMPCommunityStrategy(){}
1188
1189 ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &);
1190};
1191
1192class ACLSNMPCommunity
1193{
1194
1195private:
1196 static ACL::Prototype RegistryProtoype;
1197 static ACLStrategised<char const *> RegistryEntry_;
1198};
1199
1200ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community");
1201ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
1202
1203int
1204ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
1205{
1206 return data->match (checklist->snmp_community);
1207 ;
1208}
1209
1210ACLSNMPCommunityStrategy *
1211ACLSNMPCommunityStrategy::Instance()
1212{
1213 return &Instance_;
1214}
1215
1216ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_;