mib.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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";
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 *
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 
229 int
230 read_objid(char *input, oid *output, int *out_len)
231 {
232  struct snmp_mib_tree *root = Mib;
233  oid *op = output;
234  int i;
235 
236  if (*input == '.')
237  input++;
238  else {
239  root = find_rfc1066_mib(root);
240  for (i = 0; i < sizeof(RFC1066_MIB) / sizeof(oid); i++) {
241  if ((*out_len)-- > 0)
242  *output++ = RFC1066_MIB[i];
243  else {
244  snmplib_debug(0, "object identifier too long\n");
245  return (0);
246  }
247  }
248  }
249 
250  if (root == NULL) {
251  snmplib_debug(0, "Mib not initialized.\n");
252  return 0;
253  }
254  if ((*out_len = parse_subtree(root, input, output, out_len)) == 0)
255  return (0);
256  *out_len += output - op;
257 
258  return (1);
259 }
260 
262 void
263 print_objid(oid *objid, int objidlen)
264 {
265  char buf[256];
266  struct snmp_mib_tree *subtree = Mib;
267 
268  *buf = '.'; /* this is a fully qualified name */
269  get_symbol(objid, objidlen, subtree, buf + 1);
270  snmplib_debug(7, "%s\n", buf);
271 
272 }
273 
275 void
276 sprint_objid(char *buf, oid *objid, int objidlen)
277 {
278  struct snmp_mib_tree *subtree = Mib;
279 
280  *buf = '.'; /* this is a fully qualified name */
281  get_symbol(objid, objidlen, subtree, buf + 1);
282 }
283 
284 static struct snmp_mib_tree *
285 get_symbol(oid *objid, int objidlen, struct snmp_mib_tree *subtree, char *buf)
286 {
287  struct snmp_mib_tree *return_tree = NULL;
288 
289  for (; subtree; subtree = subtree->next_peer) {
290  if (*objid == subtree->subid) {
291  strcpy(buf, subtree->label);
292  goto found;
293  }
294  }
295 
296  /* subtree not found */
297  while (objidlen--) { /* output rest of name, uninterpreted */
298  sprintf(buf, "%u.", *objid++);
299  while (*buf)
300  buf++;
301  }
302  *(buf - 1) = '\0'; /* remove trailing dot */
303  return NULL;
304 
305 found:
306  if (objidlen > 1) {
307  while (*buf)
308  buf++;
309  *buf++ = '.';
310  *buf = '\0';
311  return_tree = get_symbol(objid + 1, objidlen - 1, subtree->child_list, buf);
312  }
313  if (return_tree != NULL)
314  return return_tree;
315  else
316  return subtree;
317 }
318 
319 void
320 print_oid_nums(oid * O, int len)
321 {
322  int x;
323 
324  for (x = 0; x < len; x++)
325  printf(".%u", O[x]);
326 }
327 
struct snmp_mib_tree * Mib
Definition: mib.c:94
static int lc_cmp(const char *s1, const char *s2)
Definition: mib.c:126
@ s1
Definition: cf_gen.cc:55
unsigned char RFC1066_MIB_text[]
Definition: mib.c:93
oid RFC1066_MIB[]
Definition: mib.c:92
static struct snmp_mib_tree * get_symbol(oid *objid, int objidlen, struct snmp_mib_tree *subtree, char *buf)
Definition: mib.c:285
struct snmp_mib_tree * child_list
Definition: parse.h:51
#define xtolower(x)
Definition: xis.h:17
void print_oid_nums(oid *O, int len)
Definition: mib.c:320
#define xisupper(x)
Definition: xis.h:26
#define NULL
Definition: types.h:145
struct snmp_mib_tree * read_mib(char *)
Definition: parse.c:1038
static struct snmp_mib_tree * find_rfc1066_mib(struct snmp_mib_tree *root)
Definition: mib.c:107
#define xisdigit(x)
Definition: xis.h:18
u_int subid
Definition: parse.h:55
u_int oid
Definition: asn1.h:42
char label[64]
Definition: parse.h:54
void init_mib(char *file)
Definition: mib.c:97
Definition: parse.c:96
static int parse_subtree(struct snmp_mib_tree *subtree, char *input, oid *output, int *out_len)
Definition: mib.c:153
void print_objid(oid *objid, int objidlen)
Definition: mib.c:263
#define MAX_SUBID
Definition: asn1.h:43
int read_objid(char *input, oid *output, int *out_len)
Definition: mib.c:230
void sprint_objid(char *buf, oid *objid, int objidlen)
Definition: mib.c:276
SQUIDCEXTERN void snmplib_debug(int, const char *,...) PRINTF_FORMAT_ARG2
Definition: snmplib_debug.c:21
struct snmp_mib_tree * next_peer
Definition: parse.h:52

 

Introduction

Documentation

Support

Miscellaneous