]> git.ipfire.org Git - thirdparty/squid.git/blob - snmplib/mib.c
SourceFormat: enforcement
[thirdparty/squid.git] / snmplib / mib.c
1
2 /***********************************************************
3 Copyright 1988, 1989 by Carnegie Mellon University
4
5 All Rights Reserved
6
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the name of CMU not be
12 used in advertising or publicity pertaining to distribution of the
13 software without specific, written prior permission.
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 ******************************************************************/
23
24 #include "config.h"
25
26 #include <stdio.h>
27
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #if HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 #if HAVE_SYS_TYPES_H
35 #include <sys/types.h>
36 #endif
37 #if HAVE_CTYPE_H
38 #include <ctype.h>
39 #endif
40 #if HAVE_GNUMALLOC_H
41 #include <gnumalloc.h>
42 #elif HAVE_MALLOC_H
43 #include <malloc.h>
44 #endif
45 #if HAVE_MEMORY_H
46 #include <memory.h>
47 #endif
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
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
72
73 #include "asn1.h"
74 #include "snmp.h"
75
76 #include "snmp_pdu.h"
77 #include "snmp_vars.h"
78 #include "snmp_session.h"
79 #include "snmp_impl.h"
80 #include "snmp_api.h"
81 #include "parse.h"
82
83 #include "util.h"
84
85 static struct snmp_mib_tree *get_symbol(oid *objid, int objidlen, struct snmp_mib_tree *subtree, char *buf);
86
87 oid RFC1066_MIB[] = {1, 3, 6, 1, 2, 1};
88 unsigned char RFC1066_MIB_text[] = ".iso.org.dod.internet.mgmt.mib";
89 struct snmp_mib_tree *Mib;
90
91 void
92 init_mib(char *file)
93 {
94 if (Mib != NULL)
95 return;
96
97 if (file != NULL)
98 Mib = read_mib(file);
99 }
100
101
102 static struct snmp_mib_tree *
103 find_rfc1066_mib(struct snmp_mib_tree *root) {
104 oid *op = RFC1066_MIB;
105 struct snmp_mib_tree *tp;
106 int len;
107
108 for (len = sizeof(RFC1066_MIB) / sizeof(oid); len; len--, op++) {
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;
117 }
118 return root;
119 }
120
121 static int
122 lc_cmp(const char *s1, const char *s2)
123 {
124 char c1, c2;
125
126 while (*s1 && *s2) {
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++;
139 }
140
141 if (*s1)
142 return -1;
143 if (*s2)
144 return 1;
145 return 0;
146 }
147
148 static int
149 parse_subtree(struct snmp_mib_tree *subtree, char *input, oid *output, int *out_len)
150 {
151 char buf[128], *to = buf;
152 u_int subid = 0;
153 struct snmp_mib_tree *tp;
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') ||
160 (*input == '.'))
161 return (0);
162
163 if (xisdigit(*input)) {
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;
176 } else {
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 }
203 }
204
205 found:
206 if (subid > (u_int) MAX_SUBID) {
207 snmplib_debug(0, "sub-identifier too large: %s\n", buf);
208 return (0);
209 }
210 if ((*out_len)-- <= 0) {
211 snmplib_debug(0, "object identifier too long\n");
212 return (0);
213 }
214 *output++ = subid;
215
216 if (*input != '.')
217 return (1);
218 if ((*out_len =
219 parse_subtree(tp ? tp->child_list : NULL, ++input, output, out_len)) == 0)
220 return (0);
221 return (++*out_len);
222 }
223
224 int
225 read_objid(input, output, out_len)
226 char *input;
227 oid *output;
228 int *out_len; /* number of subid's in "output" */
229 {
230 struct snmp_mib_tree *root = Mib;
231 oid *op = output;
232 int i;
233
234 if (*input == '.')
235 input++;
236 else {
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 }
246 }
247
248 if (root == NULL) {
249 snmplib_debug(0, "Mib not initialized.\n");
250 return 0;
251 }
252 if ((*out_len = parse_subtree(root, input, output, out_len)) == 0)
253 return (0);
254 *out_len += output - op;
255
256 return (1);
257 }
258
259 void
260 print_objid(objid, objidlen)
261 oid *objid;
262 int objidlen; /* number of subidentifiers */
263 {
264 char buf[256];
265 struct snmp_mib_tree *subtree = Mib;
266
267 *buf = '.'; /* this is a fully qualified name */
268 get_symbol(objid, objidlen, subtree, buf + 1);
269 snmplib_debug(7, "%s\n", buf);
270
271 }
272
273 void
274 sprint_objid(buf, objid, objidlen)
275 char *buf;
276 oid *objid;
277 int objidlen; /* number of subidentifiers */
278 {
279 struct snmp_mib_tree *subtree = Mib;
280
281 *buf = '.'; /* this is a fully qualified name */
282 get_symbol(objid, objidlen, subtree, buf + 1);
283 }
284
285 static struct snmp_mib_tree *
286 get_symbol(objid, objidlen, subtree, buf)
287 oid *objid;
288 int objidlen;
289 struct snmp_mib_tree *subtree;
290 char *buf;
291 {
292 struct snmp_mib_tree *return_tree = NULL;
293
294 for (; subtree; subtree = subtree->next_peer) {
295 if (*objid == subtree->subid) {
296 strcpy(buf, subtree->label);
297 goto found;
298 }
299 }
300
301 /* subtree not found */
302 while (objidlen--) { /* output rest of name, uninterpreted */
303 sprintf(buf, "%u.", *objid++);
304 while (*buf)
305 buf++;
306 }
307 *(buf - 1) = '\0'; /* remove trailing dot */
308 return NULL;
309
310 found:
311 if (objidlen > 1) {
312 while (*buf)
313 buf++;
314 *buf++ = '.';
315 *buf = '\0';
316 return_tree = get_symbol(objid + 1, objidlen - 1, subtree->child_list, buf);
317 }
318 if (return_tree != NULL)
319 return return_tree;
320 else
321 return subtree;
322 }
323
324 void
325 print_oid_nums(oid * O, int len)
326 {
327 int x;
328
329 for (x = 0; x < len; x++)
330 printf(".%u", O[x]);
331 }