2 * DEBUG: section 49 SNMP support
3 * AUTHOR: Glenn Chisholm
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
34 #include "cache_snmp.h"
35 #include "acl/FilledChecklist.h"
36 #include "ip/IpAddress.h"
38 #define SNMP_REQUEST_SIZE 4096
39 #define MAX_PROTOSTAT 5
41 IpAddress theOutSNMPAddr
;
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
{
49 oid_ParseFn
*parsefunction
;
50 instance_Fn
*instancefunction
;
53 struct _mib_tree_entry
**leaves
;
55 struct _mib_tree_entry
*parent
;
58 mib_tree_entry
*mib_tree_head
;
59 mib_tree_entry
*mib_tree_last
;
61 static mib_tree_entry
*snmpAddNode(oid
* name
, int len
, oid_ParseFn
* parsefunction
, instance_Fn
* instancefunction
, int children
,...);
62 static oid
*snmpCreateOid(int length
,...);
63 SQUIDCEXTERN
void (*snmplib_debug_hook
) (int, char *);
64 static oid
*static_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
65 static oid
*time_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
66 static oid
*peer_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
67 static oid
*client_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
);
68 static void snmpDecodePacket(snmp_request_t
* rq
);
69 static void snmpConstructReponse(snmp_request_t
* rq
);
71 static struct snmp_pdu
*snmpAgentResponse(struct snmp_pdu
*PDU
);
72 static oid_ParseFn
*snmpTreeNext(oid
* Current
, snint CurrentLen
, oid
** Next
, snint
* NextLen
);
73 static oid_ParseFn
*snmpTreeGet(oid
* Current
, snint CurrentLen
);
74 static mib_tree_entry
*snmpTreeEntry(oid entry
, snint len
, mib_tree_entry
* current
);
75 static mib_tree_entry
*snmpTreeSiblingEntry(oid entry
, snint len
, mib_tree_entry
* current
);
76 static void snmpSnmplibDebug(int lvl
, char *buf
);
79 * The functions used during startup:
82 * snmpConnectionShutdown
87 * Turns the MIB into a Tree structure. Called during the startup process.
92 debugs(49, 5, "snmpInit: Building SNMP mib tree structure");
94 snmplib_debug_hook
= snmpSnmplibDebug
;
96 mib_tree_head
= snmpAddNode(snmpCreateOid(1, 1),
98 snmpAddNode(snmpCreateOid(2, 1, 3),
100 snmpAddNode(snmpCreateOid(3, 1, 3, 6),
102 snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1),
104 snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4),
106 snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1),
108 snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495),
110 snmpAddNode(snmpCreateOid(LEN_SQUIDMIB
, SQUIDMIB
),
112 snmpAddNode(snmpCreateOid(LEN_SQ_SYS
, SQ_SYS
),
113 LEN_SQ_SYS
, NULL
, NULL
, 3,
114 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_SYS
, SYSVMSIZ
),
115 LEN_SYS
, snmp_sysFn
, static_Inst
, 0),
116 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_SYS
, SYSSTOR
),
117 LEN_SYS
, snmp_sysFn
, static_Inst
, 0),
118 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_SYS
, SYS_UPTIME
),
119 LEN_SYS
, snmp_sysFn
, static_Inst
, 0)),
120 snmpAddNode(snmpCreateOid(LEN_SQ_CONF
, SQ_CONF
),
121 LEN_SQ_CONF
, NULL
, NULL
, 6,
122 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_CONF
, CONF_ADMIN
),
123 LEN_SYS
, snmp_confFn
, static_Inst
, 0),
124 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_CONF
, CONF_VERSION
),
125 LEN_SYS
, snmp_confFn
, static_Inst
, 0),
126 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_CONF
, CONF_VERSION_ID
),
127 LEN_SYS
, snmp_confFn
, static_Inst
, 0),
128 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_CONF
, CONF_LOG_FAC
),
129 LEN_SYS
, snmp_confFn
, static_Inst
, 0),
130 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_CONF
, CONF_STORAGE
),
131 LEN_SYS
, NULL
, NULL
, 4,
132 snmpAddNode(snmpCreateOid(LEN_CONF_ST
, SQ_CONF
, CONF_STORAGE
, CONF_ST_MMAXSZ
),
133 LEN_CONF_ST
, snmp_confFn
, static_Inst
, 0),
134 snmpAddNode(snmpCreateOid(LEN_CONF_ST
, SQ_CONF
, CONF_STORAGE
, CONF_ST_SWMAXSZ
),
135 LEN_CONF_ST
, snmp_confFn
, static_Inst
, 0),
136 snmpAddNode(snmpCreateOid(LEN_CONF_ST
, SQ_CONF
, CONF_STORAGE
, CONF_ST_SWHIWM
),
137 LEN_CONF_ST
, snmp_confFn
, static_Inst
, 0),
138 snmpAddNode(snmpCreateOid(LEN_CONF_ST
, SQ_CONF
, CONF_STORAGE
, CONF_ST_SWLOWM
),
139 LEN_CONF_ST
, snmp_confFn
, static_Inst
, 0)),
140 snmpAddNode(snmpCreateOid(LEN_SYS
, SQ_CONF
, CONF_UNIQNAME
),
141 LEN_SYS
, snmp_confFn
, static_Inst
, 0)),
142 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
, SQ_PRF
),
143 LEN_SQ_PRF
, NULL
, NULL
, 2,
144 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 1, SQ_PRF
, PERF_SYS
),
145 LEN_SQ_PRF
+ 1, NULL
, NULL
, 13,
146 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_PF
),
147 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
148 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_NUMR
),
149 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
150 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_MEMUSAGE
),
151 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
152 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CPUTIME
),
153 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
154 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CPUUSAGE
),
155 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
156 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_MAXRESSZ
),
157 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
158 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_NUMOBJCNT
),
159 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
160 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CURLRUEXP
),
161 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
162 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CURUNLREQ
),
163 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
164 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CURUNUSED_FD
),
165 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
166 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CURRESERVED_FD
),
167 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
168 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CURUSED_FD
),
169 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0),
170 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_SYS
, PERF_SYS_CURMAX_FD
),
171 LEN_SQ_PRF
+ 2, snmp_prfSysFn
, static_Inst
, 0)),
172 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 1, SQ_PRF
, PERF_PROTO
),
173 LEN_SQ_PRF
+ 1, NULL
, NULL
, 2,
174 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
),
175 LEN_SQ_PRF
+ 2, NULL
, NULL
, 15,
176 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_HTTP_REQ
),
177 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
178 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_HTTP_HITS
),
179 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
180 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_HTTP_ERRORS
),
181 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
182 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN
),
183 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
184 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT
),
185 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
186 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_ICP_S
),
187 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
188 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_ICP_R
),
189 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
190 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_ICP_SKB
),
191 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
192 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_ICP_RKB
),
193 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
194 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_REQ
),
195 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
196 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_ERRORS
),
197 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
198 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_KBYTES_IN
),
199 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
200 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_KBYTES_OUT
),
201 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
202 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_CURSWAP
),
203 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0),
204 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_AGGR
, PERF_PROTOSTAT_AGGR_CLIENTS
),
205 LEN_SQ_PRF
+ 3, snmp_prfProtoFn
, static_Inst
, 0)),
206 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 2, SQ_PRF
, PERF_PROTO
, 2),
207 LEN_SQ_PRF
+ 2, NULL
, NULL
, 1,
208 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 3, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1),
209 LEN_SQ_PRF
+ 3, NULL
, NULL
, 11,
210 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_TIME
),
211 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
212 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_HTTP_ALL
),
213 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
214 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_HTTP_MISS
),
215 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
216 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_HTTP_NM
),
217 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
218 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_HTTP_HIT
),
219 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
220 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_ICP_QUERY
),
221 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
222 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_ICP_REPLY
),
223 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
224 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_DNS
),
225 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
226 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_RHR
),
227 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
228 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_BHR
),
229 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0),
230 snmpAddNode(snmpCreateOid(LEN_SQ_PRF
+ 4, SQ_PRF
, PERF_PROTO
, PERF_PROTOSTAT_MEDIAN
, 1, PERF_MEDIAN_HTTP_NH
),
231 LEN_SQ_PRF
+ 4, snmp_prfProtoFn
, time_Inst
, 0))))),
232 snmpAddNode(snmpCreateOid(LEN_SQ_NET
, SQ_NET
),
233 LEN_SQ_NET
, NULL
, NULL
, 3,
234 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 1, SQ_NET
, NET_IP_CACHE
),
235 LEN_SQ_NET
+ 1, NULL
, NULL
, 8,
236 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_ENT
),
237 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0),
238 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_REQ
),
239 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0),
240 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_HITS
),
241 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0),
242 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_PENDHIT
),
243 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0),
244 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_NEGHIT
),
245 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0),
246 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_MISS
),
247 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0),
248 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_GHBN
),
249 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0),
250 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_IP_CACHE
, IP_LOC
),
251 LEN_SQ_NET
+ 2, snmp_netIpFn
, static_Inst
, 0)),
252 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 1, SQ_NET
, NET_FQDN_CACHE
),
253 LEN_SQ_NET
+ 1, NULL
, NULL
, 7,
254 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_FQDN_CACHE
, FQDN_ENT
),
255 LEN_SQ_NET
+ 2, snmp_netFqdnFn
, static_Inst
, 0),
256 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_FQDN_CACHE
, FQDN_REQ
),
257 LEN_SQ_NET
+ 2, snmp_netFqdnFn
, static_Inst
, 0),
258 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_FQDN_CACHE
, FQDN_HITS
),
259 LEN_SQ_NET
+ 2, snmp_netFqdnFn
, static_Inst
, 0),
260 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_FQDN_CACHE
, FQDN_PENDHIT
),
261 LEN_SQ_NET
+ 2, snmp_netFqdnFn
, static_Inst
, 0),
262 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_FQDN_CACHE
, FQDN_NEGHIT
),
263 LEN_SQ_NET
+ 2, snmp_netFqdnFn
, static_Inst
, 0),
264 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_FQDN_CACHE
, FQDN_MISS
),
265 LEN_SQ_NET
+ 2, snmp_netFqdnFn
, static_Inst
, 0),
266 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_FQDN_CACHE
, FQDN_GHBN
),
267 LEN_SQ_NET
+ 2, snmp_netFqdnFn
, static_Inst
, 0)),
268 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 1, SQ_NET
, NET_DNS_CACHE
),
269 LEN_SQ_NET
+ 1, NULL
, NULL
, 3,
271 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_DNS_CACHE
, DNS_REQ
),
272 LEN_SQ_NET
+ 2, snmp_netDnsFn
, static_Inst
, 0),
273 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_DNS_CACHE
, DNS_REP
),
274 LEN_SQ_NET
+ 2, snmp_netDnsFn
, static_Inst
, 0),
275 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_DNS_CACHE
, DNS_SERVERS
),
276 LEN_SQ_NET
+ 2, snmp_netDnsFn
, static_Inst
, 0))),
278 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_DNS_CACHE
, DNS_REQ
),
279 LEN_SQ_NET
+ 2, snmp_netIdnsFn
, static_Inst
, 0),
280 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_DNS_CACHE
, DNS_REP
),
281 LEN_SQ_NET
+ 2, snmp_netIdnsFn
, static_Inst
, 0),
282 snmpAddNode(snmpCreateOid(LEN_SQ_NET
+ 2, SQ_NET
, NET_DNS_CACHE
, DNS_SERVERS
),
283 LEN_SQ_NET
+ 2, snmp_netIdnsFn
, static_Inst
, 0))),
285 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
, SQ_MESH
),
286 LEN_SQ_MESH
, NULL
, NULL
, 2,
287 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 1, SQ_MESH
, MESH_PTBL
),
288 LEN_SQ_MESH
+ 1, NULL
, NULL
, 1,
289 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 2, SQ_MESH
, 1, 1),
290 LEN_SQ_MESH
+ 2, NULL
, NULL
, 15,
291 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_INDEX
),
292 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
293 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_NAME
),
294 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
295 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_ADDR_TYPE
),
296 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
297 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_ADDR
),
298 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
299 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_HTTP
),
300 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
301 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_ICP
),
302 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
303 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_TYPE
),
304 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
305 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_STATE
),
306 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
307 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_SENT
),
308 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
309 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_PACKED
),
310 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
311 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_FETCHES
),
312 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
313 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_RTT
),
314 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
315 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_IGN
),
316 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
317 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_KEEPAL_S
),
318 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0),
319 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_PTBL
, 1, MESH_PTBL_KEEPAL_R
),
320 LEN_SQ_MESH
+ 3, snmp_meshPtblFn
, peer_Inst
, 0))),
321 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 1, SQ_MESH
, MESH_CTBL
),
322 LEN_SQ_MESH
+ 1, NULL
, NULL
, 1,
323 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 2, SQ_MESH
, MESH_CTBL
, 1),
324 LEN_SQ_MESH
+ 2, NULL
, NULL
, 10,
325 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_ADDR_TYPE
),
326 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
327 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_ADDR
),
328 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
329 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_HTREQ
),
330 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
331 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_HTBYTES
),
332 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
333 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_HTHITS
),
334 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
335 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_HTHITBYTES
),
336 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
337 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_ICPREQ
),
338 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
339 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_ICPBYTES
),
340 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
341 snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_ICPHITS
),
342 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0),
343 (mib_tree_last
= snmpAddNode(snmpCreateOid(LEN_SQ_MESH
+ 3, SQ_MESH
, MESH_CTBL
, 1, MESH_CTBL_ICPHITBYTES
),
344 LEN_SQ_MESH
+ 3, snmp_meshCtblFn
, client_Inst
, 0)))))
354 debugs(49, 9, "snmpInit: Completed SNMP mib tree structure");
358 snmpConnectionOpen(void)
360 struct addrinfo
*xaddr
= NULL
;
363 debugs(49, 5, "snmpConnectionOpen: Called");
365 if (Config
.Port
.snmp
> 0) {
366 Config
.Addrs
.snmp_incoming
.SetPort(Config
.Port
.snmp
);
368 theInSnmpConnection
= comm_open_listener(SOCK_DGRAM
,
370 Config
.Addrs
.snmp_incoming
,
375 if (theInSnmpConnection
< 0)
376 fatal("Cannot open SNMP Port");
378 commSetSelect(theInSnmpConnection
, COMM_SELECT_READ
, snmpHandleUdp
, NULL
, 0);
380 debugs(1, 1, "Accepting SNMP messages on " << Config
.Addrs
.snmp_incoming
<< ", FD " << theInSnmpConnection
<< ".");
382 if (!Config
.Addrs
.snmp_outgoing
.IsNoAddr()) {
383 Config
.Addrs
.snmp_outgoing
.SetPort(Config
.Port
.snmp
);
385 theOutSnmpConnection
= comm_open_listener(SOCK_DGRAM
,
387 Config
.Addrs
.snmp_outgoing
,
392 if (theOutSnmpConnection
< 0)
393 fatal("Cannot open Outgoing SNMP Port");
395 commSetSelect(theOutSnmpConnection
,
400 debugs(1, 1, "Outgoing SNMP messages on " << Config
.Addrs
.snmp_outgoing
<< ", FD " << theOutSnmpConnection
<< ".");
402 fd_note(theOutSnmpConnection
, "Outgoing SNMP socket");
404 fd_note(theInSnmpConnection
, "Incoming SNMP socket");
406 theOutSnmpConnection
= theInSnmpConnection
;
409 theOutSNMPAddr
.SetEmpty();
411 theOutSNMPAddr
.InitAddrInfo(xaddr
);
413 x
= getsockname(theOutSnmpConnection
, xaddr
->ai_addr
, &xaddr
->ai_addrlen
);
416 debugs(51, 1, "theOutSnmpConnection FD " << theOutSnmpConnection
<< ": getsockname: " << xstrerror());
418 theOutSNMPAddr
= *xaddr
;
420 theOutSNMPAddr
.FreeAddrInfo(xaddr
);
425 snmpConnectionShutdown(void)
427 if (theInSnmpConnection
< 0)
430 if (theInSnmpConnection
!= theOutSnmpConnection
) {
431 debugs(49, 1, "FD " << theInSnmpConnection
<< " Closing SNMP socket");
432 comm_close(theInSnmpConnection
);
436 * Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'
437 * and 'out' sockets might be just one FD. This prevents this
438 * function from executing repeatedly. When we are really ready to
439 * exit or restart, main will comm_close the 'out' descriptor.
441 theInSnmpConnection
= -1;
444 * Normally we only write to the outgoing SNMP socket, but we
445 * also have a read handler there to catch messages sent to that
446 * specific interface. During shutdown, we must disable reading
447 * on the outgoing socket.
449 assert(theOutSnmpConnection
> -1);
451 commSetSelect(theOutSnmpConnection
, COMM_SELECT_READ
, NULL
, NULL
, 0);
455 snmpConnectionClose(void)
457 snmpConnectionShutdown();
459 if (theOutSnmpConnection
> -1) {
460 debugs(49, 1, "FD " << theOutSnmpConnection
<< " Closing SNMP socket");
461 comm_close(theOutSnmpConnection
);
462 /* make sure the SNMP out connection is unset */
463 theOutSnmpConnection
= -1;
468 * Functions for handling the requests.
472 * Accept the UDP packet
475 snmpHandleUdp(int sock
, void *not_used
)
477 LOCAL_ARRAY(char, buf
, SNMP_REQUEST_SIZE
);
479 snmp_request_t
*snmp_rq
;
482 debugs(49, 5, "snmpHandleUdp: Called.");
484 commSetSelect(sock
, COMM_SELECT_READ
, snmpHandleUdp
, NULL
, 0);
486 memset(buf
, '\0', SNMP_REQUEST_SIZE
);
488 len
= comm_udp_recvfrom(sock
,
496 debugs(49, 3, "snmpHandleUdp: FD " << sock
<< ": received " << len
<< " bytes from " << from
<< ".");
498 snmp_rq
= (snmp_request_t
*)xcalloc(1, sizeof(snmp_request_t
));
499 snmp_rq
->buf
= (u_char
*) buf
;
501 snmp_rq
->sock
= sock
;
502 snmp_rq
->outbuf
= (unsigned char *)xmalloc(snmp_rq
->outlen
= SNMP_REQUEST_SIZE
);
503 snmp_rq
->from
= from
;
504 snmpDecodePacket(snmp_rq
);
505 xfree(snmp_rq
->outbuf
);
508 debugs(49, 1, "snmpHandleUdp: FD " << sock
<< " recvfrom: " << xstrerror());
513 * Turn SNMP packet into a PDU, check available ACL's
516 snmpDecodePacket(snmp_request_t
* rq
)
518 struct snmp_pdu
*PDU
;
520 u_char
*buf
= rq
->buf
;
524 debugs(49, 5, HERE
<< "Called.");
525 PDU
= snmp_pdu_create(0);
526 /* Allways answer on SNMPv1 */
527 rq
->session
.Version
= SNMP_VERSION_1
;
528 Community
= snmp_parse(&rq
->session
, PDU
, buf
, len
);
530 /* Check if we have explicit permission to access SNMP data.
531 * default (set above) is to deny all */
532 if (Community
&& Config
.accessList
.snmp
) {
533 ACLFilledChecklist
checklist(Config
.accessList
.snmp
, NULL
, NULL
);
534 checklist
.src_addr
= rq
->from
;
535 checklist
.snmp_community
= (char *) Community
;
536 allow
= checklist
.fastCheck();
539 if ((snmp_coexist_V2toV1(PDU
)) && (Community
) && (allow
)) {
540 rq
->community
= Community
;
542 debugs(49, 5, "snmpAgentParse: reqid=[" << PDU
->reqid
<< "]");
543 snmpConstructReponse(rq
);
545 debugs(49, 1, HERE
<< "Failed SNMP agent query from : " << rq
->from
);
554 * Packet OK, ACL Check OK, Create reponse.
557 snmpConstructReponse(snmp_request_t
* rq
)
560 struct snmp_pdu
*RespPDU
;
562 debugs(49, 5, "snmpConstructReponse: Called.");
563 RespPDU
= snmpAgentResponse(rq
->PDU
);
564 snmp_free_pdu(rq
->PDU
);
566 if (RespPDU
!= NULL
) {
567 snmp_build(&rq
->session
, RespPDU
, rq
->outbuf
, &rq
->outlen
);
568 comm_udp_sendto(rq
->sock
, rq
->from
, rq
->outbuf
, rq
->outlen
);
569 snmp_free_pdu(RespPDU
);
574 * Decide how to respond to the request, construct a response and
575 * return the response to the requester.
578 static struct snmp_pdu
*
580 snmpAgentResponse(struct snmp_pdu
*PDU
) {
582 struct snmp_pdu
*Answer
= NULL
;
584 debugs(49, 5, "snmpAgentResponse: Called.");
586 if ((Answer
= snmp_pdu_create(SNMP_PDU_RESPONSE
))) {
587 Answer
->reqid
= PDU
->reqid
;
588 Answer
->errindex
= 0;
590 if (PDU
->command
== SNMP_PDU_GET
|| PDU
->command
== SNMP_PDU_GETNEXT
) {
592 int get_next
= (PDU
->command
== SNMP_PDU_GETNEXT
);
593 variable_list
*VarPtr_
;
594 variable_list
**RespVars
= &(Answer
->variables
);
595 oid_ParseFn
*ParseFn
;
597 /* Loop through all variables */
599 for (VarPtr_
= PDU
->variables
; VarPtr_
; VarPtr_
= VarPtr_
->next_variable
) {
600 variable_list
*VarPtr
= VarPtr_
;
601 variable_list
*VarNew
= NULL
;
602 oid
*NextOidName
= NULL
;
603 snint NextOidNameLen
= 0;
608 ParseFn
= snmpTreeNext(VarPtr
->name
, VarPtr
->name_length
, &NextOidName
, &NextOidNameLen
);
610 ParseFn
= snmpTreeGet(VarPtr
->name
, VarPtr
->name_length
);
612 if (ParseFn
== NULL
) {
613 Answer
->errstat
= SNMP_ERR_NOSUCHNAME
;
614 debugs(49, 5, "snmpAgentResponse: No such oid. ");
617 VarPtr
= snmp_var_new(NextOidName
, NextOidNameLen
);
621 int * errstatTmp
= &(Answer
->errstat
);
623 VarNew
= (*ParseFn
) (VarPtr
, (snint
*) errstatTmp
);
626 snmp_var_free(VarPtr
);
629 if ((Answer
->errstat
!= SNMP_ERR_NOERROR
) || (VarNew
== NULL
)) {
630 Answer
->errindex
= index
;
631 debugs(49, 5, "snmpAgentResponse: error.");
634 snmp_var_free(VarNew
);
636 while ((VarPtr
= Answer
->variables
) != NULL
) {
637 Answer
->variables
= VarPtr
->next_variable
;
638 snmp_var_free(VarPtr
);
641 /* Steal the original PDU list of variables for the error response */
642 Answer
->variables
= PDU
->variables
;
644 PDU
->variables
= NULL
;
649 /* No error. Insert this var at the end, and move on to the next.
653 RespVars
= &(VarNew
->next_variable
);
662 snmpTreeGet(oid
* Current
, snint CurrentLen
)
664 oid_ParseFn
*Fn
= NULL
;
665 mib_tree_entry
*mibTreeEntry
= NULL
;
668 debugs(49, 5, "snmpTreeGet: Called");
670 debugs(49, 6, "snmpTreeGet: Current : ");
671 snmpDebugOid(6, Current
, CurrentLen
);
673 mibTreeEntry
= mib_tree_head
;
675 if (Current
[count
] == mibTreeEntry
->name
[count
]) {
678 while ((mibTreeEntry
) && (count
< CurrentLen
) && (!mibTreeEntry
->parsefunction
)) {
679 mibTreeEntry
= snmpTreeEntry(Current
[count
], count
, mibTreeEntry
);
684 if (mibTreeEntry
&& mibTreeEntry
->parsefunction
)
685 Fn
= mibTreeEntry
->parsefunction
;
687 debugs(49, 5, "snmpTreeGet: return");
693 snmpTreeNext(oid
* Current
, snint CurrentLen
, oid
** Next
, snint
* NextLen
)
695 oid_ParseFn
*Fn
= NULL
;
696 mib_tree_entry
*mibTreeEntry
= NULL
, *nextoid
= NULL
;
699 debugs(49, 5, "snmpTreeNext: Called");
701 debugs(49, 6, "snmpTreeNext: Current : ");
702 snmpDebugOid(6, Current
, CurrentLen
);
704 mibTreeEntry
= mib_tree_head
;
706 if (Current
[count
] == mibTreeEntry
->name
[count
]) {
709 while ((mibTreeEntry
) && (count
< CurrentLen
) && (!mibTreeEntry
->parsefunction
)) {
710 mib_tree_entry
*nextmibTreeEntry
= snmpTreeEntry(Current
[count
], count
, mibTreeEntry
);
712 if (!nextmibTreeEntry
)
715 mibTreeEntry
= nextmibTreeEntry
;
719 debugs(49, 5, "snmpTreeNext: Recursed down to requested object");
724 if (mibTreeEntry
== mib_tree_last
)
728 if ((mibTreeEntry
) && (mibTreeEntry
->parsefunction
)) {
729 *NextLen
= CurrentLen
;
730 *Next
= (*mibTreeEntry
->instancefunction
) (Current
, NextLen
, mibTreeEntry
, &Fn
);
732 debugs(49, 6, "snmpTreeNext: Next : ");
733 snmpDebugOid(6, *Next
, *NextLen
);
738 if ((mibTreeEntry
) && (mibTreeEntry
->parsefunction
)) {
740 nextoid
= snmpTreeSiblingEntry(Current
[count
], count
, mibTreeEntry
->parent
);
742 debugs(49, 5, "snmpTreeNext: Next OID found for sibling" << nextoid
);
743 mibTreeEntry
= nextoid
;
746 debugs(49, 5, "snmpTreeNext: Attempting to recurse up for next object");
751 if (mibTreeEntry
->parent
->parent
) {
752 nextoid
= mibTreeEntry
->parent
;
753 mibTreeEntry
= snmpTreeEntry(Current
[count
] + 1, count
, nextoid
->parent
);
756 mibTreeEntry
= nextoid
;
760 nextoid
= mibTreeEntry
;
766 while ((mibTreeEntry
) && (!mibTreeEntry
->parsefunction
)) {
767 mibTreeEntry
= mibTreeEntry
->leaves
[0];
771 *NextLen
= mibTreeEntry
->len
;
772 *Next
= (*mibTreeEntry
->instancefunction
) (mibTreeEntry
->name
, NextLen
, mibTreeEntry
, &Fn
);
776 debugs(49, 6, "snmpTreeNext: Next : ");
777 snmpDebugOid(6, *Next
, *NextLen
);
784 static_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
786 oid
*instance
= NULL
;
787 if (*len
<= current
->len
) {
788 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
+ 1));
789 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
793 *Fn
= current
->parsefunction
;
798 time_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
800 oid
*instance
= NULL
;
801 int identifier
= 0, loop
= 0;
802 int index
[TIME_INDEX_LEN
] = {TIME_INDEX
};
804 if (*len
<= current
->len
) {
805 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
+ 1));
806 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
807 instance
[*len
] = *index
;
810 identifier
= name
[*len
- 1];
812 while ((loop
< TIME_INDEX_LEN
) && (identifier
!= index
[loop
]))
815 if (loop
< (TIME_INDEX_LEN
- 1)) {
816 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
));
817 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
818 instance
[*len
- 1] = index
[++loop
];
822 *Fn
= current
->parsefunction
;
828 peer_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
830 oid
*instance
= NULL
;
831 peer
*peers
= Config
.peers
;
834 current
= current
->parent
->parent
->parent
->leaves
[1];
835 while ((current
) && (!current
->parsefunction
))
836 current
= current
->leaves
[0];
838 instance
= client_Inst(current
->name
, len
, current
, Fn
);
839 } else if (*len
<= current
->len
) {
840 instance
= (oid
*)xmalloc(sizeof(name
) * ( *len
+ 1));
841 xmemcpy(instance
, name
, (sizeof(name
) * *len
));
845 int no
= name
[current
->len
] ;
846 int i
; // Note: This works because the Confifg.peers
847 // keep its index acording to its position.
848 for ( i
=0 ; peers
&& (i
< no
) ; peers
= peers
->next
, i
++ ) ;
851 instance
= (oid
*)xmalloc(sizeof(name
) * (current
->len
+ 1 ));
852 xmemcpy(instance
, name
, (sizeof(name
) * current
->len
));
853 instance
[current
->len
] = no
+ 1 ; // i.e. the next index on cache_peeer table.
858 *Fn
= current
->parsefunction
;
863 client_Inst(oid
* name
, snint
* len
, mib_tree_entry
* current
, oid_ParseFn
** Fn
)
865 oid
*instance
= NULL
;
871 if (*len
<= current
->len
) {
872 aux
= client_entry(NULL
);
879 size
= sizeof(in_addr
);
882 size
= sizeof(in6_addr
);
885 instance
= (oid
*)xmalloc(sizeof(name
) * (*len
+ size
));
886 xmemcpy(instance
, name
, (sizeof(name
) * (*len
)));
888 if ( !laddr
.IsAnyAddr() ) {
889 addr2oid(laddr
, &instance
[ *len
]); // the addr
893 int shift
= *len
- current
->len
; // i.e 4 or 16
894 oid2addr(&name
[*len
- shift
], laddr
,shift
);
895 aux
= client_entry(&laddr
);
901 if (!laddr
.IsAnyAddr()) {
903 newshift
= sizeof(in_addr
);
906 newshift
= sizeof(in6_addr
);
908 instance
= (oid
*)xmalloc(sizeof(name
) * (current
->len
+ newshift
));
909 xmemcpy(instance
, name
, (sizeof(name
) * (current
->len
)));
910 addr2oid(laddr
, &instance
[current
->len
]); // the addr.
911 *len
= current
->len
+ newshift
;
915 *Fn
= current
->parsefunction
;
925 * Tree utility functions.
929 * Returns a sibling object for the requested child object or NULL
930 * if it does not exit
932 static mib_tree_entry
*
933 snmpTreeSiblingEntry(oid entry
, snint len
, mib_tree_entry
* current
)
935 mib_tree_entry
*next
= NULL
;
938 while ((!next
) && (count
< current
->children
)) {
939 if (current
->leaves
[count
]->name
[len
] == entry
) {
940 next
= current
->leaves
[count
];
946 /* Exactly the sibling on rigth */
947 if (count
< current
->children
) {
948 next
= current
->leaves
[count
];
957 * Returns the requested child object or NULL if it does not exist
959 static mib_tree_entry
*
960 snmpTreeEntry(oid entry
, snint len
, mib_tree_entry
* current
)
962 mib_tree_entry
*next
= NULL
;
965 while ((!next
) && (count
< current
->children
)) {
966 if (current
->leaves
[count
]->name
[len
] == entry
) {
967 next
= current
->leaves
[count
];
977 * Adds a node to the MIB tree structure and adds the appropriate children
979 static mib_tree_entry
*
980 snmpAddNode(oid
* name
, int len
, oid_ParseFn
* parsefunction
, instance_Fn
* instancefunction
, int children
,...)
984 mib_tree_entry
*entry
= NULL
;
985 va_start(args
, children
);
987 debugs(49, 6, "snmpAddNode: Children : " << children
<< ", Oid : ");
988 snmpDebugOid(6, name
, len
);
990 va_start(args
, children
);
991 entry
= (mib_tree_entry
*)xmalloc(sizeof(mib_tree_entry
));
994 entry
->parsefunction
= parsefunction
;
995 entry
->instancefunction
= instancefunction
;
996 entry
->children
= children
;
999 entry
->leaves
= (mib_tree_entry
**)xmalloc(sizeof(mib_tree_entry
*) * children
);
1001 for (loop
= 0; loop
< children
; loop
++) {
1002 entry
->leaves
[loop
] = va_arg(args
, mib_tree_entry
*);
1003 entry
->leaves
[loop
]->parent
= entry
;
1009 /* End of tree utility functions */
1012 * Returns the list of parameters in an oid
1015 snmpCreateOid(int length
,...)
1020 va_start(args
, length
);
1022 new_oid
= (oid
*)xmalloc(sizeof(oid
) * length
);
1025 for (loop
= 0; loop
< length
; loop
++) {
1026 new_oid
[loop
] = va_arg(args
, int);
1034 * Debug calls, prints out the OID for debugging purposes.
1037 snmpDebugOid(int lvl
, oid
* Name
, snint Len
)
1039 char mbuf
[16], objid
[1024];
1043 for (x
= 0; x
< Len
; x
++) {
1044 snprintf(mbuf
, sizeof(mbuf
), ".%u", (unsigned int) Name
[x
]);
1045 strncat(objid
, mbuf
, sizeof(objid
) - strlen(objid
) - 1);
1048 debugs(49, lvl
, " oid = " << objid
);
1052 snmpSnmplibDebug(int lvl
, char *buf
)
1054 debug(49, lvl
) ("%s", buf
);
1060 IPv4 address: 10.10.0.9 ==>
1062 IPv6 adress : 20:01:32:ef:a2:21:fb:32:00:00:00:00:00:00:00:00:OO:01 ==>
1063 oid == 32.1.50.239.162.33.251.20.50.0.0.0.0.0.0.0.0.0.1
1066 addr2oid(IpAddress
&addr
, oid
* Dest
)
1070 struct in_addr iaddr
;
1072 struct in6_addr i6addr
;
1073 oid code
= addr
.IsIPv4()? INETADDRESSTYPE_IPV4
: INETADDRESSTYPE_IPV6
;
1074 u_int size
= (code
== INETADDRESSTYPE_IPV4
) ? sizeof(struct in_addr
):sizeof(struct in6_addr
);
1076 oid code
= INETADDRESSTYPE_IPV4
;
1077 u_int size
= sizeof(struct in_addr
) ;
1078 #endif /* USE_IPV6 */
1080 if ( code
== INETADDRESSTYPE_IPV4
) {
1081 addr
.GetInAddr(iaddr
);
1082 cp
= (u_char
*) &(iaddr
.s_addr
);
1086 addr
.GetInAddr(i6addr
);
1087 cp
= (u_char
*) &i6addr
;
1090 for ( i
=0 ; i
< size
; i
++) {
1091 // OID's are in network order
1094 debugs(49, 7, "addr2oid: Dest : ");
1095 snmpDebugOid(7, Dest
, size
);
1100 oid == 10.10.0.9 ==>
1101 IPv4 address: 10.10.0.9
1102 oid == 32.1.50.239.162.33.251.20.50.0.0.0.0.0.0.0.0.0.1 ==>
1103 IPv6 adress : 20:01:32:ef:a2:21:fb:32:00:00:00:00:00:00:00:00:OO:01
1106 oid2addr(oid
* id
, IpAddress
&addr
, u_int size
)
1108 struct in_addr iaddr
;
1112 struct in6_addr i6addr
;
1113 if ( size
== sizeof(struct in_addr
) )
1114 #endif /* USE_IPV6 */
1115 cp
= (u_char
*) &(iaddr
.s_addr
);
1118 cp
= (u_char
*) &(i6addr
);
1119 #endif /* USE_IPV6 */
1120 debugs(49, 7, "oid2addr: id : ");
1121 snmpDebugOid(7, id
, size
);
1122 for (i
=0 ; i
<size
; i
++) {
1126 if ( size
== sizeof(struct in_addr
) )
1136 /* SNMP checklists */
1137 #include "acl/Strategy.h"
1138 #include "acl/Strategised.h"
1139 #include "acl/StringData.h"
1141 class ACLSNMPCommunityStrategy
: public ACLStrategy
<char const *>
1145 virtual int match (ACLData
<MatchType
> * &, ACLFilledChecklist
*);
1146 static ACLSNMPCommunityStrategy
*Instance();
1147 /* Not implemented to prevent copies of the instance. */
1148 /* Not private to prevent brain dead g+++ warnings about
1149 * private constructors with no friends */
1150 ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy
const &);
1153 static ACLSNMPCommunityStrategy Instance_
;
1154 ACLSNMPCommunityStrategy() {}
1156 ACLSNMPCommunityStrategy
&operator=(ACLSNMPCommunityStrategy
const &);
1159 class ACLSNMPCommunity
1163 static ACL::Prototype RegistryProtoype
;
1164 static ACLStrategised
<char const *> RegistryEntry_
;
1167 ACL::Prototype
ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_
, "snmp_community");
1168 ACLStrategised
<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData
, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
1171 ACLSNMPCommunityStrategy::match (ACLData
<MatchType
> * &data
, ACLFilledChecklist
*checklist
)
1173 return data
->match (checklist
->snmp_community
);
1176 ACLSNMPCommunityStrategy
*
1177 ACLSNMPCommunityStrategy::Instance()
1182 ACLSNMPCommunityStrategy
ACLSNMPCommunityStrategy::Instance_
;