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