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