]>
Commit | Line | Data |
---|---|---|
d2afb1f2 | 1 | /* |
43d4303e | 2 | * DEBUG: section 49 SNMP support |
dba79ac5 | 3 | * AUTHOR: Glenn Chisholm |
43d4303e | 4 | * |
2b6662ba | 5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
e25c139f | 6 | * ---------------------------------------------------------- |
43d4303e | 7 | * |
2b6662ba | 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. | |
43d4303e | 16 | * |
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. | |
26ac0430 | 21 | * |
43d4303e | 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. | |
26ac0430 | 26 | * |
43d4303e | 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 | |
cbdec147 | 29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
e25c139f | 30 | * |
43d4303e | 31 | */ |
43d4303e | 32 | #include "squid.h" |
063dc1eb | 33 | #include "comm.h" |
43d4303e | 34 | #include "cache_snmp.h" |
c0941a6a | 35 | #include "acl/FilledChecklist.h" |
9837e5f0 | 36 | #include "ip/IpAddress.h" |
43d4303e | 37 | |
38 | #define SNMP_REQUEST_SIZE 4096 | |
39 | #define MAX_PROTOSTAT 5 | |
40 | ||
ad61a2b4 | 41 | IpAddress theOutSNMPAddr; |
e1f7507e | 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 | ||
26ac0430 | 46 | struct _mib_tree_entry { |
c68e9c6b | 47 | oid *name; |
48 | int len; | |
49 | oid_ParseFn *parsefunction; | |
b6a2f15e | 50 | instance_Fn *instancefunction; |
c68e9c6b | 51 | int children; |
62e76326 | 52 | |
c68e9c6b | 53 | struct _mib_tree_entry **leaves; |
62e76326 | 54 | |
c68e9c6b | 55 | struct _mib_tree_entry *parent; |
dba79ac5 | 56 | }; |
43d4303e | 57 | |
dba79ac5 | 58 | mib_tree_entry *mib_tree_head; |
b6a2f15e | 59 | mib_tree_entry *mib_tree_last; |
43d4303e | 60 | |
b6a2f15e | 61 | static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...); |
853dead1 | 62 | static oid *snmpCreateOid(int length,...); |
8fd63c35 | 63 | SQUIDCEXTERN void (*snmplib_debug_hook) (int, char *); |
b6a2f15e | 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); | |
8a6218c6 | 68 | static void snmpDecodePacket(snmp_request_t * rq); |
74c161ea | 69 | static void snmpConstructReponse(snmp_request_t * rq); |
62e76326 | 70 | |
897029fd | 71 | static struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU); |
c68e9c6b | 72 | static oid_ParseFn *snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen); |
d439f213 | 73 | static oid_ParseFn *snmpTreeGet(oid * Current, snint CurrentLen); |
c68e9c6b | 74 | static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * current); |
897029fd | 75 | static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current); |
dba79ac5 | 76 | static void snmpSnmplibDebug(int lvl, char *buf); |
43d4303e | 77 | |
dba79ac5 | 78 | /* |
79 | * The functions used during startup: | |
80 | * snmpInit | |
81 | * snmpConnectionOpen | |
82 | * snmpConnectionShutdown | |
83 | * snmpConnectionClose | |
84 | */ | |
43d4303e | 85 | |
dba79ac5 | 86 | /* |
c68e9c6b | 87 | * Turns the MIB into a Tree structure. Called during the startup process. |
88 | */ | |
43d4303e | 89 | void |
90 | snmpInit(void) | |
91 | { | |
bf8fe701 | 92 | debugs(49, 5, "snmpInit: Building SNMP mib tree structure"); |
dba79ac5 | 93 | |
43d4303e | 94 | snmplib_debug_hook = snmpSnmplibDebug; |
95 | ||
dba79ac5 | 96 | mib_tree_head = snmpAddNode(snmpCreateOid(1, 1), |
62e76326 | 97 | 1, NULL, NULL, 1, |
98 | snmpAddNode(snmpCreateOid(2, 1, 3), | |
99 | 2, NULL, NULL, 1, | |
100 | snmpAddNode(snmpCreateOid(3, 1, 3, 6), | |
101 | 3, NULL, NULL, 1, | |
102 | snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1), | |
103 | 4, NULL, NULL, 1, | |
104 | snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4), | |
105 | 5, NULL, NULL, 1, | |
106 | snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1), | |
107 | 6, NULL, NULL, 1, | |
108 | snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495), | |
109 | 7, NULL, NULL, 1, | |
110 | snmpAddNode(snmpCreateOid(LEN_SQUIDMIB, SQUIDMIB), | |
111 | 8, NULL, NULL, 5, | |
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), | |
47a72328 | 121 | LEN_SQ_CONF, NULL, NULL, 6, |
62e76326 | 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), | |
47a72328 | 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)), | |
62e76326 | 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), | |
146e5e78 | 145 | LEN_SQ_PRF + 1, NULL, NULL, 13, |
cc192b50 | 146 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_PF), |
62e76326 | 147 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 148 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_NUMR), |
62e76326 | 149 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 150 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_MEMUSAGE), |
62e76326 | 151 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 152 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CPUTIME), |
62e76326 | 153 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 154 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CPUUSAGE), |
62e76326 | 155 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 156 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_MAXRESSZ), |
62e76326 | 157 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 158 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_NUMOBJCNT), |
62e76326 | 159 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 160 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURLRUEXP), |
62e76326 | 161 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 162 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURUNLREQ), |
62e76326 | 163 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 164 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURUNUSED_FD), |
62e76326 | 165 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
cc192b50 | 166 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURRESERVED_FD), |
146e5e78 | 167 | LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0), |
26ac0430 AJ |
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)), | |
62e76326 | 172 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_PROTO), |
173 | LEN_SQ_PRF + 1, NULL, NULL, 2, | |
cc192b50 | 174 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR), |
62e76326 | 175 | LEN_SQ_PRF + 2, NULL, NULL, 15, |
cc192b50 | 176 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_REQ), |
62e76326 | 177 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 178 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_HITS), |
62e76326 | 179 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 180 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_ERRORS), |
62e76326 | 181 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 182 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN), |
62e76326 | 183 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 184 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT), |
62e76326 | 185 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 186 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_S), |
62e76326 | 187 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 188 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_R), |
62e76326 | 189 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 190 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_SKB), |
62e76326 | 191 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 192 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_RKB), |
62e76326 | 193 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 194 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_REQ), |
62e76326 | 195 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 196 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ERRORS), |
62e76326 | 197 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 198 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_KBYTES_IN), |
62e76326 | 199 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 200 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_KBYTES_OUT), |
62e76326 | 201 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 202 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_CURSWAP), |
62e76326 | 203 | LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0), |
cc192b50 | 204 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_CLIENTS), |
62e76326 | 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, | |
cc192b50 | 208 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1), |
146e5e78 | 209 | LEN_SQ_PRF + 3, NULL, NULL, 11, |
cc192b50 | 210 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_TIME), |
62e76326 | 211 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 212 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_ALL), |
62e76326 | 213 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 214 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_MISS), |
62e76326 | 215 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 216 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_NM), |
62e76326 | 217 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 218 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_HIT), |
62e76326 | 219 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 220 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_ICP_QUERY), |
62e76326 | 221 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 222 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_ICP_REPLY), |
62e76326 | 223 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 224 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_DNS), |
62e76326 | 225 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 226 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_RHR), |
62e76326 | 227 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 228 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_BHR), |
146e5e78 | 229 | LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0), |
cc192b50 | 230 | snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_NH), |
62e76326 | 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, | |
3c573763 | 270 | #if USE_DNSSERVERS |
62e76326 | 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))), | |
3c573763 | 277 | #else |
62e76326 | 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))), | |
3c573763 | 284 | #endif |
62e76326 | 285 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH), |
286 | LEN_SQ_MESH, NULL, NULL, 2, | |
cc192b50 | 287 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, MESH_PTBL), |
62e76326 | 288 | LEN_SQ_MESH + 1, NULL, NULL, 1, |
289 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1), | |
cc192b50 | 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), | |
62e76326 | 294 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 295 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_ADDR_TYPE), |
62e76326 | 296 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 297 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_ADDR), |
62e76326 | 298 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 299 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_HTTP), |
62e76326 | 300 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 301 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_ICP), |
62e76326 | 302 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 303 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_TYPE), |
62e76326 | 304 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 305 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_STATE), |
62e76326 | 306 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 307 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_SENT), |
62e76326 | 308 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 309 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_PACKED), |
62e76326 | 310 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 311 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_FETCHES), |
62e76326 | 312 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 313 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_RTT), |
62e76326 | 314 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 315 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_IGN), |
62e76326 | 316 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0), |
cc192b50 | 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), | |
62e76326 | 320 | LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0))), |
cc192b50 | 321 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, MESH_CTBL), |
62e76326 | 322 | LEN_SQ_MESH + 1, NULL, NULL, 1, |
cc192b50 | 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), | |
62e76326 | 328 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 329 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTREQ), |
62e76326 | 330 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 331 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTBYTES), |
62e76326 | 332 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 333 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTHITS), |
62e76326 | 334 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 335 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTHITBYTES), |
62e76326 | 336 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 337 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPREQ), |
62e76326 | 338 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 339 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPBYTES), |
62e76326 | 340 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 341 | snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPHITS), |
62e76326 | 342 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0), |
cc192b50 | 343 | (mib_tree_last = snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPHITBYTES), |
62e76326 | 344 | LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0))))) |
345 | ) | |
346 | ) | |
347 | ) | |
348 | ) | |
349 | ) | |
350 | ) | |
351 | ) | |
352 | ); | |
dba79ac5 | 353 | |
bf8fe701 | 354 | debugs(49, 9, "snmpInit: Completed SNMP mib tree structure"); |
43d4303e | 355 | } |
356 | ||
357 | void | |
358 | snmpConnectionOpen(void) | |
359 | { | |
cc192b50 | 360 | struct addrinfo *xaddr = NULL; |
43d4303e | 361 | int x; |
362 | ||
bf8fe701 | 363 | debugs(49, 5, "snmpConnectionOpen: Called"); |
62e76326 | 364 | |
cc192b50 | 365 | if (Config.Port.snmp > 0) { |
366 | Config.Addrs.snmp_incoming.SetPort(Config.Port.snmp); | |
62e76326 | 367 | enter_suid(); |
31be869c | 368 | theInSnmpConnection = comm_open_listener(SOCK_DGRAM, |
04f7fd38 AJ |
369 | IPPROTO_UDP, |
370 | Config.Addrs.snmp_incoming, | |
371 | COMM_NONBLOCKING, | |
372 | "SNMP Port"); | |
62e76326 | 373 | leave_suid(); |
374 | ||
375 | if (theInSnmpConnection < 0) | |
31be869c | 376 | fatal("Cannot open SNMP Port"); |
62e76326 | 377 | |
378 | commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0); | |
379 | ||
cc192b50 | 380 | debugs(1, 1, "Accepting SNMP messages on " << Config.Addrs.snmp_incoming << ", FD " << theInSnmpConnection << "."); |
62e76326 | 381 | |
cc192b50 | 382 | if (!Config.Addrs.snmp_outgoing.IsNoAddr()) { |
383 | Config.Addrs.snmp_outgoing.SetPort(Config.Port.snmp); | |
62e76326 | 384 | enter_suid(); |
31be869c | 385 | theOutSnmpConnection = comm_open_listener(SOCK_DGRAM, |
04f7fd38 AJ |
386 | IPPROTO_UDP, |
387 | Config.Addrs.snmp_outgoing, | |
388 | COMM_NONBLOCKING, | |
389 | "SNMP Port"); | |
62e76326 | 390 | leave_suid(); |
391 | ||
392 | if (theOutSnmpConnection < 0) | |
393 | fatal("Cannot open Outgoing SNMP Port"); | |
394 | ||
395 | commSetSelect(theOutSnmpConnection, | |
396 | COMM_SELECT_READ, | |
397 | snmpHandleUdp, | |
398 | NULL, 0); | |
399 | ||
cc192b50 | 400 | debugs(1, 1, "Outgoing SNMP messages on " << Config.Addrs.snmp_outgoing << ", FD " << theOutSnmpConnection << "."); |
62e76326 | 401 | |
402 | fd_note(theOutSnmpConnection, "Outgoing SNMP socket"); | |
403 | ||
404 | fd_note(theInSnmpConnection, "Incoming SNMP socket"); | |
405 | } else { | |
406 | theOutSnmpConnection = theInSnmpConnection; | |
407 | } | |
408 | ||
cc192b50 | 409 | theOutSNMPAddr.SetEmpty(); |
62e76326 | 410 | |
cc192b50 | 411 | theOutSNMPAddr.InitAddrInfo(xaddr); |
62e76326 | 412 | |
cc192b50 | 413 | x = getsockname(theOutSnmpConnection, xaddr->ai_addr, &xaddr->ai_addrlen); |
62e76326 | 414 | |
415 | if (x < 0) | |
bf8fe701 | 416 | debugs(51, 1, "theOutSnmpConnection FD " << theOutSnmpConnection << ": getsockname: " << xstrerror()); |
62e76326 | 417 | else |
26ac0430 | 418 | theOutSNMPAddr = *xaddr; |
cc192b50 | 419 | |
420 | theOutSNMPAddr.FreeAddrInfo(xaddr); | |
43d4303e | 421 | } |
422 | } | |
423 | ||
43d4303e | 424 | void |
425 | snmpConnectionShutdown(void) | |
426 | { | |
427 | if (theInSnmpConnection < 0) | |
62e76326 | 428 | return; |
429 | ||
43d4303e | 430 | if (theInSnmpConnection != theOutSnmpConnection) { |
bf8fe701 | 431 | debugs(49, 1, "FD " << theInSnmpConnection << " Closing SNMP socket"); |
62e76326 | 432 | comm_close(theInSnmpConnection); |
43d4303e | 433 | } |
62e76326 | 434 | |
43d4303e | 435 | /* |
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. | |
634243ef AJ |
440 | */ |
441 | theInSnmpConnection = -1; | |
62e76326 | 442 | |
dba79ac5 | 443 | /* |
43d4303e | 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. | |
448 | */ | |
449 | assert(theOutSnmpConnection > -1); | |
62e76326 | 450 | |
43d4303e | 451 | commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0); |
452 | } | |
453 | ||
454 | void | |
455 | snmpConnectionClose(void) | |
456 | { | |
457 | snmpConnectionShutdown(); | |
62e76326 | 458 | |
43d4303e | 459 | if (theOutSnmpConnection > -1) { |
bf8fe701 | 460 | debugs(49, 1, "FD " << theOutSnmpConnection << " Closing SNMP socket"); |
62e76326 | 461 | comm_close(theOutSnmpConnection); |
634243ef AJ |
462 | /* make sure the SNMP out connection is unset */ |
463 | theOutSnmpConnection = -1; | |
43d4303e | 464 | } |
465 | } | |
466 | ||
dba79ac5 | 467 | /* |
c68e9c6b | 468 | * Functions for handling the requests. |
469 | */ | |
43d4303e | 470 | |
dba79ac5 | 471 | /* |
472 | * Accept the UDP packet | |
473 | */ | |
43d4303e | 474 | void |
dba79ac5 | 475 | snmpHandleUdp(int sock, void *not_used) |
43d4303e | 476 | { |
dba79ac5 | 477 | LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE); |
ad61a2b4 | 478 | IpAddress from; |
dba79ac5 | 479 | snmp_request_t *snmp_rq; |
480 | int len; | |
481 | ||
bf8fe701 | 482 | debugs(49, 5, "snmpHandleUdp: Called."); |
dba79ac5 | 483 | |
484 | commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0); | |
62e76326 | 485 | |
ec603b25 | 486 | memset(buf, '\0', SNMP_REQUEST_SIZE); |
dba79ac5 | 487 | |
7d21986b | 488 | len = comm_udp_recvfrom(sock, |
62e76326 | 489 | buf, |
490 | SNMP_REQUEST_SIZE, | |
491 | 0, | |
cc192b50 | 492 | from); |
dba79ac5 | 493 | |
494 | if (len > 0) { | |
62e76326 | 495 | buf[len] = '\0'; |
cc192b50 | 496 | debugs(49, 3, "snmpHandleUdp: FD " << sock << ": received " << len << " bytes from " << from << "."); |
62e76326 | 497 | |
498 | snmp_rq = (snmp_request_t *)xcalloc(1, sizeof(snmp_request_t)); | |
499 | snmp_rq->buf = (u_char *) buf; | |
500 | snmp_rq->len = len; | |
501 | snmp_rq->sock = sock; | |
502 | snmp_rq->outbuf = (unsigned char *)xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE); | |
cc192b50 | 503 | snmp_rq->from = from; |
62e76326 | 504 | snmpDecodePacket(snmp_rq); |
505 | xfree(snmp_rq->outbuf); | |
506 | xfree(snmp_rq); | |
dba79ac5 | 507 | } else { |
bf8fe701 | 508 | debugs(49, 1, "snmpHandleUdp: FD " << sock << " recvfrom: " << xstrerror()); |
dba79ac5 | 509 | } |
510 | } | |
43d4303e | 511 | |
dba79ac5 | 512 | /* |
513 | * Turn SNMP packet into a PDU, check available ACL's | |
514 | */ | |
9bc73deb | 515 | static void |
dba79ac5 | 516 | snmpDecodePacket(snmp_request_t * rq) |
517 | { | |
43d4303e | 518 | struct snmp_pdu *PDU; |
519 | u_char *Community; | |
dba79ac5 | 520 | u_char *buf = rq->buf; |
521 | int len = rq->len; | |
522 | int allow = 0; | |
43d4303e | 523 | |
cc192b50 | 524 | debugs(49, 5, HERE << "Called."); |
43d4303e | 525 | PDU = snmp_pdu_create(0); |
cc192b50 | 526 | /* Allways answer on SNMPv1 */ |
0536fdfc | 527 | rq->session.Version = SNMP_VERSION_1; |
528 | Community = snmp_parse(&rq->session, PDU, buf, len); | |
dba79ac5 | 529 | |
b50e327b AJ |
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) { | |
c0941a6a | 533 | ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL); |
cc192b50 | 534 | checklist.src_addr = rq->from; |
d148d5fb | 535 | checklist.snmp_community = (char *) Community; |
b448c119 | 536 | allow = checklist.fastCheck(); |
506768d9 | 537 | } |
62e76326 | 538 | |
dba79ac5 | 539 | if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) { |
62e76326 | 540 | rq->community = Community; |
541 | rq->PDU = PDU; | |
bf8fe701 | 542 | debugs(49, 5, "snmpAgentParse: reqid=[" << PDU->reqid << "]"); |
62e76326 | 543 | snmpConstructReponse(rq); |
dba79ac5 | 544 | } else { |
cc192b50 | 545 | debugs(49, 1, HERE << "Failed SNMP agent query from : " << rq->from); |
62e76326 | 546 | snmp_free_pdu(PDU); |
43d4303e | 547 | } |
62e76326 | 548 | |
5f0dc264 | 549 | if (Community) |
62e76326 | 550 | xfree(Community); |
dba79ac5 | 551 | } |
43d4303e | 552 | |
dba79ac5 | 553 | /* |
554 | * Packet OK, ACL Check OK, Create reponse. | |
555 | */ | |
9bc73deb | 556 | static void |
74c161ea | 557 | snmpConstructReponse(snmp_request_t * rq) |
dba79ac5 | 558 | { |
62e76326 | 559 | |
dba79ac5 | 560 | struct snmp_pdu *RespPDU; |
74c161ea | 561 | |
bf8fe701 | 562 | debugs(49, 5, "snmpConstructReponse: Called."); |
dba79ac5 | 563 | RespPDU = snmpAgentResponse(rq->PDU); |
564 | snmp_free_pdu(rq->PDU); | |
62e76326 | 565 | |
ecd2a33f | 566 | if (RespPDU != NULL) { |
0536fdfc | 567 | snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen); |
cc192b50 | 568 | comm_udp_sendto(rq->sock, rq->from, rq->outbuf, rq->outlen); |
62e76326 | 569 | snmp_free_pdu(RespPDU); |
43d4303e | 570 | } |
43d4303e | 571 | } |
572 | ||
dba79ac5 | 573 | /* |
574 | * Decide how to respond to the request, construct a response and | |
575 | * return the response to the requester. | |
dba79ac5 | 576 | */ |
62e76326 | 577 | |
9bc73deb | 578 | static struct snmp_pdu * |
62e76326 | 579 | |
e1381638 | 580 | snmpAgentResponse(struct snmp_pdu *PDU) { |
62e76326 | 581 | |
43d4303e | 582 | struct snmp_pdu *Answer = NULL; |
43d4303e | 583 | |
bf8fe701 | 584 | debugs(49, 5, "snmpAgentResponse: Called."); |
43d4303e | 585 | |
26ac0430 | 586 | if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE))) { |
62e76326 | 587 | Answer->reqid = PDU->reqid; |
588 | Answer->errindex = 0; | |
589 | ||
0536fdfc | 590 | if (PDU->command == SNMP_PDU_GET || PDU->command == SNMP_PDU_GETNEXT) { |
26ac0430 | 591 | /* Indirect way */ |
0536fdfc | 592 | int get_next = (PDU->command == SNMP_PDU_GETNEXT); |
593 | variable_list *VarPtr_; | |
594 | variable_list **RespVars = &(Answer->variables); | |
595 | oid_ParseFn *ParseFn; | |
596 | int index = 0; | |
62e76326 | 597 | /* Loop through all variables */ |
598 | ||
0536fdfc | 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; | |
62e76326 | 604 | |
605 | index++; | |
606 | ||
0536fdfc | 607 | if (get_next) |
608 | ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen); | |
609 | else | |
610 | ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length); | |
62e76326 | 611 | |
612 | if (ParseFn == NULL) { | |
613 | Answer->errstat = SNMP_ERR_NOSUCHNAME; | |
bf8fe701 | 614 | debugs(49, 5, "snmpAgentResponse: No such oid. "); |
0536fdfc | 615 | } else { |
616 | if (get_next) { | |
617 | VarPtr = snmp_var_new(NextOidName, NextOidNameLen); | |
618 | xfree(NextOidName); | |
619 | } | |
620 | ||
8abf232c | 621 | int * errstatTmp = &(Answer->errstat); |
622 | ||
623 | VarNew = (*ParseFn) (VarPtr, (snint *) errstatTmp); | |
62e76326 | 624 | |
0536fdfc | 625 | if (get_next) |
626 | snmp_var_free(VarPtr); | |
627 | } | |
628 | ||
0536fdfc | 629 | if ((Answer->errstat != SNMP_ERR_NOERROR) || (VarNew == NULL)) { |
62e76326 | 630 | Answer->errindex = index; |
bf8fe701 | 631 | debugs(49, 5, "snmpAgentResponse: error."); |
0536fdfc | 632 | |
633 | if (VarNew) | |
634 | snmp_var_free(VarNew); | |
635 | ||
0536fdfc | 636 | while ((VarPtr = Answer->variables) != NULL) { |
637 | Answer->variables = VarPtr->next_variable; | |
638 | snmp_var_free(VarPtr); | |
639 | } | |
640 | ||
641 | /* Steal the original PDU list of variables for the error response */ | |
642 | Answer->variables = PDU->variables; | |
643 | ||
644 | PDU->variables = NULL; | |
645 | ||
62e76326 | 646 | return (Answer); |
647 | } | |
648 | ||
649 | /* No error. Insert this var at the end, and move on to the next. | |
650 | */ | |
651 | *RespVars = VarNew; | |
652 | ||
653 | RespVars = &(VarNew->next_variable); | |
26ac0430 AJ |
654 | } |
655 | } | |
dba79ac5 | 656 | } |
62e76326 | 657 | |
dba79ac5 | 658 | return (Answer); |
659 | } | |
b644367b | 660 | |
9bc73deb | 661 | static oid_ParseFn * |
d439f213 | 662 | snmpTreeGet(oid * Current, snint CurrentLen) |
663 | { | |
664 | oid_ParseFn *Fn = NULL; | |
1810dde6 | 665 | mib_tree_entry *mibTreeEntry = NULL; |
d439f213 | 666 | int count = 0; |
667 | ||
bf8fe701 | 668 | debugs(49, 5, "snmpTreeGet: Called"); |
d439f213 | 669 | |
bf8fe701 | 670 | debugs(49, 6, "snmpTreeGet: Current : "); |
d439f213 | 671 | snmpDebugOid(6, Current, CurrentLen); |
672 | ||
673 | mibTreeEntry = mib_tree_head; | |
62e76326 | 674 | |
d439f213 | 675 | if (Current[count] == mibTreeEntry->name[count]) { |
62e76326 | 676 | count++; |
677 | ||
678 | while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) { | |
679 | mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry); | |
680 | count++; | |
681 | } | |
d439f213 | 682 | } |
62e76326 | 683 | |
ec603b25 | 684 | if (mibTreeEntry && mibTreeEntry->parsefunction) |
62e76326 | 685 | Fn = mibTreeEntry->parsefunction; |
686 | ||
bf8fe701 | 687 | debugs(49, 5, "snmpTreeGet: return"); |
62e76326 | 688 | |
d439f213 | 689 | return (Fn); |
690 | } | |
691 | ||
9bc73deb | 692 | static oid_ParseFn * |
dba79ac5 | 693 | snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen) |
694 | { | |
695 | oid_ParseFn *Fn = NULL; | |
897029fd | 696 | mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL; |
dba79ac5 | 697 | int count = 0; |
698 | ||
bf8fe701 | 699 | debugs(49, 5, "snmpTreeNext: Called"); |
dba79ac5 | 700 | |
bf8fe701 | 701 | debugs(49, 6, "snmpTreeNext: Current : "); |
dba79ac5 | 702 | snmpDebugOid(6, Current, CurrentLen); |
b644367b | 703 | |
dba79ac5 | 704 | mibTreeEntry = mib_tree_head; |
62e76326 | 705 | |
dba79ac5 | 706 | if (Current[count] == mibTreeEntry->name[count]) { |
62e76326 | 707 | count++; |
708 | ||
709 | while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) { | |
aa6d85ce | 710 | mib_tree_entry *nextmibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry); |
711 | ||
26ac0430 | 712 | if (!nextmibTreeEntry) |
aa6d85ce | 713 | break; |
714 | else | |
715 | mibTreeEntry = nextmibTreeEntry; | |
716 | ||
62e76326 | 717 | count++; |
718 | } | |
bf8fe701 | 719 | debugs(49, 5, "snmpTreeNext: Recursed down to requested object"); |
b6a2f15e | 720 | } else { |
62e76326 | 721 | return NULL; |
b6a2f15e | 722 | } |
62e76326 | 723 | |
b6a2f15e | 724 | if (mibTreeEntry == mib_tree_last) |
62e76326 | 725 | return (Fn); |
726 | ||
62e76326 | 727 | |
cc192b50 | 728 | if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) { |
26ac0430 AJ |
729 | *NextLen = CurrentLen; |
730 | *Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn); | |
731 | if (*Next) { | |
732 | debugs(49, 6, "snmpTreeNext: Next : "); | |
733 | snmpDebugOid(6, *Next, *NextLen); | |
734 | return (Fn); | |
735 | } | |
b6a2f15e | 736 | } |
62e76326 | 737 | |
b6a2f15e | 738 | if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) { |
62e76326 | 739 | count--; |
740 | nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent); | |
62e76326 | 741 | if (nextoid) { |
26ac0430 | 742 | debugs(49, 5, "snmpTreeNext: Next OID found for sibling" << nextoid ); |
62e76326 | 743 | mibTreeEntry = nextoid; |
744 | count++; | |
745 | } else { | |
bf8fe701 | 746 | debugs(49, 5, "snmpTreeNext: Attempting to recurse up for next object"); |
62e76326 | 747 | |
748 | while (!nextoid) { | |
749 | count--; | |
750 | ||
751 | if (mibTreeEntry->parent->parent) { | |
752 | nextoid = mibTreeEntry->parent; | |
753 | mibTreeEntry = snmpTreeEntry(Current[count] + 1, count, nextoid->parent); | |
754 | ||
755 | if (!mibTreeEntry) { | |
756 | mibTreeEntry = nextoid; | |
757 | nextoid = NULL; | |
758 | } | |
759 | } else { | |
760 | nextoid = mibTreeEntry; | |
761 | mibTreeEntry = NULL; | |
762 | } | |
763 | } | |
764 | } | |
b6a2f15e | 765 | } |
766 | while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) { | |
62e76326 | 767 | mibTreeEntry = mibTreeEntry->leaves[0]; |
dba79ac5 | 768 | } |
62e76326 | 769 | |
c68e9c6b | 770 | if (mibTreeEntry) { |
62e76326 | 771 | *NextLen = mibTreeEntry->len; |
772 | *Next = (*mibTreeEntry->instancefunction) (mibTreeEntry->name, NextLen, mibTreeEntry, &Fn); | |
dba79ac5 | 773 | } |
62e76326 | 774 | |
26ac0430 AJ |
775 | if (*Next) { |
776 | debugs(49, 6, "snmpTreeNext: Next : "); | |
777 | snmpDebugOid(6, *Next, *NextLen); | |
778 | return (Fn); | |
779 | } else | |
62e76326 | 780 | return NULL; |
43d4303e | 781 | } |
782 | ||
9bc73deb | 783 | static oid * |
b6a2f15e | 784 | static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn) |
785 | { | |
786 | oid *instance = NULL; | |
b6a2f15e | 787 | if (*len <= current->len) { |
62e76326 | 788 | instance = (oid *)xmalloc(sizeof(name) * (*len + 1)); |
789 | xmemcpy(instance, name, (sizeof(name) * *len)); | |
790 | instance[*len] = 0; | |
791 | *len += 1; | |
b6a2f15e | 792 | } |
793 | *Fn = current->parsefunction; | |
794 | return (instance); | |
795 | } | |
796 | ||
9bc73deb | 797 | static oid * |
b6a2f15e | 798 | time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn) |
799 | { | |
800 | oid *instance = NULL; | |
801 | int identifier = 0, loop = 0; | |
cc192b50 | 802 | int index[TIME_INDEX_LEN] = {TIME_INDEX}; |
b6a2f15e | 803 | |
804 | if (*len <= current->len) { | |
62e76326 | 805 | instance = (oid *)xmalloc(sizeof(name) * (*len + 1)); |
806 | xmemcpy(instance, name, (sizeof(name) * *len)); | |
807 | instance[*len] = *index; | |
808 | *len += 1; | |
b6a2f15e | 809 | } else { |
62e76326 | 810 | identifier = name[*len - 1]; |
811 | ||
9bdc291b | 812 | while ((loop < TIME_INDEX_LEN) && (identifier != index[loop])) |
62e76326 | 813 | loop++; |
814 | ||
26ac0430 | 815 | if (loop < (TIME_INDEX_LEN - 1)) { |
62e76326 | 816 | instance = (oid *)xmalloc(sizeof(name) * (*len)); |
817 | xmemcpy(instance, name, (sizeof(name) * *len)); | |
818 | instance[*len - 1] = index[++loop]; | |
819 | } | |
b6a2f15e | 820 | } |
62e76326 | 821 | |
b6a2f15e | 822 | *Fn = current->parsefunction; |
823 | return (instance); | |
824 | } | |
825 | ||
cc192b50 | 826 | |
9bc73deb | 827 | static oid * |
b6a2f15e | 828 | peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn) |
829 | { | |
830 | oid *instance = NULL; | |
b6a2f15e | 831 | peer *peers = Config.peers; |
62e76326 | 832 | |
b6a2f15e | 833 | if (peers == NULL) { |
62e76326 | 834 | current = current->parent->parent->parent->leaves[1]; |
62e76326 | 835 | while ((current) && (!current->parsefunction)) |
836 | current = current->leaves[0]; | |
837 | ||
838 | instance = client_Inst(current->name, len, current, Fn); | |
26ac0430 AJ |
839 | } else if (*len <= current->len) { |
840 | instance = (oid *)xmalloc(sizeof(name) * ( *len + 1)); | |
841 | xmemcpy(instance, name, (sizeof(name) * *len)); | |
842 | instance[*len] = 1 ; | |
843 | *len += 1; | |
b6a2f15e | 844 | } else { |
26ac0430 AJ |
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++ ) ; | |
849 | ||
850 | if (peers) { | |
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. | |
854 | } else { | |
855 | return (instance); | |
856 | } | |
b6a2f15e | 857 | } |
858 | *Fn = current->parsefunction; | |
859 | return (instance); | |
860 | } | |
861 | ||
9bc73deb | 862 | static oid * |
b6a2f15e | 863 | client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn) |
864 | { | |
865 | oid *instance = NULL; | |
ad61a2b4 AJ |
866 | IpAddress laddr; |
867 | IpAddress *aux; | |
dce440dd | 868 | int size = 0; |
869 | int newshift = 0; | |
b6a2f15e | 870 | |
26ac0430 AJ |
871 | if (*len <= current->len) { |
872 | aux = client_entry(NULL); | |
873 | if (aux) | |
dce440dd | 874 | laddr = *aux; |
875 | else | |
876 | laddr.SetAnyAddr(); | |
cc192b50 | 877 | |
26ac0430 | 878 | if (laddr.IsIPv4()) |
dce440dd | 879 | size = sizeof(in_addr); |
cc192b50 | 880 | #if USE_IPV6 |
dce440dd | 881 | else |
882 | size = sizeof(in6_addr); | |
cc192b50 | 883 | #endif |
62e76326 | 884 | |
dce440dd | 885 | instance = (oid *)xmalloc(sizeof(name) * (*len + size )); |
886 | xmemcpy(instance, name, (sizeof(name) * (*len))); | |
62e76326 | 887 | |
dce440dd | 888 | if ( !laddr.IsAnyAddr() ) { |
889 | addr2oid(laddr, &instance[ *len]); // the addr | |
890 | *len += size ; | |
891 | } | |
cc192b50 | 892 | } else { |
26ac0430 AJ |
893 | int shift = *len - current->len ; // i.e 4 or 16 |
894 | oid2addr(&name[*len - shift], laddr,shift); | |
895 | aux = client_entry(&laddr); | |
896 | if (aux) | |
dce440dd | 897 | laddr = *aux; |
898 | else | |
899 | laddr.SetAnyAddr(); | |
26ac0430 AJ |
900 | |
901 | if (!laddr.IsAnyAddr()) { | |
902 | if (laddr.IsIPv4()) | |
dce440dd | 903 | newshift = sizeof(in_addr); |
cc192b50 | 904 | #if USE_IPV6 |
dce440dd | 905 | else |
906 | newshift = sizeof(in6_addr); | |
cc192b50 | 907 | #endif |
dce440dd | 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 ; | |
912 | } | |
cc192b50 | 913 | } |
26ac0430 | 914 | |
b6a2f15e | 915 | *Fn = current->parsefunction; |
916 | return (instance); | |
917 | } | |
918 | ||
919 | ||
920 | /* | |
921 | * Utility functions | |
922 | */ | |
923 | ||
924 | /* | |
26ac0430 | 925 | * Tree utility functions. |
b6a2f15e | 926 | */ |
927 | ||
62e76326 | 928 | /* |
cc192b50 | 929 | * Returns a sibling object for the requested child object or NULL |
930 | * if it does not exit | |
b6a2f15e | 931 | */ |
9bc73deb | 932 | static mib_tree_entry * |
897029fd | 933 | snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current) |
43d4303e | 934 | { |
dba79ac5 | 935 | mib_tree_entry *next = NULL; |
936 | int count = 0; | |
8a6218c6 | 937 | |
897029fd | 938 | while ((!next) && (count < current->children)) { |
62e76326 | 939 | if (current->leaves[count]->name[len] == entry) { |
940 | next = current->leaves[count]; | |
941 | } | |
942 | ||
943 | count++; | |
897029fd | 944 | } |
62e76326 | 945 | |
cc192b50 | 946 | /* Exactly the sibling on rigth */ |
8a6218c6 | 947 | if (count < current->children) { |
62e76326 | 948 | next = current->leaves[count]; |
8a6218c6 | 949 | } else { |
62e76326 | 950 | next = NULL; |
897029fd | 951 | } |
62e76326 | 952 | |
897029fd | 953 | return (next); |
954 | } | |
665bc266 | 955 | |
62e76326 | 956 | /* |
b6a2f15e | 957 | * Returns the requested child object or NULL if it does not exist |
958 | */ | |
9bc73deb | 959 | static mib_tree_entry * |
897029fd | 960 | snmpTreeEntry(oid entry, snint len, mib_tree_entry * current) |
961 | { | |
962 | mib_tree_entry *next = NULL; | |
963 | int count = 0; | |
43d4303e | 964 | |
dba79ac5 | 965 | while ((!next) && (count < current->children)) { |
62e76326 | 966 | if (current->leaves[count]->name[len] == entry) { |
967 | next = current->leaves[count]; | |
968 | } | |
969 | ||
970 | count++; | |
43d4303e | 971 | } |
62e76326 | 972 | |
dba79ac5 | 973 | return (next); |
974 | } | |
43d4303e | 975 | |
d439f213 | 976 | /* |
977 | * Adds a node to the MIB tree structure and adds the appropriate children | |
978 | */ | |
9bc73deb | 979 | static mib_tree_entry * |
b6a2f15e | 980 | snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...) |
d439f213 | 981 | { |
982 | va_list args; | |
983 | int loop; | |
984 | mib_tree_entry *entry = NULL; | |
b6a2f15e | 985 | va_start(args, children); |
d439f213 | 986 | |
bf8fe701 | 987 | debugs(49, 6, "snmpAddNode: Children : " << children << ", Oid : "); |
b6a2f15e | 988 | snmpDebugOid(6, name, len); |
d439f213 | 989 | |
b6a2f15e | 990 | va_start(args, children); |
e6ccf245 | 991 | entry = (mib_tree_entry *)xmalloc(sizeof(mib_tree_entry)); |
6ccbae85 | 992 | entry->name = name; |
b6a2f15e | 993 | entry->len = len; |
994 | entry->parsefunction = parsefunction; | |
995 | entry->instancefunction = instancefunction; | |
996 | entry->children = children; | |
d439f213 | 997 | |
26ac0430 | 998 | if (children > 0) { |
62e76326 | 999 | entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children); |
1000 | ||
1001 | for (loop = 0; loop < children; loop++) { | |
1002 | entry->leaves[loop] = va_arg(args, mib_tree_entry *); | |
1003 | entry->leaves[loop]->parent = entry; | |
1004 | } | |
d439f213 | 1005 | } |
62e76326 | 1006 | |
d439f213 | 1007 | return (entry); |
1008 | } | |
1009 | /* End of tree utility functions */ | |
1010 | ||
62e76326 | 1011 | /* |
61d53e64 | 1012 | * Returns the list of parameters in an oid |
c68e9c6b | 1013 | */ |
9bc73deb | 1014 | static oid * |
c68e9c6b | 1015 | snmpCreateOid(int length,...) |
dba79ac5 | 1016 | { |
c68e9c6b | 1017 | va_list args; |
1018 | oid *new_oid; | |
1019 | int loop; | |
c68e9c6b | 1020 | va_start(args, length); |
8a6218c6 | 1021 | |
e6ccf245 | 1022 | new_oid = (oid *)xmalloc(sizeof(oid) * length); |
c68e9c6b | 1023 | |
26ac0430 | 1024 | if (length > 0) { |
62e76326 | 1025 | for (loop = 0; loop < length; loop++) { |
1026 | new_oid[loop] = va_arg(args, int); | |
1027 | } | |
c68e9c6b | 1028 | } |
62e76326 | 1029 | |
c68e9c6b | 1030 | return (new_oid); |
43d4303e | 1031 | } |
1032 | ||
dba79ac5 | 1033 | /* |
c68e9c6b | 1034 | * Debug calls, prints out the OID for debugging purposes. |
1035 | */ | |
dba79ac5 | 1036 | void |
1037 | snmpDebugOid(int lvl, oid * Name, snint Len) | |
c68e9c6b | 1038 | { |
dba79ac5 | 1039 | char mbuf[16], objid[1024]; |
1040 | int x; | |
1041 | objid[0] = '\0'; | |
43d4303e | 1042 | |
dba79ac5 | 1043 | for (x = 0; x < Len; x++) { |
62e76326 | 1044 | snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]); |
baad8a1f | 1045 | strncat(objid, mbuf, sizeof(objid) - strlen(objid) - 1); |
43d4303e | 1046 | } |
c68e9c6b | 1047 | |
bf8fe701 | 1048 | debugs(49, lvl, " oid = " << objid); |
43d4303e | 1049 | } |
b644367b | 1050 | |
c68e9c6b | 1051 | static void |
dba79ac5 | 1052 | snmpSnmplibDebug(int lvl, char *buf) |
c68e9c6b | 1053 | { |
dba79ac5 | 1054 | debug(49, lvl) ("%s", buf); |
c68e9c6b | 1055 | } |
b6a2f15e | 1056 | |
62e76326 | 1057 | |
cc192b50 | 1058 | |
26ac0430 | 1059 | /* |
cc192b50 | 1060 | IPv4 address: 10.10.0.9 ==> |
26ac0430 AJ |
1061 | oid == 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 | |
cc192b50 | 1064 | */ |
1065 | void | |
ad61a2b4 | 1066 | addr2oid(IpAddress &addr, oid * Dest) |
b6a2f15e | 1067 | { |
26ac0430 AJ |
1068 | u_int i ; |
1069 | u_char *cp = NULL; | |
1070 | struct in_addr iaddr; | |
cc192b50 | 1071 | #if USE_IPV6 |
26ac0430 AJ |
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); | |
cc192b50 | 1075 | #else |
26ac0430 AJ |
1076 | oid code = INETADDRESSTYPE_IPV4 ; |
1077 | u_int size = sizeof(struct in_addr) ; | |
cc192b50 | 1078 | #endif /* USE_IPV6 */ |
26ac0430 AJ |
1079 | // Dest[0] = code ; |
1080 | if ( code == INETADDRESSTYPE_IPV4 ) { | |
1081 | addr.GetInAddr(iaddr); | |
1082 | cp = (u_char *) &(iaddr.s_addr); | |
1083 | } | |
cc192b50 | 1084 | #if USE_IPV6 |
26ac0430 AJ |
1085 | else { |
1086 | addr.GetInAddr(i6addr); | |
1087 | cp = (u_char *) &i6addr; | |
1088 | } | |
cc192b50 | 1089 | #endif |
26ac0430 AJ |
1090 | for ( i=0 ; i < size ; i++) { |
1091 | // OID's are in network order | |
1092 | Dest[i] = *cp++; | |
cc192b50 | 1093 | } |
26ac0430 AJ |
1094 | debugs(49, 7, "addr2oid: Dest : "); |
1095 | snmpDebugOid(7, Dest, size ); | |
cc192b50 | 1096 | |
b6a2f15e | 1097 | } |
1098 | ||
26ac0430 | 1099 | /* |
cc192b50 | 1100 | oid == 10.10.0.9 ==> |
1101 | IPv4 address: 10.10.0.9 | |
26ac0430 | 1102 | oid == 32.1.50.239.162.33.251.20.50.0.0.0.0.0.0.0.0.0.1 ==> |
cc192b50 | 1103 | IPv6 adress : 20:01:32:ef:a2:21:fb:32:00:00:00:00:00:00:00:00:OO:01 |
1104 | */ | |
1105 | void | |
ad61a2b4 | 1106 | oid2addr(oid * id, IpAddress &addr, u_int size) |
b6a2f15e | 1107 | { |
26ac0430 AJ |
1108 | struct in_addr iaddr; |
1109 | u_int i; | |
1110 | u_char *cp; | |
cc192b50 | 1111 | #if USE_IPV6 |
26ac0430 AJ |
1112 | struct in6_addr i6addr; |
1113 | if ( size == sizeof(struct in_addr) ) | |
cc192b50 | 1114 | #endif /* USE_IPV6 */ |
26ac0430 | 1115 | cp = (u_char *) &(iaddr.s_addr); |
cc192b50 | 1116 | #if USE_IPV6 |
26ac0430 AJ |
1117 | else |
1118 | cp = (u_char *) &(i6addr); | |
cc192b50 | 1119 | #endif /* USE_IPV6 */ |
26ac0430 AJ |
1120 | debugs(49, 7, "oid2addr: id : "); |
1121 | snmpDebugOid(7, id, size ); | |
1122 | for (i=0 ; i<size; i++) { | |
1123 | cp[i] = id[i]; | |
cc192b50 | 1124 | } |
1125 | #if USE_IPV6 | |
26ac0430 | 1126 | if ( size == sizeof(struct in_addr) ) |
cc192b50 | 1127 | #endif |
26ac0430 | 1128 | addr = iaddr; |
cc192b50 | 1129 | #if USE_IPV6 |
26ac0430 AJ |
1130 | else |
1131 | addr = i6addr; | |
cc192b50 | 1132 | #endif |
62e76326 | 1133 | |
b6a2f15e | 1134 | } |
b0dd28ba | 1135 | |
1136 | /* SNMP checklists */ | |
c0941a6a AR |
1137 | #include "acl/Strategy.h" |
1138 | #include "acl/Strategised.h" | |
1139 | #include "acl/StringData.h" | |
b0dd28ba | 1140 | |
1141 | class ACLSNMPCommunityStrategy : public ACLStrategy<char const *> | |
1142 | { | |
1143 | ||
1144 | public: | |
c0941a6a | 1145 | virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *); |
b0dd28ba | 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 &); | |
1151 | ||
1152 | private: | |
1153 | static ACLSNMPCommunityStrategy Instance_; | |
26ac0430 | 1154 | ACLSNMPCommunityStrategy() {} |
b0dd28ba | 1155 | |
1156 | ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &); | |
1157 | }; | |
1158 | ||
1159 | class ACLSNMPCommunity | |
1160 | { | |
1161 | ||
1162 | private: | |
1163 | static ACL::Prototype RegistryProtoype; | |
1164 | static ACLStrategised<char const *> RegistryEntry_; | |
1165 | }; | |
1166 | ||
1167 | ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community"); | |
1168 | ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community"); | |
1169 | ||
1170 | int | |
c0941a6a | 1171 | ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist) |
b0dd28ba | 1172 | { |
1173 | return data->match (checklist->snmp_community); | |
b0dd28ba | 1174 | } |
1175 | ||
1176 | ACLSNMPCommunityStrategy * | |
1177 | ACLSNMPCommunityStrategy::Instance() | |
1178 | { | |
1179 | return &Instance_; | |
1180 | } | |
1181 | ||
1182 | ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_; |