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