3
* $Id: snmp_core.cc,v 1.75 2006/09/22 02:48:51 hno 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, 6,
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_SYS, SQ_CONF, CONF_UNIQNAME),
150
LEN_SYS, snmp_confFn, static_Inst, 0)),
151
snmpAddNode(snmpCreateOid(LEN_SQ_PRF, SQ_PRF),
152
LEN_SQ_PRF, NULL, NULL, 2,
153
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_SYS),
154
LEN_SQ_PRF + 1, NULL, NULL, 13,
155
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 1),
156
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
157
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 2),
158
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
159
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 3),
160
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
161
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 4),
162
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
163
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 5),
164
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
165
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 6),
166
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
167
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 7),
168
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
169
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 8),
170
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
171
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 9),
172
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
173
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 10),
174
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
175
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 11),
176
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
177
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 12),
178
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
179
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 13),
180
LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0)),
181
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_PROTO),
182
LEN_SQ_PRF + 1, NULL, NULL, 2,
183
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 1),
184
LEN_SQ_PRF + 2, NULL, NULL, 15,
185
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 1),
186
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
187
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 2),
188
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
189
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 3),
190
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
191
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 4),
192
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
193
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 5),
194
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
195
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 6),
196
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
197
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 7),
198
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
199
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 8),
200
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
201
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 9),
202
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
203
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 10),
204
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
205
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 11),
206
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
207
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 12),
208
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
209
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 13),
210
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
211
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 14),
212
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
213
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 15),
214
LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0)),
215
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 2),
216
LEN_SQ_PRF + 2, NULL, NULL, 1,
217
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 2, 1),
218
LEN_SQ_PRF + 3, NULL, NULL, 11,
219
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 1),
220
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
221
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 2),
222
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
223
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 3),
224
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
225
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 4),
226
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
227
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 5),
228
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
229
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 6),
230
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
231
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 7),
232
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
233
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 8),
234
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
235
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 9),
236
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
237
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 10),
238
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
239
snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 11),
240
LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0))))),
241
snmpAddNode(snmpCreateOid(LEN_SQ_NET, SQ_NET),
242
LEN_SQ_NET, NULL, NULL, 3,
243
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_IP_CACHE),
244
LEN_SQ_NET + 1, NULL, NULL, 8,
245
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_ENT),
246
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
247
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_REQ),
248
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
249
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_HITS),
250
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
251
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_PENDHIT),
252
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
253
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_NEGHIT),
254
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
255
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_MISS),
256
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
257
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_GHBN),
258
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
259
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_LOC),
260
LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0)),
261
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_FQDN_CACHE),
262
LEN_SQ_NET + 1, NULL, NULL, 7,
263
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_ENT),
264
LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
265
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_REQ),
266
LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
267
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_HITS),
268
LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
269
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_PENDHIT),
270
LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
271
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_NEGHIT),
272
LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
273
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_MISS),
274
LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
275
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_GHBN),
276
LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0)),
277
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_DNS_CACHE),
278
LEN_SQ_NET + 1, NULL, NULL, 3,
280
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
281
LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
282
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
283
LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
284
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
285
LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0))),
287
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
288
LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
289
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
290
LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
291
snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
292
LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0))),
294
snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH),
295
LEN_SQ_MESH, NULL, NULL, 2,
296
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 1),
297
LEN_SQ_MESH + 1, NULL, NULL, 1,
298
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1),
299
LEN_SQ_MESH + 2, NULL, NULL, 13,
300
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 1),
301
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
302
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 2),
303
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
304
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 3),
305
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
306
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 4),
307
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
308
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 5),
309
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
310
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 6),
311
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
312
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 7),
313
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
314
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 8),
315
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
316
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 9),
317
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
318
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 10),
319
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
320
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 11),
321
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
322
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 12),
323
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
324
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 13),
325
LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0))),
326
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 2),
327
LEN_SQ_MESH + 1, NULL, NULL, 1,
328
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 2, 1),
329
LEN_SQ_MESH + 2, NULL, NULL, 9,
330
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 1),
331
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
332
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 2),
333
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
334
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 3),
335
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
336
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 4),
337
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
338
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 5),
339
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
340
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 6),
341
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
342
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 7),
343
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
344
snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 8),
345
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
346
(mib_tree_last = snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 9),
347
LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0)))))
357
debug(49, 9) ("snmpInit: Completed SNMP mib tree structure\n");
361
snmpConnectionOpen(void)
365
struct sockaddr_in xaddr;
369
debug(49, 5) ("snmpConnectionOpen: Called\n");
371
if ((port = Config.Port.snmp) > (u_short) 0) {
373
theInSnmpConnection = comm_open(SOCK_DGRAM,
375
Config.Addrs.snmp_incoming,
381
if (theInSnmpConnection < 0)
382
fatal("Cannot open snmp Port");
384
commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
386
debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",
387
(int) port, theInSnmpConnection);
389
if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) {
391
theOutSnmpConnection = comm_open(SOCK_DGRAM,
393
Config.Addrs.snmp_outgoing,
399
if (theOutSnmpConnection < 0)
400
fatal("Cannot open Outgoing SNMP Port");
402
commSetSelect(theOutSnmpConnection,
407
debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",
408
(int) port, theOutSnmpConnection);
410
fd_note(theOutSnmpConnection, "Outgoing SNMP socket");
412
fd_note(theInSnmpConnection, "Incoming SNMP socket");
414
theOutSnmpConnection = theInSnmpConnection;
417
memset(&theOutSNMPAddr, '\0', sizeof(struct IN_ADDR));
419
len = sizeof(struct sockaddr_in);
420
memset(&xaddr, '\0', len);
421
x = getsockname(theOutSnmpConnection,
423
(struct sockaddr *) &xaddr, &len);
426
debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n",
427
theOutSnmpConnection, xstrerror());
429
theOutSNMPAddr = xaddr.sin_addr;
434
snmpConnectionShutdown(void)
436
if (theInSnmpConnection < 0)
439
if (theInSnmpConnection != theOutSnmpConnection) {
440
debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection);
441
comm_close(theInSnmpConnection);
445
* Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'
446
* and 'out' sockets might be just one FD. This prevents this
447
* function from executing repeatedly. When we are really ready to
448
* exit or restart, main will comm_close the 'out' descriptor.
449
*/ theInSnmpConnection = -1;
452
* Normally we only write to the outgoing SNMP socket, but we
453
* also have a read handler there to catch messages sent to that
454
* specific interface. During shutdown, we must disable reading
455
* on the outgoing socket.
457
assert(theOutSnmpConnection > -1);
459
commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
463
snmpConnectionClose(void)
465
snmpConnectionShutdown();
467
if (theOutSnmpConnection > -1) {
468
debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection);
469
comm_close(theOutSnmpConnection);
474
* Functions for handling the requests.
478
* Accept the UDP packet
481
snmpHandleUdp(int sock, void *not_used)
483
LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
485
struct sockaddr_in from;
487
snmp_request_t *snmp_rq;
490
debug(49, 5) ("snmpHandleUdp: Called.\n");
492
commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
494
from_len = sizeof(struct sockaddr_in);
495
memset(&from, '\0', from_len);
496
memset(buf, '\0', SNMP_REQUEST_SIZE);
498
len = comm_udp_recvfrom(sock,
503
(struct sockaddr *) &from,
508
debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
511
inet_ntoa(from.sin_addr));
513
snmp_rq = (snmp_request_t *)xcalloc(1, sizeof(snmp_request_t));
514
snmp_rq->buf = (u_char *) buf;
516
snmp_rq->sock = sock;
517
snmp_rq->outbuf = (unsigned char *)xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);
519
xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));
520
snmpDecodePacket(snmp_rq);
521
xfree(snmp_rq->outbuf);
524
debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror());
529
* Turn SNMP packet into a PDU, check available ACL's
532
snmpDecodePacket(snmp_request_t * rq)
535
struct snmp_pdu *PDU;
538
u_char *buf = rq->buf;
542
debug(49, 5) ("snmpDecodePacket: Called.\n");
543
/* Now that we have the data, turn it into a PDU */
544
PDU = snmp_pdu_create(0);
545
rq->session.Version = SNMP_VERSION_1;
546
Community = snmp_parse(&rq->session, PDU, buf, len);
549
ACLChecklist checklist;
550
checklist.accessList = cbdataReference(Config.accessList.snmp);
551
checklist.src_addr = rq->from.sin_addr;
552
checklist.snmp_community = (char *) Community;
553
/* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
554
allow = checklist.fastCheck();
557
if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
558
rq->community = Community;
560
debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid);
561
snmpConstructReponse(rq);
563
debug(49, 1) ("Failed SNMP agent query from : %s.\n",
564
inet_ntoa(rq->from.sin_addr));
573
* Packet OK, ACL Check OK, Create reponse.
576
snmpConstructReponse(snmp_request_t * rq)
579
struct snmp_pdu *RespPDU;
581
debug(49, 5) ("snmpConstructReponse: Called.\n");
582
RespPDU = snmpAgentResponse(rq->PDU);
583
snmp_free_pdu(rq->PDU);
585
if (RespPDU != NULL) {
586
snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen);
587
comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen);
588
snmp_free_pdu(RespPDU);
593
* Decide how to respond to the request, construct a response and
594
* return the response to the requester.
597
static struct snmp_pdu *
599
snmpAgentResponse(struct snmp_pdu *PDU)
602
struct snmp_pdu *Answer = NULL;
604
debug(49, 5) ("snmpAgentResponse: Called.\n");
606
if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE)))
608
Answer->reqid = PDU->reqid;
609
Answer->errindex = 0;
611
if (PDU->command == SNMP_PDU_GET || PDU->command == SNMP_PDU_GETNEXT) {
612
int get_next = (PDU->command == SNMP_PDU_GETNEXT);
613
variable_list *VarPtr_;
614
variable_list **RespVars = &(Answer->variables);
615
oid_ParseFn *ParseFn;
617
/* Loop through all variables */
619
for (VarPtr_ = PDU->variables; VarPtr_; VarPtr_ = VarPtr_->next_variable) {
620
variable_list *VarPtr = VarPtr_;
621
variable_list *VarNew = NULL;
622
oid *NextOidName = NULL;
623
snint NextOidNameLen = 0;
627
/* Find the parsing function for this variable */
630
ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen);
632
ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length);
634
if (ParseFn == NULL) {
635
Answer->errstat = SNMP_ERR_NOSUCHNAME;
636
debug(49, 5) ("snmpAgentResponse: No such oid. ");
639
VarPtr = snmp_var_new(NextOidName, NextOidNameLen);
643
int * errstatTmp = &(Answer->errstat);
645
VarNew = (*ParseFn) (VarPtr, (snint *) errstatTmp);
648
snmp_var_free(VarPtr);
651
/* Was there an error? */
652
if ((Answer->errstat != SNMP_ERR_NOERROR) || (VarNew == NULL)) {
653
Answer->errindex = index;
654
debug(49, 5) ("snmpAgentResponse: error.\n");
657
snmp_var_free(VarNew);
659
/* Free the already processed results, if any */
660
while ((VarPtr = Answer->variables) != NULL) {
661
Answer->variables = VarPtr->next_variable;
662
snmp_var_free(VarPtr);
665
/* Steal the original PDU list of variables for the error response */
666
Answer->variables = PDU->variables;
668
PDU->variables = NULL;
673
/* No error. Insert this var at the end, and move on to the next.
677
RespVars = &(VarNew->next_variable);
686
snmpTreeGet(oid * Current, snint CurrentLen)
688
oid_ParseFn *Fn = NULL;
689
mib_tree_entry *mibTreeEntry = NULL;
692
debug(49, 5) ("snmpTreeGet: Called\n");
694
debug(49, 6) ("snmpTreeGet: Current : \n");
695
snmpDebugOid(6, Current, CurrentLen);
697
mibTreeEntry = mib_tree_head;
699
if (Current[count] == mibTreeEntry->name[count]) {
702
while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
703
mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
708
if (mibTreeEntry && mibTreeEntry->parsefunction)
709
Fn = mibTreeEntry->parsefunction;
711
debug(49, 5) ("snmpTreeGet: return\n");
717
snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
719
oid_ParseFn *Fn = NULL;
720
mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;
723
debug(49, 5) ("snmpTreeNext: Called\n");
725
debug(49, 6) ("snmpTreeNext: Current : \n");
726
snmpDebugOid(6, Current, CurrentLen);
728
mibTreeEntry = mib_tree_head;
730
if (Current[count] == mibTreeEntry->name[count]) {
733
while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
734
mib_tree_entry *nextmibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
736
if (!nextmibTreeEntry)
739
mibTreeEntry = nextmibTreeEntry;
744
debug(49, 5) ("snmpTreeNext: Recursed down to requested object\n");
749
if (mibTreeEntry == mib_tree_last)
752
if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
753
*NextLen = CurrentLen;
754
*Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
760
if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
762
nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
765
debug(49, 5) ("snmpTreeNext: Next OID found for sibling\n");
766
mibTreeEntry = nextoid;
769
debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next object\n");
774
if (mibTreeEntry->parent->parent) {
775
nextoid = mibTreeEntry->parent;
776
mibTreeEntry = snmpTreeEntry(Current[count] + 1, count, nextoid->parent);
779
mibTreeEntry = nextoid;
783
nextoid = mibTreeEntry;
790
while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) {
791
mibTreeEntry = mibTreeEntry->leaves[0];
795
*NextLen = mibTreeEntry->len;
796
*Next = (*mibTreeEntry->instancefunction) (mibTreeEntry->name, NextLen, mibTreeEntry, &Fn);
806
static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
808
oid *instance = NULL;
810
if (*len <= current->len) {
811
instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
812
xmemcpy(instance, name, (sizeof(name) * *len));
817
*Fn = current->parsefunction;
822
time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
824
oid *instance = NULL;
825
int identifier = 0, loop = 0;
826
int index[TIME_INDEX_LEN] =
829
if (*len <= current->len) {
830
instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
831
xmemcpy(instance, name, (sizeof(name) * *len));
832
instance[*len] = *index;
835
identifier = name[*len - 1];
837
while ((identifier != index[loop]) && (loop < TIME_INDEX_LEN))
840
if (loop < TIME_INDEX_LEN - 1) {
841
instance = (oid *)xmalloc(sizeof(name) * (*len));
842
xmemcpy(instance, name, (sizeof(name) * *len));
843
instance[*len - 1] = index[++loop];
847
*Fn = current->parsefunction;
852
peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
854
oid *instance = NULL;
856
peer *peers = Config.peers;
858
struct IN_ADDR *laddr = NULL;
859
char *host_addr = NULL, *current_addr = NULL, *last_addr = NULL;
862
current = current->parent->parent->parent->leaves[1];
864
while ((current) && (!current->parsefunction))
865
current = current->leaves[0];
867
instance = client_Inst(current->name, len, current, Fn);
868
} else if (*len <= current->len) {
869
instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
870
xmemcpy(instance, name, (sizeof(name) * *len));
871
cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
872
instance[*len] = *cp++;
873
instance[*len + 1] = *cp++;
874
instance[*len + 2] = *cp++;
875
instance[*len + 3] = *cp++;
878
laddr = oid2addr(&name[*len - 4]);
879
host_addr = inet_ntoa(*laddr);
880
last_addr = (char *)xmalloc(strlen(host_addr));
881
strncpy(last_addr, host_addr, strlen(host_addr));
882
current_addr = inet_ntoa(peers->in_addr.sin_addr);
884
while ((peers) && (strncmp(last_addr, current_addr, strlen(current_addr)))) {
887
current_addr = inet_ntoa(peers->in_addr.sin_addr);
898
instance = (oid *)xmalloc(sizeof(name) * (*len));
899
xmemcpy(instance, name, (sizeof(name) * *len));
900
cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
901
instance[*len - 4] = *cp++;
902
instance[*len - 3] = *cp++;
903
instance[*len - 2] = *cp++;
904
instance[*len - 1] = *cp++;
913
*Fn = current->parsefunction;
918
client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
920
oid *instance = NULL;
923
struct IN_ADDR *laddr = NULL;
925
if (*len <= current->len) {
926
instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
927
xmemcpy(instance, name, (sizeof(name) * *len));
928
laddr = client_entry(NULL);
931
cp = (u_char *) & (laddr->s_addr);
932
instance[*len] = *cp++;
933
instance[*len + 1] = *cp++;
934
instance[*len + 2] = *cp++;
935
instance[*len + 3] = *cp++;
939
laddr = oid2addr(&name[*len - 4]);
940
laddr = client_entry(laddr);
943
instance = (oid *)xmalloc(sizeof(name) * (*len));
944
xmemcpy(instance, name, (sizeof(name) * *len));
945
cp = (u_char *) & (laddr->s_addr);
946
instance[*len - 4] = *cp++;
947
instance[*len - 3] = *cp++;
948
instance[*len - 2] = *cp++;
949
instance[*len - 1] = *cp++;
953
*Fn = current->parsefunction;
963
* Tree utility functions.
967
* Returns a the sibling object in the tree
969
static mib_tree_entry *
970
snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
972
mib_tree_entry *next = NULL;
975
while ((!next) && (count < current->children)) {
976
if (current->leaves[count]->name[len] == entry) {
977
next = current->leaves[count];
983
if (count < current->children) {
984
next = current->leaves[count];
993
* Returns the requested child object or NULL if it does not exist
995
static mib_tree_entry *
996
snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
998
mib_tree_entry *next = NULL;
1001
while ((!next) && (count < current->children)) {
1002
if (current->leaves[count]->name[len] == entry) {
1003
next = current->leaves[count];
1013
* Adds a node to the MIB tree structure and adds the appropriate children
1015
static mib_tree_entry *
1017
snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
1019
snmpAddNode(va_alist)
1026
mib_tree_entry *entry = NULL;
1027
va_start(args, children);
1032
int len = 0, children = 0, loop;
1033
oid_ParseFn *parsefunction = NULL;
1034
instance_Fn *instancefunction = NULL;
1035
mib_tree_entry *entry = NULL;
1037
name = va_arg(args, oid *);
1038
len = va_arg(args, int);
1039
parsefunction = va_arg(args, oid_ParseFn *);
1040
instancefunction = va_arg(args, instance_Fn *);
1041
children = va_arg(args, int);
1044
debug(49, 6) ("snmpAddNode: Children : %d, Oid : \n", children);
1045
snmpDebugOid(6, name, len);
1047
va_start(args, children);
1048
entry = (mib_tree_entry *)xmalloc(sizeof(mib_tree_entry));
1051
entry->parsefunction = parsefunction;
1052
entry->instancefunction = instancefunction;
1053
entry->children = children;
1057
entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children);
1059
for (loop = 0; loop < children; loop++) {
1060
entry->leaves[loop] = va_arg(args, mib_tree_entry *);
1061
entry->leaves[loop]->parent = entry;
1067
/* End of tree utility functions */
1070
* Returns the list of parameters in an oid
1074
snmpCreateOid(int length,...)
1076
snmpCreateOid(va_alist)
1084
va_start(args, length);
1088
int length = 0, loop;
1091
length va_arg(args, int);
1094
new_oid = (oid *)xmalloc(sizeof(oid) * length);
1098
for (loop = 0; loop < length; loop++) {
1099
new_oid[loop] = va_arg(args, int);
1108
* Allocate space for, and copy, an OID. Returns new oid.
1111
snmpOidDup(oid * A, snint ALen)
1113
oid *Ans = xmalloc(sizeof(oid) * ALen);
1114
xmemcpy(Ans, A, (sizeof(oid) * ALen));
1121
* Debug calls, prints out the OID for debugging purposes.
1124
snmpDebugOid(int lvl, oid * Name, snint Len)
1126
char mbuf[16], objid[1024];
1130
for (x = 0; x < Len; x++) {
1131
snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
1132
strncat(objid, mbuf, sizeof(objid));
1135
debug(49, lvl) (" oid = %s\n", objid);
1139
snmpSnmplibDebug(int lvl, char *buf)
1141
debug(49, lvl) ("%s", buf);
1146
addr2oid(struct IN_ADDR addr, oid * Dest)
1149
cp = (u_char *) & (addr.s_addr);
1161
static struct IN_ADDR laddr;
1162
u_char *cp = (u_char *) & (laddr.s_addr);
1170
/* SNMP checklists */
1171
#include "ACLStrategy.h"
1172
#include "ACLStrategised.h"
1173
#include "ACLStringData.h"
1175
class ACLSNMPCommunityStrategy : public ACLStrategy<char const *>
1179
virtual int match (ACLData<MatchType> * &, ACLChecklist *);
1180
static ACLSNMPCommunityStrategy *Instance();
1181
/* Not implemented to prevent copies of the instance. */
1182
/* Not private to prevent brain dead g+++ warnings about
1183
* private constructors with no friends */
1184
ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &);
1187
static ACLSNMPCommunityStrategy Instance_;
1188
ACLSNMPCommunityStrategy(){}
1190
ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &);
1193
class ACLSNMPCommunity
1197
static ACL::Prototype RegistryProtoype;
1198
static ACLStrategised<char const *> RegistryEntry_;
1201
ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community");
1202
ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
1205
ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
1207
return data->match (checklist->snmp_community);
1210
ACLSNMPCommunityStrategy *
1211
ACLSNMPCommunityStrategy::Instance()
1216
ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_;