CMP EMBEDDED.COM

Login | Register     Welcome Guest  
HOME DESIGN PRODUCTS COLUMNS E-LEARNING CONFERENCES CODE FORUMS/BLOGS NEWSLETTERS CONTACT FEATURES RSS RSS



Internet Appliance Design

Exposing MIB Data to a Web-based Interface, Part 2

Kedron Wolcott

This month we conclude this discussion of how web-based management can benefit from the right architecture and an SNMP MIB inheritance library.

See Part 1 of this article " Exposing MIB Data to a Web-based Interface"

L ast month, we introduced the idea of coupling an SNMP MIB inheritance library with a backplane-based architecture to leverage the advantages of each. This month, we'll present examples and look at some even more powerful advantages of adding WBM support this way.

Operation with scalar MIB objects
Again, assume that you have the following HTML found in MYFILE2 , where MYFILE2 is stored on the embedded network device using such an architecture:

<INPUT TYPE="text" SIZE="20"
NAME="sysName" VALUE="$%sysName#$">

As previously described, this HTML is a FORM element that describes a one-line text box, which allows an end user to both read and write data.

Now as before, when an HTTP request is made for MYFILE2, it gets loaded into the Web-based management solution's GET Handler. The GET Handler parses through the HTML until it runs into $%. From there, it knows that sysName is a special tag.

At that point, the GET Handler again consults the backplane in an effort to get the data associated with sysName . However, unlike the previous example, where the backplane had an entry for userName, the backplane will simply not have an entry for sysName . And when the backplane can't find an entry for sysName , it assumes that it is an SNMP MIB variable and passes it off to the SNMP MIB inheritance library.

At that point, the library takes over. Depending on the SNMP stack, the module will either access the Management Information Base directly, or it will build up a PDU and pass it off to the agent, whichever is appropriate.

Regardless, the SNMP GET routine associated with the MIB variable sysName is called, and the data represented by sysName is returned in numerical notation. The SNMP MIB Inheritance module then takes that data and converts it back into text-suitable for viewing via HTML, SMTP e-mail alerts, command-line interfaces, Java applets, and so on-and passes it into the HTML being streamed out of the device. This whole process is shown in Figure 1.


Figure 1: HTTP GET operation using SNMP MIB variables

When the backplane can't find an entry for sysName , it passes it off to the SNMP MIB inheritance library. The library, in turn, formats the request for sysName (depending on the needs of the SNMP stack), and makes a call to the GET function either via the SNMP agent, or by the MIB directly. Once retrieved, the relevant data is sent back to the SNMP MIB Inheritance library, converted, and copied into the HTML that is being streamed out to the browser.

An HTTP POST is processed in a similar fashion to an HTTP GET. A POST operation is shown in Figure 2. The POST handler parses through the CGI stream, which might look something like:


Figure 2: HTTP POST operation using SNMP MIB variables

. . .&sysName=James+Blaisdell&. . .

After that, the POST Handler consults the backplane for sysName. When the backplane is unable to locate an entry for sysName, it then passes the data and the HTML tag off to the SNMP MIB inheritance library, which formats the data. Lastly, it accesses the MIB variable's SNMP SET routine, and the data is updated to " James+Blaisdell ."

Operation with tabular MIB objects
Despite the elegance of the design so far shown, there is far more to the SNMP MIB inheritance technology than just the proper formatting and conversion of MIB variables. The library also needs to provide extensive support for SNMP tables. Since most SNMP MIB objects are in table format, this support is undoubtedly the most sophisticated part of such a library.

To show how the SNMP MIB inheritance library works with tables of data, an in-depth example is provided here.

As shown in Figure 3, the Structure of Management Information (SMI) consists of a lot of groups and subgroups. However, as you wend your way through the SMI hierarchy, eventually you wind up at a leaf node. Leaf nodes are the members of the SMI that have actual GET and SET routines associated with them. Leaf nodes are where the "rubber meets the road" in the world of SNMP.


Figure 3: Structure of management information through the system group

The variable we have discussed so far, sysName , is a leaf node, but it represents a scalar object. That is, sysName is an object that has one and only one instance-hence the "instance" variable that was appended to the numerical specification of sysName , 1.3.6.1.2.1.1.5, was 0 for a final, unique object identifier (OID) of 1.3.6.1.2.1.1.5.0.

