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