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