SNMP: Simple Network Management Protocol

25.1 Introduction

As the number of networks within an organization grows, along with the diversity of systems comprising this internet (routers from various vendors, hosts with embedded router functionality, terminal servers, etc.), managing all these systems within a coherent framework becomes important. This chapter looks at the standards used within the Internet protocol suite for network management.

Network management of a TCP/IP internet consists of network management stations (managers) communicating with network elements. The network elements can be anything that runs the TCP/IP protocol suite: hosts, routers, X terminals, terminal servers, printers, and so on. The software in the network element that runs the management software is called the agent. Management stations are normally workstations with color monitors that graphically display relevant facts about the elements being monitored (which links are up and down, volume of traffic across various links over time, etc.).

"The communication can be two way: the manager asking the agent for a specific value ("how many ICMP port unreachables have you generated?"), or the agent telling the manager that something important happened ("an attached interface has gone down"). Also, the manager should be able to set variables in the agent ("change the value of the default IP TTL to 64"), in addition to reading variables from the agent. TCP/IP network management consists of three pieces.

  1. A Management Information Base (MIB) that specifies what variables the network elements maintain (the information that can be queried and set by the manager). RFC 1213 [McCloghrie and Rose 1991] defines the second version of this, called MIB-II.
  2. A set of common structures and an identification scheme used to reference the variables in the MIB. This is called the Structure of Management Information (SMI) and is specified in RFC 1155 [Rose and McCloghrie 1990]. For example, the SMI specifies that a Counter is a nonnegative integer that counts from 0 through 4,294,967,295 and then wraps around to 0.
  3. The protocol between the manager and the element, called the Simple Network Management Protocol (SNMP). RFC 1157 [Case et al. 1990] specifies the protocol. This details the format of the packets exchanged. Although a wide variety of transport protocols could be used, UDP is normally used with SNMP.

These RFCs define what is now called SNMPv1, or just SNMP, which is the topic of this chapter. During 1993 additional RFCs were published specifying SNMP Version 2 (SNMPv2), which we describe in Section 25.12.

Our approach to SNMP in this chapter is to describe the protocol between the manager and the agent first, and then look at the data types for the variables maintained by the agent. We describe the database of information maintained by the agent (the MIB), looking at the groups that we've described in this text: IP, UDP, TCP, and so on. We show examples at each point along the way, tying network management back to the protocol concepts from earlier chapters.

25.2 Protocol

SNMP defines only five types of messages that are exchanged between the manager and agent.

  1. Fetch the value of one or more variables: the get-request operator.
  2. Fetch the next variable after one or more specified variables: the get-next-request operator. (We describe what we mean by "next" later in this chapter.)
  3. Set the value of one or more variables: the set-request operator.
  4. Return the value of one or more variables: the get-response operator. This is the message returned by the agent to the manager in response to the get-request, get-next-request, and set-request operators.
  5. Notify the manager when something happens on the agent: the trap operator.