However, leaf nodes can represent table objects as well-objects that have more than one instance. In this case, the instance variable can be more than a simple 0. In fact, the instance variable can be far more complex.

For example, suppose we want to get a particular value of tcpConnLocalAddress. Now tcpConnLocalAddress is an SNMP MIB object that fits within the SMI as a member of tcpConnEntry, which is part of tcpConnTable, which is part of thetcpgroup of MIB II. (And since it is part of MIB II, both consoles and agents will have a priori knowledge of tcpConnLocalAddress.)

The arrangement of tcpConnLocalAddress, within the SMI, is shown in Figure 4. Thus to access tcpConnLocalAddress, we need to specify (at a minimum):


Figure 4: Structure of management information through tcpConnEntry

iso.org.dod.internet.mgmt.mib-2.tcp.tcp
ConnTable.tcpConnEntry.tcpConnLocalAddress

or, in numerical form:

1.3.6.1.2.1.6.13.1.2

This is the base OID of tcpConnLocalAddress. However, as shown in Figure 3, tcpConnLocalAddress is actually part of a table, tcpConnTable, that is made up of tcpConnEntries. Furthermore, as shown in Figure 4, there are four separate instances of tcpConnLocalAddress-the instances which have values of 170.1.81.4, 170.1.81.5, 0.0.0.0, and 144.5.66.13, respectively.But how do you specify, via SNMP, which instance you are interested in getting or setting? As shown in Figure 4, four variables in this table are indexable-tcpConnLocalAddress, tcpConnLocalPort, tcpConnRemAddress, and tcpConnRemPort. According to the SNMP protocol, all indexable variables in a table are used to index the table entries. Thus, to access a particular table entry for the tcpConnTable, you would have:


a.b.(
tcpConnLocalAddress).(
tcpConnLocalPort).(
tcpConnRemAddress).(
tcpConnRemPort)

where:

a = value for tcpConnEntry ( 1.3.6.1.2.1.6.13.1 )b = value for specific column in tcpConnEntry (for example, 2 for tcpConnLocalAddress ) (name) = value in the object name. For example (tcpConnLocalAddress) means 170.1.81.4, if we are talking about the first row of tcpConnEntries

Thus, in order to fully specify the OID of the first instance of tcpConnLocalAddress-the instance in the first row of the table-we would need to append 170.1.81.4.80.170.1. 81.28.2049 to the base OID of tcpConnLocalAddress , 1.3.6.1.2.1.6.13.1.2, for a total specification of :


1.3.6.1.2.1.6.13.1.2.170.1.81.4.80.170.1.81.28.2049
\_object
identifier_/ \__________instance_______/


As shown in this example, instances can be incredibly complex entities.

When an NE receives a request for the OID above, it will first look up, in its Management Information Base, the entry for the OID 1.3.6.1.2.1.6.13.1.2, as shown in Figure 5.


Figure 5: MIB object for tcpConnLocalAddress

Then, after it gets the relevant GET or SET routine, the SNMP agent will pass the instance variable, 170.1.81.4.80.170.1.81.28.2049, into the routine, and await the appropriate response. (It is up to the GET or SET routine to deal with the massive, and sometimes hideous, instance variables.)

This is essentially the way that tabular data is used in SNMP. As highlighted in this example, tables can be quite complicated.

So how, then, does the MIB inheritance library deal with such complexity? Can it work with really complicated instance variables like the one described above? And can it work in a really general way? Lastly, is the complete separation of HTML and C still maintained? The answer to all three questions is a resounding "yes."

The SNMP MIB inheritance library is able to deal with such complexity through the use of special tags. These special tags are essentially "meta-tags," in that they do not necessarily display or alter datum individually. Instead, the glue code that is associated with each meta-tag serves to "prime" the SNMP table via GET NEXT and GET ROW calls to the specific SNMP stack. Also the glue code for the meta-tags, in case you are wondering, constitutes the "Table Logic" and the "Advanced Features." The logic is provided as part of the library.

For example, to display our table of tcpConnEntries (and thereby display tcpConnLocalAddress ), we would have the following HTML shown in Listing 1.

Listing 1: Code to display the table of tcpConnEntries

