3 * $Id: snmp_core.cc,v 1.63 2003/02/23 00:08:04 robertc Exp $
5 * DEBUG: section 49 SNMP support
6 * AUTHOR: Glenn Chisholm
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
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.
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.
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.
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
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
37 #include "cache_snmp.h"
38 #include "ACLChecklist.h"
40 #define SNMP_REQUEST_SIZE 4096
41 #define MAX_PROTOSTAT 5
43 typedef struct _mib_tree_entry mib_tree_entry
;
44 typedef oid
*(instance_Fn
) (oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
46 struct _mib_tree_entry
50 oid_ParseFn
*parsefunction
;
51 instance_Fn
*instancefunction
;
54 struct _mib_tree_entry
**leaves
;
56 struct _mib_tree_entry
*parent
;
59 mib_tree_entry
*mib_tree_head
;
60 mib_tree_entry
*mib_tree_last
;
63 static mib_tree_entry
*snmpAddNode(oid
* name
, int len
, oid_ParseFn
* parsefunction
, instance_Fn
* instancefunction
, int children
,...);
64 static oid
*snmpCreateOid(int length
,...);
66 static mib_tree_entry
*snmpAddNode();
67 static oid
*snmpCreateOid();
69 SQUIDCEXTERN
void (*snmplib_debug_hook
) (int, char *);
70 static oid
*static_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
71 static oid
*time_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
72 static oid
*peer_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
73 static oid
*client_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
74 static void snmpDecodePacket(snmp_request_t
* rq
);
75 static void snmpConstructReponse(snmp_request_t
* rq
);
77 static struct snmp_pdu
*snmpAgentResponse(struct snmp_pdu
*PDU
);
78 static oid_ParseFn
*snmpTreeNext(oid
* Current
, snint CurrentLen
, oid
** Next
, snint
* NextLen
);
79 static oid_ParseFn
*snmpTreeGet(oid
* Current
, snint CurrentLen
);
80 static mib_tree_entry
*snmpTreeEntry(oid entry
, snint len
, mib_tree_entry
* current
);
81 static mib_tree_entry
*snmpTreeSiblingEntry(oid entry
, snint len
, mib_tree_entry
* current
);
82 static void snmpSnmplibDebug(int lvl
, char *buf
);
86 * The functions used during startup:
89 * snmpConnectionShutdown
94 * Turns the MIB into a Tree structure. Called during the startup process.
99 debug(49, 5) ("snmpInit: Called.\n");
101 debug(49, 5) ("snmpInit: Building SNMP mib tree structure\n");
103 snmplib_debug_hook
= snmpSnmplibDebug
;
105 mib_tree_head
= snmpAddNode(snmpCreateOid(1, 1),
107 snmpAddNode(snmpCreateOid(2, 1, 3),
109 snmpAddNode(snmpCreateOid(3, 1, 3, 6),
111 snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1),
113 snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4),
115 snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1),
117 snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495),
119 snmpAddNode(snmpCreateOid(LEN_SQUIDMIB
, SQUIDMIB
),
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,
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))),
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))),
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)))))
349 debug(49, 9) ("snmpInit: Completed SNMP mib tree structure\n");
353 snmpConnectionOpen(void)
357 struct sockaddr_in xaddr
;
361 debug(49, 5) ("snmpConnectionOpen: Called\n");
363 if ((port
= Config
.Port
.snmp
) > (u_short
) 0) {
365 theInSnmpConnection
= comm_open(SOCK_DGRAM
,
367 Config
.Addrs
.snmp_incoming
,
373 if (theInSnmpConnection
< 0)
374 fatal("Cannot open snmp Port");
376 commSetSelect(theInSnmpConnection
, COMM_SELECT_READ
, snmpHandleUdp
, NULL
, 0);
378 debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",
379 (int) port
, theInSnmpConnection
);
381 if (Config
.Addrs
.snmp_outgoing
.s_addr
!= no_addr
.s_addr
) {
383 theOutSnmpConnection
= comm_open(SOCK_DGRAM
,
385 Config
.Addrs
.snmp_outgoing
,
391 if (theOutSnmpConnection
< 0)
392 fatal("Cannot open Outgoing SNMP Port");
394 commSetSelect(theOutSnmpConnection
,
399 debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",
400 (int) port
, theOutSnmpConnection
);
402 fd_note(theOutSnmpConnection
, "Outgoing SNMP socket");
404 fd_note(theInSnmpConnection
, "Incoming SNMP socket");
406 theOutSnmpConnection
= theInSnmpConnection
;
409 memset(&theOutSNMPAddr
, '\0', sizeof(struct in_addr
));
411 len
= sizeof(struct sockaddr_in
);
412 memset(&xaddr
, '\0', len
);
413 x
= getsockname(theOutSnmpConnection
,
415 (struct sockaddr
*) &xaddr
, &len
);
418 debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n",
419 theOutSnmpConnection
, xstrerror());
421 theOutSNMPAddr
= xaddr
.sin_addr
;
426 snmpConnectionShutdown(void)
428 if (theInSnmpConnection
< 0)
431 if (theInSnmpConnection
!= theOutSnmpConnection
) {
432 debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection
);
433 comm_close(theInSnmpConnection
);
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;
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.
449 assert(theOutSnmpConnection
> -1);
451 commSetSelect(theOutSnmpConnection
, COMM_SELECT_READ
, NULL
, NULL
, 0);
455 snmpConnectionClose(void)
457 snmpConnectionShutdown();
459 if (theOutSnmpConnection
> -1) {
460 debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection
);
461 comm_close(theOutSnmpConnection
);
466 * Functions for handling the requests.
470 * Accept the UDP packet
473 snmpHandleUdp(int sock
, void *not_used
)
475 LOCAL_ARRAY(char, buf
, SNMP_REQUEST_SIZE
);
477 struct sockaddr_in from
;
479 snmp_request_t
*snmp_rq
;
482 debug(49, 5) ("snmpHandleUdp: Called.\n");
484 commSetSelect(sock
, COMM_SELECT_READ
, snmpHandleUdp
, NULL
, 0);
486 from_len
= sizeof(struct sockaddr_in
);
487 memset(&from
, '\0', from_len
);
488 memset(buf
, '\0', SNMP_REQUEST_SIZE
);
490 len
= comm_udp_recvfrom(sock
,
495 (struct sockaddr
*) &from
,
500 debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
503 inet_ntoa(from
.sin_addr
));
505 snmp_rq
= (snmp_request_t
*)xcalloc(1, sizeof(snmp_request_t
));
506 snmp_rq
->buf
= (u_char
*) buf
;
508 snmp_rq
->sock
= sock
;
509 snmp_rq
->outbuf
= (unsigned char *)xmalloc(snmp_rq
->outlen
= SNMP_REQUEST_SIZE
);
511 xmemcpy(&snmp_rq
->from
, &from
, sizeof(struct sockaddr_in
));
512 snmpDecodePacket(snmp_rq
);
513 xfree(snmp_rq
->outbuf
);
516 debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock
, xstrerror());
521 * Turn SNMP packet into a PDU, check available ACL's
524 snmpDecodePacket(snmp_request_t
* rq
)
527 struct snmp_pdu
*PDU
;
529 struct snmp_session Session
;
531 u_char
*buf
= rq
->buf
;
535 debug(49, 5) ("snmpDecodePacket: Called.\n");
536 /* Now that we have the data, turn it into a PDU */
537 PDU
= snmp_pdu_create(0);
538 Session
.Version
= SNMP_VERSION_1
;
539 Community
= snmp_parse(&Session
, PDU
, buf
, len
);
540 ACLChecklist checklist
;
541 checklist
.src_addr
= rq
->from
.sin_addr
;
542 checklist
.snmp_community
= (char *) Community
;
545 allow
= aclCheckFast(Config
.accessList
.snmp
, &checklist
);
547 if ((snmp_coexist_V2toV1(PDU
)) && (Community
) && (allow
)) {
548 rq
->community
= Community
;
550 debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU
->reqid
);
551 snmpConstructReponse(rq
);
553 debug(49, 1) ("Failed SNMP agent query from : %s.\n",
554 inet_ntoa(rq
->from
.sin_addr
));
563 * Packet OK, ACL Check OK, Create reponse.
566 snmpConstructReponse(snmp_request_t
* rq
)
569 struct snmp_session Session
;
571 struct snmp_pdu
*RespPDU
;
573 debug(49, 5) ("snmpConstructReponse: Called.\n");
574 RespPDU
= snmpAgentResponse(rq
->PDU
);
575 snmp_free_pdu(rq
->PDU
);
577 if (RespPDU
!= NULL
) {
578 Session
.Version
= SNMP_VERSION_1
;
579 Session
.community
= rq
->community
;
580 Session
.community_len
= strlen((char *) rq
->community
);
581 snmp_build(&Session
, RespPDU
, rq
->outbuf
, &rq
->outlen
);
582 comm_udp_sendto(rq
->sock
, &rq
->from
, sizeof(rq
->from
), rq
->outbuf
, rq
->outlen
);
583 snmp_free_pdu(RespPDU
);
588 * Decide how to respond to the request, construct a response and
589 * return the response to the requester.
592 static struct snmp_pdu
*
594 snmpAgentResponse(struct snmp_pdu
*PDU
)
597 struct snmp_pdu
*Answer
= NULL
;
598 oid_ParseFn
*ParseFn
= NULL
;
600 variable_list
*VarPtr
, *VarNew
= NULL
, **VarPtrP
;
603 debug(49, 5) ("snmpAgentResponse: Called.\n");
605 if ((Answer
= snmp_pdu_create(SNMP_PDU_RESPONSE
)))
607 Answer
->reqid
= PDU
->reqid
;
608 Answer
->errindex
= 0;
610 if (PDU
->command
== SNMP_PDU_GET
) {
611 variable_list
**RespVars
;
613 RespVars
= &(Answer
->variables
);
614 /* Loop through all variables */
616 for (VarPtrP
= &(PDU
->variables
);
618 VarPtrP
= &((*VarPtrP
)->next_variable
)) {
623 /* Find the parsing function for this variable */
624 ParseFn
= snmpTreeGet(VarPtr
->name
, VarPtr
->name_length
);
626 if (ParseFn
== NULL
) {
627 Answer
->errstat
= SNMP_ERR_NOSUCHNAME
;
628 debug(49, 5) ("snmpAgentResponse: No such oid. ");
630 VarNew
= (*ParseFn
) (VarPtr
, (snint
*) & (Answer
->errstat
));
632 /* Was there an error? */
633 if ((Answer
->errstat
!= SNMP_ERR_NOERROR
) ||
635 Answer
->errindex
= index
;
636 debug(49, 5) ("snmpAgentParse: successful.\n");
637 /* Just copy the rest of the variables. Quickly. */
643 /* No error. Insert this var at the end, and move on to the next.
647 RespVars
= &(VarNew
->next_variable
);
651 } else if (PDU
->command
== SNMP_PDU_GETNEXT
) {
652 oid
*NextOidName
= NULL
;
653 int NextOidNameLen
= 0;
655 ParseFn
= snmpTreeNext(PDU
->variables
->name
, PDU
->variables
->name_length
,
656 &(NextOidName
), (snint
*) & NextOidNameLen
);
658 if (ParseFn
== NULL
) {
659 Answer
->errstat
= SNMP_ERR_NOSUCHNAME
;
660 debug(49, 5) ("snmpAgentResponse: No such oid: ");
661 snmpDebugOid(5, PDU
->variables
->name
, PDU
->variables
->name_length
);
663 xfree(PDU
->variables
->name
);
664 PDU
->variables
->name
= NextOidName
;
665 PDU
->variables
->name_length
= NextOidNameLen
;
666 VarNew
= (*ParseFn
) (PDU
->variables
, (snint
*) & Answer
->errstat
);
669 /* Was there an error? */
670 if (Answer
->errstat
!= SNMP_ERR_NOERROR
) {
671 Answer
->errindex
= 1;
672 Answer
->variables
= PDU
->variables
;
673 PDU
->variables
= NULL
;
675 Answer
->variables
= VarNew
;
679 snmp_free_pdu(Answer
);
688 snmpTreeGet(oid
* Current
, snint CurrentLen
)
690 oid_ParseFn
*Fn
= NULL
;
691 mib_tree_entry
*mibTreeEntry
= NULL
;
694 debug(49, 5) ("snmpTreeGet: Called\n");
696 debug(49, 6) ("snmpTreeGet: Current : \n");
697 snmpDebugOid(6, Current
, CurrentLen
);
699 mibTreeEntry
= mib_tree_head
;
701 if (Current
[count
] == mibTreeEntry
->name
[count
]) {
704 while ((mibTreeEntry
) && (count
< CurrentLen
) && (!mibTreeEntry
->parsefunction
)) {
705 mibTreeEntry
= snmpTreeEntry(Current
[count
], count
, mibTreeEntry
);
710 if (mibTreeEntry
&& mibTreeEntry
->parsefunction
)
711 Fn
= mibTreeEntry
->parsefunction
;
713 debug(49, 5) ("snmpTreeGet: return\n");
719 snmpTreeNext(oid
* Current
, snint CurrentLen
, oid
** Next
, snint
* NextLen
)
721 oid_ParseFn
*Fn
= NULL
;
722 mib_tree_entry
*mibTreeEntry
= NULL
, *nextoid
= NULL
;
725 debug(49, 5) ("snmpTreeNext: Called\n");
727 debug(49, 6) ("snmpTreeNext: Current : \n");
728 snmpDebugOid(6, Current
, CurrentLen
);
730 mibTreeEntry
= mib_tree_head
;
732 if (Current
[count
] == mibTreeEntry
->name
[count
]) {
735 while ((mibTreeEntry
) && (count
< CurrentLen
) && (!mibTreeEntry
->parsefunction
)) {
736 mibTreeEntry
= snmpTreeEntry(Current
[count
], count
, mibTreeEntry
);
740 debug(49, 5) ("snmpTreeNext: Recursed down to requested object\n");
745 if (mibTreeEntry
== mib_tree_last
)
748 if ((mibTreeEntry
) && (mibTreeEntry
->parsefunction
)) {
749 *NextLen
= CurrentLen
;
750 *Next
= (*mibTreeEntry
->instancefunction
) (Current
, NextLen
, mibTreeEntry
, &Fn
);
756 if ((mibTreeEntry
) && (mibTreeEntry
->parsefunction
)) {
758 nextoid
= snmpTreeSiblingEntry(Current
[count
], count
, mibTreeEntry
->parent
);
761 debug(49, 5) ("snmpTreeNext: Next OID found for sibling\n");
762 mibTreeEntry
= nextoid
;
765 debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next object\n");
770 if (mibTreeEntry
->parent
->parent
) {
771 nextoid
= mibTreeEntry
->parent
;
772 mibTreeEntry
= snmpTreeEntry(Current
[count
] + 1, count
, nextoid
->parent
);
775 mibTreeEntry
= nextoid
;
779 nextoid
= mibTreeEntry
;
786 while ((mibTreeEntry
) && (!mibTreeEntry
->parsefunction
)) {
787 mibTreeEntry
= mibTreeEntry
->leaves
[0];
791 *NextLen
= mibTreeEntry
->len
;
792 *Next
= (*mibTreeEntry
->instancefunction
) (mibTreeEntry
->name
, NextLen
, mibTreeEntry
, &Fn
);
802 static_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
804 oid
*instance
= NULL
;
806 if (*len
<= current
->len
) {
807 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
+ 1));
808 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
813 *Fn
= current
->parsefunction
;
818 time_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
820 oid
*instance
= NULL
;
821 int identifier
= 0, loop
= 0;
822 int index
[TIME_INDEX_LEN
] =
825 if (*len
<= current
->len
) {
826 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
+ 1));
827 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
828 instance
[*len
] = *index
;
831 identifier
= name
[*len
- 1];
833 while ((identifier
!= index
[loop
]) && (loop
< TIME_INDEX_LEN
))
836 if (loop
< TIME_INDEX_LEN
- 1) {
837 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
));
838 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
839 instance
[*len
- 1] = index
[++loop
];
843 *Fn
= current
->parsefunction
;
848 peer_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
850 oid
*instance
= NULL
;
852 peer
*peers
= Config
.peers
;
854 struct in_addr
*laddr
= NULL
;
855 char *host_addr
= NULL
, *current_addr
= NULL
, *last_addr
= NULL
;
858 current
= current
->parent
->parent
->parent
->leaves
[1];
860 while ((current
) && (!current
->parsefunction
))
861 current
= current
->leaves
[0];
863 instance
= client_Inst(current
->name
, len
, current
, Fn
);
864 } else if (*len
<= current
->len
) {
865 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
+ 4));
866 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
867 cp
= (u_char
*) & (peers
->in_addr
.sin_addr
.s_addr
);
868 instance
[*len
] = *cp
++;
869 instance
[*len
+ 1] = *cp
++;
870 instance
[*len
+ 2] = *cp
++;
871 instance
[*len
+ 3] = *cp
++;
874 laddr
= oid2addr(&name
[*len
- 4]);
875 host_addr
= inet_ntoa(*laddr
);
876 last_addr
= (char *)xmalloc(strlen(host_addr
));
877 strncpy(last_addr
, host_addr
, strlen(host_addr
));
878 current_addr
= inet_ntoa(peers
->in_addr
.sin_addr
);
880 while ((peers
) && (strncmp(last_addr
, current_addr
, strlen(current_addr
)))) {
883 current_addr
= inet_ntoa(peers
->in_addr
.sin_addr
);
894 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
));
895 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
896 cp
= (u_char
*) & (peers
->in_addr
.sin_addr
.s_addr
);
897 instance
[*len
- 4] = *cp
++;
898 instance
[*len
- 3] = *cp
++;
899 instance
[*len
- 2] = *cp
++;
900 instance
[*len
- 1] = *cp
++;
909 *Fn
= current
->parsefunction
;
914 client_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
916 oid
*instance
= NULL
;
919 struct in_addr
*laddr
= NULL
;
921 if (*len
<= current
->len
) {
922 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
+ 4));
923 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
924 laddr
= client_entry(NULL
);
927 cp
= (u_char
*) & (laddr
->s_addr
);
928 instance
[*len
] = *cp
++;
929 instance
[*len
+ 1] = *cp
++;
930 instance
[*len
+ 2] = *cp
++;
931 instance
[*len
+ 3] = *cp
++;
935 laddr
= oid2addr(&name
[*len
- 4]);
936 laddr
= client_entry(laddr
);
939 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
));
940 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
941 cp
= (u_char
*) & (laddr
->s_addr
);
942 instance
[*len
- 4] = *cp
++;
943 instance
[*len
- 3] = *cp
++;
944 instance
[*len
- 2] = *cp
++;
945 instance
[*len
- 1] = *cp
++;
949 *Fn
= current
->parsefunction
;
959 * Tree utility functions.
963 * Returns a the sibling object in the tree
965 static mib_tree_entry
*
966 snmpTreeSiblingEntry(oid entry
, snint len
, mib_tree_entry
* current
)
968 mib_tree_entry
*next
= NULL
;
971 while ((!next
) && (count
< current
->children
)) {
972 if (current
->leaves
[count
]->name
[len
] == entry
) {
973 next
= current
->leaves
[count
];
979 if (count
< current
->children
) {
980 next
= current
->leaves
[count
];
989 * Returns the requested child object or NULL if it does not exist
991 static mib_tree_entry
*
992 snmpTreeEntry(oid entry
, snint len
, mib_tree_entry
* current
)
994 mib_tree_entry
*next
= NULL
;
997 while ((!next
) && (count
< current
->children
)) {
998 if (current
->leaves
[count
]->name
[len
] == entry
) {
999 next
= current
->leaves
[count
];
1009 * Adds a node to the MIB tree structure and adds the appropriate children
1011 static mib_tree_entry
*
1013 snmpAddNode(oid
* name
, int len
, oid_ParseFn
* parsefunction
, instance_Fn
* instancefunction
, int children
,...)
1015 snmpAddNode(va_alist
)
1022 mib_tree_entry
*entry
= NULL
;
1023 va_start(args
, children
);
1028 int len
= 0, children
= 0, loop
;
1029 oid_ParseFn
*parsefunction
= NULL
;
1030 instance_Fn
*instancefunction
= NULL
;
1031 mib_tree_entry
*entry
= NULL
;
1033 name
= va_arg(args
, oid
*);
1034 len
= va_arg(args
, int);
1035 parsefunction
= va_arg(args
, oid_ParseFn
*);
1036 instancefunction
= va_arg(args
, instance_Fn
*);
1037 children
= va_arg(args
, int);
1040 debug(49, 6) ("snmpAddNode: Children : %d, Oid : \n", children
);
1041 snmpDebugOid(6, name
, len
);
1043 va_start(args
, children
);
1044 entry
= (mib_tree_entry
*)xmalloc(sizeof(mib_tree_entry
));
1047 entry
->parsefunction
= parsefunction
;
1048 entry
->instancefunction
= instancefunction
;
1049 entry
->children
= children
;
1053 entry
->leaves
= (mib_tree_entry
**)xmalloc(sizeof(mib_tree_entry
*) * children
);
1055 for (loop
= 0; loop
< children
; loop
++) {
1056 entry
->leaves
[loop
] = va_arg(args
, mib_tree_entry
*);
1057 entry
->leaves
[loop
]->parent
= entry
;
1063 /* End of tree utility functions */
1066 * Returns the list of parameters in an oid
1070 snmpCreateOid(int length
,...)
1072 snmpCreateOid(va_alist
)
1080 va_start(args
, length
);
1084 int length
= 0, loop
;
1087 length
va_arg(args
, int);
1090 new_oid
= (oid
*)xmalloc(sizeof(oid
) * length
);
1094 for (loop
= 0; loop
< length
; loop
++) {
1095 new_oid
[loop
] = va_arg(args
, int);
1104 * Allocate space for, and copy, an OID. Returns new oid.
1107 snmpOidDup(oid
* A
, snint ALen
)
1109 oid
*Ans
= xmalloc(sizeof(oid
) * ALen
);
1110 xmemcpy(Ans
, A
, (sizeof(oid
) * ALen
));
1117 * Debug calls, prints out the OID for debugging purposes.
1120 snmpDebugOid(int lvl
, oid
* Name
, snint Len
)
1122 char mbuf
[16], objid
[1024];
1126 for (x
= 0; x
< Len
; x
++) {
1127 snprintf(mbuf
, sizeof(mbuf
), ".%u", (unsigned int) Name
[x
]);
1128 strncat(objid
, mbuf
, sizeof(objid
));
1131 debug(49, lvl
) (" oid = %s\n", objid
);
1135 snmpSnmplibDebug(int lvl
, char *buf
)
1137 debug(49, lvl
) ("%s", buf
);
1142 addr2oid(struct in_addr addr
, oid
* Dest
)
1145 cp
= (u_char
*) & (addr
.s_addr
);
1157 static struct in_addr laddr
;
1158 u_char
*cp
= (u_char
*) & (laddr
.s_addr
);