]>
Commit | Line | Data |
---|---|---|
c04fda28 AJ |
1 | /* |
2 | * Copyright (C) 1996-2014 The Squid Software Foundation and contributors | |
3 | * | |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
43d4303e | 8 | |
85269fdf | 9 | /*********************************************************** |
f53969cc | 10 | Copyright 1988, 1989 by Carnegie Mellon University |
627f6d02 | 11 | |
12 | All Rights Reserved | |
13 | ||
26ac0430 AJ |
14 | Permission to use, copy, modify, and distribute this software and its |
15 | documentation for any purpose and without fee is hereby granted, | |
627f6d02 | 16 | provided that the above copyright notice appear in all copies and that |
26ac0430 | 17 | both that copyright notice and this permission notice appear in |
627f6d02 | 18 | supporting documentation, and that the name of CMU not be |
19 | used in advertising or publicity pertaining to distribution of the | |
26ac0430 | 20 | software without specific, written prior permission. |
627f6d02 | 21 | |
22 | CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
23 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
24 | CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
25 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
26 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
27 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
28 | SOFTWARE. | |
29 | ******************************************************************/ | |
85269fdf | 30 | |
f7f3304a | 31 | #include "squid.h" |
3170ee37 | 32 | |
33 | #if HAVE_UNISTD_H | |
34 | #include <unistd.h> | |
35 | #endif | |
36 | #if HAVE_STDLIB_H | |
37 | #include <stdlib.h> | |
38 | #endif | |
931ae822 | 39 | #if HAVE_SYS_TYPES_H |
40 | #include <sys/types.h> | |
41 | #endif | |
42 | #if HAVE_CTYPE_H | |
43 | #include <ctype.h> | |
44 | #endif | |
85269fdf | 45 | #if HAVE_GNUMALLOC_H |
46 | #include <gnumalloc.h> | |
482aa790 | 47 | #elif HAVE_MALLOC_H |
85269fdf | 48 | #include <malloc.h> |
49 | #endif | |
50 | #if HAVE_MEMORY_H | |
51 | #include <memory.h> | |
52 | #endif | |
32d002cb | 53 | #if HAVE_STRING_H |
931ae822 | 54 | #include <string.h> |
55 | #endif | |
32d002cb | 56 | #if HAVE_STRINGS_H |
931ae822 | 57 | #include <strings.h> |
58 | #endif | |
59 | #if HAVE_BSTRING_H | |
60 | #include <bstring.h> | |
61 | #endif | |
85269fdf | 62 | #if HAVE_SYS_SOCKET_H |
63 | #include <sys/socket.h> | |
64 | #endif | |
65 | #if HAVE_NETINET_IN_H | |
66 | #include <netinet/in.h> | |
67 | #endif | |
68 | #if HAVE_ARPA_INET_H | |
69 | #include <arpa/inet.h> | |
70 | #endif | |
71 | #if HAVE_SYS_TIME_H | |
72 | #include <sys/time.h> | |
73 | #endif | |
74 | #if HAVE_NETDB_H | |
75 | #include <netdb.h> | |
76 | #endif | |
627f6d02 | 77 | |
627f6d02 | 78 | #include "asn1.h" |
79 | #include "snmp.h" | |
85269fdf | 80 | |
602d9612 A |
81 | #include "parse.h" |
82 | #include "snmp_api.h" | |
83 | #include "snmp_impl.h" | |
85269fdf | 84 | #include "snmp_pdu.h" |
85269fdf | 85 | #include "snmp_session.h" |
602d9612 | 86 | #include "snmp_vars.h" |
627f6d02 | 87 | |
627f6d02 | 88 | #include "util.h" |
627f6d02 | 89 | |
d75eeb78 | 90 | static struct snmp_mib_tree *get_symbol(oid *objid, int objidlen, struct snmp_mib_tree *subtree, char *buf); |
627f6d02 | 91 | |
26ac0430 | 92 | oid RFC1066_MIB[] = {1, 3, 6, 1, 2, 1}; |
85269fdf | 93 | unsigned char RFC1066_MIB_text[] = ".iso.org.dod.internet.mgmt.mib"; |
94 | struct snmp_mib_tree *Mib; | |
95 | ||
468ae12b | 96 | void |
43d4303e | 97 | init_mib(char *file) |
85269fdf | 98 | { |
85269fdf | 99 | if (Mib != NULL) |
26ac0430 | 100 | return; |
85269fdf | 101 | |
102 | if (file != NULL) | |
26ac0430 | 103 | Mib = read_mib(file); |
85269fdf | 104 | } |
627f6d02 | 105 | |
85269fdf | 106 | static struct snmp_mib_tree * |
e1381638 | 107 | find_rfc1066_mib(struct snmp_mib_tree *root) { |
85269fdf | 108 | oid *op = RFC1066_MIB; |
109 | struct snmp_mib_tree *tp; | |
627f6d02 | 110 | int len; |
111 | ||
43d4303e | 112 | for (len = sizeof(RFC1066_MIB) / sizeof(oid); len; len--, op++) { |
26ac0430 AJ |
113 | for (tp = root; tp; tp = tp->next_peer) { |
114 | if (tp->subid == *op) { | |
115 | root = tp->child_list; | |
116 | break; | |
117 | } | |
118 | } | |
119 | if (tp == NULL) | |
120 | return NULL; | |
627f6d02 | 121 | } |
122 | return root; | |
123 | } | |
627f6d02 | 124 | |
85269fdf | 125 | static int |
5c52f59a | 126 | lc_cmp(const char *s1, const char *s2) |
627f6d02 | 127 | { |
85269fdf | 128 | char c1, c2; |
627f6d02 | 129 | |
43d4303e | 130 | while (*s1 && *s2) { |
26ac0430 AJ |
131 | if (xisupper(*s1)) |
132 | c1 = xtolower(*s1); | |
133 | else | |
134 | c1 = *s1; | |
135 | if (xisupper(*s2)) | |
136 | c2 = xtolower(*s2); | |
137 | else | |
138 | c2 = *s2; | |
139 | if (c1 != c2) | |
140 | return ((c1 - c2) > 0 ? 1 : -1); | |
141 | s1++; | |
142 | s2++; | |
627f6d02 | 143 | } |
627f6d02 | 144 | |
85269fdf | 145 | if (*s1) |
26ac0430 | 146 | return -1; |
85269fdf | 147 | if (*s2) |
26ac0430 | 148 | return 1; |
85269fdf | 149 | return 0; |
627f6d02 | 150 | } |
627f6d02 | 151 | |
152 | static int | |
5c52f59a | 153 | parse_subtree(struct snmp_mib_tree *subtree, char *input, oid *output, int *out_len) |
627f6d02 | 154 | { |
155 | char buf[128], *to = buf; | |
85269fdf | 156 | u_int subid = 0; |
157 | struct snmp_mib_tree *tp; | |
627f6d02 | 158 | |
159 | /* | |
160 | * No empty strings. Can happen if there is a trailing '.' or two '.'s | |
161 | * in a row, i.e. "..". | |
162 | */ | |
163 | if ((*input == '\0') || | |
26ac0430 AJ |
164 | (*input == '.')) |
165 | return (0); | |
627f6d02 | 166 | |
ec451a0f | 167 | if (xisdigit(*input)) { |
26ac0430 AJ |
168 | /* |
169 | * Read the number, then try to find it in the subtree. | |
170 | */ | |
171 | while (xisdigit(*input)) { | |
172 | subid *= 10; | |
173 | subid += *input++ - '0'; | |
174 | } | |
175 | for (tp = subtree; tp; tp = tp->next_peer) { | |
176 | if (tp->subid == subid) | |
177 | goto found; | |
178 | } | |
179 | tp = NULL; | |
43d4303e | 180 | } else { |
26ac0430 AJ |
181 | /* |
182 | * Read the name into a buffer. | |
183 | */ | |
184 | while ((*input != '\0') && | |
185 | (*input != '.')) { | |
186 | *to++ = *input++; | |
187 | } | |
188 | *to = '\0'; | |
189 | ||
190 | /* | |
191 | * Find the name in the subtree; | |
192 | */ | |
193 | for (tp = subtree; tp; tp = tp->next_peer) { | |
194 | if (lc_cmp(tp->label, buf) == 0) { | |
195 | subid = tp->subid; | |
196 | goto found; | |
197 | } | |
198 | } | |
199 | ||
200 | /* | |
201 | * If we didn't find the entry, punt... | |
202 | */ | |
203 | if (tp == NULL) { | |
204 | snmplib_debug(0, "sub-identifier not found: %s\n", buf); | |
205 | return (0); | |
206 | } | |
627f6d02 | 207 | } |
208 | ||
26ac0430 | 209 | found: |
43d4303e | 210 | if (subid > (u_int) MAX_SUBID) { |
26ac0430 AJ |
211 | snmplib_debug(0, "sub-identifier too large: %s\n", buf); |
212 | return (0); | |
627f6d02 | 213 | } |
43d4303e | 214 | if ((*out_len)-- <= 0) { |
26ac0430 AJ |
215 | snmplib_debug(0, "object identifier too long\n"); |
216 | return (0); | |
627f6d02 | 217 | } |
218 | *output++ = subid; | |
219 | ||
220 | if (*input != '.') | |
26ac0430 | 221 | return (1); |
627f6d02 | 222 | if ((*out_len = |
26ac0430 AJ |
223 | parse_subtree(tp ? tp->child_list : NULL, ++input, output, out_len)) == 0) |
224 | return (0); | |
627f6d02 | 225 | return (++*out_len); |
226 | } | |
227 | ||
468ae12b | 228 | int |
43d4303e | 229 | read_objid(input, output, out_len) |
26ac0430 AJ |
230 | char *input; |
231 | oid *output; | |
f53969cc | 232 | int *out_len; /* number of subid's in "output" */ |
627f6d02 | 233 | { |
85269fdf | 234 | struct snmp_mib_tree *root = Mib; |
235 | oid *op = output; | |
236 | int i; | |
237 | ||
238 | if (*input == '.') | |
26ac0430 | 239 | input++; |
85269fdf | 240 | else { |
26ac0430 AJ |
241 | root = find_rfc1066_mib(root); |
242 | for (i = 0; i < sizeof(RFC1066_MIB) / sizeof(oid); i++) { | |
243 | if ((*out_len)-- > 0) | |
244 | *output++ = RFC1066_MIB[i]; | |
245 | else { | |
246 | snmplib_debug(0, "object identifier too long\n"); | |
247 | return (0); | |
248 | } | |
249 | } | |
627f6d02 | 250 | } |
85269fdf | 251 | |
43d4303e | 252 | if (root == NULL) { |
26ac0430 AJ |
253 | snmplib_debug(0, "Mib not initialized.\n"); |
254 | return 0; | |
85269fdf | 255 | } |
a2bdd3f6 | 256 | if ((*out_len = parse_subtree(root, input, output, out_len)) == 0) |
26ac0430 | 257 | return (0); |
85269fdf | 258 | *out_len += output - op; |
259 | ||
260 | return (1); | |
627f6d02 | 261 | } |
262 | ||
468ae12b | 263 | void |
43d4303e | 264 | print_objid(objid, objidlen) |
26ac0430 | 265 | oid *objid; |
f53969cc | 266 | int objidlen; /* number of subidentifiers */ |
627f6d02 | 267 | { |
43d4303e | 268 | char buf[256]; |
269 | struct snmp_mib_tree *subtree = Mib; | |
627f6d02 | 270 | |
f53969cc | 271 | *buf = '.'; /* this is a fully qualified name */ |
85269fdf | 272 | get_symbol(objid, objidlen, subtree, buf + 1); |
273 | snmplib_debug(7, "%s\n", buf); | |
43d4303e | 274 | |
627f6d02 | 275 | } |
276 | ||
468ae12b | 277 | void |
43d4303e | 278 | sprint_objid(buf, objid, objidlen) |
26ac0430 AJ |
279 | char *buf; |
280 | oid *objid; | |
f53969cc | 281 | int objidlen; /* number of subidentifiers */ |
85269fdf | 282 | { |
43d4303e | 283 | struct snmp_mib_tree *subtree = Mib; |
85269fdf | 284 | |
f53969cc | 285 | *buf = '.'; /* this is a fully qualified name */ |
85269fdf | 286 | get_symbol(objid, objidlen, subtree, buf + 1); |
287 | } | |
627f6d02 | 288 | |
85269fdf | 289 | static struct snmp_mib_tree * |
e1381638 AJ |
290 | get_symbol(objid, objidlen, subtree, buf) |
291 | oid *objid; | |
26ac0430 AJ |
292 | int objidlen; |
293 | struct snmp_mib_tree *subtree; | |
294 | char *buf; | |
627f6d02 | 295 | { |
43d4303e | 296 | struct snmp_mib_tree *return_tree = NULL; |
627f6d02 | 297 | |
43d4303e | 298 | for (; subtree; subtree = subtree->next_peer) { |
26ac0430 AJ |
299 | if (*objid == subtree->subid) { |
300 | strcpy(buf, subtree->label); | |
301 | goto found; | |
302 | } | |
627f6d02 | 303 | } |
304 | ||
305 | /* subtree not found */ | |
f53969cc | 306 | while (objidlen--) { /* output rest of name, uninterpreted */ |
26ac0430 AJ |
307 | sprintf(buf, "%u.", *objid++); |
308 | while (*buf) | |
309 | buf++; | |
627f6d02 | 310 | } |
f53969cc | 311 | *(buf - 1) = '\0'; /* remove trailing dot */ |
627f6d02 | 312 | return NULL; |
313 | ||
26ac0430 | 314 | found: |
43d4303e | 315 | if (objidlen > 1) { |
26ac0430 AJ |
316 | while (*buf) |
317 | buf++; | |
318 | *buf++ = '.'; | |
319 | *buf = '\0'; | |
320 | return_tree = get_symbol(objid + 1, objidlen - 1, subtree->child_list, buf); | |
43d4303e | 321 | } |
627f6d02 | 322 | if (return_tree != NULL) |
26ac0430 | 323 | return return_tree; |
627f6d02 | 324 | else |
26ac0430 | 325 | return subtree; |
627f6d02 | 326 | } |
327 | ||
468ae12b | 328 | void |
43d4303e | 329 | print_oid_nums(oid * O, int len) |
330 | { | |
331 | int x; | |
332 | ||
333 | for (x = 0; x < len; x++) | |
26ac0430 | 334 | printf(".%u", O[x]); |
627f6d02 | 335 | } |
f53969cc | 336 |