The first three messages are sent from the manager to the agent, and the last two are from the agent to the manager. (We'll refer to the first three as the get, get-next, and set operators.) Figure 25.1 summarizes these five operators.

Since four of the five SNMP messages are simple request-reply protocols (the manager sends a request, the agent sends back a reply) SNMP uses UDP. This means that a request from the manager may not arrive at the agent, and the agent's reply may not make it back to the manager. The manager probably wants to implement a timeout and retransmission.


Figure 25.1 Summary of the five SNMP operators.

The manager sends its three requests to UDP port 161. The agent sends traps to UDP port 162. By using two different port numbers, a single system can easily run both a manager and an agent. (See Exercise 25.1.)

Figure 25.2 shows the format of the five SNMP messages, encapsulated in a UDP datagram.


Figure 25.2 Format of the five SNMP messages.

In this figure we specify the size in bytes of the IP and UDP headers only. This is because the encoding used for the SNMP message-called ASN.1 and BER, which we describe later in this chapter-varies depending on the type of variable and its value.

The version is 0. This value is really the version number minus one, as the version of SNMP that we describe is called SNMPv1.

Figure 25.3 shows the values for the PDU type. (PDU stands for Protocol Data Unit, a fancy word for "packet.")

PDU type
Name
0
get-request
1
get-next-request
2
set-request
3
get-response
4
trap

Figure 25.3 PDU types for SNMP messages.

The community is a character string that is a cleartext password between the manager and agent. A common value is the 6-character string public.

For the get, get-next, and set operators, the request ID is set by the manager, and returned by the agent in the get-response message. We've seen this type of variable with other UDP applications. (Recall the DNS identification field in Figure 14.3, and the transaction ID field in Figure 16.2.) It lets the client (the manager in this case) match the responses from the server (the agent) to the queries that the client issued. "This field also allows the manager to issue multiple requests to one or more agents, and then be able to sort out the returned replies.

The error status is an integer returned by the agent specifying an error. Figure 25.4 shows the values, names, and descriptions.

error status
Name
Description
0
noError all is OK
1
tooBig agent could not fit reply into a single SNMP message
2
noSuchName operation specified a nonexistent variable
3
badValue a set operation specified an invalid value or syntax
4
readonly manager tried to modify a read-only variable
5
genErr some other error

Figure 25.4 SNMP error status values.

If an error occurred, the error index is an integer offset specifying which variable was in error. It is set by the agent only for the noSuchName, badValue, and readonly errors.

A list of variable names and values follows in the get, get-next, and set requests. The value portion is ignored for the get and get-next operators.

For the trap operator (a PDU type of 4), the format of the SNMP message changes. We describe the fields in the trap header when we describe this operator in Section 25.10.

25.3 Structure of Management Information

SNMP uses only a few different types of data. In this section we'll look at those data types, without worrying about how the data is actually encoded (that is, the bit pattern used to store the data).

The number of rows in these tables is not specified by SNMP, but we'll see that a manager using the get-next operator (Section 25.7) can determine when the final row of a table has been returned. Also, in Section 25.6 we'll see how the manager specifies which row of a table it wants to get or set.

25.4 Object Identifiers

An object identifier is a data type specifying an authoritatively named object. By "authoritative" we mean that these identifiers are not assigned randomly, but are allocated by some organization that has responsibility for a group of identifiers.

An object identifier is a sequence of integers separated by decimal points. These integers traverse a tree structure, similar to the DNS (Figure 14.1) or a Unix filesystem. There is an unnamed root at the top of the tree where the object identifiers start. (This is the same direction of tree traversal that's used with a Unix filesystem.)

Figure 25.6 shows the structure of this tree when used with SNMP. All variables in the MIB start with the object identifier 1.3.6.1.2.1.

Each node in the tree is also given a textual name. The name corresponding to the object identifier 1.3.6.1.2.1 is iso.org.dod.internet.mgmt.mib. These names are for human readability. The names of the MIB variables that are in the packets exchanged between the manager and agent (Figure 25.2) are the numeric object identifiers, all of which begin with 1.3.6.1.2.1.


Figure 25.6 Object identifiers in the Management Information Base.

Besides the mib object identifiers in Figure 25.6 we also show one named iso.org.dod.internet.private.enterprises (1.3.6.1.4.1). "This is where vendor-specific MIBs are located. The Assigned Numbers RFC lists around 400 identifiers registered below this node.

25.5 Introduction to the Management Information Base

The Management Information Base, or MIB, is the database of information maintained by the agent that the manager can query or set. We describe what's called MIB-II, specified in RFC 1213 [McCloghrie and Rose 1991].

As shown in Figure 25.6, the MIB is divided into groups named system, interfaces, at (address translation), ip, and so on.

In this section we describe only the variables in the UDP group. This is a simple group with only a few variables and a single table. In the next sections we use this group to show the details of instance identification, lexicographic ordering, and some simple examples of these features. After these examples we return to the MIB in Section 25.8 and describe some of the other groups in the MIB.

In Figure 25.6 we showed the group named udp beneath mib. Figure 25.7 shows the structure of the UDP group.


Figure 25.7 Tree structure of IP address table.

There are four simple variables and a table containing two simple variables. Figure 25.8 describes the four simple variables.

Name
Datatype
R/W
Description
udpInDatagramsCounter Number of UDP datagrams delivered to user processes.
udpNoPorts Counter Number of received UDP datagrams for which no application process was at the destination port.
udpInErrorsCounter Number of undeliverable UDP datagrams for reasons other than no application at destination port (e.g., UDP checksum error).
udpOutDatagramsCounter Number of UDP datagrams sent.

Figure 25.8 Simple variables in udp group.

We'll use this format to describe all the MIB variables in this chapter. The column labeled "R/W" is empty if the variable is read-only, or contains a bullet (*) if the variable is read-write. We always include this column, even if all the variables in a group are read-only (since they are in the udp group) to reiterate that none of the variables can be set by the manager. Also, when the data type is an INTEGER with bounds, we specify the lower limit and upper limit, as we do for the UDP port number in the next figure.

Figure 25.9 describes the two simple variables in the udpTable.

UDP listener table, index = < udpLocalAddress >.< udpLocalPort >
Name
Datatype
R/W
Description
udpLocalAddresslpAddress Local IP address for this listener. 0.0.0.0 indicates the listener is willing to receive datagrams on any interface.
udpLocalPort[0..65535] Local port number for this listener.

Figure 25.9 Variables in udpTable.

Each time we describe the variables in an SNMP table, the first row of the figure indicates the value of the "index" used to reference each row of the table. We show some examples of this in the next section.

Case Diagrams

There is a relationship between the first three counters in Figure 25.8. Case Diagrams [Case and Partridge 1989] visually illustrate the relationships between the various MIB variables in a given group. Figure 25.10 is a Case Diagram for the UDP group.


Figure 25.10 Case Diagram for UDP group.

What this diagram shows is that the number of UDP datagrams delivered to applications (udpInDatagrams) is the number of UDP datagrams delivered from IP to UDP, minus udpInErrors, minus udpNoPorts. Also, the number of UDP datagrams delivered to IP (udpOutDatagrams) is the number passed to UDP from the applications. This illustrates that udpInDatagrams does not include udpInErrors or udpNoPorts.

These diagrams were used during the development of the MIB to verify that all data paths for a packet were accounted for. [Rose 1994] shows Case Diagrams for all the groups in the MIB.

25.6 Instance Identification

Every variable in the MIB must be identified when SNMP is referencing it, to fetch or set its value. First, only leaf nodes are referenced. SNMP does not manipulate entire rows or columns of tables. Returning to Figure 25.7, the leaf nodes are the four that we described in Figure 25.8 and the two in Figure 25.9. mib, udp, udpTabie, and udpEntry are not leaf nodes.

Simple Variables

Simple variables are referenced by appending ".0" to the variable's object identifier. For example, the counter udpInDatagrams from Figure 25.8, whose object identifier is 1.3.6.1.2.1.7.1, is referenced as 1.3.6.1.2.1.7.1.0. The textual name of this reference is iso.org.dod.internet.mgmt.mib.udp.udpInDatagrams.0.

Although references to this variable are normally abbreviated as just udpInDatagrams.0, we reiterate that the name of the variable that appears in the SNMP message (Figure 25.2) is the object identifier 1.3.6.1.2.1.7.1.0.

Tables

Instance identification of table entries is more detailed. Let's return to the UDP listener table (Figure 25.7).

One or more indexes are specified in the MIB for each table. For the UDP listener table, the MIB defines the index as the combination of the two variables udpLocalAddress, which is an IP address, and udpLocalPort, which is an integer. (We showed this index in the top row in Figure 25.9.)

Assume there are three rows in the UDP listener table: the first row is for IP address 0.0.0.0 and port 67, the second for 0.0.0.0 and port 161, and the third for 0.0.0.0 and port 520. Figure 25.11 shows this table.

udpLocalAddress
udpLocalPort
0.0.0.0
67
0.0.0.0
161
0.0.0.0
520

Figure 25.11 Sample UDP listener table.

This implies that the system is willing to receive UDP datagrams on any interface for ports 67 (BOOTP server), 161 (SNMP), and 520 (RIP). The three rows in the table are referenced as shown in Figure 25.12.

Lexicographic Ordering

There is an implied ordering in the MIB based on the order of the object identifiers. All the entries in MIB tables are lexicographically ordered by their object identifiers. This means the six variables in Figure 25.12 are ordered in the MIB as shown in Figure 25.13. Two key points result from this lexicographic ordering.

Row
Object identifier
Abbreviated name
Value
1
1.3.6.1.2.1.7.5.1.1.0.0.0.0.67
1.3.6.1.2.1.7.5.1.2.0.0.0.0.67
udpLocalAddress.0.0.0.0.67
udpLocalPort.0.0.0.0.67
0.0.0.0
67
2
1.3.6.1.2.1.7.5.1.1.0.0.0.0.161
1.3.6.1.2.1.7.5.1.2.0.0.0.0.161
udpLocalAddress.0.0.0.0.161
udpLocalPort.0.0.0.0.161
0.0.0.0
161
3
1.3.6.1.2.1.7.5.1.1.0.0.0.0.520
1.3.6.1.2.1.7.5.1.2.0.0.0.0.520
udpLocalAddress.0.0.0.0.520
udpLocalPort.0.0.0.0.520
0.0.0.0
520

Figure 25.12 Instance identification for rows in UDP listener table.

Column
Object identifier
(lexicographically ordered)
Abbreviated name
Value
1
1.3.6.1.2.1.7.5.1.1.0.0.0.0.67
1.3.6.1.2.1.7.5.1.1.0.0.0.0.161
1.3.6.1.2.1.7.5.1.1.0.0.0.0.520
udpLocalAddress.0.0.0.0.67
udpLocalAddress.0.0.0.0.161
udpLocalAddress.0.0.0.0.520
0.0.0.0
0.0.0.0
0.0.0.0
2
1.3.6.1.2.1.7.5.1.2.0.0.0.0.67
1.3.6.1.2.1.7.5.1.2.0.0.0.0.161
1.3.6.1.2.1.7.5.1.2.0.0.0.0.520
udpLocalPort.0.0.0.0.67
udpLocalPort.0.0.0.0.161
udpLocalPort.0.0.0.0.520
67
161
520

Figure 25.13 Lexicographic ordering of UDP listener table.
  1. Since all instances for a given variable (udpLocalAddress) appear before all instances for the next variable in the table (udpLocalPort), this implies that tables are accessed in a column-row order. This results from the lexicographic ordering of the object identifiers, not the human-readable names.
  2. The ordering of the rows in a table depends on the values of the indexes for the table. In Figure 25.13, 67 is lexicographically less than 161, which is lexicographically less than 520.

Figure 25.14 shows this column-row order for our sample UDP listener table.


Figure 25.14 UDP listener table, showing column-row ordering.

We'll also see this column-row ordering when we use the get-next operator in the next section.

25.7 Simple Examples

In this section we'll show some examples that fetch the values of variables from an SNMP agent. The software used to query the agent is called snmpi and is from the ISODE system. Both are described briefly in [Rose 1994].

Simple Variables

We'll query a router for two simple variables from the UDP group:

sun % snmpi -a gateway -c secret

snmpi> get udpInDatagrams.0 udpNoPorta.0
udplnDatagrams.0=616168
udpNoPorts.0=33

snmpi> quit

The -a option identifies the agent we want to communicate with, and the -c option specifies the SNMP community. It is a password supplied by the client (snmpi in this case) and if the server (the agent in the system gateway) recognizes the community name, it honors the manager's request. An agent could allow clients within one community read-only access to its variables, and clients in another community read-write access.

The program outputs its snmpi> prompt, and we can type commands such as get, which translates into an SNMP get-request message. When we're done, we type quit. (In all further examples we'll remove this final quit command.) Figure 25.15 shows the two lines of tcpdump output for this example.

10.0 sun.1024 > gateway.161: GetRequest(42)
1.3.6.1.2.1.7.1.0 1.3.6.1.2.1.7.2.0
20.348875 (0.3489) gateway.161 > sun.1024: GetResponse(46)
1.3.6.1.2.1.7.1.0=616168
1.3.6.1.2.1.7.2.0=33

Figure 25.15 tcpdump output for simple SNMP query.

The request for the two variables is sent in a single UDP datagram, and the response is also a single UDP datagram.

We show the variables as their respective object identifiers, because that is what's sent in the SNMP messages. We had to specify the instance of the two variables as 0. Notice also that the name of the variable (its object identifier) is always returned in the response. We'll see below that this is required for the get-next operator to work.

get-next Operator

The operation of the get-next operator is based on the lexicographic ordering of the MIB. We start the following example by asking for the next object identifier after udp (without specifying any instance, since this is not a leaf object). This returns the first object in the UDP group. We then ask for the next entry after this one, and the second entry is returned. We repeat this one more time to get the third entry:

sun % sninpi -a gateway -c secret

snmpi> next udp
udpInDatagrams.0=616318

snmpi> next udpInDatagraros.0
udpNoPorts.0=33

snmpi> next udpNoPorts.0
udpInErrors.0=0

This example shows why a get-next operator must return the name of the variable: we ask the agent for the next variable, and the agent returns its name and value.

Using the get-next operator in this fashion, one could imagine a manager with a loop that starts at the beginning of the MIB and queries the agent for every variable that the agent maintains. Another use of this operator is to iterate through tables.

Table Access

We can reiterate the column-row ordering of tables using our simple query program to step through the entire UDP listener table. We start by asking for the next variable after udpTable. Since this is not a leaf object we can't specify an instance, but the get-next operator still returns the next object in the table. We then work our way through the table, with the agent returning the next variable, in column-row order:

sun % snmpi-a gateway -c secret

snmpi> next udpTable
udpLocalAddress.0.0.0.0.67=0.0.0.0

snmpi> next udpLocalAddress.0.0.0.0.67
udpLocalAddress.0.0.0.0.161-0.0.0.0

snmpi> next udpLocalAddress.0.0.0.0.161
udpLocalAddress.0.0.0.0.52 0=0.0.0.0

snmpi> next udpLocalAddress.0.0.0.0.520
udpLocalPort.0.0.0.0.67=67

snmpi> next udpLocalPort.0.0.0.0.67
udpLocalPort.0.0.0.0.161=161

snmpi> next udpLocalPort.0.0.0.0.161
udpLocalPort.0.0.0.0.520=520

snmpi> next udpLocalPort.0.0.0.0.520
snmpInPkts.0=59
we're finished with the UDP listener table

We see that the order returned corresponds to Figure 25.14.

How does a manager know when it reaches the end of a table? Since the response to the get-next operator contains the name of the next entry in the MIB after the table, the manager can tell when the name changes. In our example the last entry in the UDP listener table is followed by the variable snmpInPkts.

25.8 Management Information Base (Continued)

We now return to the description of the MIB. We describe only the following groups: system (system identification), if (interfaces) , at (address translation), ip, icmp, and tcp. Additional groups are defined.

system Group

The system group is simple; it consists of seven simple variables (i.e., no tables). Figure 25.16 shows their names, data types, and descriptions.

Name
Datatype
R/W
Description
sysDescrDisplay String Textual description of entity.
sysObjectIDObjectID Vendor's ID within the subtree 1.3.6.1.4.1.
sysUpTimeTimeTicks Time in hundredths of a second since network management portion of system was rebooted.
sysContactDisplayString *Name of contact person and how to contact them.
sysNameDisplayString *Node's fully qualified domain name (FQDN).
sysLocationDisplayString *Physical location of node.
sysServices[0..127] Value indicating services provided by node. It is the sum of the layers in the OSI model supported by the node. The following values are added together, depending on the services provided: 0x01 (physical) , 0x02 (datalink), 0x04 (internet), 0x08 (end-to-end), 0x40 (application).

Figure 25.16 Simple variables in system group.

We can query the router netb for some of these variables:

sun % snmpi -a netb -c secret

snmpi> get sysDescr.0 sysObjectID.0 sysDpTime.0 sysServices.0
sysDescr.0="Epilogue Technology SNMP agent for Telebit NetBlazer"
sysObjectID.0=1.3.6.1.4.1.12.42.3.1
sysUpTime.0=22 days, 11 hours, 23 minutes, 2 seconds (194178200 timeticks)
sysServices.0=0xc<internet,transport>

The system's object identifier is in the internet.private.enterprises group (1.3.6.1.4.1) from Figure 25.6. From the Assigned Numbers RFC we can determine that the next object identifier (12) is assigned to the vendor (Epilogue).

We can also see that the sysServices variable is the sum of 4 and 8: this element supports the Internet layer (i.e., routing) and the transport layer (i.e., end-to-end).

interface Group

Only one simple variable is defined for this group: the number of interfaces on the system, shown in Figure 25.17.

Name
Datatype
R/W
Description
ifNumberINTEGER Number of network interfaces on system.

Figure 25.17 Simple variable in if group.

This group also defines a table with 22 columns. Each row of the table defines the characteristics for each interface, as shown in Figure 25.18.

Interface table, index = < IfIndex >
Name
Datatype
R/W
Description
ifIndexINTEGER Index of interface, between one and if Number.
ifDescrDisplayString Textual description of interface.
ifTypeINTEGER Type, for example: 6 = Ethernet, 7 = 802.3 Ethernet, 9 = 802.5 token ring, 23 = PPP, 28 = SLIP, and many other values.
ifMtuINTEGER MTU of interface.
ifSpeedGauge Speed in bits/sec.
ifPhysAddressPhysAddress Physical address, or string of 0 length for interfaces without physical addresses (e.g., serial links).
ifAdminStatus[1..3]
*
Desired state of interface: 1 = up, 2 = down, 3 = testing.
ifOperStatus[1..3] Current state of interface: 1 = up, 2 = down, 3 = testing.
ifLastChangeTimeTicks Value of sysUpTime when interface entered current operational state.
ifInoctetsCounter Total number of bytes received, including framing characters.
ifInUcastPktsCounter Number of unicast packets delivered to higher layers.
ifInNUcastPktsCounter Number of nonunicast (i.e., broadcast or multicast) packets delivered to higher layers.
ifInDiscardsCounter Number of received packets discarded even though no error in packet (i.e., out of buffers).
ifInErrorsCounter Number of received packets discarded because of errors.
ifInUnknownProtosCounter Number of received packets discarded because of unknown protocol.
ifOutoctetsCounter Number of bytes transmitted, including framing characters.
ifOutUcastPktsCounter Number of unicast packets received from higher layers.
ifOutNUcastPktsCounter Number of nonunicast (i.e., broadcast or multicast) packets received from higher layers.
ifOutDiscardsCounter Number of outbound packets discarded even though no error in packet (i.e., out of buffers).
ifOutErrorsCounter Number of outbound packets discarded because of errors.
ifOutQLenGauge Number of packets in output queue.
ifSpecificObjectID A reference to MIB definitions specific to this particular type of media.

Figure 25.18 Variables in interface table: ifTable.

We can query the host sun for some of these variables for all its interfaces. Wet expect to find three interfaces, as in Section 3.8, if the SLIP interface is up:

sun % snmpi -a sun

snropi> next ifTable first see what index of first interface is
if Index.1=1

snmpi> get ifDescr.1 if Type.1 ifMtu.1 if Speed.1 ifPhysAddress.1
ifDescr.1="le0"
if Type.1=ethernet-csmacd(6)
ifMtu.1=1500
ifSpeed, 1=10000000
ifPhysAddress.1=0x08:00:20;03:f6:42

snmpi> next ifDescr.1 if Type.1 ifMtu.1 if Speed.1 ifPhysAddress.1

ifDescr.2="sl0"
ifType.2=propPointToPointSerial(22)
ifMtu.2=552
ifSpeed.2=0
ifPhysAddress.2=0x00:00:00:00:00:00

snmpi> next ifDescr.2 ifType.2 ifMtu.2 if Speed.2 ifPhysAddress.2
ifDescr.3="lo0"
ifType.3=softwareLoopback(24)
ifMtu.3=1536
ifSpeed.3=0
ifPhysAddress.3=0x00:00:00:00:00:00

We first get five variables for the first interface using the get operator, and then get the same five variables for the second interface using the get-next operator. The last command gets these same five variables for the third interface, again using the get-next command.

The interface type for the SLIP link is reported as proprietary point-to-point serial, not SLIP. Also, the speed of the SLIP link is not reported.

It is critical to understand the relationship between the get-next operator and the column-row ordering. When we say next ifDescr.1 it returns the next row of the table for this variable, not the next variable in the same row. If tables were stored in a row-column order instead, we wouldn't be able to step to the next occurrence of a given variable this way.

at Group

The address translation group is mandatory for all systems, but was deprecated by MIB-II. Starting with MIB-II, each network protocol group (e.g., IP) contains its own address translation tables. For IP it is the ipNetToMediaTable.

Only a single table with three columns is defined for the at group, shown in Figure 25.19.

We can use a new command within the snmpi program to dump an entire table. We'll query the router named kinetics (which routes between a TCP/IP network and an AppleTalk network) for its entire ARP cache. This output reiterates the lexicographic ordering of the entries in the table:

Address translation table, index = < atIflndex >.1.< atNetAddress >
Name
Datatype
R/W
Description
atiflndexINTEGER
*
Interface number: ifIndex.
atPhysAddressPhysAddress
*
Physical address. Setting this to a string of 0 length invalidates the entry.
atNetAddressNetworkAddress
*
IP address.

Figure 25.19 Address translation table: atTable.

sun % snmpi -a kinetics -c secret dump at

atiflndex.1.1.140.252.1.4=1
atiflndex.1.1.140.252.1.22=1
atiflndex.1.1.140.252.1.183=1
atiflndex.2.1.140.252.6.4=2
atiflndex.2.1.140.252.6.6=2

atPhysAddress.1.1.140.252.1.4=0xaa:00:04:00:f4:14
atPhysAddress.1.1.140.252.1.22=0x08:00:20:0f:2d:38
atPhysAddress.1.1.140.252.1.183=0x00:80:ad:03:6a:80
atPhysAddress.2.1.140.252.6.4=0x00:02:16:48
atPhysAddress.2.1.140.252.6.6=0x00:02:3c:48

atNetAddress.1.1.140.252.1.4=140.252.1.4
atNetAddress.1.1.140.252.1.22=140.252.1.22
atNetAddress.1.1.140.252.1.183=140.252.1.183
atNetAddress.2.1.140.252.6.4=140.252.6.4
atNetAddress.2.1.140.252.6.6=140.252.6.6

If we watch the packet exchange using tcpdump, when snmpi dumps an entire table it first issues a get-next for the table name (at in this example) to get the first entry. It prints the first entry and issues another get-next. This continues until the entire table has been dumped.

Figure 25.20 shows the arrangement of this table.

atIflndexatPhysAddress atNetAddress
1
0xaa:00:04:00:f4:14 140.252.1.4
1
0x08:00:20:0f:2d:38 140.252.1.22
1
0x00:80:ad:03:6a:80 140.252.1.183
2
0x00:02:16:48 140.252.6.4
2
0x00:02:3c:48 140.252.6.6

Figure 25.20 Example of at table (ARP cache).

The AppleTalk physical addresses on interface number 2 are 32-bit values, not the 48-bit Ethernet addresses to which we're accustomed. Also note that an entry exists for our router (netb at 140.252.1.183), which we expect, since kinetics and netb are on the same Ethernet (140.252.1) and kinetics must use ARP to send the SNMP responses back to us.

ip Group

The ip group defines numerous variables and three tables. Figure 25.21 defines the simple variables.

Name
Datatype
R/W
Description
ipForwarding[1..2] *1 means the system is forwarding IP datagrams, and 2 means it is not.
ipDefaultTTLINTEGER *Default TTL value when transport layer doesn't provide one.
ipInReceivesCounter Total number of received IP datagrams from all interfaces.
ipInHdrErrorsCounter Number of IP datagrams discarded because of header errors (e.g., checksum error, version number mismatch, TTL exceeded, etc.).
ipInAddrErrorsCounter Number of IP datagrams discarded because of incorrect destination address.
ipForwDatagramsCounter Number of IP datagrams for which an attempt was made to forward.
ipInUnknownProtosCounter Number of locally addressed IP datagrams with an invalid protocol field.
ipInDiscardsCounter Number of received IP datagrams discarded because of a lack of buffer space.
ipInDeliversCounter Number of IP datagrams delivered to appropriate protocol module.
ipOutRequestsCounter Total number of IP datagrams passed to IP for transmission. Does not include those counted in ipForwDatagrams.
ipOutDiscardsCounter Number of output IP datagrams discarded because of a lack of buffer space.
ipOutNoRoutesCounter Number of IP datagrams discarded because no route could be found.
ipReasmTimeoutINTEGER Maximum number of seconds that received fragments are held while awaiting reassembly.
ipReasmReqdsCounter Number of IP fragments received that needed to be reassembled.
ipReasmOKsCounter Number of IP datagrams successfully reassembled.
ipReasmFailsCounter Number of failures by IP reassembly algorithm.
ipFragOKsCounter Number of IP datagrams that have been successfully fragmented.
ipFragFailsCounter Number of IP datagrams that needed to be fragmented but couldn't because the "don't fragment" flag was set.
ipFragCreatesCounter Number of IP fragments generated by fragmentation.
ipRoutingDiscardsCounter Number of routing entries chosen to be discarded even though they were valid.

Figure 25.21 Simple variables in ip group.

The first table in the ip group is the IP address table. It contains one row for each IP address on the system. Each row contains five variables, described in Figure 25.22.

IP address table, index = < ipAdEntAddr >
Name
Datatype
R/W
Description
ipAdEntAddrlpAddress IP address for this row.
ipAdEntIf IndexINTEGER Corresponding interface number: ifIndex.
ipAdEntNetMasklpAddress Subnet mask for this IP address.
ipAdEntBcastAddr [0..1] Value of least-significant bit of the IP broadcast address. Normally 1.
ipAdEntReasmMaxSize[0..65535] Size of largest IP datagram received on this interface that can be reassembled.

Figure 25.22 IP address table: ipAddrTable.

We can query the host sun for its entire IP address table:

sun % snmpi -a sun dump ipAddrTable
ipAdEntAddr.127.0.0.1=127.0.0.1
ipAdEntAddr.140.252.1.29=140.252.1.29
ipAdEntAddr.140.252.13.33=140.252.13.33
ipAdEntIfIndex.127.0.0.1=3
ipAdEntIfIndex.140.252.1.29=2
ipAdEntIfIndex.140.252.13.33=1
loopback interface, lo0
SLIP interface, sl0
Ethernet interface, le0
ipAdEntNetMask.127.0.0.1=255.0.0.0
ipAdEntNetMask.140.252.1.29=255.255.255.0
ipAdEntNetMask.140.252.13.33=255.255.255.224
ipAdEntBcastAddr.127.0.0.1=1
ipAdEntBcastAddr.140.252.1.29=1
ipAdEntBcastAddr.140.252.13.33=1
all three use one bits for broadcast
ipAdEntReasmMaxSize.127.0.0.1=65535
ipAdEntReasmMaxSize.140.252.1.29=65535
ipAdEntReasmMaxSize.140.252.13.33=65535

The interface numbers can be compared with the output following Figure 25.18, and the IP addresses and subnet masks can be compared with the values output by the ifconfig command in Section 3.8.

The next table, Figure 25.23, is the IP routing table. (Recall our description of routing tables in Section 9.2.) The index used to access each row of the table is the destination IP address.

Figure 25.24 is the IP routing table on the host sun obtained with the dump ipRouteTable command using snmpi. We have deleted all five of the routing metrics, since they are all -1. In the column headings we've also removed the prefix ipRoute from each variable name.

IP routing table, index = < ipRouteDest >
Name
Datatype
R/W
Description
ipRouteDestlpAddress *Destination IP address. A value of 0.0.0.0 indicates a default entry.
ipRoutelfIndexINTEGER *Interface number: ifIndex.
ipRouteMetricIINTEGER *Primary routing metric. The meaning of the metric depends on the routing protocol (ipRouteProto). A value of -1 means it's not used.
ipRouteMetric2INTEGER *Alternative routing metric.
IpRouteMetric3INTEGER *Alternative routing metric.
IpRouteMetric4INTEGER *Alternative routing metric.
IpRouteNextHopIpAddress *IP address of next-hop router.
IpRouteTypeINTEGER *Route type: 1 = other, 2 = invalidated route, 3 = direct, 4 = indirect.
IpRouteProtoINTEGER Routing protocol: 1 = other, 4 = ICMP redirect, 8 = RIP, 13 = OSPF, 14 = BGP, and others.
IpRouteAgeINTEGER *Number of seconds since route was last updated or determined to be correct.
IpRouteMaskIpAddress *Mask to be logically ANDed with destination IP address before being compared with ipRouteDest.
IpRouteMetricsINTEGER *Alternative routing metric.
ipRouteInfoObjectID Reference to MIB definitions specific to this particular routing protocol.

Figure 25.23 IP routing table: ipRouteTable.

DestIfIndex NextHopType ProtoMask
0.0.0.0
127.0.0.1
140.252.1.183
140.252.13.32
140.252.13.65
2
3
2
1
1
140.252.1.183
127.0.0.1
140.252.1.29
140.252.13.33
140.252.13.35
indirect(4)
direct(3)
direct(3)
direct(3)
indirect(4)
other(1)
other(1)
other(1)
other(1)
other(1)
0.0.0.0
255.255.255.255
255.255.255.255
255.255.0.0
255.255.255.255

Figure 25.24 IP routing table for the router sun.

For comparison, here is the IP routing table in the format output by netstat (which we discussed in Section 9.2). Figure 25.24 is lexicographically ordered, unlike the netstat output:

sun % netstat -rn
Routing tables
DestinationGateway FlagsRefcnt UseInterface
140.252.13.65140.252.13.35 UGH0 115le0
127.0.0.1127.0.0.1 UH1 1107lo0
140.252.1.183140.252.1.29 UH0 86sl0
default140.252.1.183 UG2 1628sl0
140.252.13.32140.252.13.33 U8 68359le0

The final table in the ip group is the address translation table. Figure 25.25. As we said earlier, the at group is now deprecated, and this IP table replaces it.

IP address translation table, index = < ipNetToMedialfIndex >.< ipNetToMediaNetAddress >
Name
Datatype
R/W
Description
ipNetToMedialfIndexINTEGER *Corresponding interface: if Index.
ipNetfoMediaPhysAddressPhysAddress *Physical address.
ipNetToMediaNetAddresslpAddress *IP address.
ipNetToMediaType[1..4] *Type of mapping: 1 = other, 2 = invalidated, 3 = dynamic, 4 = static.

Figure 25.25 IP address translation table: ipNetToMediaTable.

Here is the ARP cache on the system sun:

sun % arp -a

svr4 (140.252.13.34) at 0:0:c0:c2:9b:26
bsdi (140.252.13.35) at 0:0:c0:6f:2d:40

and the corresponding SNMP output:

sun % snmpi -a sun dump ipHetToMediaTable

ipNetToMedialfIndex.1.140.252.13.34=1
ipNetToMedialfIndex.1.140.252.13.35=1
ipNetToMediaPhysAddress.1.140.252.13.34=0x00:00:c0:c2:9b:26
ipNetToMediaPhysAddress.1.140.252.13.35=0x00:00:c0:6f:2d:40
ipNetToMediaNetAddress.1.140.252.13.34=140.252.13.34
ipNetToMediaNetAddress.1.140.252.13.35=140.252.13.35
ipNetToMediaType.1.140.252.13.34=dynamic(3)
ipNetToMediaType.1.140.252.13.35=dynamic(3)

icrop Group

The icmp group consists of four general counters (total number of input and output ICMP messages, and number of input and output ICMP messages with errors) and 22 counters for the different ICMP message types: II input counters and II output counters. These are shown in Figure 25.26.

Name
Datatype
R/W
Description
icmpInMsgsCounter Total number of received ICMP messages.
icmpInErrorsCounter Number of received ICMP messages with errors (e.g., invalid ICMP checksum).
icmpInDestUnreachsCounter Number of received ICMP destination unreachable message.
icmpInTimeExcdsCounter Number of received ICMP time exceeded message.
icmpInParmProbsCounter Number of received ICMP parameter problem message.
icmpInSrcQuenchsCounter Number of received ICMP source quench messages.
icmpInRedirectsCounter Number of received ICMP redirect messages.
icmpInEchosCounter Number of received ICMP echo request messages.
icmpInEchoRepsCounter Number of received ICMP echo reply messages.
icmpInTimestampsCounter Number of received ICMP timestamp request messages.
icmpInTimestampRepsCounter Number of received ICMP timestamp reply messages.
icmpInAddrMasksCounter Number of received ICMP address mask request messages.
icmpInAddrMaskRepsCounter Number of received ICMP address mask reply messages.
icmpOutMsgsCounter Total number of output ICMP messages.
icmpOutErrorsCounter Number of ICMP messages not sent because of a problem within ICMP (e.g., lack of buffers).
icmpOutDestUnreachsCounter Number of ICMP destination unreachable messages sent.
icmpOutTimeExcdsCounter Number of ICMP time exceeded messages sent.
icmpOutParmProbsCounter Number of ICMP parameter problem messages sent.
icmpOutSrcQuenchsCounter Number of ICMP source quench messages sent.
icmpOutRedirectsCounter Number of ICMP redirect messages sent.
icmpOutEchosCounter Number of ICMP echo request messages sent.
icmpOutEchoRepsCounter Number of ICMP echo reply messages sent.
icmpOutTimestampsCounter Number of ICMP timestamp requests sent.
icmpOutTimestampRepsCounter Number of ICMP timestamp reply messages sent.
icmpOutAddrMasksCounter Number of ICMP address mask request messages sent.
icmpOutAddrMaskRepsCounter Number of ICMP address mask reply messages sent.

Figure 25.26 Simple variables in icmp group.

For the ICMP messages with additional codes (recall from Figure 6.3 that there are 15 different codes for destination unreachable), a separate counter is not maintained by SNMP for each code.

tcp Group

Figure 25.27 describes the simple variables in the tcp group. Many of these refer to the TCP states that we showed in Figure 18.12.

Name
Datatype
R/W
Description
tcpRtoAlgorithmINTEGER Algorithm used to calculate retransmission timeout value: 1 = none of the following, 2 = a constant RTO, 3 = MIL-STD-1778 Appendix B, 4 = Van Jacobson's algorithm.
tcpRtoMinINTEGER Minimum retransmission timeout value, in milliseconds.
tcpRtoMaxINTEGER Maximum retransmission timeout value, in milliseconds.
tcpMaxConnINTEGER Maximum number of TCP connections. Value is -1 if dynamic.
tcpActiveOpensCounter Number of transitions from CLOSED to SYNSENT states.
tcpPassiveOpensCounter Number of transitions from LISTEN to SYNRCVD states.
tcpAttemptFailsCounter Number of transitions from SYNSENT or SYNRCVD to CLOSED, plus number of transitions from SYNRCVD to LISTEN.
tcpEstabResetsCounter Number of transitions from ESTABLISHED or CLOSEWAIT states to CLOSED.
tcpCurrEstabGauge Number of connections currently in ESTABLISHED or CLOSEWAIT states.
tcpInSegsCounter Total number of segments received.
tcpOutSegsCounter Total number of segments sent, excluding those containing only retransmitted bytes.
tcpRetransSegsCounter Total number of retransmitted segments.
tcpInErrsCounter Total number of segments received with an error (such as invalid checksum).
tcpOutRstsCounter Total number of segments sent with RST flag set.

Figure 25.27 Simple variables in tcp group.

We can query some of these variables on the system sun:

sun % snmpi -a sun

snmpi> get tcpRtoAlgorithm.0 tcpRtoMin.0 tcpRtoMax.0 tcpMaxConn.0
tcpRtoAlgorithm.0=vanj(4)
tcpRtoMin.0=200
tcpRtoMax.O=12800
tcpMaxConn.0=-1

This system (SunOS 4.1.3) uses the Van Jacobson retransmission timeout algorithm, uses timeouts between 200 ms and 12.8 seconds, and has no fixed limit on the number of TCP connections. (This upper limit of 12.8 seconds appears wrong, since most implementations use an upper limit of 64 seconds, as we saw in Chapter 21.)

The tcp group has a single table, the TCP connection table, shown in Figure 25.28. This contains one row for each connection. Each row contains five variables; the state of the connection, local IP address, local port number, remote IP address, and remote port number.

index = < tcpConnLocalAddress >.< tcpConnLocalPort >.< tcpConnRemAddress >.< tcpConnRemPort >
NameDatatype R/WDescription
tcpConnState[1..12]
*
State of connection: 1 = CLOSED, 2 = LISTEN, 3 = SYNSENT, 4 = SYNRCVD, 5 = ESTABLISHED, 6 = FINWAIT1,7= FINWAIT2,8= CLOSEWAIT, 9 = LASTACK, 10 = CLOSING, 11 = TIMEWAIT, 12 = delete TCB. The only value that the manager can set this variable to is 12 (e.g., immediately terminate the connection).
tcpConnLocalAddressIpAddress Local IP address. 0.0.0.0 indicates the listener is willing to accept connections on any interface.
tcpConnLocalPort[0..65535] Local port number.
tcpConnRemAddressIpAddress Remote IP address.
tcpConnRemPort[0..65535] Remote port number.

Figure 25.28 TCP connection table: tcpConnTable.

Let's look at this table on the system sun. We show only a portion of the table, since there are many servers listening for connections. Before dumping this table two TCP connections were established:

sun % rlogin gemini IP address o/gemini is 140.252.1.11
and
sun % telnet localhost IP address should be 127.0.0.1

The only listening server that we show is the FTP server, on port 21:

sun % snmpi -a sun dump tcpConnTable

tcpConnState.0.0.0.0.21.0.0.0.0.0=listen(2)
tcpConnState.127.0.0.1.23.127.0.0.1.1415=established(5)
tcpConnState.127.0.0.1.1415.127.0.0.1.23=established(5)
tcpConnState.140.252.1.29.1023.140.252.1.11.513=established(5)

tcpConnLocalAddress.0.0.0.0.21.0.0.0.0.0=0.0.0.0
tcpConnLocalAddress.127.0.0.1.23.127.0.0.1.1415-127.0.0.1
tcpConnLocalAddress.127.0.0.1.1415.127.0.0.1.23=127.0.0.1
tcpConnLocalAddress.140.252.1.29.1023.140.252.1.11.513=140.252.1.29

tcpConnLocalPort.0.0.0.0.21.0.0.0.0.0=21
tcpConnLocalPort.127.0.0.1.23.127.0.0.1.1415=23
tcpConnLocalPort.127.0.0.1.1415.127.0.0.1.23=1415
tcpConnLocalPort.140.252.1.29.1023.140.252.1.11.513=1023

tcpConnRemAddress.0.0.0.0.21.0.0.0.0.0=0.0.0.0
tcpConnRemAddress.127.0.0.1.23.127.0.0.1.1415=127.0.0.1
tcpConnRemAddress.127.0.0.1.1415.127.0.0.1.23=127.0.0.1
tcpConnRemAddress.140.252.1.29.1023.140.252.1.11.513=140.252.1.11

tcpConnReinPort.0.0.0.0.21.0.0.0.0.0=0
tcpConnRemPort.127.0.0.1.23.127.0.0.1.1415=1415
tcpConnRemPort.127.0.0.1.1415.127.0.0.1.23=23
tcpConnRemPort.140.252.1.29.1023.140.252.1.11.513=513

For the rlogin to gemini only one entry appears, since gemini is a different host. We only see the client end of the connection (local port 1023), but both ends of the Telnet connection appear (client port 1415 and server port 23), since the connection is through the loopback interface. We can also see that the listening FTP server has a local IP address of 0.0.0.0, indicating it will accept connections on any interface.

25.9 Additional Examples

We now return to some earlier problems we encountered in the text, and use SNMP to
understand what's happening.

Interface MTU

Recall our experiment in Section 11.6, in which we tried to determine the MTU of the SLIP link from netb to sun. We can now use SNMP to obtain this MTU. We first obtain the interface number (ipRoutelfIndex) of the SLIP link (140.252.1.29) from the IP routing table. Using this we go into the interface table and fetch the MTU (along with the description and type) of the SLIP link:

sun % snmpi -a netb -c secret

snmpi> get ipRouteIfIndex.140.252.1.29
ipRouteIfIndex.140.252.1.29=12

snmpi> get ifDescr.l2 ifType.12 ifMtu.l2
ifDescr.l2="Telebit NetBlazer dynamic dial virtual interface"
ifType.l2=other(1)
ifMtu.l2=1500

We see that even though the link is a SLIP link, the MTU is set to the Ethernet value of 1500, probably to avoid fragmentation.

Routing Tables

Recall our discussion of address sorting performed by the DNS in Section 14.4. We showed how the first IP address returned by the name server was the one that shared a subnet with the client. We also mentioned that using the other IP address would probably work, but could be less efficient. Let's look at using the alternative IP address and see what happens. We'll use SNMP to look at a routing table entry, and tie together many concepts from earlier chapters dealing with IP routing.

The host gemini is multihomed, with two Ethernet interfaces. First let's verify that we can Telnet to both addresses:

sun % telnet 140.252.1.11 daytime
Trying 140.252.1.11 ...
Connected to 140.252.1.11.
Escape character is '^]'.
Sat Mar 27 09:37:24 1993
Connection closed by foreign host.

sun % telnet 140.252.3.54 daytime
Trying 140.252.3.54 ...
Connected to 140.252.3.54.
Escape character is '^]'.
Sat Mar 27 09:37:35 1993
Connection closed by foreign host.

So there is no connectivity difference between the two addresses. Now we'll use traceroute to see if there is a different route for each address:

sun % traceroute 140.252.1.11
traceroute to 140.252.1.11 (140.252.1.11), 30 hops max, 40 byte packets
1 netb (140.252.1.183) 299 ms 234 ms 233 ms
2 gemini (140.252.1.11) 233 ms 228 ms 234 ms

sun % traceroute 140.252.3.54
traceroute to 140.252.3.54 (140.252.3.54), 30 hops max, 40 byte packets
1 netb (140.252.1.183) 245 ms 212 ms 234 ms
2 swnrt (140.252.1.6) 233 ms 229 ms 234 ms
3 gemini (140.252.3.54) 234 ms 233 ms 234 ms

There is an extra hop if we use the address on subnet 140.252.3. Let's find the reason for the extra hop. (The router swnrt is R3 from Figure 3.6.)

Figure 25.29 shows the arrangement of the systems. We can tell from the traceroute output that the host gemini and the router swnrt are both connected to two networks: 140.252.1 and 140.252.3.


Figure 25.29 Topology of systems being used for example.

Recall in Figure 4.6 that we explained how proxy ARP is used by the router netb to make it appear as though sun was directly connected to the Ethernet 140.252.1. We've also omitted the modems on the SLIP link between sun and netb, since they're not relevant to this discussion.

In Figure 25.29 we show the path of the Telnet data using dashed arrows, when the address 140.252.3.54 is specified. How do we know that the return packets go directly from gemini to netb, and don't go back the way they came? We use our version of traceroute with loose source routing from Section 8.5:

sun % traceroute -g 140.252.3.54 sun
traceroute to sun (140.252.13.33), 30 hops max, 40 byte packets
1 netb (140.252.1.183) 244 ms 256 ms 234 ms
2 * * *
3 gemini (140.252.3.54) 285 ms 227 ms 234 ms
4 netb (140.252.1.183) 263 ms 259 ms 294 ms
5 sun (140.252.13.33) 534 ms 498 ms 504 ms

When we specify loose source routing, the router swnrt never responds. If we look at the earlier output from traceroute, without source routing, we see that swnrt is indeed the second hop. The reason for the timeouts must be that the router does not generate the ICMP time exceeded errors when the datagram specifies loose source routing. What we are looking for in this traceroute output is that the return path from gemini (TTLs 3,4, and 5) goes directly to netb, and not through the router swnrt.

The question that we need SNMP to answer is what does the routing table entry on netb look like for the destination network 140.252.3? It is netb that sends the packets to swnrt and not directly to gemini. We use the get command to fetch the value of the next-hop router for this destination:

sun % snmpi -a netb -c secret get ipRouteNextHop.140.252.3.0
ipRouteNextHop.l40.252.3.0=140.252.1.6

This routing table entry tells netb to send the packets to swnrt, which is what we see happen.

Why does gemini send the packets directly back through netb? Because on gemini the destination address of the return packets is 140.252.1.29, and that network (140.252.1) is a directly connected interface.

What we're seeing in this example is a policy routing decision. The default route to network 140.252.3 is through the router swnrt because gemini is intended to be a multihomed host, not a router. This is an example of a multihomed host that does not want to be a router.

25.10 Traps

All the examples we've looked at so far in this chapter have been from the manager to the agent. As shown in Figure 25.1, it's also possible for the agent to send a trap to the manager, to indicate that something has happened on the agent that the manager might want to know about. Traps are sent to UDP port 162 on the manager.

In Figure 25.2 we showed the format of the trap PDU. We'll go through all the fields in this message when we look at some tcpdump output below.

Six specific traps are defined, with a seventh one allowing a vendor to implement an enterprise-specific trap. Figure 25.30 describes the values for the trap type in the trap message (Figure 25.2).

trap
type
Name
Description
0
coldStart Agent is initializing itself.
1
warmStart Agent is reinitializing itself.
2
linkDown An interface has changed from the up to the down state (Figure 25.18). The first variable in the message identifies the interface.
3
linkUp An interface has changed from the down to the up state (Figure 25.18). The first variable in the message identifies the interface.
4
authenticationFailure A message was received from an SNMP manager with an invalid community.
5
egpNeighborLoss An EGP peer has changed to the down state. The first variable in the messages contains the IP address of the peer.
6
enterpriseSpecific Look in the specific code field for information on the trap.

Figure 25.30 Trap types.

We can see some traps using tcpdump. We'll start the SNMP agent on the system sun and see it generate a coldStart trap. (We tell the agent to send traps to the host bsdi. Although we're not running a manager on bsdi to handle the traps, we can run tcpdump and see what packets get generated. Recall from Figure 25.1 that a trap is sent from the agent to the manager, but there is no acknowledgment sent by the manager, so we don't need a manager to handle the traps.) We then send a request using the snmpi program, but with an invalid community name. This should generate an authenticationFailure trap. Figure 25.31 shows the output.

10.0 sun.snmp > bsdi.snmp-trap: C=traps Trap (28)
E:unix.1.2.5 [140.252.13.33] coldStart 20
218.86 (18.86) sun.snmp > bsdi.snmp-trap: C=traps Trap (29)
E:unix.1.2.5 [140.252.13.33] authenticationFailure 1907

Figure 25.31 tcpdump output of traps generated by SNMP agent.

First we notice that both UDP datagrams are from the SNMP agent (port 161, printed as the name snmp) with a destination port of 162 (printed as the name snmp-trap).

The notation C=traps is the community name of the trap message. This is a configuration option with the ISODE SNMP agent being used.

The next notation. Trap(28) in line 1 and Trap(29) in line 2 is the PDU type and length.

The next field of output for both lines is E:unix.1.2.5. This is the enterprise: the agent's sysObjectID. It falls under the 1.3.6.1.4.1 node of the tree in Figure 25.6 (iso.org.dod.internet.private.enterprises), so this agent's object identifier is 1.3.6.1.4.1.4.1.2.5. Its abbreviated name is unix.agents.fourBSD-isode.5. The final number (5) is the version number of this release of the ISODE agent. This enterprise value identifies the agent software generating the trap.

The next field output by tcpdump is the IP address of the agent (140.252.13.33).

The trap type is printed as coldStart on line 1, and authenticationFailure on line 2. These correspond to trap type values of 0 and 4, respectively (Figure 25.30). Since these are not enterprise-specific traps, the specific code must be 0, and is not printed.

Next comes the timestamp field, printed as 20 and 1907. This is a TimeTicks value, representing the number of hundredths of a second since the agent initialized. In the case of the cold start trap, the trap was generated 200 ms after the agent was initialized. The tcpdump output indicates that the second trap occurred 18.86 seconds after the first one, which corresponds to the printed value of 1907 hundredths of a second, minus 200 ms.

Figure 25.2 indicates that a trap message can contain interesting variables that the agents wants to send to the manager, but there aren't any in our examples.

25.11 ASN.1 and BER

The formal specification of SNMP uses Abstract Syntax Notation 1 (ASN.1) and the actual encoding of the bits in the SNMP messages (Figure 25.2) uses the corresponding Basic Encoding Rules (BER). Unlike most texts that describe SNMP, we have purposely left a discussion of ASN.1 and BER until the end. When they're discussed first, it can confuse the reader and obfuscate the real purpose of SNMP-network management. In this section we only give an overview of these two topics. Chapter 8 of [Rose 1990] covers ASN.1 and BER in detail.

ASN.1 is a formal language for describing data and the properties of the data. It says nothing about how the data is stored or encoded. All the fields in the MIB and the SNMP messages are described using ASN.1. For example, the ASN.1 definition of the data type IpAddress from the SMI looks like:

IpAddress ::=
[APPLICATION 0] -- in network-byte order
IMPLICIT OCTET STRING (SIZE (4))

Similarly, from the MIB we find the following definition of a simple variable:

udpNoPorts OBJECT-TYPE
SYNTAX Counter
ACCESS read-only
STATUS mandatory
DESCRIPTION
"The total number of received UDP datagrams for which there was no application at the destination port."
:: = { udp 2 }

The definition of tables using SEQUENCE and SEQUENCE OF is more complex.

Given these ASN.1 definitions, there are many ways to encode the data into a stream of bits for transmission. SNMP uses BER. The representation of a small integer, such as 64, requires 3 bytes using BER. One byte says the value is an integer, the next byte says how many bytes are used to store the integer (1), and the final byte contains the binary value.

Fortunately the details of ASN.1 and BER are only important to implementors of SNMP. They are not fundamental to the understanding and use of network management.

25.12 SNMP Version 2

During 1993 11 RFCs were published defining revisions to SNMP The first of these, RFC 1441 [Case et al. 1993], provides an introduction to SNMP Version 2 (SNMPv2). Two books also describe SNMPv2 [Stallings 1993; Rose 1994]. Two publicly available implementations already exist (see Appendix B.3 of [Rose 1994]), but vendor implementations probably won't be widely available until 1994.

In this section we describe the major differences from SNMPv1 to SNMPv2.

  1. A new packet type get-bulk-request allows the manager to retrieve large blocks of data efficiently.
  2. Another new packet type inform-request allows one manager to send information to another manager.
  3. Two new MIBs are defined: the SNMPv2 MIB and the SNMPv2-M2M MIB (Manager-to-Manager).
  4. SNMPv2 provides security enhancements over SNMPv1. In SNMPv1 the community name passed from the manager to the agent is a cleartext password. SNMPv2 can provide authentication and privacy.

As vendors start to provide SNMPv2-capable agents, management stations will also appear that can handle both. [Routhier 1993] describes extending an implementation of SNMPv1 to support SNMPv2.

25.13 Summary

SNMP is a simple request-reply protocol between an SNMP manager and an SNMP agent. The management information base (MIB) defines the variables that are maintained by the agent, for the manager to query or set. Only a limited number of data types are used to define these variables.

All the variables are identified by object identifiers, a hierarchical naming scheme consisting of long strings of numbers that are normally abbreviated into a simple name, for human readability. A specific instance of a variable is identified by appending an instance to the object identifier.

Many SNMP variables are contained in tables, with a fixed number of columns, but a variable number of rows. Fundamental to SNMP is the identification scheme used to identify each row in a table (when we don't know how many rows are in the table), and the lexicographic ordering (column-row order). The end result, SNMP's get-next operator, is basic to any SNMP manager.

We then described the following groups of SNMP variables: system, interface, address translation, IP, ICMP, TCP, and UDP. This was followed by two examples, one to determine the MTU of an interface, and the other to look at the routing table of a router.

We completed the chapter by looking at SNMP traps, a way for the agent to notify the manager that something significant has occurred, and a brief mention of ASN.1 and BER. These latter two topics are probably the most confusing aspects of SNMP, but fortunately their details are needed only by implementors.

Exercises

25.1 We said that using two different ports (161 and 162) allows a system to run both a manager and agent. What would happen if the same port number were used for both?

25.2 How would you list an entire routing table using get-next?