net-snmp
Version:
JavaScript implementation of the Simple Network Management Protocol (SNMP)
847 lines (821 loc) • 47.6 kB
JavaScript
const fs = require('fs');
const path = require('path');
const MIB = function (dir) {
var initializeBuffer = function (buffer) {
return Object.assign(buffer, {
logit: false,
lastChar: '',
state: '',
open: false,
CurrentSymbol: '',
nested: 0,
isComment: false,
isEqual: false,
isOID: false,
isList: false,
isString: false,
inComment: false,
inGroup: 0,
builder: '',
ColumnIndex: 0,
RowIndex: 0,
PreviousRow: 0
});
};
var newMIB = ({
directory: dir ? dir : '',
SymbolBuffer: {},
StringBuffer: '',
Modules: {},
Objects: {},
MACROS: [],
CurrentObject: null,
TempObject: {},
CurrentClause: '',
WaitFor: '',
CharBuffer: {
Table: {},
ModuleName: {},
Append: function (char) {
this.builder += char;
},
Fill: function (FileName, row, column) {
if (this.builder.length == 0) {
return;
}
column = (column - this.builder.length);
var symbol = this.builder.toString().trim();
this.builder = "";
if (!this.Table[FileName]) {
this.Table[FileName] = [];
} else if (this.PreviousRow < row) {
this.RowIndex++;
this.ColumnIndex = 0;
this.PreviousRow = row;
}
var R = this.RowIndex;
var C = this.ColumnIndex;
if (!this.Table[FileName][R] || C === 0) {
this.Table[FileName][R] = Object.defineProperty([], "line", {
enumerable: false,
value: row + 1
});
}
this.isEqual = false;
switch (symbol) {
case ')':
this.Table[FileName][R][C] = symbol;
this.ColumnIndex++;
this.logit = false;
break;
case '(':
this.Table[FileName][R][C] = symbol;
this.ColumnIndex++;
this.logit = true;
break;
case 'DEFINITIONS':
if (C == 0) {
this.ModuleName[FileName] = this.Table[FileName][R - 1][C];
} else {
this.ModuleName[FileName] = this.Table[FileName][R][C - 1];
}
this.Table[FileName][R][C] = symbol;
this.ColumnIndex++;
break;
case '::=':
this.Table[FileName][R][C] = symbol;
this.ColumnIndex++;
this.isEqual = true;
break;
case '{':
if (this.Table[FileName][R][C - 1] != '::=') {
this.isList = true;
}
this.Table[FileName][R][C] = symbol;
this.ColumnIndex++;
break;
case 'NOTATION':
if (this.Table[FileName][R][C - 1] == 'TYPE' || this.Table[FileName][R][C - 1] == 'VALUE') {
this.Table[FileName][R][C - 1] += ' NOTATION';
}
break;
case 'OF':
if (this.Table[FileName][R][C - 1] == 'SEQUENCE') {
this.Table[FileName][R][C - 1] = 'SEQUENCE OF';
}
break;
case 'IDENTIFIER':
if (this.Table[FileName][R][C - 1] == 'OBJECT') {
this.Table[FileName][R][C - 1] = 'OBJECT IDENTIFIER';
}
break;
case 'STRING':
if (this.Table[FileName][R][C - 1] == 'OCTET') {
this.Table[FileName][R][C - 1] = 'OCTET STRING';
}
break;
default:
this.Table[FileName][R][C] = symbol;
this.ColumnIndex++;
break;
}
}
},
Import: function (FileName) {
this.ParseModule(path.basename(FileName, path.extname(FileName)), fs.readFileSync(FileName).toString());
},
ParseModule: function (FileName, Contents) {
initializeBuffer(this.CharBuffer);
var lines = Contents.split('\n');
var line = '';
var i = 0;
while ((line = lines[i]) != null && i <= lines.length) {
this.ParseLine(FileName, line, i);
i++;
}
},
ParseLine: function (FileName, line, row) {
let len = line.length;
if (line[len - 1] === '\r')
--len;
for (var i = 0; i < len; i++) {
var char = line.charAt(i);
this.ParseChar(FileName, char, row, i);
}
this.ParseChar(FileName, '\n', row, len);
},
ParseChar: function (FileName, char, row, column) {
switch (char) {
case '\r':
case '\n':
if (!this.CharBuffer.isString) {
this.CharBuffer.Fill(FileName, row, column);
this.CharBuffer.isComment = false;
this.CharBuffer.inGroup = 0; //IGNORE GROUPINGS ACROSS COMMENTS
} else if (this.CharBuffer.isString && this.CharBuffer.isComment) {
this.CharBuffer.Append(char);
}
break;
case '{':
if ( ! this.CharBuffer.isComment && this.CharBuffer.isEqual ) { this.CharBuffer.isOID = true; }
case '[':
case '(':
if ( ! this.CharBuffer.isComment && ! this.CharBuffer.isString ) {
this.CharBuffer.nested++;
if (char == '(' || char == '{') {
// Emit the previous token if this is the start of an outer group
if (this.CharBuffer.nested === 1) {
this.CharBuffer.Fill(FileName, row, column);
}
this.CharBuffer.inGroup++;
}
}
if (this.CharBuffer.isComment || ((this.CharBuffer.isOID || this.CharBuffer.nested > 0) && (!this.CharBuffer.isList || this.CharBuffer.inGroup > 0))) {
this.CharBuffer.Append(char);
} else {
this.CharBuffer.Fill(FileName, row, column);
this.CharBuffer.Append(char);
this.CharBuffer.Fill(FileName, row, column);
}
break;
case '}':
case ']':
case ')':
if ( ! this.CharBuffer.isComment && ! this.CharBuffer.isString ) {
this.CharBuffer.nested--;
if (this.CharBuffer.nested < 0) {
this.CharBuffer.nested = 0;
}
if ( char == ')') {
this.CharBuffer.inGroup--;
if (this.CharBuffer.inGroup < 0) {
this.CharBuffer.inGroup = 0; // ignore grouping across comments
}
}
}
if (this.CharBuffer.isComment || ((this.CharBuffer.isOID || this.CharBuffer.nested >= 0) && (!this.CharBuffer.isList || this.CharBuffer.inGroup >= 0))) {
this.CharBuffer.Append(char);
} else {
this.CharBuffer.Fill(FileName, row, column);
this.CharBuffer.Append(char);
this.CharBuffer.Fill(FileName, row, column);
}
if (char == '}') {
this.CharBuffer.isOID = false;
this.CharBuffer.isList = false;
}
break;
case ',':
if (this.CharBuffer.isComment) {
this.CharBuffer.Append(char);
} else {
this.CharBuffer.Fill(FileName, row, column);
this.CharBuffer.Append(char);
this.CharBuffer.Fill(FileName, row, column);
}
break;
case ';':
if (this.CharBuffer.isComment) {
this.CharBuffer.Append(char);
} else {
this.CharBuffer.Fill(FileName, row, column);
this.CharBuffer.Append(char);
this.CharBuffer.Fill(FileName, row, column);
}
break;
case " ":
case "\t":
if (this.CharBuffer.isComment || ((this.CharBuffer.isOID || this.CharBuffer.nested > 0) && (!this.CharBuffer.isList || this.CharBuffer.inGroup > 0))) {
this.CharBuffer.Append(char);
} else {
this.CharBuffer.Fill(FileName, row, column);
}
break;
case "-":
this.CharBuffer.Append(char);
if (!this.CharBuffer.isString && this.CharBuffer.lastChar == '-') {
this.CharBuffer.isComment = true;
this.CharBuffer.builder = this.CharBuffer.builder.split('--')[0];
this.CharBuffer.Fill(FileName, row, column);
this.CharBuffer.builder = '--';
}
break;
case '"':
if (this.CharBuffer.isComment && !this.CharBuffer.isString && !this.CharBuffer.inComment) {
//011 = COMMENT
//IF 011 SET 101
this.CharBuffer.isComment = true;
this.CharBuffer.isString = false;
this.CharBuffer.inComment = true;
} else if (!this.CharBuffer.isComment && !this.CharBuffer.isString && !this.CharBuffer.inComment) {
//000 = STRING
//IF 000 SET 110
this.CharBuffer.isComment = true;
this.CharBuffer.isString = true;
this.CharBuffer.inComment = false;
this.CharBuffer.Fill(FileName, row, column); //new string
} else if (this.CharBuffer.isComment && this.CharBuffer.isString && !this.CharBuffer.inComment) {
//110 = END STRING
//IF 110 SET 000
this.CharBuffer.isComment = false;
this.CharBuffer.isString = false;
this.CharBuffer.inComment = false;
} else if (this.CharBuffer.isComment && !this.CharBuffer.isString && this.CharBuffer.inComment) {
//101 = END COMMENT
//IF 101 SET 000
this.CharBuffer.isComment = true;
this.CharBuffer.isString = false;
this.CharBuffer.inComment = false;
}
if (this.CharBuffer.isComment) {
this.CharBuffer.Append(char);
} else {
this.CharBuffer.Append(char);
this.CharBuffer.Fill(FileName, row, column);
}
break;
default:
this.CharBuffer.Append(char);
break;
}
this.CharBuffer.lastChar = char;
},
Serialize: function () {
var Table = this.CharBuffer.Table;
var ModuleName = '';
for (var FileName in Table) {
ModuleName = this.CharBuffer.ModuleName[FileName];
this.SymbolBuffer[ModuleName] = [];
var foundTheEnd = false;
var lastGoodDeclaration = [ 'none' ];
var file = Table[FileName];
for (var r = 0; r < file.length; r++) {
var row = file[r];
for (var c = 0; c < row.length; c++) {
var symbol = row[c];
var addSymbol = true;
switch (symbol) {
case 'END':
foundTheEnd = true;
break;
case '::=':
foundTheEnd = false;
lastGoodDeclaration = row;
break;
default:
if (symbol.startsWith('--')) {//REMOVE COMMENTS
//console.log(ModuleName, symbol);
addSymbol = false;
} else {
foundTheEnd = false;
}
}
if (addSymbol) {
this.SymbolBuffer[ModuleName].push(symbol);
}
}
}
if (!foundTheEnd) {
// Warn that the contents are malformed
console.warn(
'[%s]: Incorrect formatting: no END statement found - last good declaration "%s" (line %s)',
ModuleName, lastGoodDeclaration.join(' '), lastGoodDeclaration.line
);
}
}
this.Compile();
},
Compile: function () {
for (var ModuleName in this.SymbolBuffer) {
if (this.SymbolBuffer.hasOwnProperty(ModuleName)) {
if (!this.Modules[ModuleName]) {
this.Modules[ModuleName] = {};
}
var Module = this.Modules[ModuleName];
var Symbols = this.SymbolBuffer[ModuleName];
var Object = Module;
var MACROName = '';
let unresolvedObjects = [];
for (var i = 0; i < Symbols.length; i++) {
switch (Symbols[i]) {
case '::=': // new OBJECT or SMIv1 TRAP-TYPE to define
// if an object assignment list is next, the next symbol is a '{' for the integer list
const isObjectIdentifierAssignment = Symbols[i + 1].indexOf('{') == 0;
// iff it is a TRAP-TYPE macro (SMIv1), the next symbol is an integer
const isTrapTypeDefinition = Number.isInteger(Number.parseInt(Symbols[i + 1]));
// Object assigment or trap type definition
if ( isObjectIdentifierAssignment || isTrapTypeDefinition ) {
let macroIndex = i - 1;
let found = false;
// Go back and find the index position of the macro
while ( ! found && macroIndex > 0) {
macroIndex--;
for (var m = 0; m < this.MACROS.length; m++) {
if (Symbols[macroIndex] == this.MACROS[m]) {
found = true;
break;
}
}
}
// Internal MIB node assignment is marked by an 'OBJECT IDENTIFIER' tag before the ::=
if (Symbols[i - 1] == 'OBJECT IDENTIFIER') {
Object[Symbols[i - 2]] = {};
Object[Symbols[i - 2]]['ObjectName'] = Symbols[i - 2];
Object[Symbols[i - 2]]['ModuleName'] = ModuleName;
Object[Symbols[i - 2]]['OBJECT IDENTIFIER'] = Symbols[i + 1].replace("{", "").replace("}", "").trim().replace(/\s+/, " ");
if (Object[Symbols[i - 2]]['OBJECT IDENTIFIER'] == '0 0') {
Object[Symbols[i - 2]]['OID'] = '0.0';
Object[Symbols[i - 2]]['NameSpace'] = 'null';
} else {
const { oidString, nameString, unresolvedObject } = this.getOidAndNamePaths(Object[Symbols[i - 2]]['OBJECT IDENTIFIER'], Symbols[i - 2], ModuleName);
Object[Symbols[i - 2]]['OID'] = oidString;
Object[Symbols[i - 2]]['NameSpace'] = nameString;
if (unresolvedObject) {
if ( ! unresolvedObjects.includes(unresolvedObject) ) {
unresolvedObjects.push(unresolvedObject);
}
}
// Object[Symbols[i - 2]]['ModuleName'] = ModuleName;
// Object[Symbols[i - 2]]['ObjectName'] = Symbols[i - 2];
}
// Leaf MIB node assignments have a macro, as do TRAP-TYPE definitions
} else {
const ObjectName = Symbols[macroIndex - 1];
Object[ObjectName] = {};
Object[ObjectName]['ObjectName'] = ObjectName;
Object[ObjectName]['ModuleName'] = ModuleName;
Object[ObjectName]['MACRO'] = Symbols[macroIndex];
// Build MACRO object from TYPE NOTATION
const MACRO = this[Symbols[macroIndex]];
let c1 = macroIndex;
const keychain = [];
keychain.push('DESCRIPTION');
let key;
for (let notation in MACRO['TYPE NOTATION']) {
key = notation;
// If TYPE NOTATION does not have a value
if (MACRO['TYPE NOTATION'][notation] == null) {
// Then look up the value from the MACRO Root
key = MACRO[notation]['MACRO'].replace(/"/g, '');
}
keychain.push(key);
}
while (c1 < (i - 1)) {
c1++;
key = Symbols[c1]; // Parse TYPE NOTATION. ex: SYNTAX, ACCESS, STATUS, DESCRIPTION.....
const regExp = /\(([^)]+)\)/; // in parentheses e.g. "ethernet-csmacd (6)"
if (keychain.indexOf(key) > -1 || key == 'REVISION') {
let val = Symbols[c1 + 1].replace(/"/g, "");
// if value array
if (val.indexOf("{") == 0) {
c1++;
while (Symbols[c1].indexOf("}") == -1) {
c1++;
val += Symbols[c1];
}
if ( key == 'DEFVAL' ) {
// DEFVAL { 1500 } is not an array
val = val.replace(/^{/, '').replace(/}$/, '').trim();
} else {
// build value array
val = val.replace("{", "").replace("}", "").split(",").map( (v) => v.trim() );
}
}
switch (key) {
case 'SYNTAX':
switch (val) {
case 'BITS':
case 'INTEGER':
case 'Integer32':
// integer value array e.g. INTEGER {...rfc877-x25 (5), ethernet-csmacd (6)...}
if (Symbols[c1 + 2].indexOf("{") == 0) {
var valObj = val;
val = {};
val[valObj] = {};
c1 = c1 + 1;
var integer;
var syntax;
while (Symbols[c1].indexOf("}") == -1) {
c1++;
var ok = false;
if (Symbols[c1].indexOf("(") == 0 && Symbols[c1].length > 1) {
integer = regExp.exec(Symbols[c1]);
syntax = Symbols[c1 - 1];
ok = true;
} else if (Symbols[c1].indexOf("(") > 0) {
integer = regExp.exec(Symbols[c1]);
syntax = Symbols[c1].split("(")[0];
ok = true;
}
if (syntax && syntax.indexOf("{") == 0) {
syntax = syntax.split("{")[1].trim();
}
if (ok) {
val[valObj][integer[1]] = syntax;
}
}
// integer range e.g. INTEGER (1..2147483647)
} else if (Symbols[c1 + 2].indexOf("(") == 0) {
let valObj = val;
val = {};
val[valObj] = {
ranges: this.GetRanges(Symbols[c1 + 2])
};
}
break;
case 'OCTET STRING':
case 'DisplayString':
// string size e.g. OCTET STRING (SIZE (0..127))
if (Symbols[c1 + 2].replace(/ */g, '').startsWith('(SIZE')) {
let valObj = val;
val = {};
val[valObj] = {
sizes: this.GetRanges(Symbols[c1 + 2])
};
}
break;
case 'SEQUENCE OF':
val += ' ' + Symbols[c1 + 2];
c1 = c1 + 2;
break;
default:
break;
}
//SYNTAX value
Object[ObjectName][key] = val;
break;
case 'DESCRIPTION':
if ( ! Object[ObjectName][key] ) {
Object[ObjectName][key] = val;
}
if ( ! Object[ObjectName]['REVISIONS-DESCRIPTIONS'] ) {
Object[ObjectName]['REVISIONS-DESCRIPTIONS'] = [];
}
Object[ObjectName]['REVISIONS-DESCRIPTIONS'].push ({
"type": "DESCRIPTION",
"value": val
});
break;
case 'REVISION':
if ( ! Object[ObjectName]['REVISIONS-DESCRIPTIONS'] ) {
Object[ObjectName]['REVISIONS-DESCRIPTIONS'] = [];
}
Object[ObjectName]['REVISIONS-DESCRIPTIONS'].push ({
"type": "REVISION",
"value": val
});
break;
default:
Object[ObjectName][key] = val;
break;
}
}
}
Object[Symbols[macroIndex - 1]]['ObjectName'] = Symbols[macroIndex - 1];
Object[Symbols[macroIndex - 1]]['ModuleName'] = ModuleName;
if ( isObjectIdentifierAssignment ) {
Object[Symbols[macroIndex - 1]]['OBJECT IDENTIFIER'] = Symbols[i + 1].replace("{", "").replace("}", "").trim().replace(/\s+/, " ");
if (Object[Symbols[macroIndex - 1]]['OBJECT IDENTIFIER'] == '0 0') {
Object[Symbols[macroIndex - 1]]['OID'] = '0.0';
Object[Symbols[macroIndex - 1]]['NameSpace'] = 'null';
} else {
const { oidString, nameString, unresolvedObject } = this.getOidAndNamePaths(Object[Symbols[macroIndex - 1]]['OBJECT IDENTIFIER'], Symbols[macroIndex - 1], ModuleName);
Object[Symbols[macroIndex - 1]]['OID'] = oidString;
Object[Symbols[macroIndex - 1]]['NameSpace'] = nameString;
if (unresolvedObject) {
if ( ! unresolvedObjects.includes(unresolvedObject) ) {
unresolvedObjects.push(unresolvedObject);
}
}
}
} else if ( isTrapTypeDefinition ) {
Object[Symbols[macroIndex - 1]]['VALUE'] = Number.parseInt(Symbols[i + 1]);
}
if ( Object[Symbols[macroIndex - 1]]['REVISIONS-DESCRIPTIONS'] &&
Object[Symbols[macroIndex - 1]]['REVISIONS-DESCRIPTIONS'].length == 1 &&
Object[Symbols[macroIndex - 1]]['REVISIONS-DESCRIPTIONS'][0]['type'] == 'DESCRIPTION' ) {
delete Object[Symbols[macroIndex - 1]]['REVISIONS-DESCRIPTIONS'];
}
}
// if object assignment list is not next, check prior symbol for processing instructions / macro creation
} else {
switch (Symbols[i - 1]) {
case 'DEFINITIONS':
break;
case 'OBJECT IDENTIFIER':
break;
case 'MACRO':
Object = Object[Symbols[i - 2]] = {};
MACROName = Symbols[i - 2];
break;
case 'VALUE NOTATION':
case 'TYPE NOTATION':
Object[Symbols[i - 1]] = {};
var j = i + 1;
while (Symbols[j + 1] != '::=' && Symbols[j + 1] != 'END') {
if (Symbols[j].indexOf('"') == 0) {
var value = Symbols[j + 1];
var t = j + 1;
if (Symbols[j + 2].indexOf('(') == 0) {
value = Symbols[j + 2];
t = j + 2;
}
Object[Symbols[i - 1]][Symbols[j].replace(/"/g, "")] = value;
j = t;
} else {
Object[Symbols[i - 1]][Symbols[j]] = null;
if (Symbols[j + 1].indexOf('(') == 0) {
Object[Symbols[i - 1]][Symbols[j]] = Symbols[j + 1];
j++;
}
}
j++;
}
// Workaround for lack of INDEX, AUGMENTS and ACCESS in OBJECT-TYPE MACRO "TYPE NOTATION"
if ( ModuleName == "SNMPv2-SMI" ) {
Object["TYPE NOTATION"].INDEX = "Index";
Object["TYPE NOTATION"].AUGMENTS = "Augments";
Object["TYPE NOTATION"].ACCESS = "Access";
} else if ( ModuleName == "RFC-1212" ) {
Object["TYPE NOTATION"].INDEX = "Index";
Object["TYPE NOTATION"].ACCESS = "Access";
}
// End INDEX/AUGMENTS/ACCESS workaround
break;
default:
// New object
Object[Symbols[i - 1]] = {};
Object[Symbols[i - 1]]['ObjectName'] = Symbols[i - 1];
Object[Symbols[i - 1]]['ModuleName'] = ModuleName;
Object[Symbols[i - 1]]['MACRO'] = Symbols[i + 1];
this.BuildObject(Object, Symbols[i - 1], Symbols[i + 1], i, Symbols);
break;
}
}
break;
case 'END':
if (MACROName != '') {
// Add macros to root for easier processing
// Still need Import feature
this[MACROName] = Object;
this.MACROS.push(MACROName);
}
// Reset Object to Module root;
Object = Module;
MACROName = '';
break;
case 'IMPORTS':
Module['IMPORTS'] = {};
var tmp = i + 1;
var IMPORTS = [];
while (Symbols[tmp] != ';') {
if (Symbols[tmp] == 'FROM') {
var ImportModule = Symbols[tmp + 1];
if (!this.Modules[ImportModule]) {
console.log(ModuleName + ': Can not find ' + ImportModule + '!!!!!!!!!!!!!!!!!!!!!');
console.log(ModuleName + ': Can not import ', IMPORTS);
}
Module['IMPORTS'][ImportModule] = IMPORTS;
tmp++;
IMPORTS = [];
} else if (Symbols[tmp] != ',') {
IMPORTS.push(Symbols[tmp]);
}
tmp++;
}
//console.log(ModuleName, 'IMPORTS', Module['IMPORTS']);
break;
case 'EXPORTS':
// EXPORTS only appears for SMIv1 once: in RFC1155-SMI - where it exports everything
// EXPORTS are forbidden for SMIv2 in RFC2578 section 3.3, as all objects are exported by default
// Therefore, we ignore EXPORTS for both SMIv1 and SMIv2
break;
default:
break;
}
}
// Attempt OID/namespace reconstruction for unresolved objects, as parsing has finished
if (unresolvedObjects.length > 0) {
for (const unresolved of unresolvedObjects) {
const obj = this.Modules[ModuleName][unresolved];
const { oidString, nameString, unresolvedObject } = this.getOidAndNamePaths(obj['OBJECT IDENTIFIER'], unresolved, ModuleName);
this.Modules[ModuleName][unresolved].NameSpace = nameString;
this.Modules[ModuleName][unresolved].OID = oidString;
// unresolvedObject is only returned if still unable to resolve (likely due to error in MIB)
// unresolved OID will propagate to all children as well
if (unresolvedObject) {
if (obj.NameSpace) {
const unresolvedParent = obj.NameSpace.split('.')[1];
if (unresolvedParent !== obj.ObjectName) {
console.warn(`Unable to mount node '${obj.ObjectName}', cannot resolve parent object '${unresolvedParent}'.`);
continue;
}
}
console.warn(`Unable to mount node '${obj.ObjectName}', cannot resolve object identifier '${obj['OBJECT IDENTIFIER']}'.`);
}
}
}
}
}
},
GetRanges: function (mibRanges) {
let rangesString = mibRanges.replace(/ */g, '').replace(/\(SIZE/, '').replace(/\)/, '').replace(/\(/, '').replace(/\)/, '');
let rangeStrings = rangesString.split('|');
let ranges = [];
for ( let rangeString of rangeStrings ) {
if ( rangeString.includes('..') ) {
let range = rangeString.split('..');
ranges.push({
min: parseInt(range[0], 10),
max: parseInt(range[1], 10)
});
} else {
ranges.push({
min: parseInt(rangeString, 10),
max: parseInt(rangeString, 10)
});
}
}
return ranges;
},
BuildObject: function (Object, ObjectName, macro, i, Symbols) {
var syntaxKeyword = Symbols.indexOf('SYNTAX', i);
var m = syntaxKeyword - i;
var c1 = syntaxKeyword + 1;
var SYNTAX = Symbols[c1];
var val = Symbols[c1 + 1];
// Normal MACROs
if (this.MACROS.indexOf(macro) > -1 && m < 10) {
if (val[0] === "{") {
this.BuildObjectEnumeration(Object, ObjectName, c1, SYNTAX, val, Symbols);
} else if (val[0] === '(') {
const key = val.startsWith('(SIZE')? 'sizes' : 'ranges';
Object[ObjectName]['SYNTAX'] = {};
Object[ObjectName]['SYNTAX'][SYNTAX] = { [key]: this.GetRanges(val) };
} else {
Object[ObjectName]['SYNTAX'] = SYNTAX;
}
// SMIv1 INTEGER enumerations
} else if ( Symbols[i + 1] == 'INTEGER' ) {
c1 = i + 1;
SYNTAX = 'INTEGER';
val = Symbols[c1 + 1];
if ( val[0] === '{' ) {
this.BuildObjectEnumeration(Object, ObjectName, c1, SYNTAX, val, Symbols);
}
}
},
BuildObjectEnumeration: function (Object, ObjectName, c1, SYNTAX, val, Symbols) {
c1++;
while (Symbols[c1].indexOf("}") == -1) {
c1++;
val += Symbols[c1].trim();
}
val = val.replace("{", "").replace("}", "").split(",");
Object[ObjectName]['SYNTAX'] = {};
Object[ObjectName]['SYNTAX'][SYNTAX] = {};
for (var TC = 0; TC < val.length; TC++) {
let openParenSplit = val[TC].split(/\s*\(\s*/);
Object[ObjectName]['SYNTAX'][SYNTAX][openParenSplit[1].replace(/\s*\)\s*$/, '')] = openParenSplit[0].trimStart();
}
},
GetSummary: function (callback) {
var summary = '';
for (var ModuleName in this.Modules) {
if (this.Modules.hasOwnProperty(ModuleName)) {
for (var ObjectName in this.Modules[ModuleName]) {
if (this.Modules[ModuleName].hasOwnProperty(ObjectName)) {
if (this.Modules[ModuleName][ObjectName]['OID']) {
//OID
summary += this.Modules[ModuleName][ObjectName]['OID'] + " : " + ObjectName + '\r\n';
//callback(this.Modules[ModuleName][ObjectName]);
//break;
}
}
}
}
}
callback(summary);
},
getOidAndNamePaths: function (OBJECT_IDENTIFIER, ObjectName, ModuleName) {
const entries = OBJECT_IDENTIFIER.split(/\s+/);
const parent = entries.shift();
const finalEntries = entries.pop();
const nameEntries = [];
const oidEntries = [];
// process middle entries if any
// e.g. { enterprises pwg(2699) mibs(1) jobmonMIB(1) }
for (const entry of entries) {
const match = entry.match(/(.*)\((.+)\)$/);
if ( match ) {
oidEntries.push(match[2]);
nameEntries.push(match[1]);
} else {
// cater for unannotated middle entries (use number entries for name entries)
// e.g. { enterprises 2699 1 1 }
oidEntries.push(entry);
nameEntries.push(entry);
}
}
// ignore name entry if it exists on final OID entry - use object name instead
// e.g. for { mibs jobmonMIB(1) } we would ignore the "jobmonMIB" name
let finalOid;
if ( finalEntries.includes('(') ) {
const oidSplit = finalEntries.match(/(.*)\((.+)\)$/);
finalOid = oidSplit[2];
} else {
finalOid = finalEntries;
}
oidEntries.push(finalOid);
nameEntries.push(ObjectName);
let parentOidPrefix;
let parentNamePrefix;
let unresolvedObject;
if ( parent == 'iso' ) {
parentOidPrefix = '1';
parentNamePrefix = 'iso';
} else {
// find parent object
// first look in the current module
let parentObject = this.Modules[ModuleName][parent];
// if not found, find the import entry for the object
if ( ! parentObject ) {
const importModules = Object.keys(this.Modules[ModuleName]['IMPORTS']);
for (let importModule of importModules) {
if (this.Modules[importModule][parent]) {
parentObject = this.Modules[importModule][parent];
break;
}
}
}
if ( ! parentObject ) {
// occurs for out-of-order dependencies in a module
// return partial OID/namespace and name of unresolved object
unresolvedObject = ObjectName;
return {
oidString: '.' + oidEntries.join('.'),
nameString: '.' + nameEntries.join('.'),
unresolvedObject
};
}
// occurs for all children of an unresolved node
if ( parentObject.OID.startsWith('.') ) {
unresolvedObject = ObjectName;
}
parentOidPrefix = parentObject['OID'];
parentNamePrefix = parentObject['NameSpace'];
}
return {
oidString: parentOidPrefix + '.' + oidEntries.join('.'),
nameString: parentNamePrefix + '.' + nameEntries.join('.'),
unresolvedObject: unresolvedObject || undefined
};
}
});
// Complete buffer setup before returning to caller.
initializeBuffer(newMIB.CharBuffer);
return newMIB;
};
module.exports = exports = MIB;
exports.MIB = MIB;
exports.native = undefined;