<! $%createTable(tcpConnLocalAddress,*,,,
include, 170-200.*-5.2-*.*.80.170.1.*.25-*.*, 
tcpConnState,
tcpConnLocalAddress, 
tcpConnLocalPort, 
tcpConnRemAddress, 
tcpConnRemPort)#$>
<! $%REPEAT(tcpConnLocalAddress,1,numCurrTcpConnEntries)#$>
<tr>
<td><font face=2Arial,
Helvetica2>$%tcpConnState#$</font></td>
<td><font face=Arial, Helvetica2>$%tcpConnLocalAddress#$</font></td>
<td><font face=Arial, Helvetica2>$%tcpConnLocalPort#$</font></td>
<td><font face=Arial, Helvetica2>$%tcpConnRemAddress#$</font></td>
<td><font face=Arial, Helvetica2>$%tcpConnRemPort#$</font></td>
</tr>
<! $%endRow(tcpConnLocalAddress)#$>
<! $%REPEAT(END)#$ >
<! $%endTable(tcpConnLocalAddress)#$ >

As you can see from this HTML example, four of the meta-tags are worth explaining-createTable, REPEAT, endRow, and endTable. These meta-tags all have glue code logic that serves to work through the SNMP table. (The other meta-tags- tcpConnState, tcpConnLocalAddress, and so on-are meta-tags that do not have any glue code associated with them. They are meta-tags that would be referenced in an identical fashion to the sysName example given earlier, in that they would be passed directly into the SNMP MIB inheritance library as shown in Figure 1.)

The "API" for each of these four meta-tags is described in the following paragraphs. As you can see from these API specifications, meta-tags can take arguments. This is a general property of meta-tags and is not limited to these tags in particular. That is, you can use arguments in your own (non-SNMP) tags as well.


$%createTable(	tableName, 
lengthInstance, 
firstInstance, 
skipAhead, 
filtertype, 
filter, 
listOfColumns)#$

This meta-tag, based on its arguments, creates a "Table Descriptor," which is an internal data structure that is used to control the display and alteration of SNMP tabular data. The arguments to this meta-tag are explained below as follows:

tableName = the ID of the table. This ID is not just a standard OID. Instead, it needs to be a table entry (a column) that is fully populated-it cannot have any holes. For example, if you are building a table of ifEntries, you should probably have ifIndex be the name of the table. It is the only row entry that is guaranteed to have a value at all times (the other entries might change if you have a system of "hot-swappable" cards, for example).

lengthInstance = the length of the instance identifier. This can be either left blank (in which case it is assumed to be 1), it can be an integer, or it can be a wildcard R*', so that its value can be calculated at run time.

firstInstance = specifies the first instance in the table to be displayed. This can be left blank, in which case the very first row in the table is sought by the createTable glue code, or it can be specified with another value of the instance variable. This is useful if you want to display different parts of a table on different HTML pages. For example, you might want to display the first 100 rows of an SNMP Table on one HTML page, and the remaining rows on another. In the createTable meta-tag on the second HTML page, then, you would specify the first instance to be the 101st row of the table.

skipAhead = determines the amount the table should be advanced from the starting row in firstInstance.

filterType = this is a string to determine the type of instance filtering to be applied to this table. It should be either "include" or "exclude."

filter = specifies how you want to filter the table display based on instances. As described in the example for tcpConnLocalAddress, these instances can be extraordinarily complex. Hence, filters are a wonderful way of managing this complexity. For example, in our tcpConnLocalAddress illustration, you could specify a filter to be:

170-200.*-5.2-*.*.80.170.1.*.25-*.*

This would allow, if the filter type is "include," the display of all instances indexable by the elements in the prescribed range. The first filter element above, for example, allows the display of all instances that have their first element fall between 170 and 200. The second filter element allows the display of all instances with a second element from the lowest allowable value through five. The third filter element allows all instances with a third element equal to two or greater to "pass." The fourth filter element allows any instance fourth element to pass, the fifth filter element requires the instance fifth element to be 80, and so on.

Thus, the row given by the instance 171.2.4.56.80.170.1.34.27.19 would be retrieved and displayed via the relevant tcpConnState or tcpConnLocalAddress special tags as appropriate.

