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