1 /*
2 * parser-smi.y --
3 *
4 * Syntax rules for parsing the SMIv1/v2 MIB module language.
5 *
6 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
7 *
8 * See the file "COPYING" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 *
11 * @(#) $Id: parser-smi.y 8090 2008-04-18 12:56:29Z strauss $
12 */
13
14 %{
15
16 #include <config.h>
17
18 #ifdef BACKEND_SMI
19
20 #include <stdio.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <time.h>
26 #include <limits.h>
27
28 #if defined(_MSC_VER)
29 #include <malloc.h>
30 #endif
31
32 #include "smi.h"
33 #include "error.h"
34 #include "parser-smi.h"
35 #include "scanner-smi.h"
36 #include "data.h"
37 #include "check.h"
38 #include "util.h"
39
40 #ifdef HAVE_DMALLOC_H
41 #include <dmalloc.h>
42 #endif
43
44
45
46 /*
47 * These arguments are passed to yyparse() and yylex().
48 */
49 #define YYPARSE_PARAM parserPtr
50 #define YYLEX_PARAM parserPtr
51
52
53
54 #define thisParserPtr ((Parser *)parserPtr)
55 #define thisModulePtr (((Parser *)parserPtr)->modulePtr)
56
57
58
59 /*
60 * NOTE: The argument lvalp is not really a void pointer. Unfortunately,
61 * we don't know it better at this point. bison generated C code declares
62 * YYSTYPE just a few lines below based on the `%union' declaration.
63 */
64 extern int yylex(void *lvalp, Parser *parserPtr);
65
66
67
68 static int impliedFlag;
69 static SmiNodekind variationkind;
70 static SmiBasetype defaultBasetype;
71 static int indexFlag;
72
73 /*
74 * Values for the indexFlag variable
75 */
76 #define INDEXFLAG_NONE 0
77 #define INDEXFLAG_PIBINDEX 1
78 #define INDEXFLAG_AUGMENTS 2
79 #define INDEXFLAG_EXTENDS 3
80
81
82 #define SMI_EPOCH 631152000 /* 01 Jan 1990 00:00:00 */
83
84
85
86 static char *convertImportv2[] = {
87 "RFC1155-SMI", "internet", "SNMPv2-SMI", "internet",
88 "RFC1155-SMI", "directory", "SNMPv2-SMI", "directory",
89 "RFC1155-SMI", "mgmt", "SNMPv2-SMI", "mgmt",
90 "RFC1155-SMI", "experimental", "SNMPv2-SMI", "experimental",
91 "RFC1155-SMI", "private", "SNMPv2-SMI", "private",
92 "RFC1155-SMI", "enterprises", "SNMPv2-SMI", "enterprises",
93 "RFC1155-SMI", "IpAddress", "SNMPv2-SMI", "IpAddress",
94 "RFC1155-SMI", "Counter", "SNMPv2-SMI", "Counter32",
95 "RFC1155-SMI", "Gauge", "SNMPv2-SMI", "Gauge32",
96 "RFC1155-SMI", "TimeTicks", "SNMPv2-SMI", "TimeTicks",
97 "RFC1155-SMI", "Opaque", "SNMPv2-SMI", "Opaque",
98 "RFC1065-SMI", "internet", "SNMPv2-SMI", "internet",
99 "RFC1065-SMI", "directory", "SNMPv2-SMI", "directory",
100 "RFC1065-SMI", "mgmt", "SNMPv2-SMI", "mgmt",
101 "RFC1065-SMI", "experimental", "SNMPv2-SMI", "experimental",
102 "RFC1065-SMI", "private", "SNMPv2-SMI", "private",
103 "RFC1065-SMI", "enterprises", "SNMPv2-SMI", "enterprises",
104 "RFC1065-SMI", "IpAddress", "SNMPv2-SMI", "IpAddress",
105 "RFC1065-SMI", "Counter", "SNMPv2-SMI", "Counter32",
106 "RFC1065-SMI", "Gauge", "SNMPv2-SMI", "Gauge32",
107 "RFC1065-SMI", "TimeTicks", "SNMPv2-SMI", "TimeTicks",
108 "RFC1065-SMI", "Opaque", "SNMPv2-SMI", "Opaque",
109 "RFC1213-MIB", "mib-2", "SNMPv2-SMI", "mib-2",
110 "RFC1213-MIB", "DisplayString", "SNMPv2-TC", "DisplayString",
111 NULL, NULL, NULL, NULL
112 };
113
114
115
116 static void
checkDescr(Parser * parser,char * descr)117 checkDescr(Parser *parser, char *descr)
118 {
119 if (descr) {
120 if (descr[0] == 0) {
121 smiPrintError(parser, ERR_EMPTY_DESCRIPTION);
122 }
123 /* we might want to add more checks since I have recently
124 seen things like DESCRIPTION "." to cirumvent warnings */
125 }
126 }
127
128
129
130 static void
checkNameLen(Parser * parser,char * name,int error_32,int error_64)131 checkNameLen(Parser *parser, char *name, int error_32, int error_64)
132 {
133 int len = strlen(name);
134
135 if (len > 64) {
136 smiPrintError(parser, error_64, name);
137 } else if (len > 32) {
138 smiPrintError(parser, error_32, name);
139 }
140 }
141
142
143
144 static void
checkModuleName(Parser * parserPtr,Module * modulePtr)145 checkModuleName(Parser *parserPtr, Module *modulePtr)
146 {
147 static char *mib_ignore[] = {
148 "SNMPv2-SMI", "SNMPv2-TC", "SNMPv2-CONF", NULL
149 };
150
151 static char *pib_ignore[] = {
152 "COPS-PR-SPPI", "COPS-PR-SPPI-TC",
153 "SNMPv2-SMI", "SNMPv2-TC", "SNMPv2-CONF", NULL
154 };
155
156 const char *name = thisModulePtr->export.name;
157 const int len = strlen(name);
158 int i;
159
160 switch (modulePtr->export.language) {
161 case SMI_LANGUAGE_SMIV1:
162 case SMI_LANGUAGE_SMIV2:
163 case SMI_LANGUAGE_SMING:
164 for (i = 0; mib_ignore[i]; i++) {
165 if (strcmp(mib_ignore[i], name) == 0) {
166 return;
167 }
168 }
169 if (len > 3 && (strcmp(name + len - 4, "-MIB") != 0)) {
170 smiPrintError(parserPtr, ERR_MIB_MODULENAME_SUFFIX, name);
171 return;
172 }
173 break;
174 case SMI_LANGUAGE_SPPI:
175 for (i = 0; pib_ignore[i]; i++) {
176 if (strcmp(pib_ignore[i], name) == 0) {
177 return;
178 }
179 }
180 if (len > 3 && (strcmp(name + len - 4, "-PIB") != 0)) {
181 smiPrintError(parserPtr, ERR_PIB_MODULENAME_SUFFIX, name);
182 }
183 break;
184 case SMI_LANGUAGE_UNKNOWN:
185 break;
186 }
187 }
188
189
190
191 static void
checkModuleIdentity(Parser * parserPtr,Module * modulePtr)192 checkModuleIdentity(Parser *parserPtr, Module *modulePtr)
193 {
194 if ((modulePtr->export.language == SMI_LANGUAGE_SMIV2)
195 && (modulePtr->numModuleIdentities < 1)
196 && strcmp(modulePtr->export.name, "SNMPv2-SMI")
197 && strcmp(modulePtr->export.name, "SNMPv2-CONF")
198 && strcmp(modulePtr->export.name, "SNMPv2-TC")
199 && strcmp(modulePtr->export.name, "COPS-PR-SPPI")) {
200 smiPrintError(parserPtr, ERR_NO_MODULE_IDENTITY);
201 }
202 }
203
204
205
206 static void
checkObjects(Parser * parserPtr,Module * modulePtr)207 checkObjects(Parser *parserPtr, Module *modulePtr)
208 {
209 Object *objectPtr;
210 Node *nodePtr;
211 int i;
212 Type *counterTypePtr, *counter32TypePtr, *counter64TypePtr;
213
214 counterTypePtr = findTypeByName("Counter");
215 counter32TypePtr = findTypeByModulenameAndName("SNMPv2-SMI", "Counter32");
216 counter64TypePtr = findTypeByModulenameAndName("SNMPv2-SMI", "Counter64");
217
218 for (objectPtr = modulePtr->firstObjectPtr;
219 objectPtr; objectPtr = objectPtr->nextPtr) {
220
221 Object *parentPtr;
222
223 if ((objectPtr->export.decl != SMI_DECL_UNKNOWN) &&
224 objectPtr->nodePtr->parentPtr &&
225 objectPtr->nodePtr->parentPtr->lastObjectPtr) {
226 parentPtr = objectPtr->nodePtr->parentPtr->lastObjectPtr;
227 } else {
228 parentPtr = NULL;
229 }
230
231 /*
232 * Set nodekinds of all newly defined objects.
233 */
234
235 if (objectPtr->export.decl == SMI_DECL_MODULEIDENTITY) {
236 objectPtr->export.nodekind = SMI_NODEKIND_NODE;
237 } else if ((objectPtr->export.decl == SMI_DECL_VALUEASSIGNMENT) ||
238 (objectPtr->export.decl == SMI_DECL_OBJECTIDENTITY)) {
239 objectPtr->export.nodekind = SMI_NODEKIND_NODE;
240 } else if ((objectPtr->export.decl == SMI_DECL_OBJECTTYPE) &&
241 (objectPtr->typePtr) &&
242 (objectPtr->typePtr->export.decl == SMI_DECL_IMPL_SEQUENCEOF)) {
243 objectPtr->export.nodekind = SMI_NODEKIND_TABLE;
244 } else if ((objectPtr->export.decl == SMI_DECL_OBJECTTYPE) &&
245 (objectPtr->export.indexkind != SMI_INDEX_UNKNOWN)) {
246 objectPtr->export.nodekind = SMI_NODEKIND_ROW;
247 } else if ((objectPtr->export.decl == SMI_DECL_NOTIFICATIONTYPE) ||
248 (objectPtr->export.decl == SMI_DECL_TRAPTYPE)) {
249 objectPtr->export.nodekind = SMI_NODEKIND_NOTIFICATION;
250 } else if ((objectPtr->export.decl == SMI_DECL_OBJECTGROUP) ||
251 (objectPtr->export.decl == SMI_DECL_NOTIFICATIONGROUP)) {
252 objectPtr->export.nodekind = SMI_NODEKIND_GROUP;
253 } else if (objectPtr->export.decl == SMI_DECL_MODULECOMPLIANCE) {
254 objectPtr->export.nodekind = SMI_NODEKIND_COMPLIANCE;
255 } else if (objectPtr->export.decl == SMI_DECL_AGENTCAPABILITIES) {
256 objectPtr->export.nodekind = SMI_NODEKIND_CAPABILITIES;
257 } else if ((objectPtr->export.decl == SMI_DECL_OBJECTTYPE) &&
258 (parentPtr) &&
259 (parentPtr->export.indexkind != SMI_INDEX_UNKNOWN)) {
260 objectPtr->export.nodekind = SMI_NODEKIND_COLUMN;
261 } else if ((objectPtr->export.decl == SMI_DECL_OBJECTTYPE) &&
262 (parentPtr) &&
263 (parentPtr->export.indexkind == SMI_INDEX_UNKNOWN)) {
264 objectPtr->export.nodekind = SMI_NODEKIND_SCALAR;
265 }
266 }
267
268 for (objectPtr = modulePtr->firstObjectPtr;
269 objectPtr; objectPtr = objectPtr->nextPtr) {
270
271 Object *parentPtr;
272
273 if (objectPtr->nodePtr->parentPtr &&
274 objectPtr->nodePtr->parentPtr->lastObjectPtr) {
275 parentPtr = objectPtr->nodePtr->parentPtr->lastObjectPtr;
276 } else {
277 parentPtr = NULL;
278 }
279
280 /*
281 * Check whether the associated type resolves to a known base type.
282 */
283
284 if (objectPtr->typePtr
285 && (objectPtr->export.nodekind == SMI_NODEKIND_COLUMN
286 || objectPtr->export.nodekind == SMI_NODEKIND_SCALAR)
287 && objectPtr->typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
288 smiPrintErrorAtLine(parserPtr, ERR_BASETYPE_UNKNOWN,
289 objectPtr->line,
290 objectPtr->typePtr->export.name ?
291 objectPtr->typePtr->export.name : "[unknown]",
292 objectPtr->export.name);
293 if (objectPtr->nodePtr->parentPtr->firstObjectPtr->export.nodekind
294 == SMI_NODEKIND_TABLE) {
295 /* the parent node is a table node, so assume this is
296 * a row node. this adjusts missing INDEXs in RFC 1158.
297 */
298 objectPtr->export.nodekind = SMI_NODEKIND_ROW;
299 }
300 }
301
302 /*
303 * Mark types that are referenced in this module.
304 */
305
306 if (objectPtr->typePtr
307 && (objectPtr->export.nodekind == SMI_NODEKIND_COLUMN
308 || objectPtr->export.nodekind == SMI_NODEKIND_SCALAR)
309 && (objectPtr->typePtr->export.decl == SMI_DECL_TYPEDEF
310 || objectPtr->typePtr->export.decl == SMI_DECL_TEXTUALCONVENTION
311 || objectPtr->typePtr->export.decl == SMI_DECL_IMPLICIT_TYPE)) {
312 addTypeFlags(objectPtr->typePtr, FLAG_INSYNTAX);
313 if (objectPtr->typePtr->export.decl == SMI_DECL_IMPLICIT_TYPE) {
314 addTypeFlags(objectPtr->typePtr->parentPtr, FLAG_INSYNTAX);
315 }
316 }
317
318 /*
319 * Check whether the status of the associated type matches the
320 * status of the object.
321 */
322
323 if (objectPtr->typePtr
324 && (objectPtr->export.nodekind == SMI_NODEKIND_COLUMN
325 || objectPtr->export.nodekind == SMI_NODEKIND_SCALAR)
326 && (objectPtr->export.status < objectPtr->typePtr->export.status)) {
327 if (objectPtr->typePtr->export.status == SMI_STATUS_DEPRECATED) {
328 smiPrintErrorAtLine(parserPtr, ERR_TYPE_STATUS_DEPRECATED,
329 objectPtr->line,
330 objectPtr->typePtr->export.name,
331 objectPtr->export.name);
332 }
333 if (objectPtr->typePtr->export.status == SMI_STATUS_OBSOLETE) {
334 smiPrintErrorAtLine(parserPtr, ERR_TYPE_STATUS_OBSOLETE,
335 objectPtr->line,
336 objectPtr->typePtr->export.name,
337 objectPtr->export.name);
338 }
339 }
340
341 /*
342 * Check the nodekind of the parent node.
343 */
344
345 if (parentPtr) {
346 switch (objectPtr->export.nodekind) {
347 case SMI_NODEKIND_COLUMN:
348 if (parentPtr->export.nodekind != SMI_NODEKIND_ROW) {
349 smiPrintErrorAtLine(parserPtr, ERR_COLUMN_PARENT_TYPE,
350 objectPtr->line, objectPtr->export.name);
351 }
352 break;
353 case SMI_NODEKIND_ROW:
354 if (parentPtr->export.nodekind != SMI_NODEKIND_TABLE) {
355 smiPrintErrorAtLine(parserPtr, ERR_ROW_PARENT_TYPE,
356 objectPtr->line, objectPtr->export.name);
357 }
358 if (parentPtr->typePtr && parentPtr->typePtr->parentPtr &&
359 strcmp(parentPtr->typePtr->parentPtr->export.name,
360 objectPtr->typePtr->export.name)) {
361 smiPrintErrorAtLine(parserPtr, ERR_TABLE_ROW_TYPE_MISMATCH,
362 objectPtr->line,
363 objectPtr->export.name);
364 }
365 break;
366 case SMI_NODEKIND_TABLE:
367 if ((parentPtr->export.nodekind != SMI_NODEKIND_UNKNOWN) &&
368 (parentPtr->export.nodekind != SMI_NODEKIND_NODE)) {
369 smiPrintErrorAtLine(parserPtr, ERR_TABLE_PARENT_TYPE,
370 objectPtr->line, objectPtr->export.name);
371 }
372 break;
373 case SMI_NODEKIND_SCALAR:
374 if ((parentPtr->export.nodekind != SMI_NODEKIND_UNKNOWN) &&
375 (parentPtr->export.nodekind != SMI_NODEKIND_NODE)) {
376 smiPrintErrorAtLine(parserPtr, ERR_SCALAR_PARENT_TYPE,
377 objectPtr->line, objectPtr->export.name);
378 }
379 break;
380 case SMI_NODEKIND_NOTIFICATION:
381 if ((parentPtr->export.nodekind != SMI_NODEKIND_NODE) &&
382 (parentPtr->export.nodekind != SMI_NODEKIND_UNKNOWN)) {
383 smiPrintErrorAtLine(parserPtr, ERR_NOTIFICATION_PARENT_TYPE,
384 objectPtr->line, objectPtr->export.name);
385 }
386 if (parserPtr && parentPtr->nodePtr->parentPtr &&
387 parentPtr->nodePtr->parentPtr->lastObjectPtr) {
388 Object *parent2Ptr = parentPtr->nodePtr->parentPtr->lastObjectPtr;
389 if ((parent2Ptr->export.nodekind != SMI_NODEKIND_NODE) &&
390 (parent2Ptr->export.nodekind != SMI_NODEKIND_UNKNOWN)) {
391 smiPrintErrorAtLine(parserPtr,
392 ERR_NOTIFICATION_PARENT_TYPE,
393 objectPtr->line,
394 objectPtr->export.name);
395 }
396 }
397 break;
398 case SMI_NODEKIND_NODE:
399 /* Node defined by OBJECT IDENTIFIER assignments can have
400 arbitrary parent node. */
401 if ((parentPtr->export.nodekind != SMI_NODEKIND_UNKNOWN) &&
402 (parentPtr->export.nodekind != SMI_NODEKIND_NODE) &&
403 (objectPtr->export.decl != SMI_DECL_VALUEASSIGNMENT)) {
404 smiPrintErrorAtLine(parserPtr, ERR_NODE_PARENT_TYPE,
405 objectPtr->line, objectPtr->export.name);
406 }
407 break;
408 case SMI_NODEKIND_GROUP:
409 if ((parentPtr->export.nodekind != SMI_NODEKIND_UNKNOWN) &&
410 (parentPtr->export.nodekind != SMI_NODEKIND_NODE)) {
411 smiPrintErrorAtLine(parserPtr, ERR_GROUP_PARENT_TYPE,
412 objectPtr->line, objectPtr->export.name);
413 }
414 break;
415 case SMI_NODEKIND_COMPLIANCE:
416 if ((parentPtr->export.nodekind != SMI_NODEKIND_UNKNOWN) &&
417 (parentPtr->export.nodekind != SMI_NODEKIND_NODE)) {
418 smiPrintErrorAtLine(parserPtr, ERR_COMPLIANCE_PARENT_TYPE,
419 objectPtr->line, objectPtr->export.name);
420 }
421 break;
422 case SMI_NODEKIND_CAPABILITIES:
423 if ((parentPtr->export.nodekind != SMI_NODEKIND_UNKNOWN) &&
424 (parentPtr->export.nodekind != SMI_NODEKIND_NODE)) {
425 smiPrintErrorAtLine(parserPtr, ERR_CAPABILITIES_PARENT_TYPE,
426 objectPtr->line, objectPtr->export.name);
427 }
428 break;
429 }
430 }
431
432 /*
433 * Check whether groups only contain scalars, columns and
434 * notifications.
435 */
436
437 if (objectPtr->export.nodekind == SMI_NODEKIND_GROUP) {
438 smiCheckGroupMembers(parserPtr, objectPtr);
439 }
440
441 /*
442 * Check whether compliance statements contain out of date
443 * groups or objects.
444 */
445
446 if (objectPtr->export.nodekind == SMI_NODEKIND_COMPLIANCE) {
447 smiCheckComplianceStatus(parserPtr, objectPtr);
448 }
449
450 /*
451 * Check whether notification statements contain useful
452 * objects.
453 */
454
455 if (objectPtr->export.nodekind == SMI_NODEKIND_NOTIFICATION) {
456 smiCheckNotificationOid(parserPtr, modulePtr, objectPtr);
457 smiCheckNotificationMembers(parserPtr, objectPtr);
458 }
459
460 if (modulePtr->export.language != SMI_LANGUAGE_SPPI) {
461 /*
462 * Check whether tables and rows are not accessible
463 * (RFC 2578 7.1.12).
464 */
465
466 if (objectPtr->export.nodekind == SMI_NODEKIND_TABLE
467 && objectPtr->export.access != SMI_ACCESS_NOT_ACCESSIBLE) {
468 smiPrintErrorAtLine(parserPtr, ERR_TABLE_ACCESS,
469 objectPtr->line, objectPtr->export.name);
470 }
471
472 if (objectPtr->export.nodekind == SMI_NODEKIND_ROW
473 && objectPtr->export.access != SMI_ACCESS_NOT_ACCESSIBLE) {
474 smiPrintErrorAtLine(parserPtr, ERR_ROW_ACCESS,
475 objectPtr->line, objectPtr->export.name);
476 }
477
478 /*
479 * Check whether counter objects are read-only or
480 * accessible-for-notify (RFC 2578, 7.1.6).
481 */
482 if (((objectPtr->export.nodekind == SMI_NODEKIND_SCALAR) ||
483 (objectPtr->export.nodekind == SMI_NODEKIND_COLUMN)) &&
484 (objectPtr->export.access != SMI_ACCESS_NOTIFY) &&
485 (objectPtr->export.access != SMI_ACCESS_READ_ONLY) &&
486 (smiTypeDerivedFrom(objectPtr->typePtr, counterTypePtr) ||
487 smiTypeDerivedFrom(objectPtr->typePtr, counter32TypePtr) ||
488 smiTypeDerivedFrom(objectPtr->typePtr, counter64TypePtr))) {
489 smiPrintErrorAtLine(parserPtr, ERR_COUNTER_ACCESS,
490 objectPtr->line, objectPtr->export.name);
491 }
492 }
493
494 /*
495 * Check whether a row's subid is 1, see RFC 2578 7.10 (1).
496 */
497
498 if (objectPtr->export.nodekind == SMI_NODEKIND_ROW) {
499 int len;
500
501 if (objectPtr->nodePtr->subid != 1) {
502 smiPrintErrorAtLine(parserPtr, ERR_ROW_SUBID_ONE,
503 objectPtr->line, objectPtr->export.name);
504 }
505
506 len = strlen(objectPtr->export.name);
507 if (len < 6 || strcmp(objectPtr->export.name+len-5, "Entry")) {
508 smiPrintErrorAtLine(parserPtr, ERR_ROWNAME_ENTRY,
509 objectPtr->line, objectPtr->export.name);
510 } else {
511
512 /*
513 * This misreports some cases where the table name
514 * does not have the "*Table" suffix. This is trying
515 * to allow Entry names of either fooTableEntry or
516 * fooEntry.
517 */
518 if (parentPtr &&
519 !(((int)strlen(parentPtr->export.name) == len ||
520 (int)strlen(parentPtr->export.name) == len - 5) &&
521 !strncmp(objectPtr->export.name, parentPtr->export.name,
522 len - 5))) {
523 smiPrintErrorAtLine(parserPtr, ERR_ROWNAME_TABLENAME,
524 objectPtr->line,
525 objectPtr->export.name,
526 parentPtr->export.name);
527 }
528 }
529 }
530
531 /*
532 * Check whether a row's SEQUENCE contains exactly the list
533 * of child nodes (columns). An unknown SEQUENCE type
534 * is handled later.
535 */
536
537 if (objectPtr->export.nodekind == SMI_NODEKIND_ROW &&
538 ((objectPtr->typePtr->flags & FLAG_INCOMPLETE) == 0)) {
539 List *p;
540 Node *seqNodePtr, *childNodePtr;
541 Object *colPtr;
542 int i;
543
544 /*
545 * Walk through the SEQUENCE elements and find those
546 * that are misordered or have no matching columnar object.
547 */
548 for (p = objectPtr->typePtr->listPtr, i = 1,
549 childNodePtr = objectPtr->nodePtr->firstChildPtr;
550 p && childNodePtr;
551 p = p->nextPtr, childNodePtr = childNodePtr->nextPtr, i++) {
552 seqNodePtr = ((Object *)p->ptr)->nodePtr;
553
554 if (seqNodePtr->parentPtr != childNodePtr->parentPtr) {
555 smiPrintErrorAtLine(parserPtr, ERR_SEQUENCE_NO_COLUMN,
556 objectPtr->typePtr->line,
557 i,
558 ((Object *)p->ptr)->export.name,
559 objectPtr->export.name);
560 continue;
561 }
562
563 if (seqNodePtr != childNodePtr) {
564 smiPrintErrorAtLine(parserPtr, ERR_SEQUENCE_ORDER,
565 objectPtr->typePtr->line,
566 i,
567 ((Object *)p->ptr)->export.name,
568 objectPtr->export.name);
569 break;
570 }
571 }
572 if ((p != NULL) && (childNodePtr == NULL)) {
573 smiPrintErrorAtLine(parserPtr, ERR_SEQUENCE_NO_COLUMN,
574 objectPtr->typePtr->line,
575 i,
576 ((Object *)p->ptr)->export.name,
577 objectPtr->export.name);
578 }
579
580 /*
581 * Walk through all child objects and find those
582 * that were missing in the SEQUENCE.
583 */
584 for (childNodePtr = objectPtr->nodePtr->firstChildPtr;
585 childNodePtr; childNodePtr = childNodePtr->nextPtr) {
586 colPtr = findObjectByModuleAndNode(modulePtr, childNodePtr);
587 if (!colPtr) continue;
588 for (p = objectPtr->typePtr->listPtr; p; p = p->nextPtr) {
589 if (((Object *)p->ptr)->nodePtr == colPtr->nodePtr)
590 break;
591 }
592 if (!p) {
593 if (colPtr->export.name) {
594 /*
595 * Don't complain, if it's an implcitly defined
596 * unnamed node (could happen for parent node of
597 * TRAP-TYPE definitions).
598 */
599 smiPrintErrorAtLine(parserPtr,
600 ERR_SEQUENCE_MISSING_COLUMN,
601 objectPtr->typePtr->line,
602 objectPtr->typePtr->export.name,
603 colPtr->export.name);
604 }
605 }
606 }
607
608 }
609
610 if (objectPtr->export.nodekind == SMI_NODEKIND_TABLE) {
611 int len;
612
613 len = strlen(objectPtr->export.name);
614 if (len < 6 || strcmp(objectPtr->export.name+len-5, "Table")) {
615 smiPrintErrorAtLine(parserPtr, ERR_TABLENAME_TABLE,
616 objectPtr->line, objectPtr->export.name);
617 }
618 }
619
620 /*
621 * TODO: check whether the row is the only node below the
622 * table node
623 */
624
625 /*
626 * Check references to unknown identifiers.
627 */
628
629 if ((objectPtr->flags & FLAG_INCOMPLETE) &&
630 (objectPtr->export.decl != SMI_DECL_IMPL_OBJECT)) {
631 if (objectPtr->export.name) {
632 smiPrintErrorAtLine(parserPtr, ERR_UNKNOWN_OIDLABEL,
633 objectPtr->line, objectPtr->export.name);
634 } else {
635 smiPrintErrorAtLine(parserPtr, ERR_IMPLICIT_NODE,
636 objectPtr->line);
637 }
638 }
639
640 /*
641 * Adjust the status of implicit type definitions.
642 */
643
644 if (objectPtr->typePtr
645 && (objectPtr->typePtr->export.decl == SMI_DECL_IMPLICIT_TYPE)
646 && (objectPtr->typePtr->export.status == SMI_STATUS_UNKNOWN)) {
647 objectPtr->typePtr->export.status = objectPtr->export.status;
648 }
649
650 /*
651 * Link implicit type definition from refinements into
652 * the type derivation tree. Adjust the status of implicit
653 * type definitions in refinements.
654 */
655
656 if (objectPtr->export.nodekind == SMI_NODEKIND_COMPLIANCE) {
657
658 List *listPtr;
659
660 for (listPtr = objectPtr->refinementlistPtr;
661 listPtr;
662 listPtr = listPtr->nextPtr) {
663
664 Refinement *refinementPtr;
665 Type *typePtr;
666
667 refinementPtr = ((Refinement *)(listPtr->ptr));
668 typePtr = refinementPtr->typePtr;
669 if (typePtr) {
670 if (typePtr->export.status == SMI_STATUS_UNKNOWN) {
671 typePtr->export.status = objectPtr->export.status;
672 }
673 }
674
675 typePtr = refinementPtr->writetypePtr;
676 if (typePtr) {
677 if (typePtr->export.status == SMI_STATUS_UNKNOWN) {
678 typePtr->export.status = objectPtr->export.status;
679 }
680 }
681
682 }
683 /* relocate the refinement type into the type tree */
684 /* relocate the write refinement type into the type tree */
685 }
686
687 /*
688 * Set the oidlen/oid values that are not yet correct.
689 */
690
691 if (objectPtr->export.oidlen == 0) {
692 if (objectPtr->nodePtr->oidlen == 0) {
693 for (nodePtr = objectPtr->nodePtr, i = 1;
694 nodePtr->parentPtr != thisParserPtr->pendingNodePtr &&
695 nodePtr->parentPtr != smiHandle->rootNodePtr &&
696 nodePtr != nodePtr->parentPtr &&
697 i <= 128;
698 nodePtr = nodePtr->parentPtr, i++);
699 if ((objectPtr->export.name) &&
700 ((i > 128) || (nodePtr == nodePtr->parentPtr))) {
701 smiPrintErrorAtLine(parserPtr, ERR_OID_RECURSIVE,
702 objectPtr->line,
703 objectPtr->export.name);
704 }
705 objectPtr->nodePtr->oid = smiMalloc(i * sizeof(SmiSubid));
706 objectPtr->nodePtr->oidlen = i;
707 for (nodePtr = objectPtr->nodePtr; i > 0; i--) {
708 objectPtr->nodePtr->oid[i-1] = nodePtr->subid;
709 nodePtr = nodePtr->parentPtr;
710 }
711 }
712 objectPtr->export.oidlen = objectPtr->nodePtr->oidlen;
713 objectPtr->export.oid = objectPtr->nodePtr->oid;
714 }
715
716 if ((objectPtr->export.decl != SMI_DECL_UNKNOWN)
717 && (objectPtr->export.nodekind != SMI_NODEKIND_NODE)
718 && objectPtr->export.name
719 && objectPtr->export.oid[objectPtr->export.oidlen-1] == 0
720 && objectPtr->export.oidlen != 2 && objectPtr->export.oid[0] != 0) {
721 smiPrintErrorAtLine(parserPtr, ERR_OID_ADMIN_ZERO,
722 objectPtr->line,
723 objectPtr->export.name);
724 }
725
726 /*
727 * Check whether the module identity is registered in a well
728 * known controlled location.
729 */
730
731 if (objectPtr->export.decl == SMI_DECL_MODULEIDENTITY) {
732 smiCheckModuleIdentityRegistration(parserPtr, objectPtr);
733 }
734
735 /*
736 * Check table linkage constraints for row objects.
737 */
738
739 if (objectPtr->export.nodekind == SMI_NODEKIND_ROW) {
740 switch (objectPtr->export.indexkind) {
741 case SMI_INDEX_INDEX:
742 smiCheckIndex(parserPtr, objectPtr);
743 break;
744 case SMI_INDEX_AUGMENT:
745 case SMI_INDEX_SPARSE:
746 smiCheckAugment(parserPtr, objectPtr);
747 break;
748 default:
749 break;
750 }
751 }
752
753 /*
754 * Determine the longest common OID prefix of all nodes.
755 */
756
757 if (!modulePtr->prefixNodePtr) {
758 modulePtr->prefixNodePtr = objectPtr->nodePtr;
759 } else {
760 if (objectPtr->nodePtr->oidlen < modulePtr->prefixNodePtr->oidlen) {
761 Node *nodePtr = findNodeByOid(objectPtr->nodePtr->oidlen,
762 modulePtr->prefixNodePtr->oid);
763 if (nodePtr)
764 modulePtr->prefixNodePtr = nodePtr;
765 else
766 smiPrintError(parserPtr, ERR_OTHER_ERROR,
767 "Failed to create complete object tree - "
768 "expect incorrect output");
769 }
770 for (i = 0; i < modulePtr->prefixNodePtr->oidlen; i++) {
771 if (modulePtr->prefixNodePtr->oid[i] !=
772 objectPtr->nodePtr->oid[i]) {
773 modulePtr->prefixNodePtr =
774 findNodeByOid(i, modulePtr->prefixNodePtr->oid);
775 break;
776 }
777 }
778 }
779 }
780
781 if (modulePtr->export.language == SMI_LANGUAGE_SMIV2) {
782 for (objectPtr = modulePtr->firstObjectPtr;
783 objectPtr; objectPtr = objectPtr->nextPtr) {
784
785 /*
786 * Check whether all objects and notifications are contained in at
787 * least one conformance group (RFC 2580 3.3 and 4.1).
788 */
789
790 smiCheckGroupMembership(parserPtr, objectPtr);
791 }
792 }
793
794 if (modulePtr->export.language == SMI_LANGUAGE_SPPI) {
795 Object *parentPtr;
796
797 for (objectPtr = modulePtr->firstObjectPtr;
798 objectPtr; objectPtr = objectPtr->nextPtr) {
799 /*
800 * All checks for SPPI constructs
801 */
802 if (objectPtr->nodePtr->parentPtr)
803 parentPtr = objectPtr->nodePtr->parentPtr->lastObjectPtr;
804 else
805 parentPtr = NULL;
806
807 /*
808 * Do all rows contain a PIB-INDEX/AUGMENTS/EXTENDS ?
809 * See RFC 3159 7.5, 7.7, 7.8
810 */
811 if (parentPtr &&
812 (parentPtr->export.nodekind == SMI_NODEKIND_TABLE) &&
813 (objectPtr->export.indexkind != SMI_INDEX_INDEX) &&
814 (objectPtr->export.indexkind != SMI_INDEX_AUGMENT) &&
815 (objectPtr->export.indexkind != SMI_INDEX_SPARSE))
816 smiPrintErrorAtLine(parserPtr, ERR_ROW_LACKS_PIB_INDEX,
817 objectPtr->line);
818
819 /*
820 * Does any non row contain a PIB-INDEX/AUGMENTS/EXTENDS ?
821 * See RFC 3159 7.5, 7.7, 7.8
822 */
823 if ((objectPtr->export.nodekind != SMI_NODEKIND_ROW) &&
824 (objectPtr->export.indexkind != SMI_INDEX_UNKNOWN))
825 smiPrintErrorAtLine(parserPtr, ERR_PIB_INDEX_FOR_NON_ROW_TYPE,
826 objectPtr->line);
827
828 /*
829 * Check the PIB-INDEX and other indices
830 */
831 if ((objectPtr->export.nodekind == SMI_NODEKIND_ROW) &&
832 (objectPtr->export.indexkind == SMI_INDEX_INDEX)) {
833
834 /*
835 * Only the first element (PIB-INDEX) has to be an InstanceId.
836 * See RFC 3159 7.5
837 */
838 if (objectPtr->listPtr && objectPtr->listPtr->ptr) {
839 Object *pibindex = (Object *)objectPtr->listPtr->ptr;
840 if (pibindex->typePtr && pibindex->typePtr->export.name &&
841 strcmp(pibindex->typePtr->export.name, "InstanceId"))
842 smiPrintErrorAtLine(thisParserPtr, ERR_PIB_INDEX_NOT_INSTANCEID,
843 pibindex->line, pibindex->export.name);
844 }
845 }
846
847 /*
848 * Do all tables contain a PIB-ACCESS clause?
849 * See RFC 3159 7.3
850 */
851 if ((objectPtr->export.nodekind == SMI_NODEKIND_TABLE) &&
852 (objectPtr->export.access == SMI_ACCESS_UNKNOWN))
853 smiPrintErrorAtLine(parserPtr, ERR_TABLE_LACKS_PIB_ACCESS,
854 objectPtr->line);
855
856 /*
857 * Does any non table types contain a PIB-ACCESS clause?
858 * See RFC 3159 7.3
859 */
860 if (((objectPtr->export.nodekind == SMI_NODEKIND_NODE) ||
861 (objectPtr->export.nodekind == SMI_NODEKIND_ROW) ||
862 (objectPtr->export.nodekind == SMI_NODEKIND_SCALAR)) &&
863 (objectPtr->export.access != SMI_ACCESS_UNKNOWN))
864 smiPrintErrorAtLine(parserPtr, ERR_PIB_ACCESS_FOR_NON_TABLE,
865 objectPtr->line);
866
867 /*
868 * Check the UNIQUENESS clause and its entries
869 * See RFC 3159 7.9
870 */
871 if (objectPtr->uniquenessPtr) {
872 if (objectPtr->export.nodekind != SMI_NODEKIND_ROW)
873 smiPrintErrorAtLine(parserPtr, ERR_UNIQUENESS_FOR_NON_ROW,
874 objectPtr->line);
875 else
876 smiCheckUniqueness(parserPtr, objectPtr);
877 }
878
879 /*
880 * Does the PIB-REFERENCES object point to a PRC (table)?
881 * See RFC 3159 7.10
882 */
883 if (objectPtr->typePtr && objectPtr->typePtr->export.name &&
884 !strcmp(objectPtr->typePtr->export.name, "ReferenceId") &&
885 objectPtr->relatedPtr &&
886 (objectPtr->relatedPtr->export.nodekind != SMI_NODEKIND_ROW))
887 smiPrintErrorAtLine(parserPtr, ERR_PIB_REFERENCES_NOT_ROW,
888 objectPtr->line);
889
890 /*
891 * Do all PIB-TAGs point to objects with a SYNTAX of TagId?
892 * See RFC 3159 7.12
893 */
894 if (objectPtr->typePtr && objectPtr->typePtr->export.name &&
895 !strcmp(objectPtr->typePtr->export.name, "TagReferenceId") &&
896 objectPtr->relatedPtr && objectPtr->relatedPtr->typePtr &&
897 objectPtr->relatedPtr->typePtr->export.name &&
898 strcmp(objectPtr->relatedPtr->typePtr->export.name, "TagId"))
899 smiPrintErrorAtLine(parserPtr, ERR_PIB_TAG_TYPE, objectPtr->line);
900
901 /*
902 * Is the attribute member of at least one compliance group?
903 * See RFC 3159 9.1
904 */
905 if (objectPtr->export.nodekind & SMI_NODEKIND_COLUMN) {
906 Object *group;
907 int found = 0;
908
909 for (group = modulePtr->firstObjectPtr; group;
910 group = group->nextPtr) {
911 if ((group->export.nodekind == SMI_NODEKIND_GROUP) &&
912 group->listPtr) {
913 List *l;
914
915 for (l = group->listPtr; l; l = l->nextPtr)
916 if (((Object *)l->ptr)->export.name &&
917 !strcmp(((Object *)l->ptr)->export.name,
918 objectPtr->export.name)) {
919 found = 1;
920 break;
921 }
922 }
923 if (found)
924 break;
925 }
926 if (!found)
927 smiPrintErrorAtLine(parserPtr, ERR_ATTRIBUTE_NOT_IN_GROUP,
928 objectPtr->line, objectPtr->export.name);
929 }
930 }
931 }
932 }
933
934
935
936 static void
checkTypes(Parser * parserPtr,Module * modulePtr)937 checkTypes(Parser *parserPtr, Module *modulePtr)
938 {
939 Type *typePtr;
940
941 for (typePtr = modulePtr->firstTypePtr;
942 typePtr; typePtr = typePtr->nextPtr) {
943
944 /*
945 * Check references to unknown types.
946 */
947
948 if ((typePtr->flags & FLAG_INCOMPLETE)
949 && typePtr->export.name
950 && (typePtr->export.decl == SMI_DECL_UNKNOWN)) {
951 smiPrintErrorAtLine(parserPtr, ERR_UNKNOWN_TYPE,
952 typePtr->line, typePtr->export.name);
953 }
954
955 /*
956 * Use TCs instead of type assignments in SMIv2.
957 */
958
959 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2
960 && typePtr->export.decl == SMI_DECL_TYPEASSIGNMENT
961 && typePtr->export.basetype != SMI_BASETYPE_UNKNOWN
962 && strcmp(thisModulePtr->export.name, "SNMPv2-SMI")) {
963 smiPrintErrorAtLine(parserPtr, ERR_SMIV2_TYPE_ASSIGNEMENT,
964 typePtr->line, typePtr->export.name);
965 }
966
967 /*
968 * Check whether we have types that are not used in this
969 * module.
970 */
971
972 if ((typePtr->export.decl == SMI_DECL_TYPEDEF
973 || typePtr->export.decl == SMI_DECL_TEXTUALCONVENTION)
974 && ! (typePtr->flags & FLAG_INSYNTAX)) {
975 static char *status[] = { "Unknown", "current", "deprecated",
976 "mandatory", "optional", "obsolete" };
977 smiPrintErrorAtLine(parserPtr, ERR_TYPE_UNREF,
978 typePtr->line,
979 status[typePtr->export.status],
980 typePtr->export.name);
981 }
982
983 /*
984 * Complain about TCs derived from other TCs (RFC 2579 3.5).
985 */
986
987 if (typePtr->parentPtr
988 && typePtr->export.decl == SMI_DECL_TEXTUALCONVENTION
989 && typePtr->export.decl == typePtr->parentPtr->export.decl) {
990 smiPrintErrorAtLine(parserPtr, ERR_SMIV2_NESTED_TEXTUAL_CONVENTION,
991 typePtr->line,
992 typePtr->export.name,
993 typePtr->parentPtr->export.name);
994
995 if (typePtr->export.status < typePtr->parentPtr->export.status) {
996 if (typePtr->parentPtr->export.status == SMI_STATUS_DEPRECATED) {
997 smiPrintErrorAtLine(parserPtr, ERR_TYPE_STATUS_DEPRECATED,
998 typePtr->line,
999 typePtr->parentPtr->export.name,
1000 typePtr->export.name);
1001 }
1002 if (typePtr->parentPtr->export.status == SMI_STATUS_OBSOLETE) {
1003 smiPrintErrorAtLine(parserPtr, ERR_TYPE_STATUS_OBSOLETE,
1004 typePtr->line,
1005 typePtr->parentPtr->export.name,
1006 typePtr->export.name);
1007 }
1008 }
1009 }
1010
1011 smiCheckTypeFormat(parserPtr, typePtr);
1012 smiCheckNamedNumberRedefinition(parserPtr, typePtr);
1013 smiCheckNamedNumberSubtyping(parserPtr, typePtr);
1014 }
1015 }
1016
1017
1018
1019 static void
adjustDefval(Parser * parserPtr,SmiValue * valuePtr,Type * typePtr,int line)1020 adjustDefval(Parser *parserPtr, SmiValue *valuePtr, Type *typePtr, int line)
1021 {
1022 Object *object2Ptr;
1023 List *bitsListPtr, *valueListPtr, *p, *pp, *nextPtr, *listPtr;
1024 Import *importPtr;
1025 int nBits, bit;
1026
1027 if (valuePtr->basetype == SMI_BASETYPE_UNKNOWN)
1028 return;
1029
1030 if (valuePtr->basetype == SMI_BASETYPE_OBJECTIDENTIFIER) {
1031 /* a len of -1 indicates an unresolved label in ptr */
1032 if (valuePtr->len == -1) {
1033 object2Ptr = findObjectByModuleAndName(parserPtr->modulePtr,
1034 (char *)valuePtr->value.ptr);
1035 if (!object2Ptr) {
1036 importPtr = findImportByName(
1037 (char *)valuePtr->value.ptr, parserPtr->modulePtr);
1038 if (importPtr) { /* imported object */
1039 importPtr->use++;
1040 object2Ptr = findObjectByModulenameAndName(
1041 importPtr->export.module,
1042 importPtr->export.name);
1043 }
1044 }
1045 if (!object2Ptr) {
1046 smiPrintErrorAtLine(parserPtr, ERR_UNKNOWN_OIDLABEL,
1047 line,
1048 (char *)valuePtr->value.ptr);
1049 smiFree(valuePtr->value.ptr);
1050 valuePtr->value.ptr = NULL;
1051 valuePtr->basetype = SMI_BASETYPE_UNKNOWN;
1052 } else {
1053 smiFree(valuePtr->value.ptr);
1054 valuePtr->len = object2Ptr->export.oidlen;
1055 valuePtr->value.ptr = smiMalloc(object2Ptr->export.oidlen *
1056 sizeof(SmiSubid));
1057 memcpy(valuePtr->value.ptr,
1058 object2Ptr->export.oid,
1059 object2Ptr->export.oidlen * sizeof(SmiSubid));
1060 }
1061 }
1062 } else if (valuePtr->basetype == SMI_BASETYPE_BITS) {
1063 bitsListPtr = typePtr->listPtr;
1064 valueListPtr = (void *)valuePtr->value.ptr;
1065 for (nBits = 0, p = bitsListPtr; p; p = p->nextPtr) {
1066 if (nBits < 1+((NamedNumber *)(p->ptr))->export.value.value.integer32) {
1067 nBits = 1+((NamedNumber *)(p->ptr))->export.value.value.integer32;
1068 }
1069 }
1070 valuePtr->value.ptr = smiMalloc((nBits+7)/8);
1071 memset(valuePtr->value.ptr, 0, (nBits+7)/8);
1072 valuePtr->len = (nBits+7)/8;
1073 for (p = valueListPtr; p;) {
1074 for (pp = bitsListPtr; pp; pp = pp->nextPtr) {
1075 if (!strcmp(p->ptr,
1076 ((NamedNumber *)(pp->ptr))->export.name)) {
1077 bit = ((NamedNumber *)(pp->ptr))->export.value.value.integer32;
1078 valuePtr->value.ptr[bit/8] |=
1079 1 << (7-(bit%8));
1080 }
1081 }
1082 smiFree(p->ptr);
1083 nextPtr = p->nextPtr;
1084 smiFree(p);
1085 p = nextPtr;
1086 }
1087 } else if (valuePtr->basetype == SMI_BASETYPE_ENUM) {
1088 /* a len of -1 indicates an unresolved enum label in ptr */
1089 if (valuePtr->len == -1) {
1090 for (listPtr = typePtr->listPtr; listPtr;
1091 listPtr = listPtr->nextPtr) {
1092 if (!strcmp(((NamedNumber *)(listPtr->ptr))->export.name,
1093 (char *)valuePtr->value.ptr)) {
1094 smiFree(valuePtr->value.ptr);
1095 valuePtr->value.integer32 =
1096 ((NamedNumber *)(listPtr->ptr))->
1097 export.value.value.integer32;
1098 valuePtr->len = 1;
1099 break;
1100 }
1101 }
1102 }
1103 }
1104 }
1105
1106
1107
1108 static void
checkDefvals(Parser * parserPtr,Module * modulePtr)1109 checkDefvals(Parser *parserPtr, Module *modulePtr)
1110 {
1111 Object *objectPtr;
1112
1113 /*
1114 * Check unknown identifiers in OID DEFVALs.
1115 */
1116
1117 for(objectPtr = modulePtr->firstObjectPtr;
1118 objectPtr; objectPtr = objectPtr->nextPtr) {
1119
1120 adjustDefval(parserPtr, &objectPtr->export.value,
1121 objectPtr->typePtr, objectPtr->line);
1122
1123 if (objectPtr->export.value.len == -1) {
1124 smiPrintErrorAtLine(parserPtr,
1125 ERR_DEFVAL_SYNTAX, objectPtr->line);
1126 }
1127
1128 smiCheckDefault(parserPtr, objectPtr);
1129 }
1130 }
1131
1132
1133
1134 static void
checkImportsUsage(Parser * parserPtr,Module * modulePtr)1135 checkImportsUsage(Parser *parserPtr, Module *modulePtr)
1136 {
1137 Import *importPtr;
1138
1139 /*
1140 * Check usage of all imported identifiers.
1141 */
1142
1143 if (strcmp(modulePtr->export.name, "SNMPv2-TC") &&
1144 strcmp(modulePtr->export.name, "SNMPv2-CONF") &&
1145 strcmp(modulePtr->export.name, "RFC-1212") &&
1146 strcmp(modulePtr->export.name, "RFC-1215")) {
1147 for(importPtr = modulePtr->firstImportPtr;
1148 importPtr; importPtr = importPtr->nextPtr) {
1149 if (! strcmp(importPtr->export.module, "SNMPv2-SMI")) {
1150 if (! strcmp(importPtr->export.name, "ExtUTCTime")
1151 || !strcmp(importPtr->export.name, "ObjectName")
1152 || !strcmp(importPtr->export.name, "NotificationName")) {
1153 smiPrintErrorAtLine(parserPtr, ERR_ILLEGAL_IMPORT,
1154 importPtr->line,
1155 importPtr->export.name,
1156 importPtr->export.module);
1157 }
1158 }
1159 /* checkImports() handles KIND_NOTFOUND */
1160 if (importPtr->use == 0 && importPtr->kind != KIND_NOTFOUND) {
1161 smiPrintErrorAtLine(parserPtr, ERR_UNUSED_IMPORT,
1162 importPtr->line,
1163 importPtr->export.name,
1164 importPtr->export.module);
1165 }
1166
1167 if (modulePtr->export.language == SMI_LANGUAGE_SMIV2) {
1168 int j;
1169 for (j = 0; convertImportv2[j]; j += 4) {
1170 if ((strcmp(convertImportv2[j],
1171 importPtr->export.module) == 0)
1172 && (strcmp(convertImportv2[j+1],
1173 importPtr->export.name) == 0)) {
1174 smiPrintErrorAtLine(parserPtr,
1175 ERR_OBSOLETE_IMPORT,
1176 importPtr->line,
1177 importPtr->export.name,
1178 convertImportv2[j+2],
1179 importPtr->export.module);
1180 }
1181 }
1182 }
1183 }
1184 }
1185 }
1186
1187
1188
1189 static time_t
checkDate(Parser * parserPtr,char * date)1190 checkDate(Parser *parserPtr, char *date)
1191 {
1192 struct tm tm;
1193 time_t anytime;
1194 int i, len;
1195 char *p;
1196
1197 memset(&tm, 0, sizeof(tm));
1198 anytime = 0;
1199
1200 len = strlen(date);
1201 if (len == 11 || len == 13) {
1202 for (i = 0; i < len; i++) {
1203 if ( (i < len-1 && ! isdigit((int) date[i]))
1204 || (i == len-1 && date[len-1] != 'Z')) {
1205 smiPrintError(parserPtr, ERR_DATE_CHARACTER, date);
1206 anytime = (time_t) -1;
1207 break;
1208 }
1209 }
1210 } else {
1211 smiPrintError(parserPtr, ERR_DATE_LENGTH, date);
1212 anytime = (time_t) -1;
1213 }
1214
1215 if (anytime == 0) {
1216 for (i = 0, p = date, tm.tm_year = 0;
1217 i < ((len == 11) ? 2 : 4); i++, p++) {
1218 tm.tm_year = tm.tm_year * 10 + (*p - '0');
1219 }
1220 if (len == 11) {
1221 tm.tm_year += 1900;
1222 if (tm.tm_year < 1990)
1223 smiPrintError(parserPtr, ERR_DATE_YEAR_2DIGITS,
1224 date, tm.tm_year);
1225 }
1226 tm.tm_mon = (p[0]-'0') * 10 + (p[1]-'0');
1227 p += 2;
1228 tm.tm_mday = (p[0]-'0') * 10 + (p[1]-'0');
1229 p += 2;
1230 tm.tm_hour = (p[0]-'0') * 10 + (p[1]-'0');
1231 p += 2;
1232 tm.tm_min = (p[0]-'0') * 10 + (p[1]-'0');
1233
1234 if (tm.tm_mon < 1 || tm.tm_mon > 12) {
1235 smiPrintError(parserPtr, ERR_DATE_MONTH, date);
1236 }
1237 if (tm.tm_mday < 1 || tm.tm_mday > 31) {
1238 smiPrintError(parserPtr, ERR_DATE_DAY, date);
1239 }
1240 if (tm.tm_hour < 0 || tm.tm_hour > 23) {
1241 smiPrintError(parserPtr, ERR_DATE_HOUR, date);
1242 }
1243 if (tm.tm_min < 0 || tm.tm_min > 59) {
1244 smiPrintError(parserPtr, ERR_DATE_MINUTES, date);
1245 }
1246
1247 tm.tm_year -= 1900;
1248 tm.tm_mon -= 1;
1249 tm.tm_isdst = 0;
1250
1251 anytime = timegm(&tm);
1252
1253 if (anytime == (time_t) -1) {
1254 smiPrintError(parserPtr, ERR_DATE_VALUE, date);
1255 } else {
1256 if (anytime < SMI_EPOCH) {
1257 smiPrintError(parserPtr, ERR_DATE_IN_PAST, date);
1258 }
1259 if (anytime > time(NULL)) {
1260 smiPrintError(parserPtr, ERR_DATE_IN_FUTURE, date);
1261 }
1262 }
1263 }
1264
1265 return (anytime == (time_t) -1) ? 0 : anytime;
1266 }
1267
1268 %}
1269
1270 /*
1271 * The grammars start symbol.
1272 */
1273 %start mibFile
1274
1275
1276
1277 /*
1278 * We call the parser from within the parser when IMPORTing modules,
1279 * hence we need reentrant parser code. This is a bison feature.
1280 */
1281 %pure_parser
1282
1283
1284
1285 /*
1286 * The attributes.
1287 */
1288 %union {
1289 char *text; /* scanned quoted text */
1290 char *id; /* identifier name */
1291 int err; /* actually just a dummy */
1292 time_t date; /* a date value */
1293 Object *objectPtr; /* object identifier */
1294 SmiStatus status; /* a STATUS value */
1295 SmiAccess access; /* an ACCESS value */
1296 Type *typePtr;
1297 List *listPtr; /* SEQUENCE and INDEX lists */
1298 NamedNumber *namedNumberPtr; /* BITS or enum item */
1299 Range *rangePtr; /* type restricting range */
1300 SmiValue *valuePtr;
1301 SmiUnsigned32 unsigned32; /* */
1302 SmiInteger32 integer32; /* */
1303 SmiUnsigned64 unsigned64; /* */
1304 SmiInteger64 integer64; /* */
1305 struct Compl compl;
1306 struct Index index;
1307 Module *modulePtr;
1308 SubjectCategories *subjectCategoriesPtr;
1309 }
1310
1311
1312
1313 /*
1314 * Tokens and their attributes.
1315 */
1316 %token DOT_DOT
1317 %token COLON_COLON_EQUAL
1318
1319 %token <id>UPPERCASE_IDENTIFIER
1320 %token <id>LOWERCASE_IDENTIFIER
1321 %token <unsigned32>NUMBER
1322 %token <integer32>NEGATIVENUMBER
1323 %token <unsigned64>NUMBER64
1324 %token <integer64>NEGATIVENUMBER64
1325 %token <text>BIN_STRING
1326 %token <text>HEX_STRING
1327 %token <text>QUOTED_STRING
1328
1329 %token <id>ACCESS
1330 %token <id>AGENT_CAPABILITIES
1331 %token <id>APPLICATION
1332 %token <id>AUGMENTS
1333 %token <id>BEGIN_
1334 %token <id>BITS
1335 %token <id>CHOICE
1336 %token <id>CONTACT_INFO
1337 %token <id>CREATION_REQUIRES
1338 %token <id>COUNTER32
1339 %token <id>COUNTER64
1340 %token <id>DEFINITIONS
1341 %token <id>DEFVAL
1342 %token <id>DESCRIPTION
1343 %token <id>DISPLAY_HINT
1344 %token <id>END
1345 %token <id>ENTERPRISE
1346 %token <id>EXPORTS
1347 %token <id>EXTENDS
1348 %token <id>FROM
1349 %token <id>GROUP
1350 %token <id>GAUGE32
1351 %token <id>IDENTIFIER
1352 %token <id>IMPLICIT
1353 %token <id>IMPLIED
1354 %token <id>IMPORTS
1355 %token <id>INCLUDES
1356 %token <id>INDEX
1357 %token <id>INSTALL_ERRORS
1358 %token <id>INTEGER
1359 %token <id>INTEGER32
1360 %token <id>INTEGER64
1361 %token <id>IPADDRESS
1362 %token <id>LAST_UPDATED
1363 %token <id>MACRO
1364 %token <id>MANDATORY_GROUPS
1365 %token <id>MAX_ACCESS
1366 %token <id>MIN_ACCESS
1367 %token <id>MODULE
1368 %token <id>MODULE_COMPLIANCE
1369 %token <id>MODULE_IDENTITY
1370 %token <id>NOT_ACCESSIBLE
1371 %token <id>NOTIFICATIONS
1372 %token <id>NOTIFICATION_GROUP
1373 %token <id>NOTIFICATION_TYPE
1374 %token <id>OBJECT
1375 %token <id>OBJECT_GROUP
1376 %token <id>OBJECT_IDENTITY
1377 %token <id>OBJECT_TYPE
1378 %token <id>OBJECTS
1379 %token <id>OCTET
1380 %token <id>OF
1381 %token <id>ORGANIZATION
1382 %token <id>OPAQUE
1383 %token <id>PIB_ACCESS
1384 %token <id>PIB_DEFINITIONS
1385 %token <id>PIB_INDEX
1386 %token <id>PIB_MIN_ACCESS
1387 %token <id>PIB_REFERENCES
1388 %token <id>PIB_TAG
1389 %token <id>POLICY_ACCESS
1390 %token <id>PRODUCT_RELEASE
1391 %token <id>REFERENCE
1392 %token <id>REVISION
1393 %token <id>SEQUENCE
1394 %token <id>SIZE
1395 %token <id>STATUS
1396 %token <id>STRING
1397 %token <id>SUBJECT_CATEGORIES
1398 %token <id>SUPPORTS
1399 %token <id>SYNTAX
1400 %token <id>TEXTUAL_CONVENTION
1401 %token <id>TIMETICKS
1402 %token <id>TRAP_TYPE
1403 %token <id>UNIQUENESS
1404 %token <id>UNITS
1405 %token <id>UNIVERSAL
1406 %token <id>UNSIGNED32
1407 %token <id>UNSIGNED64
1408 %token <id>VALUE
1409 %token <id>VARIABLES
1410 %token <id>VARIATION
1411 %token <id>WRITE_SYNTAX
1412
1413
1414
1415 /*
1416 * Types of non-terminal symbols.
1417 */
1418 %type <err>mibFile
1419 %type <err>modules
1420 %type <err>module
1421 %type <err>moduleOid
1422 %type <id>moduleName
1423 %type <id>importIdentifier
1424 %type <err>importIdentifiers
1425 %type <id>importedKeyword
1426 %type <id>importedSMIKeyword
1427 %type <id>importedSPPIKeyword
1428 %type <err>linkagePart
1429 %type <err>linkageClause
1430 %type <err>importPart
1431 %type <err>imports
1432 %type <err>declarationPart
1433 %type <err>declarations
1434 %type <err>declaration
1435 %type <err>exportsClause
1436 %type <err>macroClause
1437 %type <id>macroName
1438 %type <typePtr>choiceClause
1439 %type <id>typeName
1440 %type <id>typeSMI
1441 %type <id>typeSMIonly
1442 %type <id>typeSMIandSPPI
1443 %type <id>typeSPPIonly
1444 %type <err>typeTag
1445 %type <id>fuzzy_lowercase_identifier
1446 %type <err>valueDeclaration
1447 %type <typePtr>conceptualTable
1448 %type <typePtr>row
1449 %type <typePtr>entryType
1450 %type <listPtr>sequenceItems
1451 %type <objectPtr>sequenceItem
1452 %type <typePtr>Syntax
1453 %type <typePtr>sequenceSyntax
1454 %type <listPtr>NamedBits
1455 %type <namedNumberPtr>NamedBit
1456 %type <err>objectIdentityClause
1457 %type <err>objectTypeClause
1458 %type <err>trapTypeClause
1459 %type <text>descriptionClause
1460 %type <listPtr>VarPart
1461 %type <listPtr>VarTypes
1462 %type <objectPtr>VarType
1463 %type <text>DescrPart
1464 %type <access>MaxAccessPart
1465 %type <access>MaxOrPIBAccessPart
1466 %type <access>PibAccessPart
1467 %type <err>notificationTypeClause
1468 %type <err>moduleIdentityClause
1469 %type <err>typeDeclaration
1470 %type <typePtr>typeDeclarationRHS
1471 %type <typePtr>ObjectSyntax
1472 %type <typePtr>sequenceObjectSyntax
1473 %type <valuePtr>valueofObjectSyntax
1474 %type <typePtr>SimpleSyntax
1475 %type <valuePtr>valueofSimpleSyntax
1476 %type <typePtr>sequenceSimpleSyntax
1477 %type <typePtr>ApplicationSyntax
1478 %type <typePtr>sequenceApplicationSyntax
1479 %type <listPtr>anySubType
1480 %type <listPtr>integerSubType
1481 %type <listPtr>octetStringSubType
1482 %type <listPtr>ranges
1483 %type <rangePtr>range
1484 %type <valuePtr>value
1485 %type <listPtr>enumSpec
1486 %type <listPtr>enumItems
1487 %type <namedNumberPtr>enumItem
1488 %type <valuePtr>enumNumber
1489 %type <status>Status
1490 %type <status>Status_Capabilities
1491 %type <text>DisplayPart
1492 %type <text>UnitsPart
1493 %type <access>Access
1494 %type <index>IndexPart
1495 %type <index>MibIndex
1496 %type <listPtr>IndexTypes
1497 %type <objectPtr>IndexType
1498 %type <objectPtr>Index
1499 %type <objectPtr>Entry
1500 %type <valuePtr>DefValPart
1501 %type <valuePtr>Value
1502 %type <listPtr>BitsValue
1503 %type <listPtr>BitNames
1504 %type <objectPtr>ObjectName
1505 %type <objectPtr>NotificationName
1506 %type <text>ReferPart
1507 %type <err>RevisionPart
1508 %type <err>Revisions
1509 %type <err>Revision
1510 %type <listPtr>NotificationObjectsPart
1511 %type <listPtr>ObjectGroupObjectsPart
1512 %type <listPtr>Objects
1513 %type <objectPtr>Object
1514 %type <listPtr>NotificationsPart
1515 %type <listPtr>Notifications
1516 %type <objectPtr>Notification
1517 %type <text>Text
1518 %type <date>ExtUTCTime
1519 %type <objectPtr>objectIdentifier
1520 %type <objectPtr>subidentifiers
1521 %type <objectPtr>subidentifier
1522 %type <text>objectIdentifier_defval
1523 %type <err>subidentifiers_defval
1524 %type <err>subidentifier_defval
1525 %type <err>objectGroupClause
1526 %type <err>notificationGroupClause
1527 %type <err>moduleComplianceClause
1528 %type <compl>ComplianceModulePart
1529 %type <compl>ComplianceModules
1530 %type <compl>ComplianceModule
1531 %type <modulePtr>ComplianceModuleName
1532 %type <listPtr>MandatoryPart
1533 %type <listPtr>MandatoryGroups
1534 %type <objectPtr>MandatoryGroup
1535 %type <compl>CompliancePart
1536 %type <compl>Compliances
1537 %type <compl>Compliance
1538 %type <listPtr>ComplianceGroup
1539 %type <listPtr>ComplianceObject
1540 %type <typePtr>SyntaxPart
1541 %type <typePtr>WriteSyntaxPart
1542 %type <typePtr>WriteSyntax
1543 %type <access>AccessPart
1544 %type <err>agentCapabilitiesClause
1545 %type <err>ModulePart_Capabilities
1546 %type <err>Modules_Capabilities
1547 %type <err>Module_Capabilities
1548 %type <modulePtr>ModuleName_Capabilities
1549 %type <listPtr>CapabilitiesGroups
1550 %type <listPtr>CapabilitiesGroup
1551 %type <err>VariationPart
1552 %type <err>Variations
1553 %type <err>Variation
1554 %type <access>VariationAccessPart
1555 %type <access>VariationAccess
1556 %type <err>CreationPart
1557 %type <err>Cells
1558 %type <err>Cell
1559 %type <objectPtr>SPPIPibReferencesPart
1560 %type <objectPtr>SPPIPibTagPart
1561 %type <subjectCategoriesPtr>SubjectCategoriesPart
1562 %type <subjectCategoriesPtr>SubjectCategories
1563 %type <listPtr>CategoryIDs
1564 %type <objectPtr>CategoryID
1565 %type <objectPtr>UniqueType
1566 %type <listPtr>UniqueTypes
1567 %type <listPtr>UniqueTypesPart
1568 %type <listPtr>SPPIUniquePart
1569 %type <objectPtr>Error
1570 %type <listPtr>Errors
1571 %type <listPtr>SPPIErrorsPart
1572
1573 %%
1574
1575 /*
1576 * Yacc rules.
1577 *
1578 */
1579
1580
1581 /*
1582 * One mibFile may contain multiple MIB modules.
1583 * It's also possible that there's no module in a file.
1584 */
1585 mibFile:
1586 modules
1587 {
1588 $$ = 0;
1589 }
1590 | /* empty */
1591 {
1592 $$ = 0;
1593 }
1594 ;
1595
1596 modules: module
1597 { $$ = 0; }
1598 | modules module
1599 { $$ = 0; }
1600 ;
1601
1602 /*
1603 * The general structure of a module is described at REF:RFC1902,3. .
1604 * An example is given at REF:RFC1902,5.7. .
1605 */
1606 module: moduleName
1607 {
1608 thisParserPtr->firstStatementLine = thisParserPtr->line;
1609 thisParserPtr->currentDecl = SMI_DECL_MODULE;
1610
1611 thisParserPtr->modulePtr = findModuleByName($1);
1612 if (!thisParserPtr->modulePtr) {
1613 thisParserPtr->modulePtr =
1614 addModule($1,
1615 smiStrdup(thisParserPtr->path),
1616 0,
1617 thisParserPtr);
1618 thisParserPtr->modulePtr->
1619 numImportedIdentifiers = 0;
1620 thisParserPtr->modulePtr->
1621 numStatements = 0;
1622 thisParserPtr->modulePtr->
1623 numModuleIdentities = 0;
1624 if (!strcmp($1, "SNMPv2-SMI")) {
1625 /*
1626 * SNMPv2-SMI is an SMIv2 module
1627 * that cannot be identified by
1628 * importing from SNMPv2-SMI.
1629 */
1630 thisModulePtr->export.language =
1631 SMI_LANGUAGE_SMIV2;
1632 }
1633 } else {
1634 smiPrintError(thisParserPtr,
1635 ERR_MODULE_ALREADY_LOADED,
1636 $1);
1637 /*
1638 * this aborts parsing the whole file,
1639 * not only the current module.
1640 */
1641 YYABORT;
1642 }
1643 }
1644 moduleOid
1645 definitions
1646 COLON_COLON_EQUAL BEGIN_
1647 exportsClause
1648 linkagePart
1649 declarationPart
1650 END
1651 {
1652 if (thisModulePtr->export.language == SMI_LANGUAGE_UNKNOWN)
1653 thisModulePtr->export.language = SMI_LANGUAGE_SMIV1;
1654 checkModuleName(thisParserPtr, thisModulePtr);
1655 checkModuleIdentity(thisParserPtr, thisModulePtr);
1656 checkObjects(thisParserPtr, thisModulePtr);
1657 checkTypes(thisParserPtr, thisModulePtr);
1658 checkDefvals(thisParserPtr, thisModulePtr);
1659 checkImportsUsage(thisParserPtr, thisModulePtr);
1660 smiCheckTypeUsage(thisParserPtr, thisModulePtr);
1661
1662 thisParserPtr->capabilitiesModulePtr = NULL;
1663
1664 $$ = 0;
1665 }
1666 ;
1667
1668 moduleOid: '{' objectIdentifier '}'
1669 { $$ = 0; }
1670 | /* empty */
1671 { $$ = 0; }
1672 ;
1673
1674 definitions: DEFINITIONS
1675 { }
1676 | PIB_DEFINITIONS
1677 {
1678 thisModulePtr->export.language = SMI_LANGUAGE_SPPI;
1679 }
1680 ;
1681
1682 /*
1683 * REF:RFC1902,3.2.
1684 */
1685 linkagePart: linkageClause
1686 { $$ = 0; }
1687 | /* empty */
1688 { $$ = 0; }
1689 ;
1690
1691 linkageClause: IMPORTS importPart ';'
1692 {
1693 thisParserPtr->firstStatementLine = thisParserPtr->line;
1694 thisParserPtr->currentDecl = SMI_DECL_MODULE;
1695
1696 if ((thisModulePtr->export.language != SMI_LANGUAGE_SMIV2) &&
1697 (thisModulePtr->export.language != SMI_LANGUAGE_SPPI))
1698 thisModulePtr->export.language = SMI_LANGUAGE_SMIV1;
1699
1700 $$ = 0;
1701 }
1702
1703 ;
1704
1705 exportsClause: /* empty */
1706 { $$ = 0; }
1707 | EXPORTS
1708 {
1709 if (thisParserPtr->modulePtr->export.language ==
1710 SMI_LANGUAGE_SPPI)
1711 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "EXPORTS");
1712
1713 thisParserPtr->firstStatementLine = thisParserPtr->line;
1714 thisParserPtr->currentDecl = SMI_DECL_MODULE;
1715
1716 if (strcmp(thisParserPtr->modulePtr->export.name,
1717 "RFC1155-SMI") &&
1718 strcmp(thisParserPtr->modulePtr->export.name,
1719 "RFC1065-SMI")) {
1720 smiPrintError(thisParserPtr, ERR_EXPORTS);
1721 }
1722 }
1723 /* the scanner skips until... */
1724 ';'
1725 { $$ = 0; }
1726 ;
1727
1728 importPart: imports
1729 { $$ = 0; }
1730 | /* empty */
1731 { $$ = 0; }
1732 /* TODO: ``IMPORTS ;'' allowed? refer ASN.1! */
1733 ;
1734
1735 imports: import
1736 { $$ = 0; }
1737 | imports import
1738 { $$ = 0; }
1739 ;
1740
1741 import: importIdentifiers FROM moduleName
1742 /* TODO: multiple clauses with same moduleName
1743 * allowed? I guess so. refer ASN.1! */
1744 {
1745 Import *importPtr;
1746 Module *modulePtr;
1747
1748 /*
1749 * Recursively call the parser to suffer
1750 * the IMPORTS, if the module is not yet
1751 * loaded.
1752 */
1753 modulePtr = findModuleByName($3);
1754 if (!modulePtr) {
1755 modulePtr = loadModule($3, thisParserPtr);
1756 }
1757 checkImports(modulePtr, thisParserPtr);
1758
1759 if (modulePtr && !strcmp($3, "SNMPv2-SMI")) {
1760 /*
1761 * A module that imports a macro or
1762 * type definition from SNMPv2-SMI
1763 * seems to be SMIv2 style - but only if
1764 * it is not SPPI yet.
1765 */
1766 if (thisModulePtr->export.language != SMI_LANGUAGE_SPPI) {
1767 for (importPtr =
1768 thisModulePtr->firstImportPtr;
1769 importPtr;
1770 importPtr = importPtr->nextPtr) {
1771 if ((!strcmp(importPtr->export.module,
1772 $3)) &&
1773 ((importPtr->kind == KIND_MACRO) ||
1774 (importPtr->kind == KIND_TYPE))) {
1775 thisModulePtr->export.language =
1776 SMI_LANGUAGE_SMIV2;
1777 }
1778 }
1779 }
1780 }
1781
1782 smiFree($3);
1783 }
1784 ;
1785
1786 importIdentifiers: importIdentifier
1787 { $$ = 0; }
1788 | importIdentifiers ',' importIdentifier
1789 /* TODO: might this list list be empty? */
1790 { $$ = 0; }
1791 ;
1792
1793 /*
1794 * Note that some named types must not be imported, REF:RFC1902,590 .
1795 */
1796 importIdentifier: LOWERCASE_IDENTIFIER
1797 {
1798 addImport($1, thisParserPtr);
1799 thisParserPtr->modulePtr->numImportedIdentifiers++;
1800 $$ = 0;
1801 }
1802 | UPPERCASE_IDENTIFIER
1803 {
1804 addImport($1, thisParserPtr);
1805 thisParserPtr->modulePtr->numImportedIdentifiers++;
1806 $$ = 0;
1807 }
1808 | importedKeyword
1809 {
1810 addImport(smiStrdup($1), thisParserPtr);
1811 thisParserPtr->modulePtr->numImportedIdentifiers++;
1812 $$ = 0;
1813 }
1814 ;
1815
1816 /*
1817 * These keywords are no real keywords. They have to be imported
1818 * from the SMI, TC, CONF MIBs.
1819 */
1820 /*
1821 * TODO: Think! Shall we really leave these words as keywords or should
1822 * we prefer the symbol table appropriately??
1823 */
1824 importedKeyword: importedSMIKeyword
1825 {
1826 /*
1827 * There are PIBs that import e.g. Counter64 - so
1828 * don't complain here about SMI keywords.
1829 */
1830 /* if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
1831 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, $1);*/
1832 $$ = $1;
1833 }
1834 | importedSPPIKeyword
1835 {
1836 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
1837 smiPrintError(thisParserPtr, ERR_SPPI_TYPE_IN_MIB, $1);
1838 $$ = $1;
1839 }
1840 | BITS
1841 | INTEGER32
1842 | IPADDRESS
1843 | MANDATORY_GROUPS
1844 | MODULE_COMPLIANCE
1845 | MODULE_IDENTITY
1846 | OBJECT_GROUP
1847 | OBJECT_IDENTITY
1848 | OBJECT_TYPE
1849 | OPAQUE
1850 | TEXTUAL_CONVENTION
1851 | TIMETICKS
1852 | UNSIGNED32
1853 ;
1854
1855 importedSMIKeyword: AGENT_CAPABILITIES
1856 | COUNTER32
1857 | COUNTER64
1858 | GAUGE32
1859 | NOTIFICATION_GROUP
1860 | NOTIFICATION_TYPE
1861 | TRAP_TYPE
1862 ;
1863
1864 importedSPPIKeyword: INTEGER64
1865 | UNSIGNED64
1866 ;
1867
1868 moduleName: UPPERCASE_IDENTIFIER
1869 {
1870 checkNameLen(thisParserPtr, $1,
1871 ERR_MODULENAME_32, ERR_MODULENAME_64);
1872 $$ = $1;
1873 }
1874 ;
1875
1876 /*
1877 * The paragraph at REF:RFC1902,490 lists roughly what's allowed
1878 * in the body of an information module.
1879 */
1880 declarationPart: declarations
1881 { $$ = 0; }
1882 | /* empty */
1883 { $$ = 0; }
1884 /* TODO: might this list really be emtpy? */
1885 ;
1886
1887 declarations: declaration
1888 { $$ = 0; }
1889 | declarations declaration
1890 { $$ = 0; }
1891 ;
1892
1893 declaration: typeDeclaration
1894 {
1895 thisParserPtr->modulePtr->numStatements++;
1896 $$ = 0;
1897 }
1898 | valueDeclaration
1899 {
1900 thisParserPtr->modulePtr->numStatements++;
1901 $$ = 0;
1902 }
1903 | objectIdentityClause
1904 {
1905 thisParserPtr->modulePtr->numStatements++;
1906 $$ = 0;
1907 }
1908 | objectTypeClause
1909 {
1910 thisParserPtr->modulePtr->numStatements++;
1911 $$ = 0;
1912 }
1913 | trapTypeClause
1914 {
1915 thisParserPtr->modulePtr->numStatements++;
1916 $$ = 0;
1917 }
1918 | notificationTypeClause
1919 {
1920 thisParserPtr->modulePtr->numStatements++;
1921 $$ = 0;
1922 }
1923 | moduleIdentityClause
1924 {
1925 thisParserPtr->modulePtr->numStatements++;
1926 $$ = 0;
1927 }
1928 | moduleComplianceClause
1929 {
1930 thisParserPtr->modulePtr->numStatements++;
1931 $$ = 0;
1932 }
1933 | objectGroupClause
1934 {
1935 thisParserPtr->modulePtr->numStatements++;
1936 $$ = 0;
1937 }
1938 | notificationGroupClause
1939 {
1940 thisParserPtr->modulePtr->numStatements++;
1941 $$ = 0;
1942 }
1943 | agentCapabilitiesClause
1944 {
1945 thisParserPtr->modulePtr->numStatements++;
1946 $$ = 0;
1947 }
1948 | macroClause
1949 {
1950 thisParserPtr->modulePtr->numStatements++;
1951 $$ = 0;
1952 }
1953 | error '}'
1954 {
1955 smiPrintError(thisParserPtr,
1956 ERR_FLUSH_DECLARATION);
1957 yyerrok;
1958 $$ = 1;
1959 }
1960 ;
1961
1962 /*
1963 * Macro clauses. Its contents are not really parsed, but skipped by
1964 * the scanner until 'END' is read. This is just to make the SMI
1965 * documents readable.
1966 */
1967 macroClause: macroName
1968 {
1969 Macro *macroPtr;
1970
1971 thisParserPtr->firstStatementLine = thisParserPtr->line;
1972 thisParserPtr->currentDecl = SMI_DECL_MACRO;
1973
1974 macroPtr = addMacro(smiStrdup($1),
1975 0, thisParserPtr);
1976 setMacroLine(macroPtr, thisParserPtr->firstStatementLine,
1977 thisParserPtr);
1978 }
1979 MACRO
1980 {
1981 /*
1982 * ASN.1 macros are known to be in these
1983 * modules.
1984 */
1985 if (strcmp(thisParserPtr->modulePtr->export.name,
1986 "SNMPv2-SMI") &&
1987 strcmp(thisParserPtr->modulePtr->export.name,
1988 "SNMPv2-TC") &&
1989 strcmp(thisParserPtr->modulePtr->export.name,
1990 "SNMPv2-CONF") &&
1991 strcmp(thisParserPtr->modulePtr->export.name,
1992 "RFC-1212") &&
1993 strcmp(thisParserPtr->modulePtr->export.name,
1994 "RFC-1215") &&
1995 strcmp(thisParserPtr->modulePtr->export.name,
1996 "RFC1065-SMI") &&
1997 strcmp(thisParserPtr->modulePtr->export.name,
1998 "RFC1155-SMI") &&
1999 strcmp(thisParserPtr->modulePtr->export.name,
2000 "COPS-PR-SPPI") &&
2001 strcmp(thisParserPtr->modulePtr->export.name,
2002 "COPS-PR-SPPI-TC")) {
2003 smiPrintError(thisParserPtr, ERR_MACRO);
2004 }
2005 }
2006 /* the scanner skips until... */
2007 END
2008 {
2009 $$ = 0;
2010 }
2011 ;
2012
2013 macroName: MODULE_IDENTITY { $$ = $1; }
2014 | OBJECT_TYPE { $$ = $1; }
2015 | TRAP_TYPE { $$ = $1; }
2016 | NOTIFICATION_TYPE { $$ = $1; }
2017 | OBJECT_IDENTITY { $$ = $1; }
2018 | TEXTUAL_CONVENTION { $$ = $1; }
2019 | OBJECT_GROUP { $$ = $1; }
2020 | NOTIFICATION_GROUP { $$ = $1; }
2021 | MODULE_COMPLIANCE { $$ = $1; }
2022 | AGENT_CAPABILITIES { $$ = $1; }
2023 ;
2024
2025 choiceClause: CHOICE
2026 {
2027 if (strcmp(thisParserPtr->modulePtr->export.name,
2028 "SNMPv2-SMI") &&
2029 strcmp(thisParserPtr->modulePtr->export.name,
2030 "SNMPv2-TC") &&
2031 strcmp(thisParserPtr->modulePtr->export.name,
2032 "SNMPv2-CONF") &&
2033 strcmp(thisParserPtr->modulePtr->export.name,
2034 "RFC-1212") &&
2035 strcmp(thisParserPtr->modulePtr->export.name,
2036 "RFC1065-SMI") &&
2037 strcmp(thisParserPtr->modulePtr->export.name,
2038 "RFC1155-SMI") &&
2039 strcmp(thisParserPtr->modulePtr->export.name,
2040 "COPS-PR-SPPI")) {
2041 smiPrintError(thisParserPtr, ERR_CHOICE);
2042 }
2043 }
2044 /* the scanner skips until... */
2045 '}'
2046 {
2047 $$ = addType(NULL, SMI_BASETYPE_UNKNOWN, 0,
2048 thisParserPtr);
2049 }
2050 ;
2051
2052 /*
2053 * The only ASN.1 value declarations are for OIDs, REF:RFC1902,491 .
2054 */
2055 fuzzy_lowercase_identifier: LOWERCASE_IDENTIFIER
2056 {
2057 $$ = $1;
2058 }
2059 |
2060 UPPERCASE_IDENTIFIER
2061 {
2062 smiPrintError (thisParserPtr,
2063 ERR_BAD_LOWER_IDENTIFIER_CASE,
2064 $1);
2065 /* xxx
2066 if ((thisParserPtr->flags & SMI_FLAG_BE_LAX) == 0) {
2067 YYERROR;
2068 }
2069 */
2070 $$ = $1;
2071 }
2072 ;
2073
2074 /* valueDeclaration: LOWERCASE_IDENTIFIER */
2075 valueDeclaration: fuzzy_lowercase_identifier
2076 {
2077 thisParserPtr->firstStatementLine = thisParserPtr->line;
2078 thisParserPtr->currentDecl = SMI_DECL_VALUEASSIGNMENT;
2079
2080 checkNameLen(thisParserPtr, $1,
2081 ERR_OIDNAME_32, ERR_OIDNAME_64);
2082 smiCheckObjectName(thisParserPtr,
2083 thisModulePtr, $1);
2084 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
2085 {
2086 if (strchr($1, '-') &&
2087 (strcmp($1, "mib-2") ||
2088 strcmp(thisModulePtr->export.name, "SNMPv2-SMI"))) {
2089 smiPrintError(thisParserPtr,
2090 ERR_OIDNAME_INCLUDES_HYPHEN,
2091 $1);
2092 }
2093 }
2094 }
2095 OBJECT IDENTIFIER
2096 COLON_COLON_EQUAL '{' objectIdentifier '}'
2097 {
2098 Object *objectPtr;
2099
2100 objectPtr = $7;
2101 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
2102 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
2103 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
2104 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
2105 thisParserPtr);
2106 setObjectDecl(objectPtr,
2107 SMI_DECL_VALUEASSIGNMENT);
2108 $$ = 0;
2109 }
2110 ;
2111
2112 /*
2113 * This is for simple ASN.1 style type assignments and textual conventions.
2114 */
2115 typeDeclaration: typeName
2116 {
2117 thisParserPtr->firstStatementLine = thisParserPtr->line;
2118 thisParserPtr->currentDecl = SMI_DECL_TYPEASSIGNMENT;
2119
2120 checkNameLen(thisParserPtr, $1,
2121 ERR_TYPENAME_32, ERR_TYPENAME_64);
2122 }
2123 COLON_COLON_EQUAL typeDeclarationRHS
2124 {
2125 Type *typePtr;
2126
2127 if (strlen($1)) {
2128 if ($4->export.basetype != SMI_BASETYPE_UNKNOWN) {
2129 smiCheckTypeName(thisParserPtr,
2130 thisModulePtr, $1,
2131 thisParserPtr->firstStatementLine);
2132 }
2133 setTypeLine($4, thisParserPtr->firstStatementLine,
2134 thisParserPtr);
2135 setTypeName($4, $1);
2136 $$ = 0;
2137 } else {
2138 $$ = 0;
2139 }
2140
2141 /*
2142 * If we are in an SMI module, some type
2143 * definitions derived from ASN.1 `INTEGER'
2144 * must be modified to libsmi basetypes.
2145 */
2146 if (thisModulePtr &&
2147 (!strcmp(thisModulePtr->export.name, "SNMPv2-SMI"))) {
2148 if (!strcmp($1, "Counter32")) {
2149 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2150 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2151 if ($4->listPtr) {
2152 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2153 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2154 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2155 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2156 }
2157 } else if (!strcmp($1, "Gauge32")) {
2158 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2159 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2160 if ($4->listPtr) {
2161 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2162 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2163 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2164 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2165 }
2166 } else if (!strcmp($1, "Unsigned32")) {
2167 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2168 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2169 if ($4->listPtr) {
2170 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2171 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2172 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2173 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2174 }
2175 } else if (!strcmp($1, "TimeTicks")) {
2176 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2177 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2178 if ($4->listPtr) {
2179 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2180 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2181 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2182 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2183 }
2184 } else if (!strcmp($1, "Counter64")) {
2185 $4->export.basetype = SMI_BASETYPE_UNSIGNED64;
2186 if ($4->listPtr) {
2187 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED64;
2188 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned64 = 0;
2189 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED64;
2190 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned64 = SMI_BASETYPE_UNSIGNED64_MAX;
2191 }
2192 setTypeParent($4, smiHandle->typeUnsigned64Ptr);
2193 }
2194 }
2195 if (thisModulePtr &&
2196 (!strcmp(thisModulePtr->export.name, "RFC1155-SMI") ||
2197 !strcmp(thisModulePtr->export.name, "RFC1065-SMI"))) {
2198 if (!strcmp($1, "Counter")) {
2199 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2200 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2201 if ($4->listPtr) {
2202 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2203 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2204 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2205 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2206 }
2207 } else if (!strcmp($1, "Gauge")) {
2208 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2209 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2210 if ($4->listPtr) {
2211 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2212 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2213 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2214 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2215 }
2216 } else if (!strcmp($1, "TimeTicks")) {
2217 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2218 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2219 if ($4->listPtr) {
2220 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2221 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2222 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2223 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2224 }
2225 } else if (!strcmp($1, "NetworkAddress")) {
2226 setTypeName($4, smiStrdup("NetworkAddress"));
2227 $4->export.basetype = SMI_BASETYPE_OCTETSTRING;
2228 setTypeParent($4, findTypeByModuleAndName(
2229 thisModulePtr,
2230 "IpAddress"));
2231 } else if (!strcmp($1, "IpAddress")) {
2232 typePtr = findTypeByModuleAndName(
2233 thisModulePtr, "NetworkAddress");
2234 if (typePtr)
2235 setTypeParent(typePtr, $4);
2236 }
2237 }
2238 if (thisModulePtr &&
2239 (!strcmp(thisModulePtr->export.name, "COPS-PR-SPPI"))) {
2240 if (!strcmp($1, "Unsigned32")) {
2241 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2242 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2243 if ($4->listPtr) {
2244 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2245 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2246 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2247 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2248 }
2249 } else if (!strcmp($1, "TimeTicks")) {
2250 $4->export.basetype = SMI_BASETYPE_UNSIGNED32;
2251 setTypeParent($4, smiHandle->typeUnsigned32Ptr);
2252 if ($4->listPtr) {
2253 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED32;
2254 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned32 = 0;
2255 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED32;
2256 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned32 = 4294967295U;
2257 }
2258 } else if (!strcmp($1, "Unsigned64")) {
2259 $4->export.basetype = SMI_BASETYPE_UNSIGNED64;
2260 if ($4->listPtr) {
2261 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_UNSIGNED64;
2262 ((Range *)$4->listPtr->ptr)->export.minValue.value.unsigned64 = 0;
2263 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_UNSIGNED64;
2264 ((Range *)$4->listPtr->ptr)->export.maxValue.value.unsigned64 = SMI_BASETYPE_UNSIGNED64_MAX;
2265 }
2266 setTypeParent($4, smiHandle->typeUnsigned64Ptr);
2267 } else if (!strcmp($1, "Integer64")) {
2268 $4->export.basetype = SMI_BASETYPE_INTEGER64;
2269 if ($4->listPtr) {
2270 ((Range *)$4->listPtr->ptr)->export.minValue.basetype = SMI_BASETYPE_INTEGER64;
2271 ((Range *)$4->listPtr->ptr)->export.minValue.value.integer64 = SMI_BASETYPE_INTEGER64_MIN;
2272 ((Range *)$4->listPtr->ptr)->export.maxValue.basetype = SMI_BASETYPE_INTEGER64;
2273 ((Range *)$4->listPtr->ptr)->export.maxValue.value.integer64 = SMI_BASETYPE_INTEGER64_MAX;
2274 }
2275 setTypeParent($4, smiHandle->typeInteger64Ptr);
2276 }
2277 }
2278 }
2279 ;
2280
2281 typeName: UPPERCASE_IDENTIFIER
2282 {
2283 $$ = $1;
2284 }
2285 | typeSMI
2286 {
2287 $$ = smiStrdup($1);
2288 /*
2289 * well known types (keywords in this grammar)
2290 * are known to be defined in these modules.
2291 */
2292 if (strcmp(thisParserPtr->modulePtr->export.name,
2293 "SNMPv2-SMI") &&
2294 strcmp(thisParserPtr->modulePtr->export.name,
2295 "SNMPv2-TC") &&
2296 strcmp(thisParserPtr->modulePtr->export.name,
2297 "SNMPv2-CONF") &&
2298 strcmp(thisParserPtr->modulePtr->export.name,
2299 "RFC-1212") &&
2300 strcmp(thisParserPtr->modulePtr->export.name,
2301 "RFC1065-SMI") &&
2302 strcmp(thisParserPtr->modulePtr->export.name,
2303 "RFC1155-SMI") &&
2304 strcmp(thisParserPtr->modulePtr->export.name,
2305 "COPS-PR-SPPI")) {
2306 smiPrintError(thisParserPtr, ERR_TYPE_SMI_OR_SPPI, $1);
2307 }
2308 }
2309 | typeSPPIonly
2310 {
2311 $$ = smiStrdup($1);
2312 /*
2313 * well known types (keywords in this grammar)
2314 * are known to be defined in these modules.
2315 */
2316 if ((strcmp(thisParserPtr->modulePtr->export.name,
2317 "COPS-PR-SPPI")) &&
2318 (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI))
2319 smiPrintError(thisParserPtr, ERR_TYPE_SPPI, $1);
2320 }
2321 ;
2322
2323 typeSMI: typeSMIandSPPI
2324 | typeSMIonly
2325 {
2326 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
2327 !findImportByName($1, thisParserPtr->modulePtr))
2328 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, $1);
2329 $$ = $1;
2330 }
2331 ;
2332
2333 typeSMIandSPPI: IPADDRESS
2334 | TIMETICKS
2335 | OPAQUE
2336 | INTEGER32
2337 | UNSIGNED32
2338 ;
2339
2340 typeSMIonly: COUNTER32
2341 | GAUGE32
2342 | COUNTER64
2343 ;
2344
2345 typeSPPIonly: INTEGER64
2346 | UNSIGNED64
2347 ;
2348
2349 typeDeclarationRHS: Syntax
2350 {
2351 if ($1->export.name) {
2352 /*
2353 * If we found an already defined type,
2354 * we have to inherit a new type structure.
2355 * (Otherwise the `Syntax' rule created
2356 * a new type for us.)
2357 */
2358 $$ = duplicateType($1, 0, thisParserPtr);
2359 setTypeDecl($$, SMI_DECL_TYPEASSIGNMENT);
2360 } else {
2361 $$ = $1;
2362 setTypeDecl($$, SMI_DECL_TYPEASSIGNMENT);
2363 }
2364 }
2365 | TEXTUAL_CONVENTION
2366 {
2367 Import *importPtr;
2368
2369 thisParserPtr->currentDecl = SMI_DECL_TEXTUALCONVENTION;
2370
2371 if (thisModulePtr->export.language == SMI_LANGUAGE_UNKNOWN)
2372 thisModulePtr->export.language = SMI_LANGUAGE_SMIV2;
2373
2374 if (strcmp(thisModulePtr->export.name, "SNMPv2-TC")) {
2375 importPtr =
2376 findImportByName("TEXTUAL-CONVENTION",
2377 thisModulePtr);
2378 if (importPtr) {
2379 importPtr->use++;
2380 } else {
2381 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
2382 smiPrintError(thisParserPtr,
2383 ERR_MACRO_NOT_IMPORTED,
2384 "TEXTUAL-CONVENTION",
2385 "SNMPv2-TC");
2386 else
2387 smiPrintError(thisParserPtr,
2388 ERR_MACRO_NOT_IMPORTED,
2389 "TEXTUAL-CONVENTION",
2390 "COPS-PR-SPPI");
2391 }
2392 }
2393 }
2394 DisplayPart
2395 STATUS Status
2396 DESCRIPTION Text
2397 {
2398 checkDescr(thisParserPtr, $7);
2399 }
2400 ReferPart
2401 SYNTAX Syntax
2402 {
2403 if (($11) && !($11->export.name)) {
2404 /*
2405 * If the Type we found has just been
2406 * defined, we don't have to allocate
2407 * a new one.
2408 */
2409 $$ = $11;
2410 } else {
2411 if (!($11))
2412 smiPrintError(thisParserPtr, ERR_INTERNAL);
2413 /*
2414 * Otherwise, we have to allocate a
2415 * new Type struct, inherited from $10.
2416 */
2417 $$ = duplicateType($11, 0, thisParserPtr);
2418 }
2419 setTypeDescription($$, $7, thisParserPtr);
2420 if ($9) {
2421 setTypeReference($$, $9, thisParserPtr);
2422 }
2423 setTypeStatus($$, $5);
2424 if ($3) {
2425 if (smiCheckFormat(thisParserPtr,
2426 $$->export.basetype, $3,
2427 thisParserPtr->firstStatementLine)) {
2428 setTypeFormat($$, $3);
2429 }
2430 }
2431 setTypeDecl($$, SMI_DECL_TEXTUALCONVENTION);
2432 }
2433 | choiceClause
2434 {
2435 $$ = $1;
2436 setTypeDecl($$, SMI_DECL_TYPEASSIGNMENT);
2437 }
2438 ;
2439
2440 /* REF:RFC1902,7.1.12. */
2441 conceptualTable: SEQUENCE OF row
2442 {
2443 if ($3) {
2444 $$ = addType(NULL,
2445 SMI_BASETYPE_UNKNOWN, 0,
2446 thisParserPtr);
2447 setTypeDecl($$, SMI_DECL_IMPL_SEQUENCEOF);
2448 setTypeParent($$, $3);
2449 } else {
2450 $$ = NULL;
2451 }
2452 }
2453 ;
2454
2455 row: UPPERCASE_IDENTIFIER
2456 /*
2457 * In this case, we do NOT allow `Module.Type'.
2458 * The identifier must be defined in the local
2459 * module.
2460 */
2461 {
2462 Type *typePtr;
2463 Import *importPtr;
2464
2465 $$ = findTypeByModulenameAndName(
2466 thisParserPtr->modulePtr->export.name, $1);
2467 if (! $$) {
2468 importPtr = findImportByName($1,
2469 thisModulePtr);
2470 if (!importPtr ||
2471 (importPtr->kind == KIND_NOTFOUND)) {
2472 /*
2473 * forward referenced type. create it,
2474 * marked with FLAG_INCOMPLETE.
2475 */
2476 typePtr = addType($1,
2477 SMI_BASETYPE_UNKNOWN,
2478 FLAG_INCOMPLETE,
2479 thisParserPtr);
2480 $$ = typePtr;
2481 } else {
2482 /*
2483 * imported type.
2484 * TODO: is this allowed in a SEQUENCE?
2485 */
2486 importPtr->use++;
2487 $$ = findTypeByModulenameAndName(
2488 importPtr->export.module,
2489 importPtr->export.name);
2490 smiFree($1);
2491 }
2492 } else {
2493 smiFree($1);
2494 }
2495 }
2496 /* TODO: this must be an entryType */
2497 ;
2498
2499 /* REF:RFC1902,7.1.12. */
2500 entryType: SEQUENCE '{' sequenceItems '}'
2501 {
2502 $$ = addType(NULL, SMI_BASETYPE_UNKNOWN, 0,
2503 thisParserPtr);
2504 setTypeList($$, $3);
2505 }
2506 ;
2507
2508 sequenceItems: sequenceItem
2509 {
2510 $$ = smiMalloc(sizeof(List));
2511 $$->ptr = $1;
2512 $$->nextPtr = NULL;
2513 }
2514 | sequenceItems ',' sequenceItem
2515 /* TODO: might this list be emtpy? */
2516 {
2517 List *p, *pp;
2518
2519 p = smiMalloc(sizeof(List));
2520 p->ptr = (void *)$3;
2521 p->nextPtr = NULL;
2522 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
2523 pp->nextPtr = p;
2524 $$ = $1;
2525 }
2526 ;
2527
2528 /*
2529 * In a SEQUENCE { ... } there are no sub-types, enumerations or
2530 * named bits. REF: draft, p.29
2531 * NOTE: REF:RFC1902,7.1.12. was less clear, it said:
2532 * `normally omitting the sub-typing information'
2533 */
2534 sequenceItem: LOWERCASE_IDENTIFIER sequenceSyntax
2535 {
2536 Object *objectPtr;
2537 Import *importPtr;
2538 Type *typePtr;
2539
2540 objectPtr =
2541 findObjectByModuleAndName(thisParserPtr->modulePtr,
2542 $1);
2543
2544 if (!objectPtr) {
2545 importPtr = findImportByName($1,
2546 thisModulePtr);
2547 if (!importPtr ||
2548 (importPtr->kind == KIND_NOTFOUND)) {
2549 objectPtr = addObject($1, thisParserPtr->pendingNodePtr,
2550 0,
2551 FLAG_INCOMPLETE |
2552 FLAG_SEQTYPE,
2553 thisParserPtr);
2554 setObjectType(objectPtr, $2);
2555 } else {
2556 /*
2557 * imported object.
2558 */
2559 importPtr->use++;
2560 objectPtr = findObjectByModulenameAndName(
2561 importPtr->export.module, $1);
2562 smiFree($1);
2563
2564 if (objectPtr->typePtr->export.name) {
2565 typePtr = objectPtr->typePtr;
2566 } else {
2567 typePtr = objectPtr->typePtr->parentPtr;
2568 }
2569 if (($2 != typePtr) &&
2570 (($2->export.basetype !=
2571 SMI_BASETYPE_INTEGER32) ||
2572 (typePtr->export.basetype !=
2573 SMI_BASETYPE_ENUM)) &&
2574 (($2->export.basetype !=
2575 SMI_BASETYPE_OCTETSTRING) ||
2576 (typePtr->export.basetype !=
2577 SMI_BASETYPE_BITS))) {
2578 smiPrintError(thisParserPtr,
2579 ERR_SEQUENCE_TYPE_MISMATCH,
2580 objectPtr->export.name);
2581 }
2582 }
2583 } else {
2584 smiFree($1);
2585 if (objectPtr->typePtr) {
2586
2587 if (objectPtr->typePtr->export.name) {
2588 typePtr = objectPtr->typePtr;
2589 } else {
2590 typePtr = objectPtr->typePtr->parentPtr;
2591 }
2592 if (($2 != typePtr) &&
2593 (($2->export.basetype !=
2594 SMI_BASETYPE_INTEGER32) ||
2595 (typePtr->export.basetype !=
2596 SMI_BASETYPE_ENUM)) &&
2597 (($2->export.basetype !=
2598 SMI_BASETYPE_OCTETSTRING) ||
2599 (typePtr->export.basetype !=
2600 SMI_BASETYPE_BITS))) {
2601 smiPrintError(thisParserPtr,
2602 ERR_SEQUENCE_TYPE_MISMATCH,
2603 objectPtr->export.name);
2604 }
2605
2606 } else {
2607 setObjectType(objectPtr, $2);
2608 addObjectFlags(objectPtr,
2609 FLAG_SEQTYPE);
2610 }
2611 }
2612
2613 $$ = objectPtr;
2614 }
2615 ;
2616
2617 Syntax: ObjectSyntax
2618 {
2619 $$ = $1;
2620 if ($$)
2621 defaultBasetype = $$->export.basetype;
2622 }
2623 | BITS '{' NamedBits '}'
2624 /* TODO: standalone `BITS' ok? seen in RMON2-MIB */
2625 /* -> no, it's only allowed in a SEQUENCE {...} */
2626 {
2627 Type *typePtr;
2628 List *p;
2629
2630 defaultBasetype = SMI_BASETYPE_BITS;
2631 typePtr = addType(NULL, SMI_BASETYPE_BITS,
2632 FLAG_INCOMPLETE,
2633 thisParserPtr);
2634 setTypeDecl(typePtr, SMI_DECL_IMPLICIT_TYPE);
2635 setTypeParent(typePtr, smiHandle->typeBitsPtr);
2636 setTypeList(typePtr, $3);
2637 for (p = $3; p; p = p->nextPtr)
2638 ((NamedNumber *)p->ptr)->typePtr = typePtr;
2639 smiCheckNamedNumbersOrder(parserPtr, typePtr);
2640 $$ = typePtr;
2641 }
2642 ;
2643
2644 sequenceSyntax: /* ObjectSyntax */
2645 sequenceObjectSyntax
2646 {
2647 $$ = $1;
2648 }
2649 | BITS
2650 {
2651 /* TODO: */
2652 $$ = smiHandle->typeOctetStringPtr;
2653 }
2654 | UPPERCASE_IDENTIFIER anySubType
2655 {
2656 Type *typePtr;
2657 Import *importPtr;
2658
2659 $$ = findTypeByModulenameAndName(
2660 thisParserPtr->modulePtr->export.name, $1);
2661 if (! $$) {
2662 importPtr = findImportByName($1,
2663 thisModulePtr);
2664 if (!importPtr ||
2665 (importPtr->kind == KIND_NOTFOUND)) {
2666 /*
2667 * forward referenced type. create it,
2668 * marked with FLAG_INCOMPLETE.
2669 */
2670 typePtr = addType($1, SMI_BASETYPE_UNKNOWN,
2671 FLAG_INCOMPLETE,
2672 thisParserPtr);
2673 $$ = typePtr;
2674 } else {
2675 importPtr->use++;
2676 $$ = findTypeByModulenameAndName(
2677 importPtr->export.module,
2678 importPtr->export.name);
2679 smiFree($1);
2680 }
2681 } else {
2682 smiFree($1);
2683 }
2684 }
2685 ;
2686
2687 NamedBits: NamedBit
2688 {
2689 $$ = smiMalloc(sizeof(List));
2690 $$->ptr = $1;
2691 $$->nextPtr = NULL;
2692 }
2693 | NamedBits ',' NamedBit
2694 {
2695 List *p, *pp;
2696
2697 p = smiMalloc(sizeof(List));
2698 p->ptr = (void *)$3;
2699 p->nextPtr = NULL;
2700 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
2701 pp->nextPtr = p;
2702 $$ = $1;
2703 }
2704 ;
2705
2706 NamedBit: LOWERCASE_IDENTIFIER
2707 {
2708 checkNameLen(thisParserPtr, $1,
2709 ERR_BITNAME_32, ERR_BITNAME_64);
2710 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
2711 {
2712 if (strchr($1, '-')) {
2713 smiPrintError(thisParserPtr,
2714 ERR_NAMEDBIT_INCLUDES_HYPHEN,
2715 $1);
2716 }
2717 }
2718 }
2719 '(' NUMBER ')'
2720 {
2721 $$ = smiMalloc(sizeof(NamedNumber));
2722 $$->export.name = $1;
2723 $$->export.value.basetype =
2724 SMI_BASETYPE_UNSIGNED32;
2725 $$->export.value.value.unsigned32 = $4;
2726 /* RFC 2578 7.1.4 */
2727 if ($4 >= 65535*8) {
2728 smiPrintError(thisParserPtr,
2729 ERR_BITS_NUMBER_TOO_LARGE,
2730 $1, $4);
2731 } else {
2732 if ($4 >= 128) {
2733 smiPrintError(thisParserPtr,
2734 ERR_BITS_NUMBER_LARGE,
2735 $1, $4);
2736 }
2737 }
2738 }
2739 ;
2740
2741 objectIdentityClause: LOWERCASE_IDENTIFIER
2742 {
2743 thisParserPtr->firstStatementLine = thisParserPtr->line;
2744 thisParserPtr->currentDecl = SMI_DECL_OBJECTIDENTITY;
2745
2746 checkNameLen(thisParserPtr, $1,
2747 ERR_OIDNAME_32, ERR_OIDNAME_64);
2748 smiCheckObjectName(thisParserPtr,
2749 thisModulePtr, $1);
2750 }
2751 OBJECT_IDENTITY
2752 {
2753 Import *importPtr;
2754
2755 if (strcmp(thisModulePtr->export.name, "SNMPv2-SMI") &&
2756 strcmp(thisModulePtr->export.name, "COPS-PR-SPPI")) {
2757 importPtr = findImportByName("OBJECT-IDENTITY",
2758 thisModulePtr);
2759 if (importPtr) {
2760 importPtr->use++;
2761 } else {
2762 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
2763 smiPrintError(thisParserPtr,
2764 ERR_MACRO_NOT_IMPORTED,
2765 "OBJECT-IDENTITY",
2766 "SNMPv2-SMI");
2767 else
2768 smiPrintError(thisParserPtr,
2769 ERR_MACRO_NOT_IMPORTED,
2770 "OBJECT-IDENTITY",
2771 "COPS-PR-SPPI");
2772 }
2773 }
2774 }
2775 STATUS Status
2776 DESCRIPTION Text
2777 {
2778 checkDescr(thisParserPtr, $8);
2779 }
2780 ReferPart
2781 COLON_COLON_EQUAL
2782 '{' objectIdentifier '}'
2783 {
2784 Object *objectPtr;
2785
2786 objectPtr = $13;
2787 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
2788
2789 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
2790 setObjectDecl(objectPtr, SMI_DECL_OBJECTIDENTITY);
2791 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
2792 thisParserPtr);
2793 setObjectStatus(objectPtr, $6);
2794 setObjectDescription(objectPtr, $8, thisParserPtr);
2795 if ($10) {
2796 setObjectReference(objectPtr, $10, thisParserPtr);
2797 }
2798 addObjectFlags(objectPtr, FLAG_REGISTERED);
2799 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
2800 $$ = 0;
2801 }
2802 ;
2803
2804 objectTypeClause: LOWERCASE_IDENTIFIER
2805 {
2806 thisParserPtr->firstStatementLine = thisParserPtr->line;
2807 thisParserPtr->currentDecl = SMI_DECL_OBJECTTYPE;
2808
2809 checkNameLen(thisParserPtr, $1,
2810 ERR_OIDNAME_32, ERR_OIDNAME_64);
2811 smiCheckObjectName(thisParserPtr,
2812 thisModulePtr, $1);
2813 }
2814 OBJECT_TYPE
2815 {
2816 Import *importPtr;
2817
2818 importPtr = findImportByName("OBJECT-TYPE",
2819 thisModulePtr);
2820 if (importPtr) {
2821 importPtr->use++;
2822 } else {
2823 if (thisModulePtr->export.language ==
2824 SMI_LANGUAGE_SMIV2) {
2825 smiPrintError(thisParserPtr,
2826 ERR_MACRO_NOT_IMPORTED,
2827 "OBJECT-TYPE", "SNMPv2-SMI");
2828 } else if (thisModulePtr->export.language ==
2829 SMI_LANGUAGE_SPPI) {
2830 smiPrintError(thisParserPtr,
2831 ERR_MACRO_NOT_IMPORTED,
2832 "OBJECT-TYPE", "COPS-PR-SPPI");
2833 } else {
2834 smiPrintError(thisParserPtr,
2835 ERR_MACRO_NOT_IMPORTED,
2836 "OBJECT-TYPE", "RFC-1212");
2837 }
2838 }
2839 indexFlag = 0;
2840 }
2841 SYNTAX Syntax /* old $6, new $6 */
2842 UnitsPart /* old $7, new $7 */
2843 MaxOrPIBAccessPart /* old $8, new $8 */
2844 SPPIPibReferencesPart /* SPPI only, $9 */
2845 SPPIPibTagPart /* SPPI only, $10 */
2846 STATUS Status /* old $9 $10, new $11 $12 */
2847 descriptionClause /* old $11, new $13 */
2848 SPPIErrorsPart /* SPPI only, $14 */
2849 ReferPart /* old $12, new $15 */
2850 IndexPart /* modified, old $13, new $16 */
2851 MibIndex /* new, $17 */
2852 SPPIUniquePart /* SPPI only, $18 */
2853 DefValPart /* old $14, new $19 */
2854 COLON_COLON_EQUAL '{' ObjectName '}' /* old $17, new $22 */
2855 {
2856 Object *objectPtr, *parentPtr;
2857 Type *typePtr = NULL;
2858
2859 objectPtr = $22;
2860
2861 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
2862
2863 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
2864 setObjectDecl(objectPtr, SMI_DECL_OBJECTTYPE);
2865 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
2866 thisParserPtr);
2867 if (checkObjectFlags(objectPtr, FLAG_SEQTYPE)) {
2868 deleteObjectFlags(objectPtr, FLAG_SEQTYPE);
2869 if ($6) {
2870 if ($6->export.name) {
2871 typePtr = $6;
2872 /*
2873 * According to RFC 3159 7.1.3. Opaque must not be used
2874 * in a SYNTAX clause.
2875 */
2876 if ((thisModulePtr->export.language == SMI_LANGUAGE_SPPI) &&
2877 !strcmp(typePtr->export.name, "Opaque"))
2878 smiPrintError(thisParserPtr, ERR_OPAQUE_IN_SYNTAX);
2879 /*
2880 * According to RFC 3159 7.1.4. IpAddress must not be used
2881 * in a SYNTAX clause.
2882 */
2883 if ((thisModulePtr->export.language == SMI_LANGUAGE_SPPI) &&
2884 !strcmp(typePtr->export.name, "IpAddress"))
2885 smiPrintError(thisParserPtr, ERR_IPADDRESS_IN_SYNTAX);
2886 } else {
2887 typePtr = $6->parentPtr;
2888 }
2889 if ((objectPtr->typePtr != typePtr) &&
2890 ((objectPtr->typePtr->export.basetype !=
2891 SMI_BASETYPE_INTEGER32) ||
2892 (typePtr->export.basetype !=
2893 SMI_BASETYPE_ENUM)) &&
2894 ((objectPtr->typePtr->export.basetype !=
2895 SMI_BASETYPE_OCTETSTRING) ||
2896 (typePtr->export.basetype !=
2897 SMI_BASETYPE_BITS))) {
2898 smiPrintError(thisParserPtr,
2899 ERR_SEQUENCE_TYPE_MISMATCH,
2900 objectPtr->export.name);
2901 }
2902 }
2903 }
2904 setObjectType(objectPtr, $6);
2905 if (!($6->export.name)) {
2906 /*
2907 * An inlined type.
2908 */
2909 #if 0 /* export implicitly defined types by the node's lowercase name */
2910 setTypeName($6, $1);
2911 #endif
2912 }
2913 setObjectUnits(objectPtr, $7);
2914 setObjectAccess(objectPtr, $8);
2915 if (thisParserPtr->flags & FLAG_CREATABLE) {
2916 thisParserPtr->flags &= ~FLAG_CREATABLE;
2917 parentPtr =
2918 objectPtr->nodePtr->parentPtr->lastObjectPtr;
2919 if (parentPtr &&
2920 parentPtr->export.indexkind !=
2921 SMI_INDEX_UNKNOWN) {
2922 /*
2923 * add objectPtr to the parent object's
2924 * listPtr, which is the list of columns
2925 * needed for row creation.
2926 *
2927 * Note, that this would clash, if the
2928 * parent row object-type is not yet
2929 * defined.
2930 */
2931 /*
2932 newlistPtr = smiMalloc(sizeof(List));
2933 newlistPtr->nextPtr = NULL;
2934 newlistPtr->ptr = objectPtr;
2935 */
2936 /*
2937 * Look up the parent object-type.
2938 */
2939 /*
2940 if (parentPtr->listPtr) {
2941 for(listPtr = parentPtr->listPtr;
2942 listPtr->nextPtr;
2943 listPtr = listPtr->nextPtr);
2944 listPtr->nextPtr = newlistPtr;
2945 } else {
2946 parentPtr->listPtr = newlistPtr;
2947 }
2948 */
2949 addObjectFlags(parentPtr, FLAG_CREATABLE);
2950 setObjectCreate(parentPtr, 1);
2951 } else {
2952 smiPrintError(thisParserPtr,
2953 ERR_SCALAR_READCREATE);
2954 }
2955 }
2956 setObjectStatus(objectPtr, $12);
2957 addObjectFlags(objectPtr, FLAG_REGISTERED);
2958 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
2959 if ($13) {
2960 setObjectDescription(objectPtr, $13, thisParserPtr);
2961 }
2962 if ($15) {
2963 setObjectReference(objectPtr, $15, thisParserPtr);
2964 }
2965 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI) {
2966 /*
2967 * For SMI documents either $16 (IndexPart) or $17 (MibIndex)
2968 * are used, but not both. This is signalled via the indexFlag
2969 * which is 1 if IndexPart has been used.
2970 */
2971 if (indexFlag == INDEXFLAG_AUGMENTS) { /* IndexPart was used */
2972 if ($16.indexkind != SMI_INDEX_UNKNOWN) {
2973 setObjectList(objectPtr, $16.listPtr);
2974 setObjectImplied(objectPtr, $16.implied);
2975 setObjectIndexkind(objectPtr, $16.indexkind);
2976 setObjectRelated(objectPtr, $16.rowPtr);
2977 }
2978 } else {
2979 if ($17.indexkind != SMI_INDEX_UNKNOWN) {
2980 setObjectList(objectPtr, $17.listPtr);
2981 setObjectImplied(objectPtr, $17.implied);
2982 setObjectIndexkind(objectPtr, $17.indexkind);
2983 setObjectRelated(objectPtr, $17.rowPtr);
2984 }
2985 }
2986 } else {
2987 /*
2988 * PIBs contain either PIB-INDEX or AUGMENTS or EXTENDS -
2989 * but only with one Index entry. A PIB-INDEX may be
2990 * followed by a full INDEX. We get the indexkind
2991 * from the first.
2992 * Note that PIB-INDEX/AUGMENTS/EXTENS is always
2993 * the first element in objectPtr->listPtr.
2994 * If an optional INDEX exists then it is
2995 * appended to this list.
2996 */
2997 if ($16.indexkind != SMI_INDEX_UNKNOWN) {
2998 setObjectList(objectPtr, $16.listPtr);
2999 setObjectIndexkind(objectPtr, $16.indexkind);
3000 setObjectRelated(objectPtr, $16.rowPtr);
3001 }
3002 if ($17.indexkind != SMI_INDEX_UNKNOWN) {
3003 if (objectPtr->listPtr) {
3004 List *p;
3005 for (p = objectPtr->listPtr; p->nextPtr;
3006 p = p->nextPtr);
3007 p->nextPtr = $17.listPtr;
3008 }
3009 setObjectImplied(objectPtr, $17.implied);
3010 }
3011 }
3012 if ($18) {
3013 setObjectUniqueness(objectPtr, $18);
3014 }
3015 if ($19) {
3016 if (objectPtr->typePtr
3017 && (((objectPtr->typePtr->export.basetype == SMI_BASETYPE_OCTETSTRING) &&
3018 ($19->basetype != SMI_BASETYPE_OCTETSTRING))
3019 || ((objectPtr->typePtr->export.basetype == SMI_BASETYPE_OBJECTIDENTIFIER) &&
3020 ($19->basetype != SMI_BASETYPE_OBJECTIDENTIFIER)))) {
3021 smiPrintError(thisParserPtr,
3022 ERR_DEFVAL_SYNTAX);
3023 if ($19->basetype == SMI_BASETYPE_OBJECTIDENTIFIER) {
3024 smiFree($19->value.oid);
3025 }
3026 if (($19->basetype == SMI_BASETYPE_BITS) ||
3027 ($19->basetype == SMI_BASETYPE_OCTETSTRING)) {
3028 smiFree($19->value.ptr);
3029 }
3030 smiFree($19);
3031 } else {
3032 setObjectValue(objectPtr, $19);
3033 }
3034 }
3035 if ($9) {
3036 if (objectPtr->relatedPtr)
3037 smiPrintError(thisParserPtr, ERR_OBJECTPTR_ELEMENT_IN_USE,
3038 "relatedPtr", "PIB-REFERENCES");
3039 /*
3040 * PIB-REFERENCES clauses are only allowed for
3041 * objects with a SYNTAX of 'ReferenceId'.
3042 * See RFC 3159 7.10
3043 */
3044 if (objectPtr->typePtr && objectPtr->typePtr->export.name &&
3045 strcmp(objectPtr->typePtr->export.name, "ReferenceId"))
3046 smiPrintErrorAtLine(parserPtr, ERR_PIB_REFERENCES_WRONG_TYPE,
3047 objectPtr->line);
3048 else
3049 setObjectRelated(objectPtr, $9);
3050 } else {
3051 /*
3052 * Does this object have a SYNTAX of 'ReferenceId'
3053 * and a PIB-REFERENCES clause?
3054 * See RFC 3159 7.10
3055 */
3056 if ((thisModulePtr->export.language == SMI_LANGUAGE_SPPI) &&
3057 objectPtr->typePtr && objectPtr->typePtr->export.name &&
3058 !strcmp(objectPtr->typePtr->export.name, "ReferenceId"))
3059 smiPrintErrorAtLine(parserPtr, ERR_LACKING_PIB_REFERENCES,
3060 objectPtr->line);
3061 }
3062 if ($10) {
3063 if (objectPtr->relatedPtr)
3064 smiPrintError(thisParserPtr, ERR_OBJECTPTR_ELEMENT_IN_USE,
3065 "relatedPtr", "PIB-TAG");
3066 /*
3067 * PIB-TAG clauses are only allowed for
3068 * objects with a SYNTAX of 'TagReferenceId'.
3069 * See RFC 3159 7.11
3070 */
3071 if (objectPtr->typePtr && objectPtr->typePtr->export.name &&
3072 strcmp(objectPtr->typePtr->export.name, "TagReferenceId"))
3073 smiPrintErrorAtLine(parserPtr, ERR_PIB_TAG_WRONG_TYPE,
3074 objectPtr->line);
3075 else
3076 setObjectRelated(objectPtr, $10);
3077 } else {
3078 /*
3079 * Does this object have a SYNTAX of 'TagReferenceId'
3080 * and a PIB-TAG clause?
3081 * See RFC 3159 7.11
3082 */
3083 if ((thisModulePtr->export.language == SMI_LANGUAGE_SPPI) &&
3084 objectPtr->typePtr && objectPtr->typePtr->export.name &&
3085 !strcmp(objectPtr->typePtr->export.name, "TagReferenceId"))
3086 smiPrintErrorAtLine(parserPtr, ERR_LACKING_PIB_TAG,
3087 objectPtr->line);
3088
3089 }
3090 if ($14) {
3091 if (objectPtr->listPtr)
3092 smiPrintError(thisParserPtr, ERR_OBJECTPTR_ELEMENT_IN_USE,
3093 "listPtr", "INSTALL-ERRORS");
3094 /*
3095 * Are INSTALL-ERRORS only used with tables?
3096 * See RFC 3159 7.4
3097 */
3098 if (!((objectPtr->export.decl == SMI_DECL_OBJECTTYPE) &&
3099 (objectPtr->typePtr) &&
3100 (objectPtr->typePtr->export.decl == SMI_DECL_IMPL_SEQUENCEOF)))
3101 smiPrintErrorAtLine(parserPtr, ERR_INSTALL_ERRORS_FOR_NON_TABLE,
3102 objectPtr->line);
3103 else
3104 setObjectList(objectPtr, $14);
3105 }
3106 $$ = 0;
3107 }
3108 ;
3109
3110 descriptionClause: /* empty */
3111 {
3112 if ((thisModulePtr->export.language == SMI_LANGUAGE_SMIV2) ||
3113 (thisModulePtr->export.language == SMI_LANGUAGE_SPPI))
3114 {
3115 smiPrintError(thisParserPtr,
3116 ERR_MISSING_DESCRIPTION);
3117 }
3118 $$ = NULL;
3119 }
3120 | DESCRIPTION Text
3121 {
3122 $$ = $2;
3123 checkDescr(thisParserPtr, $2);
3124 }
3125 ;
3126
3127 trapTypeClause: fuzzy_lowercase_identifier
3128 {
3129 thisParserPtr->firstStatementLine = thisParserPtr->line;
3130 thisParserPtr->currentDecl = SMI_DECL_TRAPTYPE;
3131
3132 checkNameLen(thisParserPtr, $1,
3133 ERR_OIDNAME_32, ERR_OIDNAME_64);
3134 smiCheckObjectName(thisParserPtr,
3135 thisModulePtr, $1);
3136 }
3137 TRAP_TYPE
3138 {
3139 Import *importPtr;
3140 if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
3141 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "TRAP-TYPE");
3142
3143 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
3144 {
3145 smiPrintError(thisParserPtr, ERR_TRAP_TYPE);
3146 }
3147
3148 importPtr = findImportByName("TRAP-TYPE",
3149 thisModulePtr);
3150 if (importPtr) {
3151 importPtr->use++;
3152 } else {
3153 smiPrintError(thisParserPtr,
3154 ERR_MACRO_NOT_IMPORTED,
3155 "TRAP-TYPE", "RFC-1215");
3156 }
3157 }
3158 ENTERPRISE objectIdentifier
3159 VarPart
3160 DescrPart
3161 ReferPart
3162 COLON_COLON_EQUAL NUMBER
3163 /* TODO: range of number? */
3164 {
3165 Object *objectPtr;
3166 Node *nodePtr;
3167
3168 objectPtr = $6;
3169 nodePtr = findNodeByParentAndSubid(
3170 objectPtr->nodePtr, 0);
3171 if (nodePtr && nodePtr->lastObjectPtr &&
3172 (nodePtr->lastObjectPtr->modulePtr == thisModulePtr)) {
3173 /*
3174 * hopefully, the last defined Object for
3175 * this Node is the one we expect.
3176 */
3177 objectPtr = nodePtr->lastObjectPtr;
3178 } else {
3179 objectPtr = addObject(NULL,
3180 objectPtr->nodePtr,
3181 0,
3182 FLAG_INCOMPLETE,
3183 thisParserPtr);
3184 }
3185 objectPtr = addObject(NULL,
3186 objectPtr->nodePtr,
3187 $11,
3188 FLAG_INCOMPLETE,
3189 thisParserPtr);
3190
3191 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
3192
3193 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
3194 setObjectDecl(objectPtr,
3195 SMI_DECL_TRAPTYPE);
3196 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
3197 thisParserPtr);
3198 addObjectFlags(objectPtr, FLAG_REGISTERED);
3199 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
3200 setObjectList(objectPtr, $7);
3201 setObjectStatus(objectPtr, SMI_STATUS_CURRENT);
3202 setObjectDescription(objectPtr, $8, thisParserPtr);
3203 if ($9) {
3204 setObjectReference(objectPtr, $9, thisParserPtr);
3205 }
3206 $$ = 0;
3207 }
3208 ;
3209
3210 VarPart: VARIABLES '{' VarTypes '}'
3211 {
3212 $$ = $3;
3213 }
3214 | /* empty */
3215 {
3216 $$ = NULL;
3217 }
3218 ;
3219
3220 VarTypes: VarType
3221 {
3222 if ($1) {
3223 $$ = smiMalloc(sizeof(List));
3224 $$->ptr = $1;
3225 $$->nextPtr = NULL;
3226 } else {
3227 $$ = NULL;
3228 }
3229 }
3230 | VarTypes ',' VarType
3231 {
3232 List *p, *pp;
3233
3234 if ($3) {
3235 p = smiMalloc(sizeof(List));
3236 p->ptr = $3;
3237 p->nextPtr = NULL;
3238 if ($1) {
3239 for (pp = $1; pp->nextPtr;
3240 pp = pp->nextPtr);
3241 pp->nextPtr = p;
3242 $$ = $1;
3243 } else {
3244 $$ = p;
3245 }
3246 } else {
3247 $$ = $1;
3248 }
3249 }
3250 ;
3251
3252 VarType: ObjectName
3253 {
3254 $$ = $1;
3255 }
3256 ;
3257
3258 DescrPart: DESCRIPTION Text
3259 {
3260 $$ = $2;
3261 checkDescr(thisParserPtr, $2);
3262 }
3263 | /* empty */
3264 { $$ = NULL; }
3265 ;
3266
3267 MaxOrPIBAccessPart: MaxAccessPart
3268 {
3269 $$ = $1;
3270 }
3271 | PibAccessPart
3272 {
3273 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
3274 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "MAX-ACCESS");
3275 if ($1 == SMI_ACCESS_NOT_ACCESSIBLE)
3276 smiPrintError(thisParserPtr, ERR_NOT_ACCESSIBLE_IN_PIB_ACCESS);
3277 $$ = $1;
3278 }
3279 | /* empty */
3280 { $$ = 0; }
3281 ;
3282
3283 PibAccessPart: PibAccess Access
3284 { $$ = $2; }
3285 ;
3286
3287 PibAccess: POLICY_ACCESS
3288 {
3289 smiPrintError(thisParserPtr, ERR_POLICY_ACCESS_IN_PIB);
3290 }
3291 | PIB_ACCESS
3292 { }
3293 ;
3294
3295 SPPIPibReferencesPart: PIB_REFERENCES
3296 {
3297 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
3298 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "PIB-REFERENCES");
3299 }
3300 '{' Entry '}'
3301 { $$ = $4; }
3302 | /* empty */
3303 { $$ = 0; }
3304 ;
3305
3306 SPPIPibTagPart: PIB_TAG
3307 {
3308 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
3309 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "PIB-TAG");
3310 }
3311 '{' ObjectName '}'
3312 { $$ = $4; }
3313 | /* empty */
3314 { $$ = 0; }
3315 ;
3316
3317
3318 SPPIUniquePart: UNIQUENESS
3319 {
3320 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
3321 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "UNIQUENESS");
3322 }
3323 '{' UniqueTypesPart '}'
3324 { $$ = $4; }
3325 | /* empty */
3326 { $$ = NULL; }
3327 ;
3328
3329 UniqueTypesPart: UniqueTypes
3330 { $$ = $1; }
3331 | /* empty */
3332 { $$ = NULL; }
3333 ;
3334
3335 UniqueTypes: UniqueType
3336 {
3337 $$ = smiMalloc(sizeof(List));
3338 $$->ptr = $1;
3339 $$->nextPtr = NULL;
3340 }
3341 | UniqueTypes ',' UniqueType
3342 /* TODO: might this list be emtpy? */
3343 {
3344 List *p, *pp;
3345
3346 p = smiMalloc(sizeof(List));
3347 p->ptr = $3;
3348 p->nextPtr = NULL;
3349 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
3350 pp->nextPtr = p;
3351 $$ = $1;
3352 }
3353 ;
3354
3355 UniqueType: ObjectName
3356 { $$ = $1; }
3357 ;
3358
3359 SPPIErrorsPart: INSTALL_ERRORS
3360 {
3361 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
3362 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "INSTALL-ERRORS");
3363 }
3364 '{' Errors '}'
3365 { $$ = $4; }
3366 | /* empty */
3367 { $$ = NULL; }
3368 ;
3369
3370 Errors: Error
3371 {
3372 $$ = smiMalloc(sizeof(List));
3373 $$->ptr = $1;
3374 $$->nextPtr = NULL;
3375 }
3376 | Errors ',' Error
3377 /* TODO: might this list be emtpy? */
3378 {
3379 List *p, *pp;
3380
3381 p = smiMalloc(sizeof(List));
3382 p->ptr = $3;
3383 p->nextPtr = NULL;
3384 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
3385 pp->nextPtr = p;
3386 $$ = $1;
3387 }
3388 ;
3389
3390 Error: LOWERCASE_IDENTIFIER '(' NUMBER ')'
3391 {
3392 Object *objectPtr;
3393
3394 if (($3 < 1) || ($3 > 65536))
3395 smiPrintError(thisParserPtr, ERR_ERROR_NUMBER_RANGE, $3);
3396 /*
3397 * This is not a regular object that will be added vid
3398 * 'addObject' as error identifier have no other
3399 * meaning in PIBs. They are just used for
3400 * a direct mapping to the actual protocol fields.
3401 */
3402 objectPtr = smiMalloc(sizeof(Object));
3403 objectPtr->export.name = $1;
3404 objectPtr->export.oidlen = 1;
3405 objectPtr->export.oid = (void *)$3;
3406 $$ = objectPtr;
3407 }
3408 ;
3409
3410
3411 MaxAccessPart: MAX_ACCESS
3412 {
3413 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV1)
3414 {
3415 smiPrintError(thisParserPtr,
3416 ERR_MAX_ACCESS_IN_SMIV1);
3417 } else if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
3418 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "MAX-ACCESS");
3419 }
3420 Access
3421 { $$ = $3; }
3422 | ACCESS
3423 {
3424 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
3425 {
3426 smiPrintError(thisParserPtr, ERR_ACCESS_IN_SMIV2);
3427 } else if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
3428 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "ACCESS");
3429 }
3430 Access
3431 /* TODO: limited values in v1 */
3432 { $$ = $3; }
3433 ;
3434
3435 notificationTypeClause: LOWERCASE_IDENTIFIER
3436 {
3437 thisParserPtr->firstStatementLine = thisParserPtr->line;
3438 thisParserPtr->currentDecl = SMI_DECL_NOTIFICATIONTYPE;
3439
3440 checkNameLen(thisParserPtr, $1,
3441 ERR_OIDNAME_32, ERR_OIDNAME_64);
3442 smiCheckObjectName(thisParserPtr,
3443 thisModulePtr, $1);
3444 }
3445 NOTIFICATION_TYPE
3446 {
3447 Import *importPtr;
3448
3449 if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
3450 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "NOTIFICATION-TYPE");
3451
3452 importPtr = findImportByName("NOTIFICATION-TYPE",
3453 thisModulePtr);
3454 if (importPtr) {
3455 importPtr->use++;
3456 } else {
3457 smiPrintError(thisParserPtr,
3458 ERR_MACRO_NOT_IMPORTED,
3459 "NOTIFICATION-TYPE",
3460 "SNMPv2-SMI");
3461 }
3462 }
3463 NotificationObjectsPart
3464 STATUS Status
3465 DESCRIPTION Text
3466 {
3467 checkDescr(thisParserPtr, $9);
3468 }
3469 ReferPart
3470 COLON_COLON_EQUAL
3471 '{' NotificationName '}'
3472 {
3473 Object *objectPtr;
3474
3475 objectPtr = $14;
3476
3477 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
3478
3479 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
3480 setObjectDecl(objectPtr,
3481 SMI_DECL_NOTIFICATIONTYPE);
3482 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
3483 thisParserPtr);
3484 addObjectFlags(objectPtr, FLAG_REGISTERED);
3485 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
3486 setObjectList(objectPtr, $5);
3487 setObjectStatus(objectPtr, $7);
3488 setObjectDescription(objectPtr, $9, thisParserPtr);
3489 if ($11) {
3490 setObjectReference(objectPtr, $11, thisParserPtr);
3491 }
3492 $$ = 0;
3493 }
3494 ;
3495
3496 moduleIdentityClause: LOWERCASE_IDENTIFIER
3497 {
3498 thisParserPtr->firstStatementLine = thisParserPtr->line;
3499 thisParserPtr->currentDecl = SMI_DECL_MODULEIDENTITY;
3500
3501 checkNameLen(thisParserPtr, $1,
3502 ERR_OIDNAME_32, ERR_OIDNAME_64);
3503 smiCheckObjectName(thisParserPtr,
3504 thisModulePtr, $1);
3505 }
3506 MODULE_IDENTITY
3507 {
3508 Import *importPtr;
3509
3510 importPtr = findImportByName("MODULE-IDENTITY",
3511 thisModulePtr);
3512 if (importPtr) {
3513 importPtr->use++;
3514 } else {
3515 smiPrintError(thisParserPtr,
3516 ERR_MACRO_NOT_IMPORTED,
3517 "MODULE-IDENTITY",
3518 "SNMPv2-SMI");
3519 }
3520
3521 if (thisParserPtr->modulePtr->numModuleIdentities > 0)
3522 {
3523 smiPrintError(thisParserPtr,
3524 ERR_TOO_MANY_MODULE_IDENTITIES);
3525 }
3526 if (thisParserPtr->modulePtr->numStatements > 0) {
3527 smiPrintError(thisParserPtr,
3528 ERR_MODULE_IDENTITY_NOT_FIRST);
3529 }
3530 }
3531 SubjectCategoriesPart /* SPPI only */
3532 {
3533 /* do nothing at the moment */
3534 }
3535 LAST_UPDATED ExtUTCTime
3536 {
3537 setModuleLastUpdated(thisParserPtr->modulePtr, $8);
3538 }
3539 ORGANIZATION Text
3540 {
3541 if ($11 && !strlen($11)) {
3542 smiPrintError(thisParserPtr,
3543 ERR_EMPTY_ORGANIZATION);
3544 }
3545 }
3546 CONTACT_INFO Text
3547 {
3548 if ($14 && !strlen($14)) {
3549 smiPrintError(thisParserPtr,
3550 ERR_EMPTY_CONTACT);
3551 }
3552 }
3553 DESCRIPTION Text
3554 {
3555 checkDescr(thisParserPtr, $17);
3556 }
3557 RevisionPart
3558 {
3559 if ((!thisModulePtr->firstRevisionPtr) ||
3560 (thisModulePtr->firstRevisionPtr->export.date !=
3561 thisModulePtr->lastUpdated)) {
3562 smiPrintError(thisParserPtr,
3563 ERR_REVISION_MISSING);
3564 addRevision(thisModulePtr->lastUpdated,
3565 smiStrdup(
3566 "[Revision added by libsmi due to a LAST-UPDATED clause.]"),
3567 thisParserPtr);
3568 }
3569 }
3570 COLON_COLON_EQUAL
3571 '{' objectIdentifier '}'
3572 {
3573 Object *objectPtr;
3574
3575 objectPtr = $23;
3576 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
3577
3578 thisParserPtr->modulePtr->numModuleIdentities++;
3579
3580 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
3581 setObjectDecl(objectPtr, SMI_DECL_MODULEIDENTITY);
3582 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
3583 thisParserPtr);
3584 setObjectStatus(objectPtr, SMI_STATUS_CURRENT);
3585 addObjectFlags(objectPtr, FLAG_REGISTERED);
3586 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
3587 setModuleIdentityObject(thisParserPtr->modulePtr,
3588 objectPtr);
3589 setModuleOrganization(thisParserPtr->modulePtr,
3590 $11);
3591 setModuleContactInfo(thisParserPtr->modulePtr,
3592 $14);
3593 setModuleDescription(thisParserPtr->modulePtr,
3594 $17, thisParserPtr);
3595 if ($5 != NULL) {
3596 setObjectList(objectPtr, $5->categories);
3597 smiFree($5);
3598 }
3599 /* setObjectDescription(objectPtr, $15); */
3600 $$ = 0;
3601 }
3602 ;
3603
3604 SubjectCategoriesPart: SUBJECT_CATEGORIES '{' SubjectCategories '}'
3605 {
3606 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
3607 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "SUBJECT-CATEGORIES");
3608 $$ = $3;
3609 }
3610 | /* empty */
3611 {
3612 if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
3613 smiPrintError(thisParserPtr, ERR_SUBJECT_CATEGORIES_MISSING);
3614 $$ = NULL;
3615 }
3616 ;
3617
3618 SubjectCategories: CategoryIDs
3619 {
3620 $$ = smiMalloc(sizeof(SubjectCategories));
3621 $$->categories = $1;
3622 }
3623 ;
3624
3625 CategoryIDs: CategoryID
3626 {
3627 $$ = smiMalloc(sizeof(List));
3628 $$->ptr = $1;
3629 $$->nextPtr = NULL;
3630 }
3631 | CategoryIDs ',' CategoryID
3632 {
3633 List *p, *pp;
3634
3635 if ($1->ptr == NULL)
3636 smiPrintError(thisParserPtr, ERR_SUBJECT_CATEGORIES_ALL);
3637 p = smiMalloc(sizeof(List));
3638 p->ptr = (void *)$3;
3639 p->nextPtr = NULL;
3640 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
3641 pp->nextPtr = p;
3642 $$ = $1;
3643 }
3644 ;
3645
3646 CategoryID: LOWERCASE_IDENTIFIER
3647 {
3648 Object *objectPtr;
3649
3650 if (strcmp($1, "all"))
3651 smiPrintError(thisParserPtr, ERR_SUBJECT_CATEGORIES_MISSING_SUBID);
3652 else {
3653 /*
3654 * This is not a regular object that will be added via
3655 * 'addObject' as subject category dentifier have no
3656 * other meaning in PIBs. They are just used for
3657 * a direct mapping to the actual protocol fields.
3658 */
3659 objectPtr = smiMalloc(sizeof(Object));
3660 objectPtr->export.name = "all";
3661 objectPtr->export.oidlen = 0;
3662 objectPtr->export.oid = 0;
3663 $$ = objectPtr;
3664 }
3665 smiFree($1);
3666 }
3667 | LOWERCASE_IDENTIFIER '(' NUMBER ')'
3668 {
3669 Object *objectPtr;
3670
3671 if (!strcmp($1, "all")) {
3672 smiPrintError(thisParserPtr, ERR_SUBJECT_CATEGORIES_ALL_WITH_SUBID);
3673 $$ = NULL;
3674 } else {
3675 /*
3676 * This is not a regular object that will be added via
3677 * 'addObject' as subject category dentifier have no
3678 * other meaning in PIBs. They are just used for
3679 * a direct mapping to the actual protocol fields.
3680 */
3681 objectPtr = smiMalloc(sizeof(Object));
3682 objectPtr->export.name = $1;
3683 objectPtr->export.oidlen = 1;
3684 objectPtr->export.oid = (void *)$3;
3685 $$ = objectPtr;
3686 }
3687 }
3688 ;
3689
3690 ObjectSyntax: SimpleSyntax
3691 {
3692 $$ = $1;
3693 }
3694 | typeTag SimpleSyntax
3695 {
3696 if (strcmp(thisParserPtr->modulePtr->export.name,
3697 "SNMPv2-SMI") &&
3698 strcmp(thisParserPtr->modulePtr->export.name,
3699 "SNMPv2-TC") &&
3700 strcmp(thisParserPtr->modulePtr->export.name,
3701 "SNMPv2-CONF") &&
3702 strcmp(thisParserPtr->modulePtr->export.name,
3703 "RFC-1212") &&
3704 strcmp(thisParserPtr->modulePtr->export.name,
3705 "RFC1065-SMI") &&
3706 strcmp(thisParserPtr->modulePtr->export.name,
3707 "RFC1155-SMI") &&
3708 strcmp(thisParserPtr->modulePtr->export.name,
3709 "COPS-PR-SPPI")) {
3710 smiPrintError(thisParserPtr, ERR_TYPE_TAG, $1);
3711 }
3712 $$ = $2;
3713 }
3714 | conceptualTable /* TODO: possible? row? entry? */
3715 {
3716 /* TODO */
3717 $$ = $1;
3718 }
3719 | row /* the uppercase name of a row */
3720 {
3721 /* TODO */
3722 $$ = $1;
3723 }
3724 | entryType /* SEQUENCE { ... } phrase */
3725 {
3726 /* TODO */
3727 $$ = $1;
3728 }
3729 | ApplicationSyntax
3730 {
3731 Import *importPtr;
3732
3733 if ($1 && $1->export.name) {
3734 importPtr = findImportByName($1->export.name,
3735 thisModulePtr);
3736 if (importPtr) {
3737 importPtr->use++;
3738 }
3739 }
3740
3741 /* TODO */
3742 $$ = $1;
3743 }
3744 ;
3745
3746 typeTag: '[' APPLICATION NUMBER ']' IMPLICIT
3747 { $$ = 0; /* TODO: check range */ }
3748 | '[' UNIVERSAL NUMBER ']' IMPLICIT
3749 { $$ = 0; /* TODO: check range */ }
3750 ;
3751
3752 /*
3753 * In a SEQUENCE { ... } there are no sub-types, enumerations or
3754 * named bits. REF: draft, p.29
3755 */
3756 sequenceObjectSyntax: sequenceSimpleSyntax
3757 { $$ = $1; }
3758 /* | conceptualTable /* TODO: possible? row? entry? */
3759 /* | row /* the uppercase name of a row */
3760 /* | entryType /* it's SEQUENCE { ... } phrase */
3761 | sequenceApplicationSyntax
3762 {
3763 Import *importPtr;
3764
3765 if ($1 && $1->export.name) {
3766 importPtr = findImportByName($1->export.name,
3767 thisModulePtr);
3768 if (importPtr) {
3769 importPtr->use++;
3770 }
3771 }
3772
3773 /* TODO */
3774 $$ = $1;
3775 }
3776 ;
3777
3778 valueofObjectSyntax: valueofSimpleSyntax
3779 { $$ = $1; }
3780 /* conceptualTables and rows do not have DEFVALs
3781 */
3782 /* valueofApplicationSyntax would not introduce any
3783 * further syntax of ObjectSyntax values.
3784 */
3785 ;
3786
3787 SimpleSyntax: INTEGER /* (-2147483648..2147483647) */
3788 {
3789 if ((thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
3790 &&
3791 (strcmp(thisModulePtr->export.name, "SNMPv2-SMI") &&
3792 strcmp(thisModulePtr->export.name, "SNMPv2-TC") &&
3793 strcmp(thisModulePtr->export.name, "COPS-PR-SPPI")))
3794 smiPrintError(thisParserPtr,
3795 ERR_INTEGER_IN_SMIV2);
3796
3797 defaultBasetype = SMI_BASETYPE_INTEGER32;
3798 $$ = smiHandle->typeInteger32Ptr;
3799 }
3800 | INTEGER
3801 {
3802 defaultBasetype = SMI_BASETYPE_INTEGER32;
3803 }
3804 integerSubType
3805 {
3806 if ((thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
3807 &&
3808 (strcmp(thisModulePtr->export.name, "SNMPv2-SMI") &&
3809 strcmp(thisModulePtr->export.name, "SNMPv2-TC") &&
3810 strcmp(thisModulePtr->export.name, "COPS-PR-SPPI")))
3811 smiPrintError(thisParserPtr,
3812 ERR_INTEGER_IN_SMIV2);
3813
3814 $$ = duplicateType(smiHandle->typeInteger32Ptr, 0,
3815 thisParserPtr);
3816 setTypeList($$, $3);
3817 smiCheckTypeRanges(thisParserPtr, $$);
3818 }
3819 | INTEGER
3820 {
3821 defaultBasetype = SMI_BASETYPE_ENUM;
3822 }
3823 enumSpec
3824 {
3825 List *p;
3826
3827 $$ = duplicateType(smiHandle->typeEnumPtr, 0,
3828 thisParserPtr);
3829 setTypeList($$, $3);
3830 for (p = $3; p; p = p->nextPtr)
3831 ((NamedNumber *)p->ptr)->typePtr = $$;
3832 smiCheckNamedNumbersOrder(parserPtr, $$);
3833 }
3834 | INTEGER32 /* (-2147483648..2147483647) */
3835 {
3836 Import *importPtr;
3837
3838 defaultBasetype = SMI_BASETYPE_INTEGER32;
3839 importPtr = findImportByName("Integer32",
3840 thisModulePtr);
3841 if (importPtr) {
3842 importPtr->use++;
3843 } else {
3844 if (thisModulePtr->export.language ==
3845 SMI_LANGUAGE_SMIV2) {
3846 smiPrintError(thisParserPtr,
3847 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
3848 "Integer32");
3849 } else if (thisModulePtr->export.language ==
3850 SMI_LANGUAGE_SPPI) {
3851 smiPrintError(thisParserPtr,
3852 ERR_SPPI_BASETYPE_NOT_IMPORTED,
3853 "Integer32");
3854 }
3855 }
3856
3857 /* TODO: any need to distinguish from INTEGER? */
3858 $$ = smiHandle->typeInteger32Ptr;
3859 }
3860 | INTEGER32
3861 {
3862 defaultBasetype = SMI_BASETYPE_INTEGER32;
3863 }
3864 integerSubType
3865 {
3866 Import *importPtr;
3867
3868 importPtr = findImportByName("Integer32",
3869 thisModulePtr);
3870 if (importPtr) {
3871 importPtr->use++;
3872 } else {
3873 if (thisModulePtr->export.language ==
3874 SMI_LANGUAGE_SMIV2) {
3875 smiPrintError(thisParserPtr,
3876 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
3877 "Integer32");
3878 } else if (thisModulePtr->export.language ==
3879 SMI_LANGUAGE_SPPI) {
3880 smiPrintError(thisParserPtr,
3881 ERR_SPPI_BASETYPE_NOT_IMPORTED,
3882 "Integer32");
3883 }
3884 }
3885
3886 $$ = duplicateType(smiHandle->typeInteger32Ptr, 0,
3887 thisParserPtr);
3888 setTypeList($$, $3);
3889 smiCheckTypeRanges(thisParserPtr, $$);
3890 }
3891 | UPPERCASE_IDENTIFIER
3892 {
3893 defaultBasetype = SMI_BASETYPE_ENUM;
3894 }
3895 enumSpec
3896 {
3897 Type *parentPtr;
3898 Import *importPtr;
3899 List *p;
3900
3901 parentPtr = findTypeByModuleAndName(
3902 thisParserPtr->modulePtr, $1);
3903 if (!parentPtr) {
3904 importPtr = findImportByName($1,
3905 thisModulePtr);
3906 if (importPtr &&
3907 importPtr->kind == KIND_TYPE) {
3908 importPtr->use++;
3909 parentPtr = findTypeByModulenameAndName(
3910 importPtr->export.module, $1);
3911 }
3912 }
3913 if (parentPtr) {
3914 if ((parentPtr->export.basetype !=
3915 SMI_BASETYPE_ENUM) &&
3916 (parentPtr->export.basetype !=
3917 SMI_BASETYPE_BITS)) {
3918 smiPrintError(thisParserPtr,
3919 ERR_ILLEGAL_ENUM_FOR_PARENT_TYPE,
3920 $1);
3921 $$ = duplicateType(smiHandle->typeEnumPtr, 0,
3922 thisParserPtr);
3923 } else {
3924 $$ = duplicateType(parentPtr, 0,
3925 thisParserPtr);
3926 }
3927 smiFree($1);
3928 } else {
3929 /*
3930 * forward referenced type. create it,
3931 * marked with FLAG_INCOMPLETE.
3932 */
3933 parentPtr = addType($1,
3934 SMI_BASETYPE_UNKNOWN,
3935 FLAG_INCOMPLETE,
3936 thisParserPtr);
3937 $$ = duplicateType(parentPtr, 0,
3938 thisParserPtr);
3939 }
3940 setTypeList($$, $3);
3941 for (p = $3; p; p = p->nextPtr)
3942 ((NamedNumber *)p->ptr)->typePtr = $$;
3943 smiCheckNamedNumbersOrder(parserPtr, $$);
3944 }
3945 | moduleName '.' UPPERCASE_IDENTIFIER enumSpec
3946 /* TODO: UPPERCASE_IDENTIFIER must be an INTEGER */
3947 {
3948 Type *parentPtr;
3949 Import *importPtr;
3950 List *p;
3951
3952 defaultBasetype = SMI_BASETYPE_ENUM;
3953 parentPtr = findTypeByModulenameAndName($1, $3);
3954 if (!parentPtr) {
3955 importPtr =
3956 findImportByModulenameAndName($1,
3957 $3, thisModulePtr);
3958 if (importPtr &&
3959 importPtr->kind == KIND_TYPE) {
3960 importPtr->use++;
3961 parentPtr =
3962 findTypeByModulenameAndName($1, $3);
3963 }
3964 }
3965 if (parentPtr) {
3966 if ((parentPtr->export.basetype !=
3967 SMI_BASETYPE_ENUM) &&
3968 (parentPtr->export.basetype !=
3969 SMI_BASETYPE_BITS)) {
3970 smiPrintError(thisParserPtr,
3971 ERR_ILLEGAL_ENUM_FOR_PARENT_TYPE,
3972 $3);
3973 $$ = duplicateType(smiHandle->typeEnumPtr, 0,
3974 thisParserPtr);
3975 } else {
3976 $$ = duplicateType(parentPtr, 0,
3977 thisParserPtr);
3978 }
3979 } else {
3980 smiPrintError(thisParserPtr,
3981 ERR_UNKNOWN_TYPE, $3);
3982 $$ = duplicateType(smiHandle->typeEnumPtr, 0,
3983 thisParserPtr);
3984 }
3985 setTypeList($$, $4);
3986 for (p = $4; p; p = p->nextPtr)
3987 ((NamedNumber *)p->ptr)->typePtr = $$;
3988 smiCheckNamedNumbersOrder(parserPtr, $$);
3989 smiFree($1);
3990 smiFree($3);
3991 }
3992 | UPPERCASE_IDENTIFIER integerSubType
3993 {
3994 Type *parentPtr;
3995 Import *importPtr;
3996
3997 parentPtr = findTypeByModuleAndName(
3998 thisParserPtr->modulePtr, $1);
3999 if (!parentPtr) {
4000 importPtr = findImportByName($1,
4001 thisModulePtr);
4002 if (importPtr &&
4003 importPtr->kind == KIND_TYPE) {
4004 importPtr->use++;
4005 parentPtr = findTypeByModulenameAndName(
4006 importPtr->export.module, $1);
4007 }
4008 }
4009 if (parentPtr) {
4010 if ((parentPtr->export.basetype !=
4011 SMI_BASETYPE_INTEGER32) &&
4012 (parentPtr->export.basetype !=
4013 SMI_BASETYPE_INTEGER64) &&
4014 (parentPtr->export.basetype !=
4015 SMI_BASETYPE_UNSIGNED32) &&
4016 (parentPtr->export.basetype !=
4017 SMI_BASETYPE_UNSIGNED64)) {
4018 smiPrintError(thisParserPtr,
4019 ERR_ILLEGAL_RANGE_FOR_PARENT_TYPE,
4020 $1);
4021 $$ = duplicateType(smiHandle->typeInteger32Ptr, 0,
4022 thisParserPtr);
4023 defaultBasetype = SMI_BASETYPE_INTEGER32;
4024 } else {
4025 defaultBasetype =
4026 parentPtr->export.basetype;
4027 $$ = duplicateType(parentPtr, 0,
4028 thisParserPtr);
4029 }
4030 smiFree($1);
4031 } else {
4032 /*
4033 * forward referenced type. create it,
4034 * marked with FLAG_INCOMPLETE.
4035 */
4036 parentPtr = addType($1,
4037 SMI_BASETYPE_UNKNOWN,
4038 FLAG_INCOMPLETE,
4039 thisParserPtr);
4040 $$ = duplicateType(parentPtr, 0,
4041 thisParserPtr);
4042 defaultBasetype = SMI_BASETYPE_INTEGER32;
4043 }
4044 setTypeList($$, $2);
4045 smiCheckTypeRanges(thisParserPtr, $$);
4046 }
4047 | moduleName '.' UPPERCASE_IDENTIFIER integerSubType
4048 /* TODO: UPPERCASE_IDENTIFIER must be an INT/Int32. */
4049 {
4050 Type *parentPtr;
4051 Import *importPtr;
4052
4053 parentPtr = findTypeByModulenameAndName($1, $3);
4054 if (!parentPtr) {
4055 importPtr = findImportByModulenameAndName($1,
4056 $3, thisModulePtr);
4057 if (importPtr &&
4058 importPtr->kind == KIND_TYPE) {
4059 importPtr->use++;
4060 parentPtr = findTypeByModulenameAndName(
4061 $1, $3);
4062 }
4063 }
4064 if (parentPtr) {
4065 if ((parentPtr->export.basetype !=
4066 SMI_BASETYPE_INTEGER32) &&
4067 (parentPtr->export.basetype !=
4068 SMI_BASETYPE_INTEGER64) &&
4069 (parentPtr->export.basetype !=
4070 SMI_BASETYPE_UNSIGNED32) &&
4071 (parentPtr->export.basetype !=
4072 SMI_BASETYPE_UNSIGNED64)) {
4073 smiPrintError(thisParserPtr,
4074 ERR_ILLEGAL_RANGE_FOR_PARENT_TYPE,
4075 $3);
4076 $$ = duplicateType(smiHandle->typeInteger32Ptr, 0,
4077 thisParserPtr);
4078 defaultBasetype = SMI_BASETYPE_INTEGER32;
4079 } else {
4080 defaultBasetype =
4081 parentPtr->export.basetype;
4082 $$ = duplicateType(parentPtr, 0,
4083 thisParserPtr);
4084 }
4085 } else {
4086 smiPrintError(thisParserPtr,
4087 ERR_UNKNOWN_TYPE, $3);
4088 $$ = duplicateType(smiHandle->typeInteger32Ptr, 0,
4089 thisParserPtr);
4090 defaultBasetype = SMI_BASETYPE_INTEGER32;
4091 }
4092 setTypeList($$, $4);
4093 smiCheckTypeRanges(thisParserPtr, $$);
4094 smiFree($1);
4095 smiFree($3);
4096 }
4097 | OCTET STRING /* (SIZE (0..65535)) */
4098 {
4099 defaultBasetype = SMI_BASETYPE_OCTETSTRING;
4100 $$ = smiHandle->typeOctetStringPtr;
4101 }
4102 | OCTET STRING
4103 {
4104 defaultBasetype = SMI_BASETYPE_OCTETSTRING;
4105 }
4106 octetStringSubType
4107 {
4108
4109 $$ = duplicateType(smiHandle->typeOctetStringPtr, 0,
4110 thisParserPtr);
4111 setTypeList($$, $4);
4112 smiCheckTypeRanges(thisParserPtr, $$);
4113 }
4114 | UPPERCASE_IDENTIFIER octetStringSubType
4115 {
4116 Type *parentPtr;
4117 Import *importPtr;
4118
4119 defaultBasetype = SMI_BASETYPE_OCTETSTRING;
4120 parentPtr = findTypeByModuleAndName(
4121 thisParserPtr->modulePtr, $1);
4122 if (!parentPtr) {
4123 importPtr = findImportByName($1,
4124 thisModulePtr);
4125 if (importPtr &&
4126 importPtr->kind == KIND_TYPE) {
4127 importPtr->use++;
4128 parentPtr = findTypeByModulenameAndName(
4129 importPtr->export.module, $1);
4130 }
4131 }
4132 if (parentPtr) {
4133 if (parentPtr->export.basetype !=
4134 SMI_BASETYPE_OCTETSTRING) {
4135 smiPrintError(thisParserPtr,
4136 ERR_ILLEGAL_SIZE_FOR_PARENT_TYPE,
4137 $1);
4138 $$ = duplicateType(smiHandle->typeOctetStringPtr, 0,
4139 thisParserPtr);
4140 } else {
4141 $$ = duplicateType(parentPtr, 0,
4142 thisParserPtr);
4143 }
4144 smiFree($1);
4145 } else {
4146 /*
4147 * forward referenced type. create it,
4148 * marked with FLAG_INCOMPLETE.
4149 */
4150 parentPtr = addType($1,
4151 SMI_BASETYPE_UNKNOWN,
4152 FLAG_INCOMPLETE,
4153 thisParserPtr);
4154 $$ = duplicateType(parentPtr, 0,
4155 thisParserPtr);
4156 }
4157 setTypeList($$, $2);
4158 smiCheckTypeRanges(thisParserPtr, $$);
4159 }
4160 | moduleName '.' UPPERCASE_IDENTIFIER octetStringSubType
4161 /* TODO: UPPERCASE_IDENTIFIER must be an OCTET STR. */
4162 {
4163 Type *parentPtr;
4164 Import *importPtr;
4165
4166 defaultBasetype = SMI_BASETYPE_OCTETSTRING;
4167 parentPtr = findTypeByModulenameAndName($1, $3);
4168 if (!parentPtr) {
4169 importPtr = findImportByModulenameAndName($1,
4170 $3, thisModulePtr);
4171 if (importPtr &&
4172 importPtr->kind == KIND_TYPE) {
4173 importPtr->use++;
4174 parentPtr = findTypeByModulenameAndName(
4175 $1, $3);
4176 }
4177 }
4178 if (parentPtr) {
4179 if (parentPtr->export.basetype !=
4180 SMI_BASETYPE_OCTETSTRING) {
4181 smiPrintError(thisParserPtr,
4182 ERR_ILLEGAL_SIZE_FOR_PARENT_TYPE,
4183 $3);
4184 $$ = duplicateType(smiHandle->typeOctetStringPtr, 0,
4185 thisParserPtr);
4186 } else {
4187 $$ = duplicateType(parentPtr, 0,
4188 thisParserPtr);
4189 }
4190 } else {
4191 smiPrintError(thisParserPtr,
4192 ERR_UNKNOWN_TYPE, $3);
4193 $$ = duplicateType(smiHandle->typeOctetStringPtr, 0,
4194 thisParserPtr);
4195 }
4196 setTypeList($$, $4);
4197 smiCheckTypeRanges(thisParserPtr, $$);
4198 smiFree($1);
4199 smiFree($3);
4200 }
4201 | OBJECT IDENTIFIER anySubType
4202 {
4203 defaultBasetype = SMI_BASETYPE_OBJECTIDENTIFIER;
4204 $$ = smiHandle->typeObjectIdentifierPtr;
4205 }
4206 ;
4207
4208 valueofSimpleSyntax: NUMBER /* 0..2147483647 */
4209 /* NOTE: Counter64 must not have a DEFVAL */
4210 {
4211 $$ = smiMalloc(sizeof(SmiValue));
4212 $$->basetype = SMI_BASETYPE_UNSIGNED32;
4213 $$->value.unsigned32 = $1;
4214 }
4215 | NEGATIVENUMBER /* -2147483648..0 */
4216 {
4217 $$ = smiMalloc(sizeof(SmiValue));
4218 $$->basetype = SMI_BASETYPE_INTEGER32;
4219 $$->value.integer32 = $1;
4220 }
4221 | NUMBER64 /* 0..18446744073709551615 */
4222 {
4223 /* The scanner already checks for the language */
4224 $$ = smiMalloc(sizeof(SmiValue));
4225 $$->basetype = SMI_BASETYPE_UNSIGNED64;
4226 $$->value.unsigned64 = $1;
4227 }
4228 | NEGATIVENUMBER64 /* -9223372036854775807..0 */
4229 {
4230 /* The scanner already checks for the language */
4231 $$ = smiMalloc(sizeof(SmiValue));
4232 $$->basetype = SMI_BASETYPE_INTEGER64;
4233 $$->value.integer64 = $1;
4234 }
4235 | BIN_STRING /* number or OCTET STRING */
4236 {
4237 char s[9];
4238 int i, len, j;
4239
4240 $$ = smiMalloc(sizeof(SmiValue));
4241 if (defaultBasetype == SMI_BASETYPE_OCTETSTRING) {
4242 $$->basetype = SMI_BASETYPE_OCTETSTRING;
4243 len = strlen($1);
4244 $$->value.ptr =
4245 smiMalloc((len+7)/8+1);
4246 for (i = 0; i < len; i += 8) {
4247 strncpy(s, &$1[i], 8);
4248 for (j = 1; j < 8; j++) {
4249 if (!s[j]) s[j] = '0';
4250 }
4251 s[8] = 0;
4252 $$->value.ptr[i/8] =
4253 (unsigned char)strtol(s, 0, 2);
4254 }
4255 $$->len = (len+7)/8;
4256 } else {
4257 $$->basetype = SMI_BASETYPE_UNSIGNED32;
4258 $$->value.unsigned32 = strtoul($1, NULL, 2);
4259 }
4260 }
4261 | HEX_STRING /* number or OCTET STRING */
4262 {
4263 char s[3];
4264 int i, len;
4265
4266 $$ = smiMalloc(sizeof(SmiValue));
4267 if (defaultBasetype == SMI_BASETYPE_OCTETSTRING) {
4268 $$->basetype = SMI_BASETYPE_OCTETSTRING;
4269 len = strlen($1);
4270 $$->value.ptr = smiMalloc((len+1)/2+1);
4271 for (i = 0; i < len; i += 2) {
4272 strncpy(s, &$1[i], 2);
4273 if (!s[1]) s[1] = '0';
4274 s[2] = 0;
4275 $$->value.ptr[i/2] =
4276 (unsigned char)strtol(s, 0, 16);
4277 }
4278 $$->len = (len+1)/2;
4279 } else {
4280 $$->basetype = SMI_BASETYPE_UNSIGNED32;
4281 $$->value.unsigned32 = strtoul($1, NULL, 16);
4282 }
4283 }
4284 | LOWERCASE_IDENTIFIER /* enumeration or named oid */
4285 {
4286 $$ = smiMalloc(sizeof(SmiValue));
4287 if ((defaultBasetype != SMI_BASETYPE_ENUM) &&
4288 (defaultBasetype != SMI_BASETYPE_OBJECTIDENTIFIER)) {
4289 smiPrintError(thisParserPtr, ERR_DEFVAL_SYNTAX);
4290 $$->basetype = defaultBasetype;
4291 if (defaultBasetype == SMI_BASETYPE_ENUM) {
4292 $$->len = 1;
4293 $$->value.unsigned32 = 0;
4294 } else {
4295 $$->len = 0;
4296 $$->value.ptr = NULL;
4297 }
4298 } else {
4299 $$->basetype = defaultBasetype;
4300 $$->len = -1; /* indicates unresolved ptr */
4301 $$->value.ptr = $1; /* JS: needs strdup? */
4302 }
4303 }
4304 | QUOTED_STRING /* an OCTET STRING */
4305 {
4306 $$ = smiMalloc(sizeof(SmiValue));
4307 $$->basetype = SMI_BASETYPE_OCTETSTRING;
4308 $$->value.ptr = smiStrdup($1);
4309 $$->len = strlen($1);
4310 }
4311 /* NOTE: If the value is an OBJECT IDENTIFIER, then
4312 * it must be expressed as a single ASN.1
4313 * identifier, and not as a collection of
4314 * of sub-identifiers.
4315 * REF: draft,p.34
4316 * Anyway, we try to accept it. But it's only
4317 * possible for numbered sub-identifiers, since
4318 * other identifiers would make something like
4319 * { gaga } indistiguishable from a BitsValue.
4320 */
4321 | '{' objectIdentifier_defval '}'
4322 /*
4323 * This is only for some MIBs with invalid numerical
4324 * OID notation for DEFVALs. We DO NOT parse them
4325 * correctly. We just don't want to produce a
4326 * parser error.
4327 */
4328 {
4329 /*
4330 * SMIv1 allows something like { 0 0 } !
4331 * SMIv2 does not!
4332 */
4333 /* TODO: make it work correctly for SMIv1 */
4334 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2) {
4335 smiPrintError(thisParserPtr,
4336 ERR_OID_DEFVAL_TOO_LONG_SMIV2);
4337 } else {
4338 smiPrintError(thisParserPtr,
4339 ERR_OID_DEFVAL_TOO_LONG_SMIV1);
4340 }
4341 $$ = smiMalloc(sizeof(SmiValue));
4342 $$->basetype = SMI_BASETYPE_OBJECTIDENTIFIER;
4343 $$->len = 2;
4344 $$->value.oid = smiMalloc(2 * sizeof(SmiSubid));
4345 $$->value.oid[0] = 0;
4346 $$->value.oid[1] = 0;
4347 }
4348 ;
4349
4350 /*
4351 * In a SEQUENCE { ... } there are no sub-types, enumerations or
4352 * named bits. REF: draft, p.29
4353 */
4354 sequenceSimpleSyntax: INTEGER anySubType
4355 {
4356 $$ = smiHandle->typeInteger32Ptr;
4357 }
4358 | INTEGER32 anySubType
4359 {
4360 Import *importPtr;
4361
4362 /* TODO: any need to distinguish from INTEGER? */
4363 $$ = smiHandle->typeInteger32Ptr;
4364
4365 importPtr = findImportByName("Integer32",
4366 thisModulePtr);
4367 if (importPtr) {
4368 importPtr->use++;
4369 } else {
4370 if (thisModulePtr->export.language ==
4371 SMI_LANGUAGE_SMIV2) {
4372 smiPrintError(thisParserPtr,
4373 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4374 "Integer32");
4375 } else if (thisModulePtr->export.language ==
4376 SMI_LANGUAGE_SPPI) {
4377 smiPrintError(thisParserPtr,
4378 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4379 "Integer32");
4380 }
4381 }
4382 }
4383 | OCTET STRING anySubType
4384 {
4385 $$ = smiHandle->typeOctetStringPtr;
4386 }
4387 | OBJECT IDENTIFIER anySubType
4388 {
4389 $$ = smiHandle->typeObjectIdentifierPtr;
4390 }
4391 ;
4392
4393 ApplicationSyntax: IPADDRESS anySubType
4394 {
4395 Import *importPtr;
4396
4397 $$ = findTypeByName("IpAddress");
4398 if (! $$) {
4399 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4400 "IpAddress");
4401 }
4402
4403 importPtr = findImportByName("IpAddress",
4404 thisModulePtr);
4405 if (importPtr) {
4406 importPtr->use++;
4407 } else {
4408 if (thisModulePtr->export.language ==
4409 SMI_LANGUAGE_SMIV2) {
4410 smiPrintError(thisParserPtr,
4411 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4412 "IpAddress");
4413 } else if (thisModulePtr->export.language ==
4414 SMI_LANGUAGE_SPPI) {
4415 smiPrintError(thisParserPtr,
4416 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4417 "IpAddress");
4418 }
4419 }
4420 }
4421 | COUNTER32 anySubType /* (0..4294967295) */
4422 {
4423 Import *importPtr;
4424
4425 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4426 !findImportByName("Counter32", thisParserPtr->modulePtr))
4427 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "COUNTER32");
4428 $$ = findTypeByName("Counter32");
4429 if (! $$) {
4430 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4431 "Counter32");
4432 }
4433
4434 importPtr = findImportByName("Counter32",
4435 thisModulePtr);
4436 if (importPtr) {
4437 importPtr->use++;
4438 } else {
4439 if (thisModulePtr->export.language ==
4440 SMI_LANGUAGE_SMIV2) {
4441 smiPrintError(thisParserPtr,
4442 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4443 "Counter32");
4444 }
4445 }
4446 }
4447 | COUNTER32 integerSubType
4448 {
4449 Import *importPtr;
4450 List *listPtr, *nextListPtr;
4451
4452 smiPrintError(thisParserPtr,
4453 ERR_ILLEGAL_RANGE_FOR_COUNTER,
4454 "Counter32");
4455 for (listPtr = $2; listPtr;
4456 listPtr = nextListPtr) {
4457 nextListPtr = listPtr->nextPtr;
4458 smiFree((Range *)listPtr->ptr);
4459 smiFree(listPtr);
4460 }
4461
4462 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4463 !findImportByName("Counter32", thisParserPtr->modulePtr))
4464 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Counter32");
4465 $$ = findTypeByName("Counter32");
4466 if (! $$) {
4467 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4468 "Counter32");
4469 }
4470
4471 importPtr = findImportByName("Counter32",
4472 thisModulePtr);
4473 if (importPtr) {
4474 importPtr->use++;
4475 } else {
4476 if (thisModulePtr->export.language ==
4477 SMI_LANGUAGE_SMIV2) {
4478 smiPrintError(thisParserPtr,
4479 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4480 "Counter32");
4481 }
4482 }
4483 }
4484 | GAUGE32 /* (0..4294967295) */
4485 {
4486 Import *importPtr;
4487
4488 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4489 !findImportByName("Gauge32", thisParserPtr->modulePtr))
4490 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Gauge32");
4491 $$ = findTypeByName("Gauge32");
4492 if (! $$) {
4493 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4494 "Gauge32");
4495 }
4496
4497 importPtr = findImportByName("Gauge32",
4498 thisModulePtr);
4499 if (importPtr) {
4500 importPtr->use++;
4501 } else {
4502 if (thisModulePtr->export.language ==
4503 SMI_LANGUAGE_SMIV2) {
4504 smiPrintError(thisParserPtr,
4505 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4506 "Gauge32");
4507 }
4508 }
4509 }
4510 | GAUGE32 integerSubType
4511 {
4512 Type *parentPtr;
4513 Import *importPtr;
4514
4515 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4516 !findImportByName("Gauge32", thisParserPtr->modulePtr))
4517 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Gauge32");
4518 parentPtr = findTypeByName("Gauge32");
4519 if (! parentPtr) {
4520 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4521 "Gauge32");
4522 $$ = NULL;
4523 } else {
4524 $$ = duplicateType(parentPtr, 0,
4525 thisParserPtr);
4526 setTypeList($$, $2);
4527 smiCheckTypeRanges(thisParserPtr, $$);
4528 }
4529
4530 importPtr = findImportByName("Gauge32",
4531 thisModulePtr);
4532 if (importPtr) {
4533 importPtr->use++;
4534 } else {
4535 if (thisModulePtr->export.language ==
4536 SMI_LANGUAGE_SMIV2) {
4537 smiPrintError(thisParserPtr,
4538 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4539 "Gauge32");
4540 }
4541 }
4542 }
4543 | UNSIGNED32 /* (0..4294967295) */
4544 {
4545 Import *importPtr;
4546
4547 $$ = smiHandle->typeUnsigned32Ptr;
4548
4549 importPtr = findImportByName("Unsigned32",
4550 thisModulePtr);
4551 if (importPtr) {
4552 importPtr->use++;
4553 } else {
4554 if (thisModulePtr->export.language ==
4555 SMI_LANGUAGE_SMIV2) {
4556 smiPrintError(thisParserPtr,
4557 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4558 "Unsigned32");
4559 } else if (thisModulePtr->export.language ==
4560 SMI_LANGUAGE_SPPI) {
4561 smiPrintError(thisParserPtr,
4562 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4563 "Unsigned32");
4564 }
4565 }
4566 }
4567 | UNSIGNED32 integerSubType
4568 {
4569 Import *importPtr;
4570
4571 $$ = duplicateType(smiHandle->typeUnsigned32Ptr, 0,
4572 thisParserPtr);
4573 setTypeList($$, $2);
4574 smiCheckTypeRanges(thisParserPtr, $$);
4575
4576 importPtr = findImportByName("Unsigned32",
4577 thisModulePtr);
4578 if (importPtr) {
4579 importPtr->use++;
4580 } else {
4581 if (thisModulePtr->export.language ==
4582 SMI_LANGUAGE_SMIV2) {
4583 smiPrintError(thisParserPtr,
4584 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4585 "Unsigned32");
4586 } else if (thisModulePtr->export.language ==
4587 SMI_LANGUAGE_SPPI) {
4588 smiPrintError(thisParserPtr,
4589 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4590 "Unsigned32");
4591 }
4592 }
4593 }
4594 | TIMETICKS anySubType
4595 {
4596 Import *importPtr;
4597
4598 $$ = findTypeByName("TimeTicks");
4599 if (! $$) {
4600 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4601 "TimeTicks");
4602 }
4603
4604 importPtr = findImportByName("TimeTicks",
4605 thisModulePtr);
4606 if (importPtr) {
4607 importPtr->use++;
4608 } else {
4609 if (thisModulePtr->export.language ==
4610 SMI_LANGUAGE_SMIV2) {
4611 smiPrintError(thisParserPtr,
4612 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4613 "TimeTicks");
4614 } else if (thisModulePtr->export.language ==
4615 SMI_LANGUAGE_SPPI) {
4616 smiPrintError(thisParserPtr,
4617 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4618 "TimeTicks");
4619 }
4620 }
4621 }
4622 | OPAQUE /* IMPLICIT OCTET STRING */
4623 {
4624 Import *importPtr;
4625
4626 $$ = findTypeByName("Opaque");
4627 if (! $$) {
4628 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4629 "Opaque");
4630 } else {
4631 if (thisModulePtr->export.language ==
4632 SMI_LANGUAGE_SMIV2) {
4633 smiPrintError(thisParserPtr,
4634 ERR_SMIV2_OPAQUE_OBSOLETE);
4635 } else if (thisModulePtr->export.language ==
4636 SMI_LANGUAGE_SPPI) {
4637 smiPrintError(thisParserPtr,
4638 ERR_SPPI_OPAQUE_OBSOLETE);
4639 }
4640 }
4641
4642 importPtr = findImportByName("Opaque",
4643 thisModulePtr);
4644 if (importPtr) {
4645 importPtr->use++;
4646 } else {
4647 if (thisModulePtr->export.language ==
4648 SMI_LANGUAGE_SMIV2) {
4649 smiPrintError(thisParserPtr,
4650 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4651 "Opaque");
4652 } else if (thisModulePtr->export.language ==
4653 SMI_LANGUAGE_SPPI) {
4654 smiPrintError(thisParserPtr,
4655 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4656 "Opaque");
4657 }
4658 }
4659 }
4660 | OPAQUE octetStringSubType
4661 {
4662 Type *parentPtr;
4663 Import *importPtr;
4664
4665 parentPtr = findTypeByName("Opaque");
4666 if (! parentPtr) {
4667 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4668 "Opaque");
4669 $$ = NULL;
4670 } else {
4671 if (thisModulePtr->export.language ==
4672 SMI_LANGUAGE_SMIV2) {
4673 smiPrintError(thisParserPtr,
4674 ERR_SMIV2_OPAQUE_OBSOLETE,
4675 "Opaque");
4676 } else if (thisModulePtr->export.language ==
4677 SMI_LANGUAGE_SPPI) {
4678 smiPrintError(thisParserPtr,
4679 ERR_SPPI_OPAQUE_OBSOLETE,
4680 "Opaque");
4681 }
4682 $$ = duplicateType(parentPtr, 0,
4683 thisParserPtr);
4684 setTypeList($$, $2);
4685 smiCheckTypeRanges(thisParserPtr, $$);
4686 }
4687
4688 importPtr = findImportByName("Opaque",
4689 thisModulePtr);
4690 if (importPtr) {
4691 importPtr->use++;
4692 } else {
4693 if (thisModulePtr->export.language ==
4694 SMI_LANGUAGE_SMIV2) {
4695 smiPrintError(thisParserPtr,
4696 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4697 "Opaque");
4698 } else if (thisModulePtr->export.language ==
4699 SMI_LANGUAGE_SPPI) {
4700 smiPrintError(thisParserPtr,
4701 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4702 "Opaque");
4703 }
4704 }
4705 }
4706 | COUNTER64 anySubType /* (0..18446744073709551615) */
4707 {
4708 Import *importPtr;
4709
4710 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4711 !findImportByName("Counter64", thisParserPtr->modulePtr))
4712 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Counter64");
4713 $$ = findTypeByName("Counter64");
4714 if (! $$) {
4715 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4716 "Counter64");
4717 }
4718
4719 importPtr = findImportByName("Counter64",
4720 thisModulePtr);
4721 if (importPtr) {
4722 importPtr->use++;
4723 } else {
4724 if (thisModulePtr->export.language ==
4725 SMI_LANGUAGE_SMIV2) {
4726 smiPrintError(thisParserPtr,
4727 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4728 "Counter64");
4729 }
4730 }
4731 }
4732 | COUNTER64 integerSubType
4733 {
4734 Import *importPtr;
4735 List *listPtr, *nextListPtr;
4736
4737 smiPrintError(thisParserPtr,
4738 ERR_ILLEGAL_RANGE_FOR_COUNTER,
4739 "Counter64");
4740 for (listPtr = $2; listPtr;
4741 listPtr = nextListPtr) {
4742 nextListPtr = listPtr->nextPtr;
4743 smiFree((Range *)listPtr->ptr);
4744 smiFree(listPtr);
4745 }
4746
4747 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4748 !findImportByName("Counter64", thisParserPtr->modulePtr))
4749 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Counter64");
4750 $$ = findTypeByName("Counter64");
4751 if (! $$) {
4752 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4753 "Counter64");
4754 }
4755
4756 importPtr = findImportByName("Counter64",
4757 thisModulePtr);
4758 if (importPtr) {
4759 importPtr->use++;
4760 } else {
4761 if (thisModulePtr->export.language ==
4762 SMI_LANGUAGE_SMIV2) {
4763 smiPrintError(thisParserPtr,
4764 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4765 "Counter64");
4766 }
4767 }
4768 }
4769 | INTEGER64 /* (-9223372036854775807..9223372036854775807) */
4770 {
4771 Import *importPtr;
4772
4773 $$ = findTypeByModulenameAndName(
4774 thisParserPtr->modulePtr->export.name, "Integer64");
4775 if (! $$) {
4776 importPtr = findImportByName("Integer64",
4777 thisModulePtr);
4778 if (!importPtr) {
4779 $$ = findTypeByName("Integer64");
4780 if ((thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)) {
4781 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "Integer64");
4782 } else {
4783 smiPrintError(thisParserPtr,
4784 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4785 "Integer64");
4786 }
4787 } else {
4788 importPtr->use++;
4789 $$ = findTypeByModulenameAndName(
4790 importPtr->export.module,
4791 importPtr->export.name);
4792 }
4793 }
4794 }
4795 | INTEGER64 integerSubType
4796 {
4797 Type *parentPtr;
4798 Import *importPtr;
4799
4800 parentPtr = findTypeByModulenameAndName(
4801 thisParserPtr->modulePtr->export.name, "Integer64");
4802 if (! parentPtr) {
4803 importPtr = findImportByName("Integer64",
4804 thisModulePtr);
4805 if (!importPtr) {
4806 parentPtr = findTypeByName("Integer64");
4807 if ((thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)) {
4808 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "Integer64");
4809 } else {
4810 smiPrintError(thisParserPtr,
4811 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4812 "Integer64");
4813 }
4814 } else {
4815 importPtr->use++;
4816 parentPtr = findTypeByModulenameAndName(
4817 importPtr->export.module,
4818 importPtr->export.name);
4819 }
4820 }
4821 if (! parentPtr) {
4822 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4823 "Integer64");
4824 $$ = NULL;
4825 } else {
4826 $$ = duplicateType(parentPtr, 0,
4827 thisParserPtr);
4828 setTypeList($$, $2);
4829 smiCheckTypeRanges(thisParserPtr, $$);
4830 }
4831 }
4832 | UNSIGNED64 /* (0..18446744073709551615) */
4833 {
4834 Import *importPtr;
4835
4836 $$ = findTypeByModulenameAndName(
4837 thisParserPtr->modulePtr->export.name, "Unsigned64");
4838 if (! $$) {
4839 importPtr = findImportByName("Unsigned64",
4840 thisModulePtr);
4841 if (!importPtr) {
4842 $$ = findTypeByName("Unsigned64");
4843 if ((thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)) {
4844 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "Unsigned64");
4845 } else {
4846 smiPrintError(thisParserPtr,
4847 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4848 "Unsigned64");
4849 }
4850 } else {
4851 importPtr->use++;
4852 $$ = findTypeByModulenameAndName(
4853 importPtr->export.module,
4854 importPtr->export.name);
4855 }
4856 }
4857 }
4858 | UNSIGNED64 integerSubType
4859 {
4860 Type *parentPtr;
4861 Import *importPtr;
4862
4863 parentPtr = findTypeByModulenameAndName(
4864 thisParserPtr->modulePtr->export.name, "Unsigned64");
4865 if (! parentPtr) {
4866 importPtr = findImportByName("Unsigned64",
4867 thisModulePtr);
4868 if (!importPtr) {
4869 parentPtr = findTypeByName("Unsigned64");
4870 if ((thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)) {
4871 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "Unsigned64");
4872 } else {
4873 smiPrintError(thisParserPtr,
4874 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4875 "Unsigned64");
4876 }
4877 } else {
4878 importPtr->use++;
4879 parentPtr = findTypeByModulenameAndName(
4880 importPtr->export.module,
4881 importPtr->export.name);
4882 }
4883 }
4884 if (! parentPtr) {
4885 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4886 "Unsigned64");
4887 $$ = NULL;
4888 } else {
4889 $$ = duplicateType(parentPtr, 0,
4890 thisParserPtr);
4891 setTypeList($$, $2);
4892 smiCheckTypeRanges(thisParserPtr, $$);
4893 }
4894 }
4895 ;
4896
4897 /*
4898 * In a SEQUENCE { ... } there are no sub-types, enumerations or
4899 * named bits. REF: draft, p.29
4900 */
4901 sequenceApplicationSyntax: IPADDRESS anySubType
4902 {
4903 Import *importPtr;
4904
4905 $$ = findTypeByName("IpAddress");
4906 if (! $$) {
4907 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4908 "IpAddress");
4909 }
4910
4911 importPtr = findImportByName("IpAddress",
4912 thisModulePtr);
4913 if (importPtr) {
4914 importPtr->use++;
4915 } else {
4916 if (thisModulePtr->export.language ==
4917 SMI_LANGUAGE_SMIV2) {
4918 smiPrintError(thisParserPtr,
4919 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4920 "IpAddress");
4921 } else if (thisModulePtr->export.language ==
4922 SMI_LANGUAGE_SPPI) {
4923 smiPrintError(thisParserPtr,
4924 ERR_SPPI_BASETYPE_NOT_IMPORTED,
4925 "IpAddress");
4926 }
4927 }
4928 }
4929 | COUNTER32 anySubType
4930 {
4931 Import *importPtr;
4932
4933 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4934 !findImportByName("Counter32", thisParserPtr->modulePtr))
4935 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Counter32");
4936 $$ = findTypeByName("Counter32");
4937 if (! $$) {
4938 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4939 "Counter32");
4940 }
4941
4942 importPtr = findImportByName("Counter32",
4943 thisModulePtr);
4944 if (importPtr) {
4945 importPtr->use++;
4946 } else {
4947 if (thisModulePtr->export.language ==
4948 SMI_LANGUAGE_SMIV2) {
4949 smiPrintError(thisParserPtr,
4950 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4951 "Counter32");
4952 }
4953 }
4954 }
4955 | GAUGE32 anySubType /* (0..4294967295) */
4956 {
4957 Import *importPtr;
4958
4959 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
4960 !findImportByName("Gauge32", thisParserPtr->modulePtr))
4961 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Gauge32");
4962 $$ = findTypeByName("Gauge32");
4963 if (! $$) {
4964 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
4965 "Gauge32");
4966 }
4967
4968 importPtr = findImportByName("Gauge32",
4969 thisModulePtr);
4970 if (importPtr) {
4971 importPtr->use++;
4972 } else {
4973 if (thisModulePtr->export.language ==
4974 SMI_LANGUAGE_SMIV2) {
4975 smiPrintError(thisParserPtr,
4976 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4977 "Gauge32");
4978 }
4979 }
4980 }
4981 | UNSIGNED32 anySubType /* (0..4294967295) */
4982 {
4983 Import *importPtr;
4984
4985 $$ = smiHandle->typeUnsigned32Ptr;
4986
4987 importPtr = findImportByName("Unsigned32",
4988 thisModulePtr);
4989 if (importPtr) {
4990 importPtr->use++;
4991 } else {
4992 if (thisModulePtr->export.language ==
4993 SMI_LANGUAGE_SMIV2) {
4994 smiPrintError(thisParserPtr,
4995 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
4996 "Unsigned32");
4997 } else if (thisModulePtr->export.language ==
4998 SMI_LANGUAGE_SPPI) {
4999 smiPrintError(thisParserPtr,
5000 ERR_SPPI_BASETYPE_NOT_IMPORTED,
5001 "Unsigned32");
5002 }
5003 }
5004 }
5005 | TIMETICKS anySubType /* (0..4294967295) */
5006 {
5007 Import *importPtr;
5008
5009 $$ = findTypeByName("TimeTicks");
5010 if (! $$) {
5011 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
5012 "TimeTicks");
5013 }
5014
5015 importPtr = findImportByName("TimeTicks",
5016 thisModulePtr);
5017 if (importPtr) {
5018 importPtr->use++;
5019 } else {
5020 if (thisModulePtr->export.language ==
5021 SMI_LANGUAGE_SMIV2) {
5022 smiPrintError(thisParserPtr,
5023 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
5024 "TimeTicks");
5025 } else if (thisModulePtr->export.language ==
5026 SMI_LANGUAGE_SPPI) {
5027 smiPrintError(thisParserPtr,
5028 ERR_SPPI_BASETYPE_NOT_IMPORTED,
5029 "TimeTicks");
5030 }
5031 }
5032 }
5033 | OPAQUE /* IMPLICIT OCTET STRING */
5034 {
5035 Import *importPtr;
5036
5037 $$ = findTypeByName("Opaque");
5038 if (! $$) {
5039 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
5040 "Opaque");
5041 } else {
5042 if (thisModulePtr->export.language ==
5043 SMI_LANGUAGE_SMIV2) {
5044 smiPrintError(thisParserPtr,
5045 ERR_SMIV2_OPAQUE_OBSOLETE,
5046 "Opaque");
5047 } else if (thisModulePtr->export.language ==
5048 SMI_LANGUAGE_SPPI) {
5049 smiPrintError(thisParserPtr,
5050 ERR_SPPI_OPAQUE_OBSOLETE,
5051 "Opaque");
5052 }
5053 }
5054
5055 importPtr = findImportByName("Opaque",
5056 thisModulePtr);
5057 if (importPtr) {
5058 importPtr->use++;
5059 } else {
5060 if (thisModulePtr->export.language ==
5061 SMI_LANGUAGE_SMIV2) {
5062 smiPrintError(thisParserPtr,
5063 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
5064 "Opaque");
5065 } else if (thisModulePtr->export.language ==
5066 SMI_LANGUAGE_SPPI) {
5067 smiPrintError(thisParserPtr,
5068 ERR_SPPI_BASETYPE_NOT_IMPORTED,
5069 "Opaque");
5070 }
5071 }
5072 }
5073 | COUNTER64 anySubType /* (0..18446744073709551615) */
5074 {
5075 Import *importPtr;
5076
5077 if ((thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI) &&
5078 !findImportByName("Counter64", thisModulePtr))
5079 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "Counter64");
5080 $$ = findTypeByName("Counter64");
5081 if (! $$) {
5082 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
5083 "Counter64");
5084 }
5085
5086 importPtr = findImportByName("Counter64",
5087 thisModulePtr);
5088 if (importPtr) {
5089 importPtr->use++;
5090 } else {
5091 if (thisModulePtr->export.language ==
5092 SMI_LANGUAGE_SMIV2) {
5093 smiPrintError(thisParserPtr,
5094 ERR_SMIV2_BASETYPE_NOT_IMPORTED,
5095 "Counter64");
5096 }
5097 }
5098 }
5099 | INTEGER64 /* (-9223372036854775807..9223372036854775807) */
5100 {
5101 Import *importPtr;
5102
5103 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
5104 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "Integer64");
5105 $$ = findTypeByName("Integer64");
5106 if (! $$) {
5107 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
5108 "Integer64");
5109 }
5110
5111 importPtr = findImportByName("Integer64",
5112 thisModulePtr);
5113 if (importPtr) {
5114 importPtr->use++;
5115 } else {
5116 if (thisModulePtr->export.language ==
5117 SMI_LANGUAGE_SPPI) {
5118 smiPrintError(thisParserPtr,
5119 ERR_SPPI_BASETYPE_NOT_IMPORTED,
5120 "Integer64");
5121 }
5122 }
5123 }
5124 | UNSIGNED64 /* (0..18446744073709551615) */
5125 {
5126 Import *importPtr;
5127
5128 importPtr = findImportByName("Unsigned64",
5129 thisModulePtr);
5130 if ((thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI) && (!importPtr))
5131 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "Unsigned64");
5132 $$ = findTypeByName("Unsigned64");
5133 if (! $$) {
5134 smiPrintError(thisParserPtr, ERR_UNKNOWN_TYPE,
5135 "Unsigned64");
5136 }
5137
5138 if (importPtr) {
5139 importPtr->use++;
5140 } else {
5141 if (thisModulePtr->export.language ==
5142 SMI_LANGUAGE_SPPI) {
5143 smiPrintError(thisParserPtr,
5144 ERR_SPPI_BASETYPE_NOT_IMPORTED,
5145 "Unsigned64");
5146 }
5147 }
5148 }
5149 ;
5150
5151 anySubType: integerSubType
5152 {
5153 List *listPtr, *nextListPtr;
5154
5155 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
5156 smiPrintError(thisParserPtr,
5157 ERR_UNEXPECTED_TYPE_RESTRICTION);
5158
5159 for (listPtr = $1; listPtr;
5160 listPtr = nextListPtr) {
5161 nextListPtr = listPtr->nextPtr;
5162 smiFree((Range *)(listPtr->ptr));
5163 smiFree(listPtr);
5164 }
5165
5166 $$ = NULL;
5167 }
5168 | octetStringSubType
5169 {
5170 List *listPtr, *nextListPtr;
5171
5172 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
5173 smiPrintError(thisParserPtr,
5174 ERR_UNEXPECTED_TYPE_RESTRICTION);
5175
5176 for (listPtr = $1; listPtr;
5177 listPtr = nextListPtr) {
5178 nextListPtr = listPtr->nextPtr;
5179 smiFree((Range *)(listPtr->ptr));
5180 smiFree(listPtr);
5181 }
5182
5183 $$ = NULL;
5184 }
5185 | enumSpec
5186 {
5187 List *listPtr, *nextListPtr;
5188
5189 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
5190 smiPrintError(thisParserPtr,
5191 ERR_UNEXPECTED_TYPE_RESTRICTION);
5192
5193 for (listPtr = $1; listPtr;
5194 listPtr = nextListPtr) {
5195 nextListPtr = listPtr->nextPtr;
5196 smiFree(((NamedNumber *)(listPtr->ptr))->export.name);
5197 smiFree((NamedNumber *)(listPtr->ptr));
5198 smiFree(listPtr);
5199 }
5200
5201 $$ = NULL;
5202 }
5203 | /* empty */
5204 {
5205 $$ = NULL;
5206 }
5207 ;
5208
5209
5210 /* REF: draft,p.46 */
5211 integerSubType: '(' ranges ')' /* at least one range */
5212 /*
5213 * the specification mentions an alternative of an
5214 * empty RHS here. this would lead to reduce/reduce
5215 * conflicts. instead, we differentiate the parent
5216 * rule(s) (SimpleSyntax).
5217 */
5218 { $$ = $2; }
5219 ;
5220
5221 octetStringSubType: '(' SIZE '(' ranges ')' ')'
5222 /*
5223 * the specification mentions an alternative of an
5224 * empty RHS here. this would lead to reduce/reduce
5225 * conflicts. instead, we differentiate the parent
5226 * rule(s) (SimpleSyntax).
5227 */
5228 {
5229 $$ = $4;
5230 }
5231 ;
5232
5233 ranges: range
5234 {
5235 $$ = smiMalloc(sizeof(List));
5236 $$->ptr = $1;
5237 $$->nextPtr = NULL;
5238 }
5239 | ranges '|' range
5240 {
5241 List *p, *pp;
5242
5243 p = smiMalloc(sizeof(List));
5244 p->ptr = (void *)$3;
5245 p->nextPtr = NULL;
5246 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
5247 pp->nextPtr = p;
5248
5249 $$ = $1;
5250 }
5251 ;
5252
5253 range: value
5254 {
5255 $$ = smiMalloc(sizeof(Range));
5256 $$->export.minValue = *$1;
5257 $$->export.maxValue = *$1;
5258 smiFree($1);
5259 }
5260 | value DOT_DOT value
5261 {
5262 $$ = smiMalloc(sizeof(Range));
5263 $$->export.minValue = *$1;
5264 $$->export.maxValue = *$3;
5265 smiFree($1);
5266 smiFree($3);
5267 }
5268 ;
5269
5270 value: NEGATIVENUMBER
5271 {
5272 $$ = smiMalloc(sizeof(SmiValue));
5273 $$->basetype = SMI_BASETYPE_INTEGER32;
5274 $$->value.integer32 = $1;
5275 }
5276 | NUMBER
5277 {
5278 $$ = smiMalloc(sizeof(SmiValue));
5279 $$->basetype = SMI_BASETYPE_UNSIGNED32;
5280 $$->value.unsigned32 = $1;
5281 }
5282 | NEGATIVENUMBER64
5283 {
5284 $$ = smiMalloc(sizeof(SmiValue));
5285 $$->basetype = SMI_BASETYPE_INTEGER64;
5286 $$->value.integer64 = $1;
5287 }
5288 | NUMBER64
5289 {
5290 $$ = smiMalloc(sizeof(SmiValue));
5291 $$->basetype = SMI_BASETYPE_UNSIGNED64;
5292 $$->value.unsigned64 = $1;
5293 }
5294 | HEX_STRING
5295 {
5296 char s[3];
5297 int i, len;
5298
5299 $$ = smiMalloc(sizeof(SmiValue));
5300 if (defaultBasetype == SMI_BASETYPE_OCTETSTRING) {
5301 $$->basetype = SMI_BASETYPE_OCTETSTRING;
5302 len = strlen($1);
5303 $$->value.ptr = smiMalloc((len+1)/2+1);
5304 for (i = 0; i < len; i += 2) {
5305 strncpy(s, &$1[i], 2);
5306 if (!s[1]) s[1] = '0';
5307 s[2] = 0;
5308 $$->value.ptr[i/2] =
5309 (unsigned char)strtol(s, 0, 16);
5310 }
5311 $$->len = (len+1)/2;
5312 } else {
5313 $$->basetype = SMI_BASETYPE_UNSIGNED32;
5314 $$->value.unsigned32 = strtoul($1, NULL, 16);
5315 }
5316 }
5317 | BIN_STRING
5318 {
5319 char s[9];
5320 int i, len, j;
5321
5322 $$ = smiMalloc(sizeof(SmiValue));
5323 if (defaultBasetype == SMI_BASETYPE_OCTETSTRING) {
5324 $$->basetype = SMI_BASETYPE_OCTETSTRING;
5325 len = strlen($1);
5326 $$->value.ptr = smiMalloc((len+7)/8+1);
5327 for (i = 0; i < len; i += 8) {
5328 strncpy(s, &$1[i], 8);
5329 for (j = 1; j < 8; j++) {
5330 if (!s[j]) s[j] = '0';
5331 }
5332 s[8] = 0;
5333 $$->value.ptr[i/8] =
5334 (unsigned char)strtol(s, 0, 2);
5335 }
5336 $$->len = (len+7)/8;
5337 } else {
5338 $$->basetype = SMI_BASETYPE_UNSIGNED32;
5339 $$->value.unsigned32 = strtoul($1, NULL, 2);
5340 }
5341 }
5342 ;
5343
5344 enumSpec: '{' enumItems '}'
5345 {
5346 $$ = $2;
5347 }
5348 ;
5349
5350 enumItems: enumItem
5351 {
5352 $$ = smiMalloc(sizeof(List));
5353 $$->ptr = $1;
5354 $$->nextPtr = NULL;
5355 }
5356 | enumItems ',' enumItem
5357 {
5358 List *p, *pp;
5359
5360 p = smiMalloc(sizeof(List));
5361 p->ptr = (void *)$3;
5362 p->nextPtr = NULL;
5363 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
5364 pp->nextPtr = p;
5365 $$ = $1;
5366 }
5367 ;
5368
5369 enumItem: LOWERCASE_IDENTIFIER
5370 {
5371 checkNameLen(thisParserPtr, $1,
5372 ERR_ENUMNAME_32, ERR_ENUMNAME_64);
5373 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
5374 {
5375 if (strchr($1, '-')) {
5376 smiPrintError(thisParserPtr,
5377 ERR_NAMEDNUMBER_INCLUDES_HYPHEN,
5378 $1);
5379 }
5380 }
5381 }
5382 '(' enumNumber ')'
5383 {
5384 $$ = smiMalloc(sizeof(NamedNumber));
5385 $$->export.name = $1;
5386 $$->export.value = *$4;
5387 smiFree($4);
5388 }
5389 ;
5390
5391 enumNumber: NUMBER
5392 {
5393 if ($1 > SMI_BASETYPE_INTEGER32_MAX) {
5394 smiPrintError(thisParserPtr,
5395 ERR_INTEGER32_TOO_LARGE, $1);
5396 }
5397 if ((thisModulePtr->export.language == SMI_LANGUAGE_SMIV1) &&
5398 ($1 == 0)) {
5399 smiPrintError(thisParserPtr,
5400 ERR_ENUM_ZERO);
5401 }
5402 $$ = smiMalloc(sizeof(SmiValue));
5403 $$->basetype = SMI_BASETYPE_INTEGER32;
5404 $$->value.integer32 = $1;
5405 }
5406 | NEGATIVENUMBER
5407 {
5408 $$ = smiMalloc(sizeof(SmiValue));
5409 $$->basetype = SMI_BASETYPE_INTEGER32;
5410 $$->value.integer32 = $1;
5411 /* TODO: non-negative is suggested */
5412 }
5413 ;
5414
5415 Status: LOWERCASE_IDENTIFIER
5416 {
5417 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
5418 {
5419 if (!strcmp($1, "current")) {
5420 $$ = SMI_STATUS_CURRENT;
5421 } else if (!strcmp($1, "deprecated")) {
5422 $$ = SMI_STATUS_DEPRECATED;
5423 } else if (!strcmp($1, "obsolete")) {
5424 $$ = SMI_STATUS_OBSOLETE;
5425 } else {
5426 smiPrintError(thisParserPtr,
5427 ERR_INVALID_SMIV2_STATUS,
5428 $1);
5429 if (!strcmp($1, "mandatory")
5430 || !strcmp($1, "optional")) {
5431 /* best guess */
5432 $$ = SMI_STATUS_CURRENT;
5433 } else {
5434 $$ = SMI_STATUS_UNKNOWN;
5435 }
5436 }
5437 } else if (thisModulePtr->export.language != SMI_LANGUAGE_SPPI) {
5438 if (!strcmp($1, "mandatory")) {
5439 $$ = SMI_STATUS_MANDATORY;
5440 } else if (!strcmp($1, "optional")) {
5441 $$ = SMI_STATUS_OPTIONAL;
5442 } else if (!strcmp($1, "obsolete")) {
5443 $$ = SMI_STATUS_OBSOLETE;
5444 } else if (!strcmp($1, "deprecated")) {
5445 $$ = SMI_STATUS_OBSOLETE;
5446 } else {
5447 smiPrintError(thisParserPtr,
5448 ERR_INVALID_SMIV1_STATUS,
5449 $1);
5450 if (!strcmp($1, "current")) {
5451 /* best guess */
5452 $$ = SMI_STATUS_MANDATORY;
5453 } else {
5454 $$ = SMI_STATUS_UNKNOWN;
5455 }
5456 }
5457 } else { /* it is SPPI */
5458 if (!strcmp($1, "current")) {
5459 $$ = SMI_STATUS_CURRENT;
5460 } else if (!strcmp($1, "obsolete")) {
5461 $$ = SMI_STATUS_OBSOLETE;
5462 } else if (!strcmp($1, "deprecated")) {
5463 $$ = SMI_STATUS_OBSOLETE;
5464 } else {
5465 smiPrintError(thisParserPtr,
5466 ERR_INVALID_SPPI_STATUS, $1);
5467 $$ = SMI_STATUS_UNKNOWN;
5468 }
5469 }
5470 smiFree($1);
5471 }
5472 ;
5473
5474 Status_Capabilities: LOWERCASE_IDENTIFIER
5475 {
5476 if (!strcmp($1, "current")) {
5477 $$ = SMI_STATUS_CURRENT;
5478 } else if (!strcmp($1, "obsolete")) {
5479 $$ = SMI_STATUS_OBSOLETE;
5480 } else {
5481 smiPrintError(thisParserPtr,
5482 ERR_INVALID_CAPABILITIES_STATUS,
5483 $1);
5484 $$ = SMI_STATUS_UNKNOWN;
5485 }
5486 smiFree($1);
5487 }
5488 ;
5489
5490 DisplayPart: DISPLAY_HINT Text
5491 {
5492 $$ = $2;
5493
5494 if ($2 && !strlen($2)) {
5495 smiPrintError(thisParserPtr,
5496 ERR_EMPTY_FORMAT);
5497 }
5498 }
5499 | /* empty */
5500 {
5501 $$ = NULL;
5502 }
5503 ;
5504
5505 UnitsPart: UNITS Text
5506 {
5507 $$ = $2;
5508
5509 if ($2 && !strlen($2)) {
5510 smiPrintError(thisParserPtr,
5511 ERR_EMPTY_UNITS);
5512 }
5513 }
5514 | /* empty */
5515 {
5516 $$ = NULL;
5517 }
5518 ;
5519
5520 Access: LOWERCASE_IDENTIFIER
5521 {
5522 if (thisModulePtr->export.language == SMI_LANGUAGE_SMIV2)
5523 {
5524 if (!strcmp($1, "not-accessible")) {
5525 $$ = SMI_ACCESS_NOT_ACCESSIBLE;
5526 } else if (!strcmp($1,
5527 "accessible-for-notify")) {
5528 $$ = SMI_ACCESS_NOTIFY;
5529 } else if (!strcmp($1, "read-only")) {
5530 $$ = SMI_ACCESS_READ_ONLY;
5531 } else if (!strcmp($1, "read-write")) {
5532 $$ = SMI_ACCESS_READ_WRITE;
5533 } else if (!strcmp($1, "read-create")) {
5534 $$ = SMI_ACCESS_READ_WRITE;
5535 thisParserPtr->flags |= FLAG_CREATABLE;
5536 /* TODO:remember it's really read-create */
5537 } else if (!strcmp($1, "write-only")) {
5538 smiPrintError(thisParserPtr,
5539 ERR_SMIV2_WRITE_ONLY);
5540 $$ = SMI_ACCESS_READ_WRITE;
5541 } else {
5542 smiPrintError(thisParserPtr,
5543 ERR_INVALID_SMIV2_ACCESS,
5544 $1);
5545 $$ = SMI_ACCESS_UNKNOWN;
5546 }
5547 } else if (thisModulePtr->export.language != SMI_LANGUAGE_SPPI) {
5548 if (!strcmp($1, "not-accessible")) {
5549 $$ = SMI_ACCESS_NOT_ACCESSIBLE;
5550 } else if (!strcmp($1, "read-only")) {
5551 $$ = SMI_ACCESS_READ_ONLY;
5552 } else if (!strcmp($1, "read-write")) {
5553 $$ = SMI_ACCESS_READ_WRITE;
5554 } else if (!strcmp($1, "write-only")) {
5555 smiPrintError(thisParserPtr,
5556 ERR_SMIV1_WRITE_ONLY);
5557 $$ = SMI_ACCESS_READ_WRITE;
5558 } else {
5559 smiPrintError(thisParserPtr,
5560 ERR_INVALID_SMIV1_ACCESS,
5561 $1);
5562 $$ = SMI_ACCESS_UNKNOWN;
5563 }
5564 } else {
5565 if (!strcmp($1, "install")) {
5566 $$ = SMI_ACCESS_INSTALL;
5567 } else if (!strcmp($1, "install-notify")) {
5568 $$ = SMI_ACCESS_INSTALL_NOTIFY;
5569 } else if (!strcmp($1, "notify")) {
5570 $$ = SMI_ACCESS_NOTIFY;
5571 } else if (!strcmp($1, "report-only")) {
5572 $$ = SMI_ACCESS_REPORT_ONLY;
5573 } else if (!strcmp($1, "not-accessible")) {
5574 $$ = SMI_ACCESS_NOT_ACCESSIBLE;
5575 } else {
5576 smiPrintError(thisParserPtr,
5577 ERR_INVALID_SPPI_ACCESS,
5578 $1);
5579 $$ = SMI_ACCESS_UNKNOWN;
5580 }
5581 }
5582 smiFree($1);
5583 }
5584 ;
5585
5586 IndexPart: PIB_INDEX
5587 {
5588 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
5589 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "PIB-INDEX");
5590 }
5591 '{' Entry '}'
5592 {
5593 List *p = smiMalloc(sizeof(List));
5594
5595 p->ptr = $4;
5596 p->nextPtr = NULL;
5597
5598 $$.indexkind = SMI_INDEX_INDEX;
5599 $$.implied = impliedFlag;
5600 $$.listPtr = p;
5601 $$.rowPtr = NULL;
5602 indexFlag = INDEXFLAG_PIBINDEX;
5603 }
5604 | AUGMENTS '{' Entry '}'
5605 /* TODO: no AUGMENTS clause in v1 */
5606 /* TODO: how to differ INDEX and AUGMENTS ? */
5607 {
5608 $$.indexkind = SMI_INDEX_AUGMENT;
5609 $$.implied = 0;
5610 $$.listPtr = NULL;
5611 $$.rowPtr = $3;
5612 indexFlag = INDEXFLAG_AUGMENTS;
5613 }
5614 | EXTENDS
5615 {
5616 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
5617 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "EXTENDS");
5618 }
5619 '{' Entry '}'
5620 {
5621 $$.indexkind = SMI_INDEX_SPARSE;
5622 $$.implied = 0;
5623 $$.listPtr = NULL;
5624 $$.rowPtr = $4;
5625 indexFlag = INDEXFLAG_EXTENDS;
5626 }
5627 | /* empty */
5628 {
5629 $$.indexkind = SMI_INDEX_UNKNOWN;
5630 }
5631 ;
5632
5633 MibIndex: INDEX
5634 {
5635 /*
5636 * To avoid ambiguity caused by merging
5637 * the SMI and SPPI parser we use a flag.
5638 */
5639 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI) {
5640 /*
5641 * Only INDEX or AUGMENTS are allowed for SMI
5642 */
5643 if (indexFlag != INDEXFLAG_NONE)
5644 smiPrintError(thisParserPtr, ERR_INDEX_AND_AUGMENTS_USED);
5645 } else {
5646 /*
5647 * INDEX may only be used if PIB_INDEX was used
5648 */
5649 if (indexFlag != INDEXFLAG_PIBINDEX)
5650 smiPrintError(thisParserPtr, ERR_INDEX_WITHOUT_PIB_INDEX);
5651 }
5652
5653 /*
5654 * Use a global variable to fetch and remember
5655 * whether we have seen an IMPLIED keyword.
5656 */
5657 impliedFlag = 0;
5658 }
5659 '{' IndexTypes '}'
5660 {
5661 $$.indexkind = SMI_INDEX_INDEX;
5662 $$.implied = impliedFlag;
5663 $$.listPtr = $4;
5664 $$.rowPtr = NULL;
5665 }
5666 | /* empty */
5667 {
5668 $$.indexkind = SMI_INDEX_UNKNOWN;
5669 }
5670 ;
5671
5672 IndexTypes: IndexType
5673 {
5674 $$ = smiMalloc(sizeof(List));
5675 $$->ptr = $1;
5676 $$->nextPtr = NULL;
5677 }
5678 | IndexTypes ',' IndexType
5679 /* TODO: might this list be emtpy? */
5680 {
5681 List *p, *pp;
5682
5683 p = smiMalloc(sizeof(List));
5684 p->ptr = $3;
5685 p->nextPtr = NULL;
5686 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
5687 pp->nextPtr = p;
5688 $$ = $1;
5689 }
5690 ;
5691
5692 IndexType: IMPLIED Index
5693 {
5694 impliedFlag = 1;
5695 $$ = $2;
5696 }
5697 | Index
5698 {
5699 $$ = $1;
5700 }
5701 ;
5702
5703 Index: ObjectName
5704 /*
5705 * TODO: use the SYNTAX value of the correspondent
5706 * OBJECT-TYPE invocation
5707 */
5708 {
5709 $$ = $1;
5710 }
5711 ;
5712
5713 Entry: ObjectName
5714 {
5715 $$ = $1;
5716 }
5717 ;
5718
5719 DefValPart: DEFVAL '{' Value '}'
5720 {
5721 $$ = $3;
5722 if ((defaultBasetype == SMI_BASETYPE_BITS) &&
5723 ($$->basetype != SMI_BASETYPE_BITS)) {
5724 smiPrintError(thisParserPtr,
5725 ERR_DEFVAL_SYNTAX);
5726 if ($$->basetype == SMI_BASETYPE_OCTETSTRING) {
5727 smiFree($$->value.ptr);
5728 }
5729 smiFree($$);
5730 $$ = NULL;
5731 }
5732 }
5733 | /* empty */
5734 { $$ = NULL; }
5735 /* TODO: different for DefValPart in AgentCaps ? */
5736 ;
5737
5738 Value: valueofObjectSyntax
5739 { $$ = $1; }
5740 | '{' BitsValue '}'
5741 {
5742 $$ = smiMalloc(sizeof(SmiValue));
5743 $$->basetype = SMI_BASETYPE_BITS;
5744 $$->value.ptr = (void *)$2;
5745 }
5746 ;
5747
5748 BitsValue: BitNames
5749 { $$ = $1; }
5750 | /* empty */
5751 { $$ = NULL; }
5752 ;
5753
5754 BitNames: LOWERCASE_IDENTIFIER
5755 {
5756 $$ = smiMalloc(sizeof(List));
5757 $$->ptr = $1;
5758 $$->nextPtr = NULL;
5759 }
5760 | BitNames ',' LOWERCASE_IDENTIFIER
5761 {
5762 List *p, *pp;
5763
5764 p = smiMalloc(sizeof(List));
5765 p->ptr = $3;
5766 p->nextPtr = NULL;
5767 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
5768 pp->nextPtr = p;
5769 $$ = $1;
5770 }
5771 ;
5772
5773 ObjectName: objectIdentifier
5774 {
5775 $$ = $1;
5776 }
5777 ;
5778
5779 NotificationName: objectIdentifier
5780 {
5781 $$ = $1;
5782 }
5783 ;
5784
5785 ReferPart: REFERENCE Text
5786 {
5787 $$ = $2;
5788
5789 if ($2 && !strlen($2)) {
5790 smiPrintError(thisParserPtr,
5791 ERR_EMPTY_REFERENCE);
5792 }
5793 }
5794 | /* empty */
5795 { $$ = NULL; }
5796 ;
5797
5798 RevisionPart: Revisions
5799 { $$ = 0; }
5800 | /* empty */
5801 { $$ = 0; }
5802 ;
5803
5804 Revisions: Revision
5805 { $$ = 0; }
5806 | Revisions Revision
5807 { $$ = 0; }
5808 ;
5809
5810 Revision: REVISION ExtUTCTime
5811 {
5812 thisParserPtr->firstRevisionLine = thisParserPtr->line;
5813
5814 if (thisParserPtr->modulePtr->lastRevisionPtr &&
5815 ($2 >= thisParserPtr->modulePtr->lastRevisionPtr->export.date)) {
5816 smiPrintError(thisParserPtr,
5817 ERR_REVISION_NOT_DESCENDING);
5818 }
5819
5820 if ($2 > thisParserPtr->modulePtr->lastUpdated) {
5821 smiPrintError(thisParserPtr,
5822 ERR_REVISION_AFTER_LAST_UPDATE);
5823 }
5824 }
5825 DESCRIPTION Text
5826 {
5827 Revision *revisionPtr;
5828
5829 checkDescr(thisParserPtr, $5);
5830
5831 revisionPtr = addRevision($2, $5, thisParserPtr);
5832 if (revisionPtr) {
5833 setRevisionLine(revisionPtr,
5834 thisParserPtr->firstRevisionLine,
5835 thisParserPtr);
5836 }
5837 $$ = revisionPtr ? 0 : -1;
5838 }
5839 ;
5840
5841 NotificationObjectsPart: OBJECTS '{' Objects '}'
5842 {
5843 $$ = $3;
5844 }
5845 | /* empty */
5846 {
5847 $$ = NULL;
5848 }
5849 ;
5850
5851 ObjectGroupObjectsPart: OBJECTS '{' Objects '}'
5852 {
5853 $$ = $3;
5854 }
5855 ;
5856
5857 Objects: Object
5858 {
5859 $$ = smiMalloc(sizeof(List));
5860 $$->ptr = $1;
5861 $$->nextPtr = NULL;
5862 }
5863 | Objects ',' Object
5864 {
5865 List *p, *pp;
5866
5867 p = smiMalloc(sizeof(List));
5868 p->ptr = $3;
5869 p->nextPtr = NULL;
5870 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
5871 pp->nextPtr = p;
5872 $$ = $1;
5873 }
5874 ;
5875
5876 Object: ObjectName
5877 {
5878 $$ = $1;
5879 if ((thisParserPtr->currentDecl == SMI_DECL_OBJECTGROUP) &&
5880 $$->modulePtr != thisParserPtr->modulePtr) {
5881 smiPrintError(thisParserPtr,
5882 ERR_COMPLIANCE_MEMBER_NOT_LOCAL,
5883 $$->export.name);
5884 }
5885 }
5886 ;
5887
5888 NotificationsPart: NOTIFICATIONS '{' Notifications '}'
5889 {
5890 $$ = $3;
5891 }
5892 ;
5893
5894 Notifications: Notification
5895 {
5896 $$ = smiMalloc(sizeof(List));
5897 $$->ptr = $1;
5898 $$->nextPtr = NULL;
5899 }
5900 | Notifications ',' Notification
5901 {
5902 List *p, *pp;
5903
5904 p = smiMalloc(sizeof(List));
5905 p->ptr = $3;
5906 p->nextPtr = NULL;
5907 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
5908 pp->nextPtr = p;
5909 $$ = $1;
5910 }
5911 ;
5912
5913 Notification: NotificationName
5914 {
5915 $$ = $1;
5916 if ($$->modulePtr != thisParserPtr->modulePtr) {
5917 smiPrintError(thisParserPtr,
5918 ERR_COMPLIANCE_MEMBER_NOT_LOCAL,
5919 $$->export.name);
5920 }
5921 }
5922 ;
5923
5924 Text: QUOTED_STRING
5925 {
5926 int len;
5927 $$ = smiStrdup($1);
5928 len = strlen($$);
5929 while (len > 0 && $$[len-1] == '\n') {
5930 $$[--len] = 0;
5931 }
5932 }
5933 ;
5934
5935 ExtUTCTime: QUOTED_STRING
5936 {
5937 $$ = checkDate(thisParserPtr, $1);
5938 }
5939 ;
5940
5941 objectIdentifier: {
5942 thisParserPtr->parentNodePtr = smiHandle->rootNodePtr;
5943 }
5944 subidentifiers
5945 {
5946 $$ = $2;
5947 if ($$) {
5948 thisParserPtr->parentNodePtr = $2->nodePtr;
5949 } else {
5950 thisParserPtr->parentNodePtr = NULL;
5951 }
5952 }
5953 ;
5954
5955 subidentifiers:
5956 subidentifier
5957 {
5958 $$ = $1;
5959 }
5960 | subidentifiers
5961 subidentifier
5962 {
5963 $$ = $2;
5964 }
5965 ;
5966
5967 subidentifier:
5968 /* LOWERCASE_IDENTIFIER */
5969 fuzzy_lowercase_identifier
5970 {
5971 Object *objectPtr;
5972 Import *importPtr;
5973
5974 if (thisParserPtr->parentNodePtr != smiHandle->rootNodePtr) {
5975 smiPrintError(thisParserPtr,
5976 ERR_OIDLABEL_NOT_FIRST, $1);
5977 }
5978 objectPtr = findObjectByModuleAndName(
5979 thisParserPtr->modulePtr, $1);
5980 if (objectPtr) {
5981 $$ = objectPtr;
5982 smiFree($1);
5983 } else {
5984 importPtr = findImportByName($1,
5985 thisModulePtr);
5986 if (!importPtr ||
5987 (importPtr->kind == KIND_NOTFOUND)) {
5988 /*
5989 * If we are in a MODULE-COMPLIANCE
5990 * statement with a given MODULE...
5991 */
5992 if (thisParserPtr->complianceModulePtr) {
5993 objectPtr =
5994 findObjectByModuleAndName(
5995 thisParserPtr->complianceModulePtr, $1);
5996 if (objectPtr) {
5997 importPtr = addImport(
5998 $1,
5999 thisParserPtr);
6000 setImportModulename(importPtr,
6001 thisParserPtr->complianceModulePtr->export.name);
6002 addImportFlags(importPtr,
6003 FLAG_INCOMPLIANCE);
6004 importPtr->use++;
6005 } else {
6006 objectPtr = addObject($1,
6007 thisParserPtr->pendingNodePtr, 0,
6008 FLAG_INCOMPLETE,
6009 thisParserPtr);
6010 smiPrintError(thisParserPtr,
6011 ERR_IDENTIFIER_NOT_IN_MODULE, $1,
6012 thisParserPtr->complianceModulePtr->export.name);
6013 }
6014 } else if (thisParserPtr->capabilitiesModulePtr) {
6015 objectPtr =
6016 findObjectByModuleAndName(
6017 thisParserPtr->capabilitiesModulePtr, $1);
6018 if (objectPtr) {
6019 importPtr = addImport(
6020 $1,
6021 thisParserPtr);
6022 setImportModulename(importPtr,
6023 thisParserPtr->capabilitiesModulePtr->
6024 export.name);
6025 addImportFlags(importPtr,
6026 FLAG_INCOMPLIANCE);
6027 importPtr->use++;
6028 } else {
6029 objectPtr = addObject($1,
6030 thisParserPtr->pendingNodePtr, 0,
6031 FLAG_INCOMPLETE,
6032 thisParserPtr);
6033 smiPrintError(thisParserPtr,
6034 ERR_IDENTIFIER_NOT_IN_MODULE, $1,
6035 thisParserPtr->capabilitiesModulePtr->export.name);
6036 }
6037 } else {
6038 /*
6039 * forward referenced node.
6040 * create it,
6041 * marked with FLAG_INCOMPLETE.
6042 */
6043 objectPtr = addObject($1,
6044 thisParserPtr->pendingNodePtr,
6045 0,
6046 FLAG_INCOMPLETE,
6047 thisParserPtr);
6048 }
6049 $$ = objectPtr;
6050 } else {
6051 /*
6052 * imported object.
6053 */
6054 importPtr->use++;
6055 $$ = findObjectByModulenameAndName(
6056 importPtr->export.module, $1);
6057 smiFree($1);
6058 }
6059 }
6060 if ($$)
6061 thisParserPtr->parentNodePtr = $$->nodePtr;
6062 }
6063 | moduleName '.' LOWERCASE_IDENTIFIER
6064 {
6065 Object *objectPtr;
6066 Import *importPtr;
6067 char *md;
6068
6069 if (thisParserPtr->parentNodePtr != smiHandle->rootNodePtr) {
6070 md = smiMalloc(sizeof(char) *
6071 (strlen($1) + strlen($3) + 2));
6072 sprintf(md, "%s.%s", $1, $3);
6073 smiPrintError(thisParserPtr,
6074 ERR_OIDLABEL_NOT_FIRST, md);
6075 smiFree(md);
6076 } else {
6077 objectPtr = findObjectByModulenameAndName(
6078 $1, $3);
6079 if (objectPtr) {
6080 $$ = objectPtr;
6081 smiFree($1);
6082 smiFree($3);
6083 } else {
6084 importPtr = findImportByModulenameAndName(
6085 $1, $3, thisModulePtr);
6086 if (!importPtr ||
6087 (importPtr->kind == KIND_NOTFOUND)) {
6088 /* TODO: check: $1 == thisModule ? */
6089 /*
6090 * If we are in a MODULE-COMPLIANCE
6091 * statement with a given MODULE...
6092 */
6093 if (thisParserPtr->complianceModulePtr) {
6094 objectPtr =
6095 findObjectByModuleAndName(
6096 thisParserPtr->complianceModulePtr, $1);
6097 if (objectPtr) {
6098 importPtr = addImport(
6099 $1,
6100 thisParserPtr);
6101 setImportModulename(importPtr,
6102 thisParserPtr->complianceModulePtr->export.name);
6103 addImportFlags(importPtr,
6104 FLAG_INCOMPLIANCE);
6105 importPtr->use++;
6106 } else {
6107 objectPtr = addObject($1,
6108 thisParserPtr->pendingNodePtr, 0,
6109 FLAG_INCOMPLETE,
6110 thisParserPtr);
6111 smiPrintError(thisParserPtr,
6112 ERR_IDENTIFIER_NOT_IN_MODULE, $1,
6113 thisParserPtr->complianceModulePtr->export.name);
6114 }
6115 } else if (thisParserPtr->capabilitiesModulePtr) {
6116 objectPtr =
6117 findObjectByModuleAndName(
6118 thisParserPtr->capabilitiesModulePtr, $1);
6119 if (objectPtr) {
6120 importPtr = addImport(
6121 $1,
6122 thisParserPtr);
6123 setImportModulename(importPtr,
6124 thisParserPtr->capabilitiesModulePtr->
6125 export.name);
6126 addImportFlags(importPtr,
6127 FLAG_INCOMPLIANCE);
6128 importPtr->use++;
6129 } else {
6130 objectPtr = addObject($1,
6131 thisParserPtr->pendingNodePtr, 0,
6132 FLAG_INCOMPLETE,
6133 thisParserPtr);
6134 smiPrintError(thisParserPtr,
6135 ERR_IDENTIFIER_NOT_IN_MODULE, $1,
6136 thisParserPtr->capabilitiesModulePtr->export.name);
6137 }
6138 } else {
6139 /*
6140 * forward referenced node.
6141 * create it,
6142 * marked with FLAG_INCOMPLETE.
6143 */
6144 objectPtr = addObject($3,
6145 thisParserPtr->pendingNodePtr,
6146 0,
6147 FLAG_INCOMPLETE,
6148 thisParserPtr);
6149 smiFree($1);
6150 }
6151 $$ = objectPtr;
6152 } else {
6153 /*
6154 * imported object.
6155 */
6156 importPtr->use++;
6157 $$ = findObjectByModulenameAndName(
6158 importPtr->export.module, $3);
6159 smiFree($1);
6160 smiFree($3);
6161 }
6162 }
6163 if ($$)
6164 thisParserPtr->parentNodePtr = $$->nodePtr;
6165 }
6166 }
6167 | NUMBER
6168 {
6169 Node *nodePtr;
6170 Object *objectPtr;
6171
6172 nodePtr = findNodeByParentAndSubid(thisParserPtr->parentNodePtr,
6173 $1);
6174 if (nodePtr && nodePtr->lastObjectPtr &&
6175 (nodePtr->lastObjectPtr->modulePtr == thisModulePtr)) {
6176 /*
6177 * hopefully, the last defined Object for
6178 * this Node is the one we expect.
6179 */
6180 $$ = nodePtr->lastObjectPtr;
6181 } else {
6182 objectPtr = addObject(NULL,
6183 thisParserPtr->parentNodePtr,
6184 $1,
6185 FLAG_INCOMPLETE,
6186 thisParserPtr);
6187 $$ = objectPtr;
6188 }
6189 thisParserPtr->parentNodePtr = $$->nodePtr;
6190 }
6191 | LOWERCASE_IDENTIFIER '(' NUMBER ')'
6192 {
6193 Object *objectPtr = NULL;
6194 Object *oldObjectPtr = NULL;
6195 Node *oldNodePtr = NULL;
6196
6197 /* TODO: search in local module and
6198 * in imported modules
6199 */
6200
6201 oldNodePtr = findNodeByParentAndSubid(
6202 thisParserPtr->parentNodePtr, $3);
6203 oldObjectPtr = findObjectByModuleAndName(
6204 thisParserPtr->modulePtr, $1);
6205
6206 if (oldObjectPtr &&
6207 ((oldObjectPtr->nodePtr->subid != $3) ||
6208 (oldObjectPtr->nodePtr->parentPtr != thisParserPtr->parentNodePtr))) {
6209 smiPrintError(thisParserPtr,
6210 ERR_IDENTIFIER_OID_CHANGED,
6211 $1);
6212 smiPrintErrorAtLine(thisParserPtr,
6213 ERR_PREVIOUS_DEFINITION,
6214 oldObjectPtr->line,
6215 oldObjectPtr->export.name);
6216 objectPtr = addObject($1,
6217 thisParserPtr->parentNodePtr,
6218 $3, 0, thisParserPtr);
6219 setObjectDecl(objectPtr,
6220 SMI_DECL_IMPL_OBJECT);
6221 $$ = objectPtr;
6222 thisParserPtr->parentNodePtr = $$->nodePtr;
6223 } else if (oldNodePtr &&
6224 oldNodePtr->lastObjectPtr &&
6225 oldNodePtr->lastObjectPtr->export.name &&
6226 strcmp(oldNodePtr->lastObjectPtr->export.name, $1)) {
6227 smiPrintError(thisParserPtr,
6228 ERR_OIDLABEL_CHANGED,
6229 $1, oldNodePtr->lastObjectPtr->export.name);
6230 smiPrintErrorAtLine(thisParserPtr,
6231 ERR_PREVIOUS_DEFINITION,
6232 oldNodePtr->lastObjectPtr->line,
6233 oldNodePtr->lastObjectPtr->export.name);
6234 objectPtr = addObject($1,
6235 thisParserPtr->parentNodePtr,
6236 $3, 0, thisParserPtr);
6237 setObjectDecl(objectPtr,
6238 SMI_DECL_IMPL_OBJECT);
6239 $$ = objectPtr;
6240 thisParserPtr->parentNodePtr = $$->nodePtr;
6241 } else {
6242 objectPtr = addObject($1, thisParserPtr->parentNodePtr,
6243 $3, 0,
6244 thisParserPtr);
6245 setObjectDecl(objectPtr,
6246 SMI_DECL_IMPL_OBJECT);
6247 $$ = objectPtr;
6248 thisParserPtr->parentNodePtr = $$->nodePtr;
6249 }
6250 }
6251 | moduleName '.' LOWERCASE_IDENTIFIER '(' NUMBER ')'
6252 {
6253 Object *objectPtr = NULL;
6254 Object *oldObjectPtr = NULL;
6255 Node *oldNodePtr = NULL;
6256 char *md;
6257
6258 md = smiMalloc(sizeof(char) *
6259 (strlen($1) + strlen($3) + 2));
6260 sprintf(md, "%s.%s", $1, $3);
6261
6262 oldNodePtr = findNodeByParentAndSubid(
6263 thisParserPtr->parentNodePtr, $5);
6264 oldObjectPtr = findObjectByModulenameAndName(
6265 $1, $3);
6266
6267 if (oldObjectPtr &&
6268 ((oldObjectPtr->nodePtr->subid != $5) ||
6269 (oldObjectPtr->nodePtr->parentPtr != thisParserPtr->parentNodePtr))) {
6270 smiPrintError(thisParserPtr,
6271 ERR_ILLEGALLY_QUALIFIED, md);
6272 smiPrintError(thisParserPtr,
6273 ERR_IDENTIFIER_OID_CHANGED,
6274 $3);
6275 smiPrintErrorAtLine(thisParserPtr,
6276 ERR_PREVIOUS_DEFINITION,
6277 oldObjectPtr->line,
6278 oldObjectPtr->export.name);
6279 objectPtr = addObject($3,
6280 thisParserPtr->parentNodePtr,
6281 $5, 0, thisParserPtr);
6282 setObjectDecl(objectPtr,
6283 SMI_DECL_IMPL_OBJECT);
6284 $$ = objectPtr;
6285 thisParserPtr->parentNodePtr = $$->nodePtr;
6286 } else if (oldNodePtr &&
6287 oldNodePtr->lastObjectPtr &&
6288 strcmp(oldNodePtr->lastObjectPtr->export.name, $3)) {
6289 smiPrintError(thisParserPtr,
6290 ERR_ILLEGALLY_QUALIFIED, md);
6291 smiPrintError(thisParserPtr,
6292 ERR_OIDLABEL_CHANGED,
6293 $3, oldNodePtr->lastObjectPtr->export.name);
6294 smiPrintErrorAtLine(thisParserPtr,
6295 ERR_PREVIOUS_DEFINITION,
6296 oldNodePtr->lastObjectPtr->line,
6297 oldNodePtr->lastObjectPtr->export.name);
6298 objectPtr = addObject($3,
6299 thisParserPtr->parentNodePtr,
6300 $5, 0, thisParserPtr);
6301 setObjectDecl(objectPtr,
6302 SMI_DECL_IMPL_OBJECT);
6303 $$ = objectPtr;
6304 thisParserPtr->parentNodePtr = $$->nodePtr;
6305 } else {
6306 smiPrintError(thisParserPtr,
6307 ERR_ILLEGALLY_QUALIFIED, md);
6308 objectPtr = addObject($3, thisParserPtr->parentNodePtr,
6309 $5, 0,
6310 thisParserPtr);
6311 setObjectDecl(objectPtr,
6312 SMI_DECL_IMPL_OBJECT);
6313 $$ = objectPtr;
6314 thisParserPtr->parentNodePtr = $$->nodePtr;
6315 }
6316 smiFree(md);
6317 }
6318 ;
6319
6320 objectIdentifier_defval: subidentifiers_defval
6321 { $$ = NULL; }
6322 ; /* TODO */
6323
6324 subidentifiers_defval: subidentifier_defval
6325 { $$ = 0; }
6326 | subidentifiers_defval subidentifier_defval
6327 { $$ = 0; }
6328 ; /* TODO */
6329
6330 subidentifier_defval: LOWERCASE_IDENTIFIER '(' NUMBER ')'
6331 { $$ = 0; }
6332 | NUMBER
6333 { $$ = 0; }
6334 ; /* TODO */
6335
6336 objectGroupClause: LOWERCASE_IDENTIFIER
6337 {
6338 thisParserPtr->firstStatementLine = thisParserPtr->line;
6339 thisParserPtr->currentDecl = SMI_DECL_OBJECTGROUP;
6340
6341 checkNameLen(thisParserPtr, $1,
6342 ERR_OIDNAME_32, ERR_OIDNAME_64);
6343 smiCheckObjectName(thisParserPtr,
6344 thisModulePtr, $1);
6345 }
6346 OBJECT_GROUP
6347 {
6348 Import *importPtr;
6349
6350 if (thisModulePtr->export.language == SMI_LANGUAGE_UNKNOWN)
6351 thisModulePtr->export.language = SMI_LANGUAGE_SMIV2;
6352
6353 importPtr = findImportByName("OBJECT-GROUP",
6354 thisModulePtr);
6355 if (importPtr) {
6356 importPtr->use++;
6357 } else {
6358 smiPrintError(thisParserPtr,
6359 ERR_MACRO_NOT_IMPORTED,
6360 "OBJECT-GROUP", "SNMPv2-CONF");
6361 }
6362 }
6363 ObjectGroupObjectsPart
6364 STATUS Status
6365 DESCRIPTION Text
6366 {
6367 checkDescr(thisParserPtr, $9);
6368 }
6369 ReferPart
6370 COLON_COLON_EQUAL '{' objectIdentifier '}'
6371 {
6372 Object *objectPtr;
6373
6374 objectPtr = $14;
6375
6376 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
6377
6378 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
6379 setObjectDecl(objectPtr, SMI_DECL_OBJECTGROUP);
6380 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
6381 thisParserPtr);
6382 addObjectFlags(objectPtr, FLAG_REGISTERED);
6383 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
6384 setObjectStatus(objectPtr, $7);
6385 setObjectDescription(objectPtr, $9, thisParserPtr);
6386 if ($11) {
6387 setObjectReference(objectPtr, $11, thisParserPtr);
6388 }
6389 setObjectAccess(objectPtr,
6390 SMI_ACCESS_NOT_ACCESSIBLE);
6391 setObjectList(objectPtr, $5);
6392 $$ = 0;
6393 }
6394 ;
6395
6396 notificationGroupClause: LOWERCASE_IDENTIFIER
6397 {
6398 thisParserPtr->firstStatementLine = thisParserPtr->line;
6399 thisParserPtr->currentDecl = SMI_DECL_NOTIFICATIONGROUP;
6400
6401 checkNameLen(thisParserPtr, $1,
6402 ERR_OIDNAME_32, ERR_OIDNAME_64);
6403 smiCheckObjectName(thisParserPtr,
6404 thisModulePtr, $1);
6405 }
6406 NOTIFICATION_GROUP
6407 {
6408 Import *importPtr;
6409 if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
6410 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "NOTIFICATION-GROUP");
6411
6412 if (thisModulePtr->export.language == SMI_LANGUAGE_UNKNOWN)
6413 thisModulePtr->export.language = SMI_LANGUAGE_SMIV2;
6414
6415 importPtr = findImportByName("NOTIFICATION-GROUP",
6416 thisModulePtr);
6417 if (importPtr) {
6418 importPtr->use++;
6419 } else {
6420 smiPrintError(thisParserPtr,
6421 ERR_MACRO_NOT_IMPORTED,
6422 "NOTIFICATION-GROUP",
6423 "SNMPv2-CONF");
6424 }
6425 }
6426 NotificationsPart
6427 STATUS Status
6428 DESCRIPTION Text
6429 {
6430 checkDescr(thisParserPtr, $9);
6431 }
6432 ReferPart
6433 COLON_COLON_EQUAL '{' objectIdentifier '}'
6434 {
6435 Object *objectPtr;
6436
6437 objectPtr = $14;
6438
6439 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
6440
6441 objectPtr = setObjectName(objectPtr, $1, thisParserPtr);
6442 setObjectDecl(objectPtr,
6443 SMI_DECL_NOTIFICATIONGROUP);
6444 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
6445 thisParserPtr);
6446 addObjectFlags(objectPtr, FLAG_REGISTERED);
6447 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
6448 setObjectStatus(objectPtr, $7);
6449 setObjectDescription(objectPtr, $9, thisParserPtr);
6450 if ($11) {
6451 setObjectReference(objectPtr, $11, thisParserPtr);
6452 }
6453 setObjectAccess(objectPtr,
6454 SMI_ACCESS_NOT_ACCESSIBLE);
6455 setObjectList(objectPtr, $5);
6456 $$ = 0;
6457 }
6458 ;
6459
6460 moduleComplianceClause: LOWERCASE_IDENTIFIER
6461 {
6462 thisParserPtr->firstStatementLine = thisParserPtr->line;
6463 thisParserPtr->currentDecl = SMI_DECL_MODULECOMPLIANCE;
6464
6465 checkNameLen(thisParserPtr, $1,
6466 ERR_OIDNAME_32, ERR_OIDNAME_64);
6467 smiCheckObjectName(thisParserPtr,
6468 thisModulePtr, $1);
6469 }
6470 MODULE_COMPLIANCE
6471 {
6472 Import *importPtr;
6473
6474 if (thisModulePtr->export.language == SMI_LANGUAGE_UNKNOWN)
6475 thisModulePtr->export.language = SMI_LANGUAGE_SMIV2;
6476 importPtr = findImportByName("MODULE-COMPLIANCE",
6477 thisModulePtr);
6478 if (importPtr) {
6479 importPtr->use++;
6480 } else {
6481 smiPrintError(thisParserPtr,
6482 ERR_MACRO_NOT_IMPORTED,
6483 "MODULE-COMPLIANCE",
6484 "SNMPv2-CONF");
6485 }
6486 }
6487 STATUS Status
6488 DESCRIPTION Text
6489 {
6490 checkDescr(thisParserPtr, $8);
6491 }
6492 ReferPart
6493 ComplianceModulePart
6494 COLON_COLON_EQUAL '{' objectIdentifier '}'
6495 {
6496 Object *objectPtr;
6497 Option *optionPtr;
6498 Refinement *refinementPtr;
6499 List *listPtr;
6500
6501 objectPtr = $14;
6502
6503 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
6504
6505 setObjectName(objectPtr, $1, thisParserPtr);
6506 setObjectDecl(objectPtr,
6507 SMI_DECL_MODULECOMPLIANCE);
6508 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
6509 thisParserPtr);
6510 addObjectFlags(objectPtr, FLAG_REGISTERED);
6511 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
6512 setObjectStatus(objectPtr, $6);
6513 setObjectDescription(objectPtr, $8, thisParserPtr);
6514 if ($10) {
6515 setObjectReference(objectPtr, $10, thisParserPtr);
6516 }
6517 setObjectAccess(objectPtr,
6518 SMI_ACCESS_NOT_ACCESSIBLE);
6519 setObjectList(objectPtr, $11.mandatorylistPtr);
6520 objectPtr->optionlistPtr = $11.optionlistPtr;
6521 objectPtr->refinementlistPtr =
6522 $11.refinementlistPtr;
6523
6524 if ($11.optionlistPtr) {
6525 for (listPtr = $11.optionlistPtr;
6526 listPtr;
6527 listPtr = listPtr->nextPtr) {
6528 optionPtr = ((Option *)(listPtr->ptr));
6529 optionPtr->compliancePtr = objectPtr;
6530 }
6531 }
6532
6533 /*
6534 * Dirty: Fake the types' names in the
6535 * refinement list:
6536 * ``<compliancename>+<objecttypename>+type''
6537 * ``<compliancename>+<objecttypename>+writetype''
6538 */
6539 if ($11.refinementlistPtr) {
6540 for (listPtr = $11.refinementlistPtr;
6541 listPtr;
6542 listPtr = listPtr->nextPtr) {
6543 refinementPtr =
6544 ((Refinement *)(listPtr->ptr));
6545 refinementPtr->compliancePtr = objectPtr;
6546 }
6547 }
6548
6549 $$ = 0;
6550 }
6551 ;
6552
6553 ComplianceModulePart: ComplianceModules
6554 {
6555 $$ = $1;
6556 }
6557 ;
6558
6559 ComplianceModules: ComplianceModule
6560 {
6561 $$ = $1;
6562 }
6563 | ComplianceModules ComplianceModule
6564 {
6565 List *listPtr;
6566
6567 /* concatenate lists in $1 and $2 */
6568 if ($1.mandatorylistPtr) {
6569 for (listPtr = $1.mandatorylistPtr;
6570 listPtr->nextPtr;
6571 listPtr = listPtr->nextPtr);
6572 listPtr->nextPtr = $2.mandatorylistPtr;
6573 $$.mandatorylistPtr = $1.mandatorylistPtr;
6574 } else {
6575 $$.mandatorylistPtr = $2.mandatorylistPtr;
6576 }
6577 if ($1.optionlistPtr) {
6578 for (listPtr = $1.optionlistPtr;
6579 listPtr->nextPtr;
6580 listPtr = listPtr->nextPtr);
6581 listPtr->nextPtr = $2.optionlistPtr;
6582 $$.optionlistPtr = $1.optionlistPtr;
6583 } else {
6584 $$.optionlistPtr = $2.optionlistPtr;
6585 }
6586 if ($1.refinementlistPtr) {
6587 for (listPtr = $1.refinementlistPtr;
6588 listPtr->nextPtr;
6589 listPtr = listPtr->nextPtr);
6590 listPtr->nextPtr = $2.refinementlistPtr;
6591 $$.refinementlistPtr = $1.refinementlistPtr;
6592 } else {
6593 $$.refinementlistPtr = $2.refinementlistPtr;
6594 }
6595 }
6596 ;
6597
6598 ComplianceModule: MODULE ComplianceModuleName
6599 {
6600 /*
6601 * Remember the module. SMIv2 is broken by
6602 * design to allow subsequent clauses to
6603 * refer identifiers that are not
6604 * imported. Although, SMIv2 does not
6605 * require, we will fake it by inserting
6606 * appropriate imports.
6607 */
6608 if ($2 == thisModulePtr)
6609 thisParserPtr->complianceModulePtr = NULL;
6610 else
6611 thisParserPtr->complianceModulePtr = $2;
6612 }
6613 MandatoryPart
6614 CompliancePart
6615 {
6616 $$.mandatorylistPtr = $4;
6617 $$.optionlistPtr = $5.optionlistPtr;
6618 $$.refinementlistPtr = $5.refinementlistPtr;
6619 if (thisParserPtr->complianceModulePtr) {
6620 checkImports(thisParserPtr->complianceModulePtr,
6621 thisParserPtr);
6622 thisParserPtr->complianceModulePtr = NULL;
6623 }
6624 }
6625 ;
6626
6627 ComplianceModuleName: UPPERCASE_IDENTIFIER objectIdentifier
6628 {
6629 $$ = findModuleByName($1);
6630 /* TODO: handle objectIdentifier */
6631 if (!$$) {
6632 $$ = loadModule($1, thisParserPtr);
6633 }
6634 smiFree($1);
6635 }
6636 | UPPERCASE_IDENTIFIER
6637 {
6638 $$ = findModuleByName($1);
6639 if (!$$) {
6640 $$ = loadModule($1, thisParserPtr);
6641 }
6642 smiFree($1);
6643 }
6644 | /* empty, only if contained in MIB module */
6645 /* TODO: RFC 1904 looks a bit different, is this ok? */
6646 {
6647 $$ = thisModulePtr;
6648 }
6649 ;
6650
6651 MandatoryPart: MANDATORY_GROUPS '{' MandatoryGroups '}'
6652 {
6653 $$ = $3;
6654 }
6655 | /* empty */
6656 {
6657 $$ = NULL;
6658 }
6659 ;
6660
6661 MandatoryGroups: MandatoryGroup
6662 {
6663 $$ = smiMalloc(sizeof(List));
6664 $$->ptr = $1;
6665 $$->nextPtr = NULL;
6666 }
6667 | MandatoryGroups ',' MandatoryGroup
6668 {
6669 List *p, *pp;
6670
6671 p = smiMalloc(sizeof(List));
6672 p->ptr = $3;
6673 p->nextPtr = NULL;
6674 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
6675 pp->nextPtr = p;
6676 $$ = $1;
6677 }
6678 ;
6679
6680 MandatoryGroup: objectIdentifier
6681 {
6682 /* TODO: check that objectIdentifier is
6683 found, is defined in thisParserPtr->complianceModulePtr,
6684 and is a group node. */
6685 Import *importPtr;
6686
6687 $$ = $1;
6688 if (thisParserPtr->complianceModulePtr) {
6689 $$ = findObjectByModuleAndName(
6690 thisParserPtr->complianceModulePtr,
6691 $1->export.name);
6692 }
6693 if (thisParserPtr->complianceModulePtr && $1->export.name) {
6694 importPtr = findImportByModulenameAndName(
6695 thisParserPtr->complianceModulePtr->export.name,
6696 $1->export.name, thisModulePtr);
6697 if (importPtr)
6698 importPtr->use++;
6699 }
6700 }
6701 ;
6702
6703 CompliancePart: Compliances
6704 {
6705 $$.mandatorylistPtr = NULL;
6706 $$.optionlistPtr = $1.optionlistPtr;
6707 $$.refinementlistPtr = $1.refinementlistPtr;
6708 }
6709 | /* empty */
6710 {
6711 $$.mandatorylistPtr = NULL;
6712 $$.optionlistPtr = NULL;
6713 $$.refinementlistPtr = NULL;
6714 }
6715 ;
6716
6717 Compliances: Compliance
6718 {
6719 $$ = $1;
6720 }
6721 | Compliances Compliance
6722 {
6723 List *listPtr;
6724 int stop;
6725
6726 $$.mandatorylistPtr = NULL;
6727
6728 /* check for duplicates in optionlist */
6729 stop = 0;
6730 if ($2.optionlistPtr) {
6731 for (listPtr = $1.optionlistPtr; listPtr;
6732 listPtr = listPtr->nextPtr) {
6733 if (((Option *)listPtr->ptr)->objectPtr ==
6734 ((Option *)$2.optionlistPtr->ptr)->objectPtr) {
6735 smiPrintError(thisParserPtr,
6736 ERR_OPTIONALGROUP_ALREADY_EXISTS,
6737 ((Option *)$2.optionlistPtr->ptr)->objectPtr->export.name);
6738 stop = 1;
6739 $$.optionlistPtr = $1.optionlistPtr;
6740 }
6741 }
6742 }
6743
6744 /* concatenate optionlists */
6745 if ($1.optionlistPtr) {
6746 for (listPtr = $1.optionlistPtr;
6747 listPtr->nextPtr;
6748 listPtr = listPtr->nextPtr);
6749 if (!stop) {
6750 listPtr->nextPtr = $2.optionlistPtr;
6751 }
6752 $$.optionlistPtr = $1.optionlistPtr;
6753 } else {
6754 $$.optionlistPtr = $2.optionlistPtr;
6755 }
6756
6757 /* check for duplicates in refinementlist */
6758 stop = 0;
6759 if ($2.refinementlistPtr) {
6760 for (listPtr = $1.refinementlistPtr; listPtr;
6761 listPtr = listPtr->nextPtr) {
6762 if (((Refinement *)listPtr->ptr)->objectPtr ==
6763 ((Refinement *)$2.refinementlistPtr->ptr)->objectPtr) {
6764 smiPrintError(thisParserPtr,
6765 ERR_REFINEMENT_ALREADY_EXISTS,
6766 ((Refinement *)$2.refinementlistPtr->ptr)->objectPtr->export.name);
6767 stop = 1;
6768 $$.refinementlistPtr = $1.refinementlistPtr;
6769 }
6770 }
6771 }
6772
6773 /* concatenate refinementlists */
6774 if ($1.refinementlistPtr) {
6775 for (listPtr = $1.refinementlistPtr;
6776 listPtr->nextPtr;
6777 listPtr = listPtr->nextPtr);
6778 if (!stop) {
6779 listPtr->nextPtr = $2.refinementlistPtr;
6780 }
6781 $$.refinementlistPtr = $1.refinementlistPtr;
6782 } else {
6783 $$.refinementlistPtr = $2.refinementlistPtr;
6784 }
6785 }
6786 ;
6787
6788 Compliance: ComplianceGroup
6789 {
6790 $$.mandatorylistPtr = NULL;
6791 $$.optionlistPtr = $1;
6792 $$.refinementlistPtr = NULL;
6793 }
6794 | ComplianceObject
6795 {
6796 $$.mandatorylistPtr = NULL;
6797 $$.optionlistPtr = NULL;
6798 $$.refinementlistPtr = $1;
6799 }
6800 ;
6801
6802 ComplianceGroup: GROUP
6803 {
6804 thisParserPtr->firstNestedStatementLine = thisParserPtr->line;
6805 }
6806 objectIdentifier
6807 DESCRIPTION Text
6808 {
6809 Import *importPtr;
6810
6811 if (thisParserPtr->complianceModulePtr && $3->export.name) {
6812 importPtr = findImportByModulenameAndName(
6813 thisParserPtr->complianceModulePtr->export.name,
6814 $3->export.name,
6815 thisModulePtr);
6816 if (importPtr)
6817 importPtr->use++;
6818 }
6819
6820 checkDescr(thisParserPtr, $5);
6821
6822 $$ = smiMalloc(sizeof(List));
6823 $$->nextPtr = NULL;
6824 $$->ptr = smiMalloc(sizeof(Option));
6825 ((Option *)($$->ptr))->line = thisParserPtr->firstNestedStatementLine;
6826 ((Option *)($$->ptr))->objectPtr = $3;
6827 if (! (thisModulePtr->flags & SMI_FLAG_NODESCR)) {
6828 ((Option *)($$->ptr))->export.description = $5;
6829 } else {
6830 smiFree($5);
6831 }
6832 }
6833 ;
6834
6835 ComplianceObject: OBJECT
6836 {
6837 thisParserPtr->firstNestedStatementLine = thisParserPtr->line;
6838 }
6839 ObjectName
6840 SyntaxPart
6841 WriteSyntaxPart /* modified for SPPI */
6842 AccessPart /* modified for SPPI */
6843 DESCRIPTION Text
6844 {
6845 Import *importPtr;
6846
6847 if (thisParserPtr->complianceModulePtr && $3->export.name) {
6848 importPtr = findImportByModulenameAndName(
6849 thisParserPtr->complianceModulePtr->export.name,
6850 $3->export.name,
6851 thisModulePtr);
6852 if (importPtr)
6853 importPtr->use++;
6854 }
6855
6856 checkDescr(thisParserPtr, $8);
6857
6858 thisParserPtr->flags &= ~FLAG_CREATABLE;
6859 $$ = smiMalloc(sizeof(List));
6860 $$->nextPtr = NULL;
6861 $$->ptr = smiMalloc(sizeof(Refinement));
6862 ((Refinement *)($$->ptr))->line =
6863 thisParserPtr->firstNestedStatementLine;
6864 ((Refinement *)($$->ptr))->objectPtr = $3;
6865 ((Refinement *)($$->ptr))->typePtr = $4;
6866 if ($4) {
6867 $4->parentPtr = $3->typePtr;
6868 }
6869 ((Refinement *)($$->ptr))->writetypePtr = $5;
6870 if ($5) {
6871 $5->parentPtr = $3->typePtr;
6872 }
6873 ((Refinement *)($$->ptr))->export.access = $6;
6874 if (! (thisParserPtr->flags & SMI_FLAG_NODESCR)) {
6875 ((Refinement *)($$->ptr))->export.description = $8;
6876 } else {
6877 smiFree($8);
6878 }
6879 }
6880 ;
6881
6882 SyntaxPart: SYNTAX Syntax
6883 {
6884 if ($2->export.name) {
6885 $$ = duplicateType($2, 0, thisParserPtr);
6886 } else {
6887 $$ = $2;
6888 }
6889 }
6890 | /* empty */
6891 {
6892 $$ = NULL;
6893 }
6894 ;
6895
6896 WriteSyntaxPart: WRITE_SYNTAX WriteSyntax
6897 {
6898 /* must not be present in PIBs */
6899 if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
6900 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "WRITE-SYNTAX");
6901 if ($2->export.name) {
6902 $$ = duplicateType($2, 0, thisParserPtr);
6903 } else {
6904 $$ = $2;
6905 }
6906 }
6907 | /* empty */
6908 {
6909 $$ = NULL;
6910 }
6911 ;
6912
6913 WriteSyntax: Syntax
6914 {
6915 $$ = $1;
6916 }
6917 ;
6918
6919 AccessPart: MIN_ACCESS Access
6920 {
6921 if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
6922 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "MIN-ACCESS");
6923 $$ = $2;
6924 }
6925 | PIB_MIN_ACCESS Access
6926 {
6927 if (thisParserPtr->modulePtr->export.language != SMI_LANGUAGE_SPPI)
6928 smiPrintError(thisParserPtr, ERR_SPPI_CONSTRUCT_IN_MIB, "PIB-MIN-ACCESS");
6929 if ($2 == SMI_ACCESS_REPORT_ONLY)
6930 smiPrintError(thisParserPtr, ERR_REPORT_ONLY_IN_PIB_MIN_ACCESS);
6931 $$ = $2;
6932 }
6933 | /* empty */
6934 {
6935 $$ = SMI_ACCESS_UNKNOWN;
6936 }
6937 ;
6938
6939 agentCapabilitiesClause: LOWERCASE_IDENTIFIER
6940 {
6941 thisParserPtr->firstStatementLine = thisParserPtr->line;
6942 thisParserPtr->currentDecl = SMI_DECL_AGENTCAPABILITIES;
6943
6944 checkNameLen(thisParserPtr, $1,
6945 ERR_OIDNAME_32, ERR_OIDNAME_64);
6946 smiCheckObjectName(thisParserPtr,
6947 thisModulePtr, $1);
6948 }
6949 AGENT_CAPABILITIES
6950 {
6951 Import *importPtr;
6952 if (thisParserPtr->modulePtr->export.language == SMI_LANGUAGE_SPPI)
6953 smiPrintError(thisParserPtr, ERR_SMI_CONSTRUCT_IN_PIB, "AGENT-CAAPABILITIES");
6954
6955 if (thisModulePtr->export.language == SMI_LANGUAGE_UNKNOWN)
6956 thisModulePtr->export.language = SMI_LANGUAGE_SMIV2;
6957
6958 importPtr = findImportByName("AGENT-CAPABILITIES",
6959 thisModulePtr);
6960 if (importPtr) {
6961 importPtr->use++;
6962 } else {
6963 smiPrintError(thisParserPtr,
6964 ERR_MACRO_NOT_IMPORTED,
6965 "AGENT-CAPABILITIES",
6966 "SNMPv2-CONF");
6967 }
6968 }
6969 PRODUCT_RELEASE Text
6970 STATUS Status_Capabilities
6971 DESCRIPTION Text
6972 {
6973 checkDescr(thisParserPtr, $10);
6974 }
6975 ReferPart
6976 ModulePart_Capabilities
6977 COLON_COLON_EQUAL '{' objectIdentifier '}'
6978 {
6979 Object *objectPtr;
6980
6981 objectPtr = $16;
6982
6983 smiCheckObjectReuse(thisParserPtr, $1, &objectPtr);
6984
6985 setObjectName(objectPtr, $1, thisParserPtr);
6986 setObjectDecl(objectPtr,
6987 SMI_DECL_AGENTCAPABILITIES);
6988 setObjectLine(objectPtr, thisParserPtr->firstStatementLine,
6989 thisParserPtr);
6990 addObjectFlags(objectPtr, FLAG_REGISTERED);
6991 deleteObjectFlags(objectPtr, FLAG_INCOMPLETE);
6992 setObjectStatus(objectPtr, $8);
6993 setObjectDescription(objectPtr, $10, thisParserPtr);
6994 if ($12) {
6995 setObjectReference(objectPtr, $12, thisParserPtr);
6996 }
6997 setObjectAccess(objectPtr,
6998 SMI_ACCESS_NOT_ACCESSIBLE);
6999 /*
7000 * TODO: PRODUCT_RELEASE Text
7001 * TODO: ModulePart_Capabilities
7002 */
7003 $$ = 0;
7004 }
7005 ;
7006
7007 ModulePart_Capabilities: Modules_Capabilities
7008 { $$ = 0; }
7009 | /* empty */
7010 { $$ = 0; }
7011 ;
7012
7013 Modules_Capabilities: Module_Capabilities
7014 { $$ = 0; }
7015 | Modules_Capabilities Module_Capabilities
7016 { $$ = 0; }
7017 ;
7018
7019 Module_Capabilities: SUPPORTS ModuleName_Capabilities
7020 {
7021 /*
7022 * Remember the module. SMIv2 is broken by
7023 * design to allow subsequent clauses to
7024 * refer identifiers that are not
7025 * imported. Although, SMIv2 does not
7026 * require, we will fake it by inserting
7027 * appropriate imports.
7028 */
7029 if ($2 == thisModulePtr)
7030 thisParserPtr->capabilitiesModulePtr = NULL;
7031 else
7032 thisParserPtr->capabilitiesModulePtr = $2;
7033 }
7034 INCLUDES '{' CapabilitiesGroups '}'
7035 VariationPart
7036 {
7037 if (thisParserPtr->capabilitiesModulePtr) {
7038 checkImports(thisParserPtr->capabilitiesModulePtr,
7039 thisParserPtr);
7040 thisParserPtr->capabilitiesModulePtr = NULL;
7041 }
7042 $$ = 0;
7043 }
7044 ;
7045
7046 CapabilitiesGroups: CapabilitiesGroup
7047 {
7048 #if 0
7049 $$ = smiMalloc(sizeof(List));
7050 $$->ptr = $1;
7051 $$->nextPtr = NULL;
7052 #else
7053 $$ = NULL;
7054 #endif
7055 }
7056 | CapabilitiesGroups ',' CapabilitiesGroup
7057 {
7058 #if 0
7059 List *p, *pp;
7060
7061 p = smiMalloc(sizeof(List));
7062 p->ptr = $3;
7063 p->nextPtr = NULL;
7064 for (pp = $1; pp->nextPtr; pp = pp->nextPtr);
7065 pp->nextPtr = p;
7066 $$ = $1;
7067 #else
7068 $$ = NULL;
7069 #endif
7070 }
7071 ;
7072
7073 CapabilitiesGroup: objectIdentifier
7074 {
7075 $$ = NULL;
7076 }
7077 ;
7078
7079 ModuleName_Capabilities: UPPERCASE_IDENTIFIER objectIdentifier
7080 {
7081 $$ = findModuleByName($1);
7082 /* TODO: handle objectIdentifier */
7083 if (!$$) {
7084 $$ = loadModule($1, thisParserPtr);
7085 }
7086 smiFree($1);
7087 }
7088 | UPPERCASE_IDENTIFIER
7089 {
7090 $$ = findModuleByName($1);
7091 if (!$$) {
7092 $$ = loadModule($1, thisParserPtr);
7093 }
7094 smiFree($1);
7095 }
7096 ;
7097
7098 VariationPart: Variations
7099 { $$ = 0; }
7100 | /* empty */
7101 { $$ = 0; }
7102 ;
7103
7104 Variations: Variation
7105 { $$ = 0; }
7106 | Variations Variation
7107 { $$ = 0; }
7108 ;
7109
7110 Variation: VARIATION ObjectName
7111 {
7112 if ($2) {
7113 variationkind = $2->export.nodekind;
7114 } else {
7115 variationkind = SMI_NODEKIND_UNKNOWN;
7116 }
7117 }
7118 SyntaxPart
7119 {
7120 if (variationkind == SMI_NODEKIND_NOTIFICATION) {
7121 smiPrintError(thisParserPtr,
7122 ERR_NOTIFICATION_VARIATION_SYNTAX);
7123 }
7124 }
7125 WriteSyntaxPart
7126 {
7127 if (variationkind == SMI_NODEKIND_NOTIFICATION) {
7128 smiPrintError(thisParserPtr,
7129 ERR_NOTIFICATION_VARIATION_WRITESYNTAX);
7130 }
7131 }
7132 VariationAccessPart
7133 CreationPart
7134 {
7135 if (variationkind == SMI_NODEKIND_NOTIFICATION) {
7136 smiPrintError(thisParserPtr,
7137 ERR_NOTIFICATION_VARIATION_CREATION);
7138 }
7139 }
7140 DefValPart
7141 {
7142 if (variationkind == SMI_NODEKIND_NOTIFICATION) {
7143 smiPrintError(thisParserPtr,
7144 ERR_NOTIFICATION_VARIATION_DEFVAL);
7145 } else if ($11) {
7146 adjustDefval(thisParserPtr,
7147 $11, $2->typePtr,
7148 thisParserPtr->line);
7149 smiCheckValueType(thisParserPtr,
7150 $11, $2->typePtr,
7151 thisParserPtr->line);
7152 }
7153 }
7154 DESCRIPTION Text
7155 {
7156 thisParserPtr->flags &= ~FLAG_CREATABLE;
7157 $$ = 0;
7158 variationkind = SMI_NODEKIND_UNKNOWN;
7159
7160 checkDescr(thisParserPtr, $14);
7161 }
7162 ;
7163
7164 VariationAccessPart: ACCESS VariationAccess
7165 { $$ = $2; }
7166 | /* empty */
7167 { $$ = 0; }
7168 ;
7169
7170 VariationAccess: LOWERCASE_IDENTIFIER
7171 {
7172 if (!strcmp($1, "not-implemented")) {
7173 $$ = SMI_ACCESS_NOT_IMPLEMENTED;
7174 } else if (!strcmp($1, "accessible-for-notify")) {
7175 if (variationkind ==
7176 SMI_NODEKIND_NOTIFICATION) {
7177 smiPrintError(thisParserPtr,
7178 ERR_INVALID_NOTIFICATION_VARIATION_ACCESS,
7179 $1);
7180 $$ = SMI_ACCESS_UNKNOWN;
7181 } else {
7182 $$ = SMI_ACCESS_NOTIFY;
7183 }
7184 } else if (!strcmp($1, "read-only")) {
7185 if (variationkind ==
7186 SMI_NODEKIND_NOTIFICATION) {
7187 smiPrintError(thisParserPtr,
7188 ERR_INVALID_NOTIFICATION_VARIATION_ACCESS,
7189 $1);
7190 $$ = SMI_ACCESS_UNKNOWN;
7191 } else {
7192 $$ = SMI_ACCESS_READ_ONLY;
7193 }
7194 } else if (!strcmp($1, "read-write")) {
7195 if (variationkind ==
7196 SMI_NODEKIND_NOTIFICATION) {
7197 smiPrintError(thisParserPtr,
7198 ERR_INVALID_NOTIFICATION_VARIATION_ACCESS,
7199 $1);
7200 $$ = SMI_ACCESS_UNKNOWN;
7201 } else {
7202 $$ = SMI_ACCESS_READ_WRITE;
7203 }
7204 } else if (!strcmp($1, "read-create")) {
7205 if (variationkind ==
7206 SMI_NODEKIND_NOTIFICATION) {
7207 smiPrintError(thisParserPtr,
7208 ERR_INVALID_NOTIFICATION_VARIATION_ACCESS,
7209 $1);
7210 $$ = SMI_ACCESS_UNKNOWN;
7211 } else {
7212 $$ = SMI_ACCESS_READ_WRITE;
7213 }
7214 } else if (!strcmp($1, "write-only")) {
7215 if (variationkind ==
7216 SMI_NODEKIND_NOTIFICATION) {
7217 smiPrintError(thisParserPtr,
7218 ERR_INVALID_NOTIFICATION_VARIATION_ACCESS,
7219 $1);
7220 $$ = SMI_ACCESS_UNKNOWN;
7221 } else {
7222 $$ = SMI_ACCESS_READ_WRITE; /* TODO */
7223 smiPrintError(thisParserPtr,
7224 ERR_SMIV2_WRITE_ONLY);
7225 }
7226 } else {
7227 smiPrintError(thisParserPtr,
7228 ERR_INVALID_VARIATION_ACCESS,
7229 $1);
7230 $$ = SMI_ACCESS_UNKNOWN;
7231 }
7232 }
7233 ;
7234
7235 CreationPart: CREATION_REQUIRES '{' Cells '}'
7236 { $$ = 0; }
7237 | /* empty */
7238 { $$ = 0; }
7239 ;
7240
7241 Cells: Cell
7242 { $$ = 0; }
7243 | Cells ',' Cell
7244 { $$ = 0; }
7245 ;
7246
7247 Cell: ObjectName
7248 { $$ = 0; }
7249 ;
7250
7251 %%
7252
7253 #endif
7254