However, the row given by 171.2.1.99.81.170.1.34.27.19 would not be retrieved, and hence its objects would not be displayed, because this instance failed on elements three and five (1 is less than 2-*, and 81 doesn't equal 80).

listOfColumns = a listing of the columns in the table-in this example, it is tcpConnState, tcpConnLocalAddress, tcpConnLocalPort, tcpConnRemAddress, and tcpConnRemPort.

$%REPEAT( tableName, m, n )#$

This meta-tag is used to cycle through the rows of a table. It takes the tableName, which is used to identify the proper "Table Descriptor," and retrieves the row specified by the firstInstance argument in the createTable tag. Then, it essentially does a loop of the form:


for (index = m; index 
<
= n; index++)
{
code
}

The arguments are:

tableName = the table ID. This is the same tableID as given in createTablem = the starting index n = the ending index

Both m and n can be tags themselves (either normal glue-code based tags or MIB variables). That way, the table can have a dynamic number of entries. The tag numCurrTcpConnEntries, given in the HTML example above, is a normal HTML tag that has "Read" and "Write" glue code routines, which are accessed in the normal way.

The $%REPEAT(S)#$ meta-tag is delimited by the $%REPEAT(S)#$ meta-tag. That is, all the HTML, and all of the tags, that lie between the first call to $%REPEAT(S)#$ and the call to $%REPEAT(S)#$ are repeated (displayed) n m times.

$%endRow( tableName )#$

This tag tells the Table Logic to advance to the next row, based on the filter characteristics. Namely, every time $%endRow( tableName )#$ is encountered, the next conceptual row in the SNMP Table is retrieved, based on the filter logic. From there, the individual tags can be used to retrieve the data. Note that as per the operation outlined for the REPEAT meta-tag, $%endRow( tableName )#$ must be located between the $%REPEAT(...)#$ and the $%REPEAT(END)#$ tags.

tableName = the table ID. This is the same table ID as in createTable and REPEAT.

$%endTable( tableName )#$

This tag clears the "Table Descriptor" for tableName and frees up all the relevant memory, mutex semaphores, etc. It must come after the $%REPEAT(END)#$ tag.

tableName = again the standard table ID mechanism.

Last Notes
This is just about the end of our my description of the SNMP MIB inheritance library technology. However, two last features should be mentioned.

First, the SNMP MIB inheritance library should support the concept of overrides. Namely, the SNMP data type conversion methods built-in to the library can be overwritten within the HTML. For example, you could have the HTML tag:

$%MACADDR:ifEntryMacAddr.0#$

While the default method would print a string in dotted decimal notation, the overload method (MACADDR) would display hexadecimal values delimited by R:R characters, such as 03:15:a2:ff:24:73 .

Second, the library should supports inline instances. For example, you could have the tag:

$%TrpRcvrEventLast.{[TrpRcvrIpAddr]}#$

where each element is a dynamic variable in its own right. These elements, in turn, can be nested with no real limit to the depth of the nesting. The code first looks up TrpRcvrIpAddr in the normal way (see Figure 1), and then uses that to instance TrpRcvrEventLast. Also, the inline capabilities can be used with any of the above features.

UI flexibility
I've outlined a pair of technologies: a backplane-based architecture for extensible and scalable Web-based management and an SNMP MIB inheritance library that together give a network equipment vendor unprecedented power and leverage in creating a WBM interface.

First, by completely separating the HTML from the C code, the a backplane-based architecture allows UI development to be completely separated from the back-end engineering. This opens up tremendous opportunities for rapid UI prototyping, for localizing your product to foreign markets, and for OEM deals. In short, by separating the HTML from the C, the backplane makes WBM not just another "checkbox item," but a strategic business imperative.

Second, through a properly designed SNMP MIB inheritance library, it's extraordinarily easy to leverage all of the engineering effort that went into specifying the MIB variables in a network element (NE). In fact, it requires little or no additional engineering effort.

Thus, using these two technologies in tandem gives a company the capability to have a rich, full- featured WebUI that is easily customizable, scaleable for OEM and foreign market opportunities, and yet requires almost no engineering effort to achieve.

Kedron Wolcott is VP of engineering for Rapid Logic, which he co-founded in 1996. With nearly 10 years of experience, he has expertise in Internet-based management for network devices. Before Rapid Logc, he developed routing, bridging, and frame relay software for Tribe Computer Works. Wolcott joined Tribe from the Kennedy Space Center, where he designed and implemented the data acquisition and analysis software and robot control software. He has earned engineering degrees from both MIT and Stanford.
Embedded.com Career Center
Looking for a new job?
SEARCH JOBS

Browse all jobs

SPONSOR
RECENT JOB POSTINGS





 :