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