/* $OpenBSD: mib.y,v 1.2 2024/02/20 12:41:13 martijn Exp $ */ /* * Copyright (c) 2023 Martijn van Duren * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ %{ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "mib.h" /* RFC2578 section 3.1 */ #define DESCRIPTOR_MAX 64 /* Values from real life testing, could be adjusted */ #define ITEM_MAX DESCRIPTOR_MAX #define MODULENAME_MAX 64 #define SYMBOLS_MAX 256 #define IMPORTS_MAX 16 #define TEXT_MAX 16384 #ifndef nitems #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #endif struct objidcomponent { enum { OCT_DESCRIPTOR, OCT_NUMBER, OCT_NAMEANDNUMBER } type; uint32_t number; char name[DESCRIPTOR_MAX + 1]; }; struct oid_unresolved { /* Unusual to have long lists of unresolved components */ struct objidcomponent bo_id[16]; size_t bo_n; }; struct oid_resolved { uint32_t *bo_id; size_t bo_n; }; enum status { CURRENT, DEPRECATED, OBSOLETE }; enum access { NOTACCESSIBLE, ACCESSIBLEFORNOTIFY, READONLY, READWRITE, READCREATE }; struct objectidentity { enum status status; char *description; char *reference; }; struct objecttype { void *syntax; char *units; enum access maxaccess; enum status status; char *description; char *reference; void *index; void *defval; }; struct notificationtype { void *objects; enum status status; char *description; char *reference; }; struct textualconvention { char *displayhint; enum status status; char *description; char *reference; void *syntax; }; struct item { char name[DESCRIPTOR_MAX + 1]; enum item_type { IT_OID, IT_MACRO, IT_MODULE_IDENTITY, IT_OBJECT_IDENTITY, IT_APPLICATIONSYNTAX, IT_OBJECT_TYPE, IT_NOTIFICATION_TYPE, IT_TEXTUAL_CONVENTION, IT_OBJECT_GROUP, IT_NOTIFICATION_GROUP, IT_MODULE_COMPLIANCE, IT_AGENT_CAPABITIES } type; int resolved; struct module *module; union { struct oid_unresolved *oid_unresolved; struct oid_resolved oid; }; union { struct objectidentity objectidentity; struct objecttype objecttype; struct notificationtype notificationtype; struct textualconvention textualconvention; }; /* Global case insensitive */ RB_ENTRY(item) entrygci; /* Module case insensitive */ RB_ENTRY(item) entryci; /* Module case sensitive */ RB_ENTRY(item) entrycs; /* Global oid */ RB_ENTRY(item) entry; }; struct import_symbol { char name[DESCRIPTOR_MAX + 1]; struct item *item; }; struct import { char name[MODULENAME_MAX + 1]; struct module *module; struct import_symbol symbols[SYMBOLS_MAX]; size_t nsymbols; }; static struct module { char name[MODULENAME_MAX + 1]; int8_t resolved; time_t lastupdated; struct import *imports; RB_HEAD(itemscs, item) itemscs; RB_HEAD(itemsci, item) itemsci; RB_ENTRY(module) entryci; RB_ENTRY(module) entrycs; } *module; int yylex(void); static void yyerror(const char *, ...) __attribute__((__format__ (printf, 1, 2))); void mib_defaults(void); void mib_modulefree(struct module *); int mib_imports_add(char *, char **); int mib_oid_append(struct oid_unresolved *, const struct objidcomponent *); int mib_macro(const char *); int mib_oid_concat(struct oid_unresolved *, const struct oid_unresolved *); struct item *mib_item(const char *, enum item_type); int mib_item_oid(struct item *, const struct oid_unresolved *); int mib_macro(const char *); int mib_applicationsyntax(const char *); struct item *mib_oid(const char *, const struct oid_unresolved *); int mib_moduleidentity(const char *, time_t, const char *, const char *, const char *, const struct oid_unresolved *); int mib_objectidentity(const char *, enum status, const char *, const char *, const struct oid_unresolved *); int mib_objecttype(const char *, void *, const char *, enum access, enum status, const char *, const char *, void *, void *, const struct oid_unresolved *); int mib_notificationtype(const char *, void *, enum status, const char *, const char *, const struct oid_unresolved *); int mib_textualconvetion(const char *, const char *, enum status, const char *, const char *, void *); int mib_objectgroup(const char *, void *, enum status, const char *, const char *, const struct oid_unresolved *); int mib_notificationgroup(const char *, void *, enum status, const char *, const char *, const struct oid_unresolved *); int mib_modulecompliance(const char *, enum status, const char *, const char *, void *, const struct oid_unresolved *); struct item *mib_item_find(struct item *, const char *); struct item *mib_item_parent(struct ber_oid *); int mib_resolve_oid(struct oid_resolved *, struct oid_unresolved *, struct item *); int mib_resolve_item(struct item *); int mib_resolve_module(struct module *); int module_cmp_cs(struct module *, struct module *); int module_cmp_ci(struct module *, struct module *); int item_cmp_cs(struct item *, struct item *); int item_cmp_ci(struct item *, struct item *); int item_cmp_oid(struct item *, struct item *); RB_HEAD(modulesci, module) modulesci = RB_INITIALIZER(&modulesci); RB_HEAD(modulescs, module) modulescs = RB_INITIALIZER(&modulescs); RB_HEAD(items, item) items = RB_INITIALIZER(&items); RB_HEAD(itemsgci, item) itemsci = RB_INITIALIZER(&itemsci); /* * Use case sensitive matching internally (for resolving IMPORTS) and * case sensitive matching, followed by case insensitive matching * for end-user resolving (e.g. mib_string2oid()). * It shouldn't happen there's case-based overlap in module/item names, * but allow all to be resolved in case there is. */ RB_PROTOTYPE_STATIC(modulesci, module, entryci, module_cmp_ci); RB_PROTOTYPE_STATIC(modulescs, module, entrycs, module_cmp_cs); /* * mib_string2oid() should match case insensitive on: * :: * */ RB_PROTOTYPE_STATIC(itemsgci, item, entrygci, item_cmp_ci); RB_PROTOTYPE_STATIC(itemsci, item, entryci, item_cmp_ci); RB_PROTOTYPE_STATIC(itemscs, item, entrycs, item_cmp_cs); RB_PROTOTYPE_STATIC(items, item, entry, item_cmp_oid); struct file { FILE *stream; const char *name; size_t lineno; enum { FILE_UNDEFINED, FILE_ASN1, FILE_SMI2 } state; } file; typedef union { char string[TEXT_MAX]; unsigned long long number; long long signednumber; char symbollist[SYMBOLS_MAX][DESCRIPTOR_MAX + 1]; struct objidcomponent objidcomponent; struct oid_unresolved oid; time_t time; enum status status; enum access access; } YYSTYPE; %} %token ERROR %token HSTRING BSTRING /* RFC2578 section 3.7 */ %token ABSENT ACCESS AGENTCAPABILITIES ANY APPLICATION AUGMENTS BEGIN %token BIT BITS BOOLEAN BY CHOICE COMPONENT COMPONENTS CONTACTINFO %token CREATIONREQUIRES Counter32 Counter64 DEFAULT DEFINED %token DEFINITIONS DEFVAL DESCRIPTION DISPLAYHINT END ENUMERATED %token ENTERPRISE EXPLICIT EXPORTS EXTERNAL FALSE FROM GROUP Gauge32 %token IDENTIFIER IMPLICIT IMPLIED IMPORTS INCLUDES INDEX INTEGER %token Integer32 IpAddress LASTUPDATED MANDATORYGROUPS MAX MAXACCESS %token MIN MINACCESS MINUSINFINITY MODULE MODULECOMPLIANCE MODULEIDENTITY %token NOTIFICATIONGROUP NOTIFICATIONTYPE NOTIFICATIONS ASNNULL %token OBJECT OBJECTGROUP OBJECTIDENTITY OBJECTTYPE OBJECTS OCTET OF %token OPTIONAL ORGANIZATION Opaque PLUSINFINITY PRESENT PRIVATE %token PRODUCTRELEASE REAL REFERENCE REVISION SEQUENCE SET SIZE STATUS %token STRING SUPPORTS SYNTAX TAGS TEXTUALCONVENTION TRAPTYPE TRUE %token TimeTicks UNITS UNIVERSAL Unsigned32 VARIABLES VARIATION WITH %token WRITESYNTAX /* SMIv2 */ %token SNMPv2SMI SNMPv2CONF SNMPv2TC /* X.208 */ %token PRODUCTION RANGESEPARATOR %token typereference identifier TEXT HSTRING BSTRING %token NUMBER %token SIGNEDNUMBER %type moduleidentifier smiv2moduleidentifier %type symbolsfrom %type symbollist %type descriptor symbol %type objidcomponentfirst objidcomponent %type objidcomponentlist objectidentifiervalue %type displaypart referpart unitspart %type