source: squid-ssl/trunk/fuentes/lib/snmplib/mib.c @ 5495

Last change on this file since 5495 was 5495, checked in by Juanma, 2 years ago

Initial release

File size: 7.7 KB
Line 
1/*
2 * Copyright (C) 1996-2015 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
14Permission to use, copy, modify, and distribute this software and its
15documentation for any purpose and without fee is hereby granted,
16provided that the above copyright notice appear in all copies and that
17both that copyright notice and this permission notice appear in
18supporting documentation, and that the name of CMU not be
19used in advertising or publicity pertaining to distribution of the
20software without specific, written prior permission.
21
22CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
23ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
24CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
25ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
26WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
27ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
28SOFTWARE.
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
90static struct snmp_mib_tree *get_symbol(oid *objid, int objidlen, struct snmp_mib_tree *subtree, char *buf);
91
92oid RFC1066_MIB[] = {1, 3, 6, 1, 2, 1};
93unsigned char RFC1066_MIB_text[] = ".iso.org.dod.internet.mgmt.mib";
94struct snmp_mib_tree *Mib;
95
96void
97init_mib(char *file)
98{
99    if (Mib != NULL)
100        return;
101
102    if (file != NULL)
103        Mib = read_mib(file);
104}
105
106static struct snmp_mib_tree *
107find_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
125static int
126lc_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
152static int
153parse_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
209found:
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
228int
229read_objid(input, output, out_len)
230char *input;
231oid *output;
232int *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
263void
264print_objid(objid, objidlen)
265oid *objid;
266int 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
277void
278sprint_objid(buf, objid, objidlen)
279char *buf;
280oid *objid;
281int 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
289static struct snmp_mib_tree *
290get_symbol(objid, objidlen, subtree, buf)
291oid *objid;
292int objidlen;
293struct snmp_mib_tree *subtree;
294char *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
314found:
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
328void
329print_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
Note: See TracBrowser for help on using the repository browser.