Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c
106929 views
1
/*-
2
* Copyright (c) 2006 The FreeBSD Project
3
* All rights reserved.
4
*
5
* Author: Shteryana Shopova <[email protected]>
6
*
7
* Redistribution of this software and documentation and use in source and
8
* binary forms, with or without modification, are permitted provided that
9
* the following conditions are met:
10
*
11
* 1. Redistributions of source code or documentation must retain the above
12
* copyright notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
/*
31
* Read file containing table description - reuse magic from gensnmptree.c.
32
* Hopefully one day most of the code here will be part of libbsnmp and
33
* this duplication won't be necessary.
34
*
35
* Syntax is:
36
* ---------
37
* file := top | top file
38
*
39
* top := tree | typedef | include
40
*
41
* tree := head elements ')'
42
*
43
* entry := head ':' index STRING elements ')'
44
*
45
* leaf := head type STRING ACCESS ')'
46
*
47
* column := head type ACCESS ')'
48
*
49
* type := BASETYPE | BASETYPE '|' subtype | enum | bits
50
*
51
* subtype := STRING
52
*
53
* enum := ENUM '(' value ')'
54
*
55
* bits := BITS '(' value ')'
56
*
57
* value := INT STRING | INT STRING value
58
*
59
* head := '(' INT STRING
60
*
61
* elements := EMPTY | elements element
62
*
63
* element := tree | leaf | column
64
*
65
* index := type | index type
66
*
67
* typedef := 'typedef' STRING type
68
*
69
* include := 'include' filespec
70
*
71
* filespec := '"' STRING '"' | '<' STRING '>'
72
*/
73
74
#include <sys/param.h>
75
#include <sys/queue.h>
76
#include <sys/uio.h>
77
78
#include <ctype.h>
79
#include <err.h>
80
#include <errno.h>
81
#include <fcntl.h>
82
#include <paths.h>
83
#include <stdio.h>
84
#include <stdlib.h>
85
#include <string.h>
86
#include <syslog.h>
87
#include <unistd.h>
88
89
#include <bsnmp/asn1.h>
90
#include <bsnmp/snmp.h>
91
#include <bsnmp/snmpagent.h> /* SNMP_INDEXES_MAX */
92
#include "bsnmptc.h"
93
#include "bsnmptools.h"
94
95
enum snmp_tbl_entry {
96
ENTRY_NONE = 0,
97
ENTRY_INDEX,
98
ENTRY_DATA
99
};
100
101
enum {
102
FL_GET = 0x01,
103
FL_SET = 0x02,
104
};
105
106
/************************************************************
107
*
108
* Allocate memory and panic just in the case...
109
*/
110
static void *
111
xalloc(size_t size)
112
{
113
void *ptr;
114
115
if ((ptr = malloc(size)) == NULL)
116
err(1, "allocing %zu bytes", size);
117
118
return (ptr);
119
}
120
121
static char *
122
savestr(const char *s)
123
{
124
if (s == NULL)
125
return (NULL);
126
127
return (strcpy(xalloc(strlen(s) + 1), s));
128
}
129
130
/************************************************************
131
*
132
* Input stack
133
*/
134
struct input {
135
FILE *fp;
136
uint32_t lno;
137
char *fname;
138
char *path;
139
LIST_ENTRY(input) link;
140
};
141
142
static LIST_HEAD(, input) inputs = LIST_HEAD_INITIALIZER(inputs);
143
static struct input *input = NULL;
144
static int32_t pbchar = -1;
145
146
#define MAX_PATHS 100
147
148
static const char *paths[MAX_PATHS + 1] = {
149
"/usr/share/snmp/defs",
150
_PATH_LOCALBASE "/share/snmp/defs",
151
NULL
152
};
153
154
static void
155
input_new(FILE *fp, const char *path, const char *fname)
156
{
157
struct input *ip;
158
159
ip = xalloc(sizeof(*ip));
160
ip->fp = fp;
161
ip->lno = 1;
162
ip->fname = savestr(fname);
163
ip->path = savestr(path);
164
LIST_INSERT_HEAD(&inputs, ip, link);
165
166
input = ip;
167
}
168
169
static void
170
input_close(void)
171
{
172
if (input == NULL)
173
return;
174
175
fclose(input->fp);
176
free(input->fname);
177
free(input->path);
178
LIST_REMOVE(input, link);
179
free(input);
180
181
input = LIST_FIRST(&inputs);
182
}
183
184
static FILE *
185
tryopen(const char *path, const char *fname)
186
{
187
char *fn;
188
FILE *fp;
189
190
if (path == NULL)
191
fn = savestr(fname);
192
else {
193
fn = xalloc(strlen(path) + strlen(fname) + 2);
194
sprintf(fn, "%s/%s", path, fname);
195
}
196
fp = fopen(fn, "r");
197
free(fn);
198
return (fp);
199
}
200
201
static int32_t
202
input_fopen(const char *fname)
203
{
204
FILE *fp;
205
u_int p;
206
207
if (fname[0] == '/' || fname[0] == '.' || fname[0] == '~') {
208
if ((fp = tryopen(NULL, fname)) != NULL) {
209
input_new(fp, NULL, fname);
210
return (0);
211
}
212
213
} else {
214
215
for (p = 0; paths[p] != NULL; p++)
216
if ((fp = tryopen(paths[p], fname)) != NULL) {
217
input_new(fp, paths[p], fname);
218
return (0);
219
}
220
}
221
222
warnx("cannot open '%s'", fname);
223
return (-1);
224
}
225
226
static int32_t
227
tgetc(void)
228
{
229
int c;
230
231
if (pbchar != -1) {
232
c = pbchar;
233
pbchar = -1;
234
return (c);
235
}
236
237
for (;;) {
238
if (input == NULL)
239
return (EOF);
240
241
if ((c = getc(input->fp)) != EOF)
242
return (c);
243
244
input_close();
245
}
246
}
247
248
static int32_t
249
tungetc(int c)
250
{
251
252
if (pbchar != -1)
253
return (-1);
254
255
pbchar = c;
256
return (1);
257
}
258
259
/************************************************************
260
*
261
* Parsing input
262
*/
263
enum tok {
264
TOK_EOF = 0200, /* end-of-file seen */
265
TOK_NUM, /* number */
266
TOK_STR, /* string */
267
TOK_ACCESS, /* access operator */
268
TOK_TYPE, /* type operator */
269
TOK_ENUM, /* enum token (kind of a type) */
270
TOK_TYPEDEF, /* typedef directive */
271
TOK_DEFTYPE, /* defined type */
272
TOK_INCLUDE, /* include directive */
273
TOK_FILENAME, /* filename ("foo.bar" or <foo.bar>) */
274
TOK_BITS, /* bits token (kind of a type) */
275
TOK_ERR /* unexpected char - exit */
276
};
277
278
static const struct {
279
const char *str;
280
enum tok tok;
281
uint32_t val;
282
} keywords[] = {
283
{ "GET", TOK_ACCESS, FL_GET },
284
{ "SET", TOK_ACCESS, FL_SET },
285
{ "NULL", TOK_TYPE, SNMP_SYNTAX_NULL },
286
{ "INTEGER", TOK_TYPE, SNMP_SYNTAX_INTEGER },
287
{ "INTEGER32", TOK_TYPE, SNMP_SYNTAX_INTEGER },
288
{ "UNSIGNED32", TOK_TYPE, SNMP_SYNTAX_GAUGE },
289
{ "OCTETSTRING", TOK_TYPE, SNMP_SYNTAX_OCTETSTRING },
290
{ "IPADDRESS", TOK_TYPE, SNMP_SYNTAX_IPADDRESS },
291
{ "OID", TOK_TYPE, SNMP_SYNTAX_OID },
292
{ "TIMETICKS", TOK_TYPE, SNMP_SYNTAX_TIMETICKS },
293
{ "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
294
{ "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
295
{ "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
296
{ "ENUM", TOK_ENUM, SNMP_SYNTAX_INTEGER },
297
{ "BITS", TOK_BITS, SNMP_SYNTAX_OCTETSTRING },
298
{ "typedef", TOK_TYPEDEF, 0 },
299
{ "include", TOK_INCLUDE, 0 },
300
{ NULL, 0, 0 }
301
};
302
303
static struct {
304
/* Current OID type, regarding table membership. */
305
enum snmp_tbl_entry tbl_type;
306
/* A pointer to a structure in table list to add to its members. */
307
struct snmp_index_entry *table_idx;
308
} table_data;
309
310
static struct asn_oid current_oid;
311
static char nexttok[MAXSTR];
312
static u_long val; /* integer values */
313
static int32_t all_cond; /* all conditions are true */
314
static int32_t saved_token = -1;
315
316
/* Prepare the global data before parsing a new file. */
317
static void
318
snmp_import_init(struct asn_oid *append)
319
{
320
memset(&table_data, 0, sizeof(table_data));
321
memset(&current_oid, 0, sizeof(struct asn_oid));
322
memset(nexttok, 0, MAXSTR);
323
324
if (append != NULL)
325
asn_append_oid(&current_oid, append);
326
327
all_cond = 0;
328
val = 0;
329
saved_token = -1;
330
}
331
332
static int32_t
333
gettoken(struct snmp_toolinfo *snmptoolctx)
334
{
335
int c;
336
struct enum_type *t;
337
338
if (saved_token != -1) {
339
c = saved_token;
340
saved_token = -1;
341
return (c);
342
}
343
344
again:
345
/*
346
* Skip any whitespace before the next token.
347
*/
348
while ((c = tgetc()) != EOF) {
349
if (c == '\n')
350
input->lno++;
351
if (!isspace(c))
352
break;
353
}
354
if (c == EOF)
355
return (TOK_EOF);
356
357
if (!isascii(c)) {
358
warnx("unexpected character %#2x", (u_int) c);
359
return (TOK_ERR);
360
}
361
362
/*
363
* Skip comments.
364
*/
365
if (c == '#') {
366
while ((c = tgetc()) != EOF) {
367
if (c == '\n') {
368
input->lno++;
369
goto again;
370
}
371
}
372
warnx("unexpected EOF in comment");
373
return (TOK_ERR);
374
}
375
376
/*
377
* Single character tokens.
378
*/
379
if (strchr("():|", c) != NULL)
380
return (c);
381
382
if (c == '"' || c == '<') {
383
int32_t end = c;
384
size_t n = 0;
385
386
val = 1;
387
if (c == '<') {
388
val = 0;
389
end = '>';
390
}
391
392
while ((c = tgetc()) != EOF) {
393
if (c == end)
394
break;
395
if (n == sizeof(nexttok) - 1) {
396
nexttok[n++] = '\0';
397
warnx("filename too long '%s...'", nexttok);
398
return (TOK_ERR);
399
}
400
nexttok[n++] = c;
401
}
402
nexttok[n++] = '\0';
403
return (TOK_FILENAME);
404
}
405
406
/*
407
* Sort out numbers.
408
*/
409
if (isdigit(c)) {
410
size_t n = 0;
411
nexttok[n++] = c;
412
while ((c = tgetc()) != EOF) {
413
if (!isdigit(c)) {
414
if (tungetc(c) < 0)
415
return (TOK_ERR);
416
break;
417
}
418
if (n == sizeof(nexttok) - 1) {
419
nexttok[n++] = '\0';
420
warnx("number too long '%s...'", nexttok);
421
return (TOK_ERR);
422
}
423
nexttok[n++] = c;
424
}
425
nexttok[n++] = '\0';
426
sscanf(nexttok, "%lu", &val);
427
return (TOK_NUM);
428
}
429
430
/*
431
* So that has to be a string.
432
*/
433
if (isalpha(c) || c == '_' || c == '-') {
434
size_t n = 0;
435
nexttok[n++] = c;
436
while ((c = tgetc()) != EOF) {
437
if (!isalnum(c) && c != '_' && c != '-') {
438
if (tungetc (c) < 0)
439
return (TOK_ERR);
440
break;
441
}
442
if (n == sizeof(nexttok) - 1) {
443
nexttok[n++] = '\0';
444
warnx("string too long '%s...'", nexttok);
445
return (TOK_ERR);
446
}
447
nexttok[n++] = c;
448
}
449
nexttok[n++] = '\0';
450
451
/*
452
* Keywords.
453
*/
454
for (c = 0; keywords[c].str != NULL; c++)
455
if (strcmp(keywords[c].str, nexttok) == 0) {
456
val = keywords[c].val;
457
return (keywords[c].tok);
458
}
459
460
if ((t = snmp_enumtc_lookup(snmptoolctx, nexttok)) != NULL) {
461
val = t->syntax;
462
return (TOK_DEFTYPE);
463
}
464
465
return (TOK_STR);
466
}
467
468
if (isprint(c))
469
warnx("%u: unexpected character '%c'", input->lno, c);
470
else
471
warnx("%u: unexpected character 0x%02x", input->lno, (u_int) c);
472
473
return (TOK_ERR);
474
}
475
476
/*
477
* Update table information.
478
*/
479
static struct snmp_index_entry *
480
snmp_import_update_table(enum snmp_tbl_entry te, struct snmp_index_entry *tbl)
481
{
482
switch (te) {
483
case ENTRY_NONE:
484
if (table_data.tbl_type == ENTRY_NONE)
485
return (NULL);
486
if (table_data.tbl_type == ENTRY_INDEX)
487
table_data.table_idx = NULL;
488
table_data.tbl_type--;
489
return (NULL);
490
491
case ENTRY_INDEX:
492
if (tbl == NULL)
493
warnx("No table_index to add!!!");
494
table_data.table_idx = tbl;
495
table_data.tbl_type = ENTRY_INDEX;
496
return (tbl);
497
498
case ENTRY_DATA:
499
if (table_data.tbl_type == ENTRY_INDEX) {
500
table_data.tbl_type = ENTRY_DATA;
501
return (table_data.table_idx);
502
}
503
return (NULL);
504
505
default:
506
/* NOTREACHED */
507
warnx("Unknown table entry type!!!");
508
break;
509
}
510
511
return (NULL);
512
}
513
514
static int32_t
515
parse_enum(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
516
struct enum_pairs *enums)
517
{
518
while ((*tok = gettoken(snmptoolctx)) == TOK_STR) {
519
if (enum_pair_insert(enums, val, nexttok) < 0)
520
return (-1);
521
if ((*tok = gettoken(snmptoolctx)) != TOK_NUM)
522
break;
523
}
524
525
if (*tok != ')') {
526
warnx("')' at end of enums");
527
return (-1);
528
}
529
530
return (1);
531
}
532
533
static int32_t
534
parse_subtype(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
535
enum snmp_tc *tc)
536
{
537
if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
538
warnx("subtype expected after '|'");
539
return (-1);
540
}
541
542
*tc = snmp_get_tc(nexttok);
543
*tok = gettoken(snmptoolctx);
544
545
return (1);
546
}
547
548
static int32_t
549
parse_type(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
550
enum snmp_tc *tc, struct enum_pairs **snmp_enum)
551
{
552
int32_t syntax, mem;
553
554
syntax = val;
555
*tc = 0;
556
557
if (*tok == TOK_ENUM || *tok == TOK_BITS) {
558
if (*snmp_enum == NULL) {
559
if ((*snmp_enum = enum_pairs_init()) == NULL)
560
return (-1);
561
mem = 1;
562
*tc = SNMP_TC_OWN;
563
} else
564
mem = 0;
565
566
if (gettoken(snmptoolctx) != '(') {
567
warnx("'(' expected after ENUM/BITS");
568
return (-1);
569
}
570
571
if ((*tok = gettoken(snmptoolctx)) != TOK_NUM) {
572
warnx("need value for ENUM//BITS");
573
if (mem == 1) {
574
free(*snmp_enum);
575
*snmp_enum = NULL;
576
}
577
return (-1);
578
}
579
580
if (parse_enum(snmptoolctx, tok, *snmp_enum) < 0) {
581
enum_pairs_free(*snmp_enum);
582
*snmp_enum = NULL;
583
return (-1);
584
}
585
586
*tok = gettoken(snmptoolctx);
587
588
} else if (*tok == TOK_DEFTYPE) {
589
struct enum_type *t;
590
591
*tc = 0;
592
t = snmp_enumtc_lookup(snmptoolctx, nexttok);
593
if (t != NULL)
594
*snmp_enum = t->snmp_enum;
595
596
*tok = gettoken(snmptoolctx);
597
598
} else {
599
if ((*tok = gettoken(snmptoolctx)) == '|') {
600
if (parse_subtype(snmptoolctx, tok, tc) < 0)
601
return (-1);
602
}
603
}
604
605
return (syntax);
606
}
607
608
static int32_t
609
snmp_import_head(struct snmp_toolinfo *snmptoolctx)
610
{
611
enum tok tok;
612
613
if ((tok = gettoken(snmptoolctx)) == '(')
614
tok = gettoken(snmptoolctx);
615
616
if (tok != TOK_NUM || val > ASN_MAXID ) {
617
warnx("Suboid expected - line %d", input->lno);
618
return (-1);
619
}
620
621
if (gettoken(snmptoolctx) != TOK_STR) {
622
warnx("Node name expected at line %d", input->lno);
623
return (-1);
624
}
625
626
return (1);
627
}
628
629
static int32_t
630
snmp_import_table(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *obj)
631
{
632
int32_t i, tok;
633
enum snmp_tc tc;
634
struct snmp_index_entry *entry;
635
636
if ((entry = calloc(1, sizeof(struct snmp_index_entry))) == NULL) {
637
syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
638
return (-1);
639
}
640
641
STAILQ_INIT(&(entry->index_list));
642
643
for (i = 0, tok = gettoken(snmptoolctx); i < SNMP_INDEXES_MAX; i++) {
644
int32_t syntax;
645
struct enum_pairs *enums = NULL;
646
647
if (tok != TOK_TYPE && tok != TOK_DEFTYPE && tok != TOK_ENUM &&
648
tok != TOK_BITS)
649
break;
650
651
if ((syntax = parse_type(snmptoolctx, &tok, &tc, &enums)) < 0) {
652
enum_pairs_free(enums);
653
snmp_index_listfree(&(entry->index_list));
654
free(entry);
655
return (-1);
656
}
657
658
if (snmp_syntax_insert(&(entry->index_list), enums, syntax,
659
tc) < 0) {
660
snmp_index_listfree(&(entry->index_list));
661
enum_pairs_free(enums);
662
free(entry);
663
return (-1);
664
}
665
}
666
667
if (i == 0 || i > SNMP_INDEXES_MAX) {
668
warnx("Bad number of indexes at line %d", input->lno);
669
snmp_index_listfree(&(entry->index_list));
670
free(entry);
671
return (-1);
672
}
673
674
if (tok != TOK_STR) {
675
warnx("String expected after indexes at line %d", input->lno);
676
snmp_index_listfree(&(entry->index_list));
677
free(entry);
678
return (-1);
679
}
680
681
entry->string = obj->string;
682
entry->strlen = obj->strlen;
683
asn_append_oid(&(entry->var), &(obj->var));
684
685
if ((i = snmp_table_insert(snmptoolctx, entry)) < 0) {
686
snmp_index_listfree(&(entry->index_list));
687
free(entry);
688
return (-1);
689
} else if (i == 0) {
690
/* Same entry already present in lists. */
691
free(entry->string);
692
free(entry);
693
return (0);
694
}
695
696
(void) snmp_import_update_table(ENTRY_INDEX, entry);
697
698
return (1);
699
}
700
701
/*
702
* Read everything after the syntax type that is certainly a leaf OID info.
703
*/
704
static int32_t
705
snmp_import_leaf(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
706
struct snmp_oid2str *oid2str)
707
{
708
int32_t i, syntax;
709
710
if ((syntax = parse_type(snmptoolctx, tok, &(oid2str->tc), &(oid2str->snmp_enum)))
711
< 0)
712
return(-1);
713
714
oid2str->syntax = syntax;
715
/*
716
* That is the name of the function, corresponding to the entry.
717
* It is used by bsnmpd, but is not interesting for us.
718
*/
719
if (*tok == TOK_STR)
720
*tok = gettoken(snmptoolctx);
721
722
for (i = 0; i < SNMP_ACCESS_GETSET && *tok == TOK_ACCESS; i++) {
723
oid2str->access |= (uint32_t) val;
724
*tok = gettoken(snmptoolctx);
725
}
726
727
if (*tok != ')') {
728
warnx("')' expected at end of line %d", input->lno);
729
return (-1);
730
}
731
732
oid2str->table_idx = snmp_import_update_table(ENTRY_DATA, NULL);
733
734
if ((i = snmp_leaf_insert(snmptoolctx, oid2str)) < 0) {
735
warnx("Error adding leaf %s to list", oid2str->string);
736
return (-1);
737
}
738
739
/*
740
* Same entry is already present in the mapping lists and
741
* the new one was not inserted.
742
*/
743
if (i == 0) {
744
free(oid2str->string);
745
free(oid2str);
746
}
747
748
(void) snmp_import_update_table(ENTRY_NONE, NULL);
749
750
return (1);
751
}
752
753
static int32_t
754
snmp_import_object(struct snmp_toolinfo *snmptoolctx)
755
{
756
char *string;
757
int i;
758
int32_t tok;
759
struct snmp_oid2str *oid2str;
760
761
if (snmp_import_head(snmptoolctx) < 0)
762
return (-1);
763
764
if ((oid2str = calloc(1, sizeof(struct snmp_oid2str))) == NULL) {
765
syslog(LOG_ERR, "calloc() failed: %s", strerror(errno));
766
return (-1);
767
}
768
769
if ((string = strdup(nexttok)) == NULL) {
770
syslog(LOG_ERR, "strdup() failed: %s", strerror(errno));
771
free(oid2str);
772
return (-1);
773
}
774
775
oid2str->string = string;
776
oid2str->strlen = strlen(nexttok);
777
778
asn_append_oid(&(oid2str->var), &(current_oid));
779
if (snmp_suboid_append(&(oid2str->var), (asn_subid_t) val) < 0)
780
goto error;
781
782
/*
783
* Prepared the entry - now figure out where to insert it.
784
* After the object we have following options:
785
* 1) new line, blank, ) - then it is an enum oid -> snmp_enumlist;
786
* 2) new line , ( - nonleaf oid -> snmp_nodelist;
787
* 2) ':' - table entry - a variable length SYNTAX_TYPE (one or more)
788
* may follow and second string must end line -> snmp_tablelist;
789
* 3) OID , string ) - this is a trap entry or a leaf -> snmp_oidlist;
790
* 4) SYNTAX_TYPE, string (not always), get/set modifier - always last
791
* and )- this is definitely a leaf.
792
*/
793
794
switch (tok = gettoken(snmptoolctx)) {
795
case ')':
796
if ((i = snmp_enum_insert(snmptoolctx, oid2str)) < 0)
797
goto error;
798
if (i == 0) {
799
free(oid2str->string);
800
free(oid2str);
801
}
802
return (1);
803
804
case '(':
805
if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
806
goto error;
807
808
/*
809
* Ignore the error for nodes since the .def files currently
810
* contain different strings for 1.3.6.1.2.1 - mibII. Only make
811
* sure the memory is freed and don't complain.
812
*/
813
if ((i = snmp_node_insert(snmptoolctx, oid2str)) <= 0) {
814
free(string);
815
free(oid2str);
816
}
817
return (snmp_import_object(snmptoolctx));
818
819
case ':':
820
if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
821
goto error;
822
if (snmp_import_table(snmptoolctx, oid2str) < 0)
823
goto error;
824
/*
825
* A different table entry type was malloced and the data is
826
* contained there.
827
*/
828
free(oid2str);
829
return (1);
830
831
case TOK_TYPE:
832
/* FALLTHROUGH */
833
case TOK_DEFTYPE:
834
/* FALLTHROUGH */
835
case TOK_ENUM:
836
/* FALLTHROUGH */
837
case TOK_BITS:
838
if (snmp_import_leaf(snmptoolctx, &tok, oid2str) < 0)
839
goto error;
840
return (1);
841
842
default:
843
warnx("Unexpected token at line %d - %s", input->lno,
844
input->fname);
845
break;
846
}
847
848
error:
849
snmp_mapping_entryfree(oid2str);
850
851
return (-1);
852
}
853
854
static int32_t
855
snmp_import_tree(struct snmp_toolinfo *snmptoolctx, int32_t *tok)
856
{
857
while (*tok != TOK_EOF) {
858
switch (*tok) {
859
case TOK_ERR:
860
return (-1);
861
case '(':
862
if (snmp_import_object(snmptoolctx) < 0)
863
return (-1);
864
break;
865
case ')':
866
if (snmp_suboid_pop(&current_oid) < 0)
867
return (-1);
868
(void) snmp_import_update_table(ENTRY_NONE, NULL);
869
break;
870
default:
871
/* Anything else here would be illegal. */
872
return (-1);
873
}
874
*tok = gettoken(snmptoolctx);
875
}
876
877
return (0);
878
}
879
880
static int32_t
881
snmp_import_top(struct snmp_toolinfo *snmptoolctx, int32_t *tok)
882
{
883
enum snmp_tc tc;
884
struct enum_type *t;
885
886
if (*tok == '(')
887
return (snmp_import_tree(snmptoolctx, tok));
888
889
if (*tok == TOK_TYPEDEF) {
890
if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
891
warnx("type name expected after typedef - %s",
892
input->fname);
893
return (-1);
894
}
895
896
t = snmp_enumtc_init(nexttok);
897
898
*tok = gettoken(snmptoolctx);
899
t->is_enum = (*tok == TOK_ENUM);
900
t->is_bits = (*tok == TOK_BITS);
901
t->syntax = parse_type(snmptoolctx, tok, &tc, &(t->snmp_enum));
902
snmp_enumtc_insert(snmptoolctx, t);
903
904
return (1);
905
}
906
907
if (*tok == TOK_INCLUDE) {
908
int i;
909
910
*tok = gettoken(snmptoolctx);
911
if (*tok != TOK_FILENAME) {
912
warnx("filename expected in include directive - %s",
913
nexttok);
914
return (-1);
915
}
916
917
if (( i = add_filename(snmptoolctx, nexttok, NULL, 1)) == 0) {
918
*tok = gettoken(snmptoolctx);
919
return (1);
920
}
921
922
if (i == -1)
923
return (-1);
924
925
input_fopen(nexttok);
926
*tok = gettoken(snmptoolctx);
927
return (1);
928
}
929
930
warnx("'(' or 'typedef' expected - %s", nexttok);
931
return (-1);
932
}
933
934
static int32_t
935
snmp_import(struct snmp_toolinfo *snmptoolctx)
936
{
937
int i;
938
int32_t tok;
939
940
tok = gettoken(snmptoolctx);
941
942
do
943
i = snmp_import_top(snmptoolctx, &tok);
944
while (i > 0);
945
946
return (i);
947
}
948
949
/*
950
* Read a .def file and import oid<->string mapping.
951
* Mappings are inserted into a global structure containing list for each OID
952
* syntax type.
953
*/
954
int32_t
955
snmp_import_file(struct snmp_toolinfo *snmptoolctx, struct fname *file)
956
{
957
int idx;
958
959
snmp_import_init(&(file->cut));
960
input_fopen(file->name);
961
if ((idx = snmp_import(snmptoolctx)) < 0)
962
warnx("Failed to read mappings from file %s", file->name);
963
964
input_close();
965
966
return (idx);
967
}
968
969