/* * dump-mosy.c -- * * Operations to dump MIB modules in the MOSY output format. * * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig. * Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig. * * See the file "COPYING" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * @(#) $Id: dump-mosy.c 8090 2008-04-18 12:56:29Z strauss $ */ #include #include #include #include "smi.h" #include "smidump.h" static char *ignoreTypeRanges[] = { "TimeTicks", "Counter32", "Gauge32", "Counter64", NULL }; static char *getStatusString(SmiStatus status) { return (status == SMI_STATUS_CURRENT) ? "current" : (status == SMI_STATUS_DEPRECATED) ? "deprecated" : (status == SMI_STATUS_OBSOLETE) ? "obsolete" : (status == SMI_STATUS_MANDATORY) ? "mandatory" : (status == SMI_STATUS_OPTIONAL) ? "optional" : ""; } static char *getAccessString(SmiAccess access, int create) { return (create && (access == SMI_ACCESS_READ_WRITE)) ? "read-create" : (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "not-accessible" : (access == SMI_ACCESS_NOTIFY) ? "accessible-for-notify" : (access == SMI_ACCESS_READ_ONLY) ? "read-only" : (access == SMI_ACCESS_READ_WRITE) ? "read-write" : ""; } static char *getBasetypeString(SmiBasetype basetype) { return (basetype == SMI_BASETYPE_UNKNOWN) ? "" : (basetype == SMI_BASETYPE_OCTETSTRING) ? "OctetString" : (basetype == SMI_BASETYPE_OBJECTIDENTIFIER) ? "ObjectID" : (basetype == SMI_BASETYPE_UNSIGNED32) ? "Unsigned32" : (basetype == SMI_BASETYPE_INTEGER32) ? "Integer32" : (basetype == SMI_BASETYPE_UNSIGNED64) ? "Unsigned64" : (basetype == SMI_BASETYPE_INTEGER64) ? "Integer64" : (basetype == SMI_BASETYPE_FLOAT32) ? "Float32" : (basetype == SMI_BASETYPE_FLOAT64) ? "Float64" : (basetype == SMI_BASETYPE_FLOAT128) ? "Float128" : (basetype == SMI_BASETYPE_ENUM) ? "INTEGER" : (basetype == SMI_BASETYPE_BITS) ? "Bits" : ""; } static char *getOidString(SmiNode *smiNode, int importedParent) { SmiNode *parentNode; SmiModule *smiModule; static char s[200]; char append[200]; unsigned int i; append[0] = 0; parentNode = smiNode; smiModule = smiGetNodeModule(smiNode); do { if (parentNode->oidlen <= 1) { break; } /* prepend the cut-off subidentifier to `append'. */ strcpy(s, append); sprintf(append, ".%u%s", parentNode->oid[parentNode->oidlen-1], s); /* retrieve the parent SmiNode */ parentNode = smiGetParentNode(parentNode); if (!parentNode) { sprintf(s, "%s", append); return s; } /* found an imported or a local parent node? */ if ((parentNode->decl != SMI_DECL_IMPL_OBJECT) && ((parentNode->name && strlen(parentNode->name)) && (smiIsImported(smiModule, NULL, parentNode->name) || (!importedParent && (smiGetNodeModule(parentNode) == smiModule)) || (parentNode->oidlen == 1)))) { sprintf(s, "%s%s", parentNode->name, append); return s; } } while (parentNode); s[0] = 0; for (i=0; i < smiNode->oidlen; i++) { if (i) strcat(s, "."); sprintf(&s[strlen(s)], "%u", smiNode->oid[i]); } return s; } static char *getValueString(SmiValue *valuePtr) { static char s[1024]; s[0] = 0; switch (valuePtr->basetype) { case SMI_BASETYPE_UNSIGNED32: sprintf(s, "%lu", valuePtr->value.unsigned32); break; case SMI_BASETYPE_INTEGER32: sprintf(s, "%ld", valuePtr->value.integer32); break; case SMI_BASETYPE_UNSIGNED64: sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64); break; case SMI_BASETYPE_INTEGER64: sprintf(s, INT64_FORMAT, valuePtr->value.integer64); break; case SMI_BASETYPE_FLOAT32: case SMI_BASETYPE_FLOAT64: case SMI_BASETYPE_FLOAT128: break; case SMI_BASETYPE_ENUM: case SMI_BASETYPE_OCTETSTRING: case SMI_BASETYPE_BITS: case SMI_BASETYPE_OBJECTIDENTIFIER: /* not required in MOSY format */ break; case SMI_BASETYPE_UNKNOWN: break; case SMI_BASETYPE_POINTER: break; } return s; } static void printIndex(FILE *f, SmiNode *smiNode) { char *indexname; int i; SmiElement *smiElement; fprintf(f, "%%%-19s %-16s \"", "ei", smiNode->name); indexname = NULL; for (i = -1, smiElement = smiGetFirstElement(smiNode); smiElement; smiElement = smiGetNextElement(smiElement), i++) { if (i > 0) fprintf(f, " "); if (indexname) { fprintf(f, "%s", indexname); } indexname = smiGetElementNode(smiElement)->name; } if (indexname) { fprintf(f, "%s%s%s", (i > 0) ? " " : "", (smiNode->implied) ? "*" : "", indexname); } fprintf(f, "\"\n"); } static void printAssignements(FILE *f, SmiModule *smiModule) { int cnt = 0; SmiNode *smiNode; for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE); smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) { cnt++; if (smiNode->status == SMI_STATUS_UNKNOWN && smiNode != smiGetModuleIdentityNode(smiModule)) { fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0)); fprintf(f, "%%n0 %-16s object-id\n", smiNode->name); } } if (cnt) { fprintf(f, "\n"); } } static void printTypedefs(FILE *f, SmiModule *smiModule) { int i; SmiType *smiType, *smiParentType; SmiNamedNumber *nn; char *type_name; for (i = 0, smiType = smiGetFirstType(smiModule); smiType; smiType = smiGetNextType(smiType)) { smiParentType = smiGetParentType(smiType); type_name = smiParentType->name; if (smiParentType->decl == SMI_DECL_IMPLICIT_TYPE) { smiParentType = smiGetParentType(smiParentType); type_name = smiParentType->name; } if (smiParentType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER) { type_name = "ObjectID"; } if (smiParentType->basetype == SMI_BASETYPE_ENUM) { type_name = "INTEGER"; } fprintf(f, "%%%-19s %-16s %-15s \"%s\"\n", "tc", smiType->name, type_name, smiType->format ? smiType->format : ""); for (i = 0, nn = smiGetFirstNamedNumber(smiType); nn ; i++, nn = smiGetNextNamedNumber(nn)) { fprintf(f, "%%%-19s %-16s %-15s %s\n", "es", smiType->name, nn->name, getValueString(&nn->value)); } } } static void printObjects(FILE *f, SmiModule *smiModule) { int i, j, ignore, cnt = 0, aggregate, create; char *type_name; SmiNode *smiNode, *relatedNode; SmiType *smiType; SmiNamedNumber *smiNamedNumber; SmiRange *smiRange; for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY); smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) { if (smiNode->nodekind != SMI_NODEKIND_NODE && smiNode->nodekind != SMI_NODEKIND_SCALAR && smiNode->nodekind != SMI_NODEKIND_TABLE && smiNode->nodekind != SMI_NODEKIND_ROW && smiNode->nodekind != SMI_NODEKIND_COLUMN) { continue; } cnt++; if (smiNode->nodekind == SMI_NODEKIND_NODE) { if (smiNode->status != SMI_STATUS_UNKNOWN && smiNode != smiGetModuleIdentityNode(smiModule)) { fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0)); fprintf(f, "%%n0 %-16s object-id\n", smiNode->name); } continue; } aggregate = smiNode->nodekind == SMI_NODEKIND_TABLE || smiNode->nodekind == SMI_NODEKIND_ROW; type_name = NULL; smiType = smiGetNodeType(smiNode); if (!aggregate) { if (! smiType) { continue; } type_name = getBasetypeString(smiType->basetype); if (smiType && (smiType->decl != SMI_DECL_IMPLICIT_TYPE)) { type_name = smiType->name; if (!strcmp(type_name, "ObjectIdentifier")) { type_name = "ObjectID"; } } if (smiType && smiType->decl == SMI_DECL_IMPLICIT_TYPE) { type_name = smiGetParentType(smiType)->name; if (smiType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER) { type_name = "ObjectID"; } if (smiType->basetype == SMI_BASETYPE_ENUM) { type_name = "INTEGER"; } } } else { type_name = "Aggregate"; } if (smiNode->nodekind == SMI_NODEKIND_COLUMN) { create = smiGetParentNode(smiNode)->create; } else { create = 0; } fprintf(f, "%-20s %-16s ", smiNode->name, getOidString(smiNode, 0)); fprintf(f, "%-15s %-15s %s\n", type_name, getAccessString(smiNode->access, create), getStatusString(smiNode->status)); relatedNode = smiGetRelatedNode(smiNode); switch (smiNode->indexkind) { case SMI_INDEX_INDEX: case SMI_INDEX_REORDER: printIndex(f, smiNode); break; case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */ break; case SMI_INDEX_AUGMENT: if (relatedNode) { fprintf(f, "%%%-19s %-16s %s\n", "ea", smiNode->name, relatedNode->name); } break; case SMI_INDEX_SPARSE: if (relatedNode) { printIndex(f, relatedNode); } break; case SMI_INDEX_UNKNOWN: break; } if (smiType && smiType->decl == SMI_DECL_IMPLICIT_TYPE) { for (i = 0, smiNamedNumber = smiGetFirstNamedNumber(smiType); smiNamedNumber; i++, smiNamedNumber = smiGetNextNamedNumber(smiNamedNumber)) { fprintf(f, "%%%-19s %-16s %-15s %s\n", "ev", smiNode->name, smiNamedNumber->name, getValueString(&smiNamedNumber->value)); } for (ignore = 0, j = 0; ignoreTypeRanges[j]; j++) { if (strcmp(type_name, ignoreTypeRanges[j]) == 0) { ignore++; break; } } if (! ignore) { for (smiRange = smiGetFirstRange(smiType); smiRange; smiRange = smiGetNextRange(smiRange)) { fprintf(f, "%%%-19s %-16s %-15s ", "er", smiNode->name, getValueString(&smiRange->minValue)); fprintf(f, "%s\n", getValueString(&smiRange->maxValue)); } } } } if (cnt) { fprintf(f, "\n"); } } static void printNotifications(FILE *f, SmiModule *smiModule) { int cnt = 0; SmiNode *smiNode; for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION); smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) { cnt++; fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0)); fprintf(f, "%%n0 %-16s notification\n", smiNode->name); } if (cnt) { fprintf(f, "\n"); } } static void printGroups(FILE *f, SmiModule *smiModule) { SmiNode *smiNode, *smiNodeMember; SmiElement *smiElement; int cnt = 0, objects, notifications; for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP); smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) { cnt ++; for (objects = 0, notifications = 0, smiElement = smiGetFirstElement(smiNode); smiElement; smiElement = smiGetNextElement(smiElement)) { smiNodeMember = smiGetElementNode(smiElement); objects += (smiNodeMember->nodekind == SMI_NODEKIND_SCALAR) || (smiNodeMember->nodekind == SMI_NODEKIND_COLUMN); notifications += (smiNodeMember->nodekind == SMI_NODEKIND_NOTIFICATION); } fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0)); fprintf(f, "%%n0 %-16s %s\n", smiNode->name, (objects && ! notifications) ? "object-group" : (! objects && notifications) ? "notification-group" : "group"); } if (cnt) { fprintf(f, "\n"); } } static void printCompliances(FILE *f, SmiModule *smiModule) { int cnt = 0; SmiNode *smiNode; for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE); smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) { cnt++; fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0)); fprintf(f, "%%n0 %-16s module-compliance\n", smiNode->name); } if (cnt) { fprintf(f, "\n"); } } static void dumpMosy(int modc, SmiModule **modv, int flags, char *output) { SmiNode *smiNode; int i; FILE *f = stdout; if (output) { f = fopen(output, "w"); if (!f) { fprintf(stderr, "smidump: cannot open %s for writing: ", output); perror(NULL); exit(1); } } for (i = 0; i < modc; i++) { if (! (flags & SMIDUMP_FLAG_SILENT)) { fprintf(f, "-- automatically generated by smidump %s, do not edit!\n", SMI_VERSION_STRING); fprintf(f, "\n-- object definitions compiled from %s\n\n", modv[i]->name); } if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) { fprintf(f, "-- WARNING: this output may be incorrect due to " "significant parse errors\n\n"); } smiNode = smiGetModuleIdentityNode(modv[i]); if (smiNode) { SmiNode *parent = smiGetParentNode(smiNode); fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, !parent || parent->nodekind == SMI_NODEKIND_UNKNOWN )); fprintf(f, "%%n0 %-16s module-identity\n", smiNode->name); fprintf(f, "\n"); } printAssignements(f, modv[i]); printTypedefs(f, modv[i]); printObjects(f, modv[i]); printNotifications(f, modv[i]); printGroups(f, modv[i]); printCompliances(f, modv[i]); } if (fflush(f) || ferror(f)) { perror("smidump: write error"); exit(1); } if (output) { fclose(f); } } void initMosy() { static SmidumpDriver driver = { "mosy", dumpMosy, SMI_FLAG_NODESCR, SMIDUMP_DRIVER_CANT_UNITE, "intermediate format generated by the mosy compiler", NULL, NULL }; smidumpRegisterDriver(&driver); }