]> git.ipfire.org Git - thirdparty/squid.git/blob - snmplib/mib.c
Renamed squid.h to squid-old.h and config.h to squid.h
[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 #define SQUID_NO_STRING_BUFFER_PROTECT 1
25 #include "squid.h"
26
27 #include <stdio.h>
28
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #if HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35 #if HAVE_SYS_TYPES_H
36 #include <sys/types.h>
37 #endif
38 #if HAVE_CTYPE_H
39 #include <ctype.h>
40 #endif
41 #if HAVE_GNUMALLOC_H
42 #include <gnumalloc.h>
43 #elif HAVE_MALLOC_H
44 #include <malloc.h>
45 #endif
46 #if HAVE_MEMORY_H
47 #include <memory.h>
48 #endif
49 #if HAVE_STRING_H
50 #include <string.h>
51 #endif
52 #if HAVE_STRINGS_H
53 #include <strings.h>
54 #endif
55 #if HAVE_BSTRING_H
56 #include <bstring.h>
57 #endif
58 #if HAVE_SYS_SOCKET_H
59 #include <sys/socket.h>
60 #endif
61 #if HAVE_NETINET_IN_H
62 #include <netinet/in.h>
63 #endif
64 #if HAVE_ARPA_INET_H
65 #include <arpa/inet.h>
66 #endif
67 #if HAVE_SYS_TIME_H
68 #include <sys/time.h>
69 #endif
70 #if HAVE_NETDB_H
71 #include <netdb.h>
72 #endif
73
74 #include "asn1.h"
75 #include "snmp.h"
76
77 #include "snmp_pdu.h"
78 #include "snmp_vars.h"
79 #include "snmp_session.h"
80 #include "snmp_impl.h"
81 #include "snmp_api.h"
82 #include "parse.h"
83
84 #include "util.h"
85
86 static struct snmp_mib_tree *get_symbol(oid *objid, int objidlen, struct snmp_mib_tree *subtree, char *buf);
87
88 oid RFC1066_MIB[] = {1, 3, 6, 1, 2, 1};
89 unsigned char RFC1066_MIB_text[] = ".iso.org.dod.internet.mgmt.mib";
90 struct snmp_mib_tree *Mib;
91
92 void
93 init_mib(char *file)
94 {
95 if (Mib != NULL)
96 return;
97
98 if (file != NULL)
99 Mib = read_mib(file);
100 }
101
102
103 static struct snmp_mib_tree *
104 find_rfc1066_mib(struct snmp_mib_tree *root) {
105 oid *op = RFC1066_MIB;
106 struct snmp_mib_tree *tp;
107 int len;
108
109 for (len = sizeof(RFC1066_MIB) / sizeof(oid); len; len--, op++) {
110 for (tp = root; tp; tp = tp->next_peer) {
111 if (tp->subid == *op) {
112 root = tp->child_list;
113 break;
114 }
115 }
116 if (tp == NULL)
117 return NULL;
118 }
119 return root;
120 }
121
122 static int
123 lc_cmp(const char *s1, const char *s2)
124 {
125 char c1, c2;
126
127 while (*s1 && *s2) {
128 if (xisupper(*s1))
129 c1 = xtolower(*s1);
130 else
131 c1 = *s1;
132 if (xisupper(*s2))
133 c2 = xtolower(*s2);
134 else
135 c2 = *s2;
136 if (c1 != c2)
137 return ((c1 - c2) > 0 ? 1 : -1);
138 s1++;
139 s2++;
140 }
141
142 if (*s1)
143 return -1;
144 if (*s2)
145 return 1;
146 return 0;
147 }
148
149 static int
150 parse_subtree(struct snmp_mib_tree *subtree, char *input, oid *output, int *out_len)
151 {
152 char buf[128], *to = buf;
153 u_int subid = 0;
154 struct snmp_mib_tree *tp;
155
156 /*
157 * No empty strings. Can happen if there is a trailing '.' or two '.'s
158 * in a row, i.e. "..".
159 */
160 if ((*input == '\0') ||
161 (*input == '.'))
162 return (0);
163
164 if (xisdigit(*input)) {
165 /*
166 * Read the number, then try to find it in the subtree.
167 */
168 while (xisdigit(*input)) {
169 subid *= 10;
170 subid += *input++ - '0';
171 }
172 for (tp = subtree; tp; tp = tp->next_peer) {
173 if (tp->subid == subid)
174 goto found;
175 }
176 tp = NULL;
177 } else {
178 /*
179 * Read the name into a buffer.
180 */
181 while ((*input != '\0') &&
182 (*input != '.')) {
183 *to++ = *input++;
184 }
185 *to = '\0';
186
187 /*
188 * Find the name in the subtree;
189 */
190 for (tp = subtree; tp; tp = tp->next_peer) {
191 if (lc_cmp(tp->label, buf) == 0) {
192 subid = tp->subid;
193 goto found;
194 }
195 }
196
197 /*
198 * If we didn't find the entry, punt...
199 */
200 if (tp == NULL) {
201 snmplib_debug(0, "sub-identifier not found: %s\n", buf);
202 return (0);
203 }
204 }
205
206 found:
207 if (subid > (u_int) MAX_SUBID) {
208 snmplib_debug(0, "sub-identifier too large: %s\n", buf);
209 return (0);
210 }
211 if ((*out_len)-- <= 0) {
212 snmplib_debug(0, "object identifier too long\n");
213 return (0);
214 }
215 *output++ = subid;
216
217 if (*input != '.')
218 return (1);
219 if ((*out_len =
220 parse_subtree(tp ? tp->child_list : NULL, ++input, output, out_len)) == 0)
221 return (0);
222 return (++*out_len);
223 }
224
225 int
226 read_objid(input, output, out_len)
227 char *input;
228 oid *output;
229 int *out_len; /* number of subid's in "output" */
230 {
231 struct snmp_mib_tree *root = Mib;
232 oid *op = output;
233 int i;
234
235 if (*input == '.')
236 input++;
237 else {
238 root = find_rfc1066_mib(root);
239 for (i = 0; i < sizeof(RFC1066_MIB) / sizeof(oid); i++) {
240 if ((*out_len)-- > 0)
241 *output++ = RFC1066_MIB[i];
242 else {
243 snmplib_debug(0, "object identifier too long\n");
244 return (0);
245 }
246 }
247 }
248
249 if (root == NULL) {
250 snmplib_debug(0, "Mib not initialized.\n");
251 return 0;
252 }
253 if ((*out_len = parse_subtree(root, input, output, out_len)) == 0)
254 return (0);
255 *out_len += output - op;
256
257 return (1);
258 }
259
260 void
261 print_objid(objid, objidlen)
262 oid *objid;
263 int objidlen; /* number of subidentifiers */
264 {
265 char buf[256];
266 struct snmp_mib_tree *subtree = Mib;
267
268 *buf = '.'; /* this is a fully qualified name */
269 get_symbol(objid, objidlen, subtree, buf + 1);
270 snmplib_debug(7, "%s\n", buf);
271
272 }
273
274 void
275 sprint_objid(buf, objid, objidlen)
276 char *buf;
277 oid *objid;
278 int objidlen; /* number of subidentifiers */
279 {
280 struct snmp_mib_tree *subtree = Mib;
281
282 *buf = '.'; /* this is a fully qualified name */
283 get_symbol(objid, objidlen, subtree, buf + 1);
284 }
285
286 static struct snmp_mib_tree *
287 get_symbol(objid, objidlen, subtree, buf)
288 oid *objid;
289 int objidlen;
290 struct snmp_mib_tree *subtree;
291 char *buf;
292 {
293 struct snmp_mib_tree *return_tree = NULL;
294
295 for (; subtree; subtree = subtree->next_peer) {
296 if (*objid == subtree->subid) {
297 strcpy(buf, subtree->label);
298 goto found;
299 }
300 }
301
302 /* subtree not found */
303 while (objidlen--) { /* output rest of name, uninterpreted */
304 sprintf(buf, "%u.", *objid++);
305 while (*buf)
306 buf++;
307 }
308 *(buf - 1) = '\0'; /* remove trailing dot */
309 return NULL;
310
311 found:
312 if (objidlen > 1) {
313 while (*buf)
314 buf++;
315 *buf++ = '.';
316 *buf = '\0';
317 return_tree = get_symbol(objid + 1, objidlen - 1, subtree->child_list, buf);
318 }
319 if (return_tree != NULL)
320 return return_tree;
321 else
322 return subtree;
323 }
324
325 void
326 print_oid_nums(oid * O, int len)
327 {
328 int x;
329
330 for (x = 0; x < len; x++)
331 printf(".%u", O[x]);
332 }