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