
This is from someone in my company using libsmi, but not on the mailing list. This problem may have been fixed already, as this is with Lib SMI 0.4.1.
Pete
========
I have attached two simple MIB files FOO-TEST-MIB and FOO-CORP-MIB1 (sic) the “1” is appended so that it is not automatically imported when loading FOO-TEST-MIB.
The Problem: FOO-TEST-MIB top node (fooTest) is defined in terms of fooProductOID which is imported from FOO-CORP-MIB. If the corp mib is not in SMI path nor previously imported, there is an error correctly reported regarding 1) the inability to find the module but also 2) the lack of parent node for fooTest. This is fine but, subsequently attempting to load FOO-CORP-MIB1 causes a problem during setObjectName mergeNodeTrees call that ultimately results in a crash due to objectPtr remaining on lists after being freed.
I have also included a revised version of 'setObjectName' which seems to work for me. I have not studied the data structures and relationships between objects in great detail, so, I suspect this is not the best solution nor a complete solution. However, it performed perfectly in all of my test cases. If you have time to analyze it and recommend a better fix, I would greatly appreciate it. You are free to use this code for libsmi if it is, in fact, a valid solution.
Sincerely, Ted Latonik Melbourne, FL USA
Object *setObjectName( Object *objectPtr, char *name ) { Node *nodePtr, *nextPtr; Module *modulePtr; Object *newObjectPtr; Module *newModulePtr; // ADDED TO SUPPORT BUGFIX
if ( objectPtr->export.name ) { smiFree( objectPtr->export.name ); }
objectPtr->export.name = name;
/* * If this name is found on the pending list (at depth==1 in * pendingRootNode), we have to move the corresponding subtree to * the main tree. */ for ( nodePtr = smiHandle->pendingNodePtr->firstChildPtr; nodePtr; nodePtr = nextPtr ) { /* * probably we change the contents of `pending', so remember * the next pointer. */ nextPtr = nodePtr->nextPtr;
if ( !strcmp( nodePtr->firstObjectPtr->export.name, name ) ) { /* * remove nodePtr from the pendingRootNode tree. */ if ( nodePtr->prevPtr ) { nodePtr->prevPtr->nextPtr = nodePtr->nextPtr; } else { smiHandle->pendingNodePtr->firstChildPtr = nodePtr->nextPtr; }
if ( nodePtr->nextPtr ) { nodePtr->nextPtr->prevPtr = nodePtr->prevPtr; } else { smiHandle->pendingNodePtr->lastChildPtr = nodePtr->prevPtr; }
#if 0 objectPtr->nodePtr->firstObjectPtr = NULL; objectPtr->nodePtr->lastObjectPtr = NULL; #else if ( objectPtr->nodePtr->lastObjectPtr != NULL ) { if ( objectPtr->nodePtr->lastObjectPtr->export.oid == NULL ) { objectPtr->nodePtr->lastObjectPtr =
objectPtr->nodePtr->lastObjectPtr->prevSameNodePtr; if ( objectPtr->nodePtr->lastObjectPtr == NULL ) { objectPtr->nodePtr->firstObjectPtr = NULL; } } }
#endif // ADDED TO SUPPORT BUGFIX----------------------- newModulePtr = objectPtr->modulePtr; //-----------------------------------------------
newObjectPtr = nodePtr->firstObjectPtr; if ( newObjectPtr ) { modulePtr = newObjectPtr->modulePtr; if ( modulePtr->objectPtr == objectPtr ) { modulePtr->objectPtr = newObjectPtr; }
if ( modulePtr->firstObjectPtr == objectPtr ) { modulePtr->firstObjectPtr = objectPtr->nextPtr; modulePtr->firstObjectPtr->prevPtr = NULL; }
if ( modulePtr->lastObjectPtr == objectPtr ) { modulePtr->lastObjectPtr = objectPtr->prevPtr; modulePtr->lastObjectPtr->nextPtr = NULL; } // FIX BEGINS HERE
//--------------------------------------------------------- // If If the forward reference is in the same module just // merge and free
//--------------------------------------------------------- if ( modulePtr == newModulePtr ) { mergeNodeTrees( objectPtr->nodePtr, nodePtr ); smiFree( objectPtr->export.name ); smiFree( objectPtr );
}
//--------------------------------------------------------- // This happens when a previously undefined prefix is being // defined
//--------------------------------------------------------- else if ( !strcmp( name, objectPtr->export.name ) ) {
//----------------------------------------------------- // Remove the object from the old module
//----------------------------------------------------- modulePtr->firstObjectPtr =
modulePtr->firstObjectPtr->nextPtr; modulePtr->firstObjectPtr->prevPtr = NULL;
//----------------------------------------------------- // Merge the nodes
//----------------------------------------------------- mergeNodeTrees( objectPtr->nodePtr, nodePtr );
//----------------------------------------------------- // Replace the object in the new module // It always seems to be the lastObjectPtr but the // following is added in case
//----------------------------------------------------- if ( newModulePtr->firstObjectPtr == objectPtr ) { if ( newObjectPtr->nextPtr = objectPtr->nextPtr ) newObjectPtr->nextPtr->prevPtr = newObjectPtr; newModulePtr->firstObjectPtr = newObjectPtr; newObjectPtr->prevPtr = NULL; } if ( newModulePtr->lastObjectPtr == objectPtr ) { if ( newObjectPtr->prevPtr = objectPtr->prevPtr ) newObjectPtr->prevPtr->nextPtr = newObjectPtr; newModulePtr->lastObjectPtr = newObjectPtr; newObjectPtr->nextPtr = NULL; }
//----------------------------------------------------- // Fix the prefix node and the module ptr
//----------------------------------------------------- modulePtr->prefixNodePtr = modulePtr->firstObjectPtr->nodePtr; objectPtr->nodePtr->firstObjectPtr->modulePtr = objectPtr->modulePtr;
newModulePtr->prefixNodePtr =
newModulePtr->firstObjectPtr->nodePtr;
//----------------------------------------------------- // Reset the OID so the parser will fill it in
//----------------------------------------------------- newObjectPtr->export.oidlen = 0; if ( newObjectPtr->export.oid ) { free( newObjectPtr->export.oid ); newObjectPtr->export.oid = NULL; } smiFree( objectPtr->export.name ); smiFree( objectPtr ); } else { printf( "Is this case possible?" ); } return newObjectPtr; } } } return objectPtr; }
--*********************************************************************** -- MIB fooTest from project `foosample' -- -- Auto-generated by SNMP IQ Application Builder on 11/10/2003 -- Version: -- Authored on: 05/20/2002 -- -- Foo Corporation Test Definition -- -- --*********************************************************************** --
FOOTEST-MIB DEFINITIONS ::= BEGIN
IMPORTS --============================================================== -- -- Imports from: FOO-CORP-MIB -- --============================================================== fooProjectOID FROM FOO-CORP-MIB
--============================================================== -- -- Imports from: SNMPv2-CONF -- --============================================================== OBJECT-GROUP FROM SNMPv2-CONF
--============================================================== -- -- Imports from: SNMPv2-SMI -- --============================================================== Counter32, Counter64, Gauge32, Integer32, IpAddress, MODULE-IDENTITY, NOTIFICATION-TYPE, OBJECT-TYPE, Opaque, TimeTicks, Unsigned32 FROM SNMPv2-SMI
--============================================================== -- -- Imports from: SNMPv2-TC -- --============================================================== DisplayString, RowStatus, TruthValue FROM SNMPv2-TC;
--============================================================== fooTest MODULE-IDENTITY LAST-UPDATED "200205200000Z" ORGANIZATION "Foo Corporation" CONTACT-INFO " Icon Laboratories, Inc."
DESCRIPTION "Foo Corporation Test Definition"
::= { fooProjectOID 1 }
-- ************************************************************************ -- TYPE ASSIGNMENTS -- ************************************************************************
Real32 ::= DisplayString
-- Top-level structure of the MIB
fooTestEvent OBJECT IDENTIFIER ::= { fooTest 0 } powerAlarm NOTIFICATION-TYPE OBJECTS { mySet, myByteList } STATUS current DESCRIPTION "powerAlarm"
::= { fooTestEvent 1 } bombshellEvent NOTIFICATION-TYPE OBJECTS { myByteList, myUint, myInt, myStr, myCntr64, myBool, myVarStr, mySet, myIpAddr, myGauge, myCntr32, myTime, myRowStat, myObjectID, tbl1RowStat, entry4 } STATUS current DESCRIPTION "Must have a description"
::= { fooTestEvent 500 }
myByteList OBJECT-TYPE SYNTAX Opaque (SIZE(0..20)) MAX-ACCESS read-write STATUS current DESCRIPTION "Test the opaque datatype"
::= { fooTest 1 }
myUint OBJECT-TYPE SYNTAX Unsigned32 (3..5|8|10..12) MAX-ACCESS read-write STATUS current DESCRIPTION "Test the uint datatype with ranges"
DEFVAL { 12 } ::= { fooTest 2 }
myInt OBJECT-TYPE SYNTAX Integer32 (-12|-8..10) MAX-ACCESS read-write STATUS current DESCRIPTION "Test the int datatype with ranges"
DEFVAL { -6 } ::= { fooTest 3 }
myStr OBJECT-TYPE SYNTAX DisplayString (SIZE(5)) MAX-ACCESS read-write STATUS current DESCRIPTION "Fixed-length string with default"
DEFVAL { "12345" } ::= { fooTest 4 }
myCntr64 OBJECT-TYPE SYNTAX Counter64 MAX-ACCESS read-only STATUS current DESCRIPTION "Counter64 variable, read-only."
::= { fooTest 5 }
myBool OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-write STATUS current DESCRIPTION "Boolean with default of false"
DEFVAL { false } ::= { fooTest 6 }
myVarStr OBJECT-TYPE SYNTAX DisplayString (SIZE(3..8)) MAX-ACCESS read-write STATUS current DESCRIPTION "Var-length string"
DEFVAL { "larry" } ::= { fooTest 7 }
mySet OBJECT-TYPE SYNTAX INTEGER { on(1), off(2), maybe(3) } MAX-ACCESS read-write STATUS current DESCRIPTION "Enumerated set with default value"
DEFVAL { off } ::= { fooTest 8 }
myIpAddr OBJECT-TYPE SYNTAX IpAddress MAX-ACCESS read-write STATUS current DESCRIPTION "Inet address with default."
DEFVAL { '7f000001'H } ::= { fooTest 9 }
myGauge OBJECT-TYPE SYNTAX Gauge32 MAX-ACCESS read-write STATUS current DESCRIPTION "Gauge datatype."
::= { fooTest 10 }
myCntr32 OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "32-bit counter - readonly."
::= { fooTest 11 }
myTime OBJECT-TYPE SYNTAX TimeTicks MAX-ACCESS read-write STATUS current DESCRIPTION "Time type."
::= { fooTest 12 }
myRowStat OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-write STATUS current DESCRIPTION "Rowstat enumeration."
DEFVAL { active } ::= { fooTest 13 }
myObjectID OBJECT-TYPE SYNTAX OBJECT IDENTIFIER MAX-ACCESS read-write STATUS current DESCRIPTION "An object."
::= { fooTest 14 }
myReal32 OBJECT-TYPE SYNTAX Real32 MAX-ACCESS read-write STATUS current DESCRIPTION "A floating type."
DEFVAL { "0.000000" } ::= { fooTest 15 }
myBitStr OBJECT-TYPE SYNTAX BITS { zero(0), one(1), two(2), three(3), four(4), five(5), six(6), seven(7), eight(8) } MAX-ACCESS read-write STATUS current DESCRIPTION "myBitStr"
::= { fooTest 16 }
myOctetStr OBJECT-TYPE SYNTAX OCTET STRING (SIZE(0..32)) MAX-ACCESS read-write STATUS current DESCRIPTION "myOctetStr"
::= { fooTest 17 }
-- Begin Table table1Table ===================================================== table1Table OBJECT-TYPE SYNTAX SEQUENCE OF Table1Entry MAX-ACCESS not-accessible STATUS current DESCRIPTION "This is my dorky description."
::= { fooTest 100 }
table1Entry OBJECT-TYPE SYNTAX Table1Entry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Row of table table1Table"
INDEX { mainIndex, index2 } ::= { table1Table 1 }
Table1Entry ::= SEQUENCE { mainIndex Unsigned32, index2 Unsigned32, tbl1Bits BITS, tbl1OctetStr OCTET STRING, tbl1ByteList Opaque, tbl1Uint Unsigned32, tbl1Int Integer32, tbl1Str DisplayString, tbl1Cntr64 Counter64, tbl1Bool TruthValue, tbl1VarStr DisplayString, tbl1Set INTEGER, tbl1IpAddr IpAddress, tbl1Gauge Gauge32, tbl1Cntr32 Counter32, tbl1Time TimeTicks, tbl1RowStat RowStatus, tbl1ObjectID OBJECT IDENTIFIER, tbl1Real32 Real32 }
mainIndex OBJECT-TYPE SYNTAX Unsigned32 (1..12) MAX-ACCESS not-accessible STATUS current DESCRIPTION "Must have a description"
::= { table1Entry 151 }
index2 OBJECT-TYPE SYNTAX Unsigned32 (1..12) MAX-ACCESS not-accessible STATUS current DESCRIPTION "Must have a description"
::= { table1Entry 152 }
tbl1Bits OBJECT-TYPE SYNTAX BITS { zero(0), one(1), two(2), three(3), four(4), five(5), six(6), seven(7), eight(8) } MAX-ACCESS read-create STATUS current DESCRIPTION "tbl1Bits"
::= { table1Entry 1 }
tbl1OctetStr OBJECT-TYPE SYNTAX OCTET STRING (SIZE(0..24)) MAX-ACCESS read-create STATUS current DESCRIPTION "tbl1OctetStr"
::= { table1Entry 2 }
tbl1ByteList OBJECT-TYPE SYNTAX Opaque (SIZE(0..20)) MAX-ACCESS read-create STATUS current DESCRIPTION "Test the opaque datatype"
::= { table1Entry 101 }
tbl1Uint OBJECT-TYPE SYNTAX Unsigned32 (3..5|8|10..12) MAX-ACCESS read-create STATUS current DESCRIPTION "Test the uint datatype with ranges"
DEFVAL { 3 } ::= { table1Entry 102 }
tbl1Int OBJECT-TYPE SYNTAX Integer32 (-12|-8..10) MAX-ACCESS read-create STATUS current DESCRIPTION "Test the int datatype with ranges"
::= { table1Entry 103 }
tbl1Str OBJECT-TYPE SYNTAX DisplayString (SIZE(5)) MAX-ACCESS read-create STATUS current DESCRIPTION "Fixed-length string with default"
DEFVAL { "Smith" } ::= { table1Entry 104 }
tbl1Cntr64 OBJECT-TYPE SYNTAX Counter64 MAX-ACCESS read-only STATUS current DESCRIPTION "Counter64 variable, read-only."
::= { table1Entry 105 }
tbl1Bool OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-create STATUS current DESCRIPTION "Boolean with default of false"
DEFVAL { false } ::= { table1Entry 106 }
tbl1VarStr OBJECT-TYPE SYNTAX DisplayString (SIZE(3..8)) MAX-ACCESS read-create STATUS current DESCRIPTION "Var-length string"
DEFVAL { "larry" } ::= { table1Entry 107 }
tbl1Set OBJECT-TYPE SYNTAX INTEGER { on(1), off(2), maybe(3) } MAX-ACCESS read-create STATUS current DESCRIPTION "Enumerated set with no default value"
DEFVAL { off } ::= { table1Entry 108 }
tbl1IpAddr OBJECT-TYPE SYNTAX IpAddress MAX-ACCESS read-create STATUS current DESCRIPTION "Inet address with no default."
::= { table1Entry 109 }
tbl1Gauge OBJECT-TYPE SYNTAX Gauge32 MAX-ACCESS read-create STATUS current DESCRIPTION "Gauge datatype."
::= { table1Entry 110 }
tbl1Cntr32 OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "32-bit counter - readonly."
::= { table1Entry 111 }
tbl1Time OBJECT-TYPE SYNTAX TimeTicks MAX-ACCESS read-create STATUS current DESCRIPTION "Time type."
::= { table1Entry 112 }
tbl1RowStat OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "Rowstat enumeration."
DEFVAL { notReady } ::= { table1Entry 113 }
tbl1ObjectID OBJECT-TYPE SYNTAX OBJECT IDENTIFIER MAX-ACCESS read-create STATUS current DESCRIPTION "An object."
::= { table1Entry 114 }
tbl1Real32 OBJECT-TYPE SYNTAX Real32 MAX-ACCESS read-create STATUS current DESCRIPTION "A floating type."
DEFVAL { "0.000000" } ::= { table1Entry 115 }
-- End Table table1Table =======================================================
-- Begin Table table2Table ===================================================== table2Table OBJECT-TYPE SYNTAX SEQUENCE OF Table2Entry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A description for table2."
::= { fooTest 200 }
table2Entry OBJECT-TYPE SYNTAX Table2Entry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Row of table table2Table"
INDEX { mainIndex, index3 } ::= { table2Table 1 }
Table2Entry ::= SEQUENCE { index3 DisplayString, entry3 TruthValue, entry4 Opaque, entry5 OBJECT IDENTIFIER }
index3 OBJECT-TYPE SYNTAX DisplayString (SIZE(1..5)) MAX-ACCESS not-accessible STATUS current DESCRIPTION "Must have a description"
::= { table2Entry 201 }
entry3 OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-write STATUS current DESCRIPTION "This is the index description."
DEFVAL { false } ::= { table2Entry 202 }
entry4 OBJECT-TYPE SYNTAX Opaque (SIZE(0..10)) MAX-ACCESS read-write STATUS current DESCRIPTION "This is the entry description."
::= { table2Entry 203 }
entry5 OBJECT-TYPE SYNTAX OBJECT IDENTIFIER MAX-ACCESS read-write STATUS current DESCRIPTION "This is the entry description."
::= { table2Entry 204 }
-- End Table table2Table =======================================================
statScalarGroup OBJECT-GROUP OBJECTS { myByteList, myUint, myStr, myCntr64, myBool, myVarStr, mySet, myIpAddr, myGauge, myCntr32, myTime, myRowStat, myObjectID, myReal32, myInt, myByteList, myUint, myInt, myStr, myCntr64, myBool, myVarStr, mySet, myIpAddr, myGauge, myCntr32, myTime, myRowStat, myObjectID, myReal32, myBitStr, myOctetStr } STATUS current DESCRIPTION "Must have a description"
::= { fooTest 300 }
statTableGroup OBJECT-GROUP OBJECTS { tbl1ByteList, tbl1Uint, tbl1Int, tbl1Str, tbl1Cntr64, tbl1Bool, tbl1VarStr, tbl1Set, tbl1IpAddr, tbl1Gauge, tbl1Cntr32, tbl1Time, tbl1RowStat, tbl1ObjectID, tbl1Real32, entry3, entry4, entry5 } STATUS current DESCRIPTION "Must have a description"
::= { fooTest 301 } myNode OBJECT IDENTIFIER ::= { fooTest 400 }
END
--*********************************************************************** -- MIB fooCorp from project `TEST' -- -- Auto-generated by SNMP IQ Application Builder on 11/10/2003 -- Version: -- Authored on: 05/23/2001 -- -- The root of the foo Corporation enterprise MIB. -- foo Corp is a fictional organization with an -- enterprise number that SNMP trainers can use. -- -- --*********************************************************************** --
FOO-CORP-MIB DEFINITIONS ::= BEGIN
IMPORTS --============================================================== -- -- Imports from: SNMPv2-SMI -- --============================================================== MODULE-IDENTITY, enterprises FROM SNMPv2-SMI;
--============================================================== fooCorp MODULE-IDENTITY LAST-UPDATED "200105230000Z" ORGANIZATION "foo Corporation" CONTACT-INFO " Icon Laboratories, Inc. 3636 Westown Parkway, Suite 101 West Des Moines, IA 50266 USA"
DESCRIPTION "The root of the foo Corporation enterprise MIB. foo Corp is a fictional organization with an enterprise number that SNMP trainers can use."
::= { enterprises 9547 }
-- ************************************************************************ -- TYPE ASSIGNMENTS -- ************************************************************************
-- Top-level structure of the MIB
fooCorpAdmin OBJECT IDENTIFIER ::= { fooCorp 1 } fooProjectOID OBJECT IDENTIFIER ::= { fooCorpAdmin 1 } fooProductOID OBJECT IDENTIFIER ::= { fooCorpAdmin 2 } fooClientOID OBJECT IDENTIFIER ::= { fooCorpAdmin 3 } fooEmployeeID OBJECT IDENTIFIER ::= { fooCorpAdmin 4 } fooPhoneNo OBJECT IDENTIFIER ::= { fooCorpAdmin 5 } fooMibModules OBJECT IDENTIFIER ::= { fooCorpAdmin 6 } fooProjects OBJECT IDENTIFIER ::= { fooCorp 2 } fooProducts OBJECT IDENTIFIER ::= { fooCorp 3 } fooExperimental OBJECT IDENTIFIER ::= { fooCorp 4 }
END
participants (1)
-
Pete Flugstad