What is the snmp protocol. SNMP: Network Management Protocol

Most modern types of network equipment support the SNMP protocol. This standard is considered to be very simple in structure. Its implementation in modern companies is easy. Control of computers by means of the appropriate protocol can be carried out using a wide range of software solutions. What are the main features of SNMP? How is the relevant protocol used in practice?

What is the SNMP protocol?

To begin with, we will study the basic information about the technology in question. What is SNMP? Given as Simple Network Management Protocol, it stands for "Simple Network Management Protocol". This standard is one of the most common that are used to manage various devices in IP networks operating on the basis of the TCP / IP architecture. For example, routers, switches, workstations, network printers.

The protocol under consideration is most often used in cases where the infrastructure involves monitoring devices that are connected to the network in order to fulfill the conditions set by the administrator. The structure of information that is traded within the SNMP protocol includes, in particular, those that are presented in the form of variables, through which you can describe the configuration of what is in the network system. By means of control applications, the corresponding variables can be requested, and in some cases, set.

SNMP Capabilities

The protocol in question allows you to configure certain devices using the main server without resorting to special programs, the functionality of which is designed to monitor various network processes. With the help of the protocol in question, during the administration of processes in the network, it is possible not only to manage (SNMP in this sense is a unique tool) certain procedures, but, in particular, also to monitor the performance of the infrastructure, identify problems that arise in it, to monitor the use of network resources.

Let us now consider what key components form the infrastructure of networks based on SMTP.

SNMP: Basic Components

SNMP is a protocol that involves several network components. The main ones include:

Managed object - a computer or application to which certain commands are sent using the protocol in question, the network administrator;

MIB database;

Agent application;

Program manager;

System for providing network interaction.

A managed object can not only receive commands from the administrator, but also send them in accordance with the specified parameters. The data from the object is transferred to the manager program, which interprets them according to the established algorithms. In turn, an agent application functions on the managed device. It collects information on the corresponding device and, if necessary, broadcasts it in a format adapted to the specifics of the SNMP protocol.

The networking system allows the administrator to work with several manager programs in order to control the operation of the infrastructure. At the same time, several types of software of the corresponding type can be installed in networks.

Perhaps the most important element of the SNMP protocol is the MIB, or management information base. Its purpose is to describe the data structure that is exchanged in the process of managing devices. In fact, the corresponding database allows you to place information that is used to manage the device directly on it, whether it be a modem, a server or, for example, SNMP is a universal protocol, and in many respects its functionality can be implemented thanks, first of all, to the capabilities of the database MIB.

Devices compatible with this technology contain both standard variables and those that characterize the features of a particular device. The main elements of this base are identifiers of the OID type. They allow you to set variables that are read or defined using the SMNP protocol.

The agent application, which is a component of the SMNP network infrastructure, usually receives requests using port 161. In turn, the manager program can use any ports available on the network. At the same time, this type of software usually receives notifications on port 162.

Let's consider the main tools used by administrators who use the SNMP protocol in their work, in more detail. Among them is the program manager.

SNMP manager program: main features

This type of software allows, thanks to the capabilities of the protocol under consideration, to manage groups of various devices within the network infrastructure. The program in question can function if a special agent application, which we mentioned above, is installed on devices that are controlled through its interfaces. It sends the necessary data to the administration server using the SNMP protocol. In turn, on the side of the main PC, the manager program in question functions, which processes information coming from managed devices.

What software is used to manage the network via SNMP?

What specific programs can be used as managers? In principle, there are solutions adapted for implementation in various operating systems of the SNMP protocol - Windows, Solaris. If we talk about software for Windows, then among the popular ones that work on this OS and use SNMP is a package released by Castle Rock Computing. In turn, another effective solution has been developed for Solaris - Sun NetManager. With both options, an efficient network map based on the SNMP protocol can be built. In addition, they allow direct communication with the MIB.

Within the appropriate interfaces, you can manage routers of various brands that support the SNMP protocol, Cisco in particular. As a rule, modern manufacturers of network devices release documentation on the MIB of a device, which reflects the ability to manage the corresponding infrastructure components within the network.

Another popular solution for managing network devices is Zabbix. SNMP is a protocol that this program also uses. The corresponding solution has a large number of functions.

In terms of using SNMP, for example, it allows for effective monitoring of network processes. Data exchange within the SNMP protocol is carried out by means of special messages. Let's consider their specifics in more detail.

Features of SNMP messages

The main messages that the administrator server can initiate via the SNMP protocol include such commands as:

GetNextRequest;

GetBulkRequest;

Inform Request.

The essence of the 1st command is to send a request from the manager program to the agent application in order to obtain one or another value for a variable - one or a list. In turn, the manager program receives a response with certain values.

The specificity of the 2nd command is to send a message also from the manager program to the agent application, but in this case in order to adjust the variable - one or from the list. The agent application accepts the changes, after which it sends new values ​​for certain variables to the manager program.

The essence of the 3rd command is to send a request from the manager program to the agent application of certain commands in order to find all available variables on the device, as well as the values ​​​​that are set for them. In turn, the agent application returns a response that contains the value of one variable, as well as a link to the next relative to its position in the list. The next request involves passing data that reflects information about the next variable, as well as a link to the one that comes next in the queue. In the future, the data turnover algorithm using the considered SNMP command is repeated.

The specificity of the 4th command is that, in fact, it is a modernized version of the GetNextRequest message. It assumes that the agent application will send a response to the manager program containing data on several variables at the same time, starting with the one presented in the original request.

The essence of the 5th command is in the implementation of the procedure for returning the associated variable, as well as the values ​​from the agent application to the manager program using the 4 types of messages discussed above. At the same time, error messages are exchanged between the devices by means of the appropriate command.

The specificity of the 6th command is in the transfer of messages from the agent application without a preliminary request from the manager program. The structure of this message contains the current value of the variable. Note that the recipient of the command in this case is determined by special configurations within the MIB.

The essence of the 7th command is that it, in fact, corresponds to the notification of sending a message from the manager program to the agent application and vice versa. Its use is due to the fact that certain messages in the network infrastructure in some cases can be delivered incorrectly. The InformRequest command, in fact, confirms the fact of the successful transmission of the command from one device to another.

Correct SNMP configuration in many cases requires the administrator to pay more attention to verifying the functionality of the MIB. Let's take a look at what its features are.

MIB: features of the base functioning

A key procedure within the functioning of the MIB base is variable addressing. It is carried out taking into account the structure of the considered component of the SNMP protocol. The MIB base looks like a tree diagram consisting of several elements, each of which has a special identifier attached to it.

The name of a variable within the MIB base reflects the address up to it, starting from the root directory. The structure of a variable can contain a variety of information, for example, about the device's operating time. In the tree structure, MIBs can be present as standard branches that are supported by most devices, or those added by the device manufacturer or the organization in which the computer network infrastructure is being implemented. The main thing in this case is to correctly place the appropriate sets of variables.

So, if they are introduced into the MIB structure temporarily, then it makes sense to place them in the experimental section. Immediately before the statement, you should assign a separate number to the set of variables. For this, the private-enterprises section is used. This will allow network engineers or administrators who are responsible for SNMP monitoring and other infrastructure maintenance tasks to open a new branch in the MIB structure in order to place variables only from their company.

History of SMNP

It will be interesting to learn about the history of SNMP development. The main software environment in which the SNMP protocol is currently used is Windows. However, its development was initiated back in 1988 - long before the operating system from Microsoft, presented in familiar interfaces, began to conquer the markets. In fact, SNMP was originally developed for UNIX, a family of operating systems designed to solve a wide range of tasks to ensure the functionality of various computer networks. Although, of course, by that time, many experts saw the potential of Windows, and it is possible that the development of a universal network protocol was largely predetermined by the fact of the potential growth in popularity of the new operating system.

Of course, there was another factor that played an important role in accelerating the work on SNMP - the Web. Even then, the first online services appeared, and it was clear to the experts that ahead was the active integration of network interfaces on a global scale.

One way or another, the largest manufacturers of network devices in 1988 decided that they needed to develop a universal set of tools designed to manage devices. By that time, companies were releasing their own solutions for monitoring and configuring devices. We needed unification.

SNMP Development: Basic Instructions

In August 1988, the enterprises that produce network equipment came to a consensus. During the development of the new protocol, some concepts that were already in place were applied. The specialists who worked together identified 3 key documents: RFC 1065, 1066, and 1067. Subsequently, they were supplemented, and new ones appeared - RFC 1155, 1156, and 1157. These sources were revised, and in 1991 they the first version of the SNMP protocol was released.

For example, RFC 1155 contained instructions defining:

The structure in which the control information should be reflected;

What are the basic principles for applying the syntax when defining names for variables.

RFC 1155 has been supplemented by RFC 1212 in terms of, again, variable syntax. At the time of the adoption of the SMNP protocol, a number of new documents were developed, such as RFC 1213. It reflected a list of key variables through which the configuration of the network infrastructure was to be carried out.

The RFC 1157 source contained the parameters needed to:

Definitions of commands through which the server and the managed object could interact with each other;

Implementation of the exchange of trap messages.

As soon as the SNMP protocol was published and introduced, an adapter, a server - in principle, any device that would be part of the network infrastructure could become an object of management carried out within the framework of standard procedures. The introduction of SNMP has become the strongest factor in the growth of the global network equipment market. Also, thanks to standardization, it became possible to introduce new interfaces on the widest scale, such as, for example, Ethernet, FDDI.

Summary

So, what is it - SNMP, we learned. This abbreviation corresponds to one of the key network protocols that are used to maintain the functionality of modern computer networks. This protocol involves the implementation between various elements of the infrastructure - control servers and managed devices, the exchange of standardized messages. In this case, the MIB database of a particular device is accessed.

Through standardized messages within the SNMP protocol, the following are carried out:

Requests for one or more MIB parameters;

Sequential reading of various values ​​​​for one or another parameter, for example, tabular;

Setting specific values ​​for one or more MIB variables;

Return by the device of a response to a particular request of another device;

Sending notification messages about certain network processes.

MIB algorithms can be both common to all devices, and those that are prescribed by manufacturers for specific types of network equipment.

What is SNMP in terms of importance for the modern IT market? This technology is obviously among the most important, and in many cases has no alternative. And this despite its simplicity, which, however, was the result of many years of development and harmonization of network standards with the participation of leading equipment manufacturers.

Network communications, within which the capabilities of the MIB protocol are used, involve the use of manager programs, as well as agent applications. The former send various commands to the latter, after which the device software executes certain algorithms. Data is also transferred according to established schemes from the agent application to the manager program.

Network computers can be managed from the main server. A special program, for example, Zabbix, can be used for this. SNMP is a protocol supported by programs that can run on different operating systems. Initially, SNMP was developed for UNIX, but types of software were created that allowed it to be used in Windows, Sun Solaris.

So what is SNMP? An international standard that allows, first of all, to integrate solutions from different manufacturers. Initially, brands set their own algorithms for managing them. But thanks to the development of SNMP, they had the opportunity to use unified commands, which stimulated the demand for manufactured network devices, became an effective driver for the growth of the market for the corresponding type of equipment.

A lot has already been written about the fact that in the name of the Simple Network Management Protocol, the word Simple can be safely written in quotation marks. The SNMP protocol is quite simple in terms of creating SNMP agents, however, on the SNMP manager side, competent processing of complex data structure is usually a non-trivial task.

We have tried to simplify the process of configuring SNMP data collection and events and allow users to:

  • Never look inside MIB files
  • Don't know what OIDs are and never operate with them
  • Do not use a separate SNMP preview utility during configuration

Step 1: Add MIB Files

First of all, you need to deal with MIB files. The description of the logic of relationships between data elements and their syntax was implemented in SNMP using these files in order to reduce network load and simplify the implementation of agents. Users, however, do not always want to deal with their internal structure.

The SNMP module of our AggreGate Network Manager system at startup loads all MIB files located in a special server folder, after which it allows you to add new ones using a simple dialog:

When files are loaded, they are automatically compiled. A built-in MIB editor with syntax highlighting is only available in case of out-of-spec MIBs. They rarely need to be used.

MIB editor



This completes the work with MIB files, further their names are used only for logical grouping of already collected data. If necessary, downloaded files can be viewed and searched in the MIB table, but during normal operation this is also not required.

MIB table


Step 2: connect the SNMP device

In the case of building a classic monitoring system, this step is usually not required, since all devices are added to the system automatically during periodic device discovery (network discovery). However, while adding devices discovered by network scanning, approximately the same steps are followed:

Step 3: Examining the Snapshot of the Device

After the device connection phase is completed, the system needs from several seconds to several minutes to complete the polling of the device within the selected MIBs. When the device icon turns green, you can open and explore the so-called "device snapshot":

This snapshot captures almost the entire essence of our approach to working with SNMP data. First of all, it always contains "at hand" all the real data of the device. In this case, all data is read only once, the subsequent poll is only for important metrics. A complete re-reading of the device snapshot is performed once a day; to reduce the load on the network, it can be turned off altogether. The device snapshot is optionally stored in the database when the monitoring system is restarted.

There is usually no need to resort to any external utilities when it is necessary to find suitable monitoring data from their descriptions in the MIB file or values. All data is already grouped by MIB files, but you can also group them by OID hierarchy:

To view a detailed description of any metric or table contained in a MIB file, just hover over the description or metric value with the mouse. The tooltip also shows the SNMP data type and full OID:

If a metric can take one of several numeric values ​​described in the MIB file by text constants, the device snapshot immediately shows the constant corresponding to the current value. The full list of constants and their numerical values ​​is available through the context menu:

In this case, the current numerical value can always be viewed in a tooltip. For editable metrics, it's even easier, you can select a constant and see its value directly in the drop-down list:

But our SNMP data approach is most useful when it comes to table processing. Each SNMP table is shown in a device snapshot as a separate table-type metric:

Editing data in tables can be done right while viewing, for example, to disable the network interface, just change the value of the field ifAdminStatus in the corresponding line.

When hovering over a column header, the tooltip shows the description of the field obtained from the MIB file, as well as its type and OID:

If there are several related tables, such as those using external indexes or augmentation, the system automatically handles all internal relationships and brings the data of the related tables together. In most cases, users are not even aware of the existence of such difficulties. Here is how the table looks like hrSWRunPerfTable:

At the MIB file level, this table consists of two columns ( hrSWRunPerfCPU and hrSWRunPerfMem) extending the table hrSWRunTable. In a device snapshot, these tables are already merged, making it easy to analyze data, build reports and charts, configure storage, and more.

Because AggreGate's unified data model is table-oriented, SNMP data tables are an ideal candidate for native processing. They enable L2/L3 topology building, MPLS TE and MPLS VPN data analysis, IP SLA monitoring and test creation, and hundreds of simpler tasks.

Step 4: Set Up Polling Periods and Retention Periods

AggreGate Network Manager is, therefore, in most cases, after automatically or manually adding a device, polling periods and metric storage periods are already preconfigured for all metrics and tables that the system "understands", i.e. shows on dashboards and analyzes for the need to generate alarm messages.

You can adjust the survey (synchronization) and storage settings of the metric through its context menu, or through the account settings (for all metrics at once).

Polling and storage settings


The storage settings dialog shows only the storage period for "raw" data in a regular database (relational or NoSQL, depending on the server settings). In most cases, SNMP data is stored in the Round-Robin Database (RRD) that is built into the AggreGate platform. On the topic of creating statistics channels, which shift metrics and parts of tables into a ring database, there will be a separate article.

Step 5: move on to data processing and visualization

When the data is collected and stored in the server database, you can start using it for business, that is, to monitor and manage the IT infrastructure. The context menu of any metric in a device snapshot provides access to wizards that allow you to start configuring alarms, reports, graphs, queries, dashboards, and other analysis and visualization tools.

With the help of these tools, the influence of metrics and tables on the system-wide operations of finding the causes of failures, performance analysis, planning and inventory, configuration management, and other system functions is configured. Along the way, various interfaces are “drawn”:

As a result

The process described above may seem complicated due to the many details mentioned, but in practice, from the moment you connect a completely new device to the appearance of its specific data on standard dashboards, it takes only a few minutes. During this time, logging out of our system is required only while searching for specific MIB files on the website of the manufacturer of the connected equipment.

When setting up monitoring, you do not need to manually specify the names of MIBs, enter OIDs and other low-level identifiers. This makes setting up SNMP monitoring fairly quick and easy.

Of course, we still have work to do. An improvement in the mechanisms for selecting individual metrics is required to avoid even a single poll of entire MIBs. There is a need to exclude individual rows and columns of SNMP tables from polling. We would be interested to hear about other shortcomings of the process of setting up SNMP monitoring in our system.

And detail?

This article does not cover receiving, processing and sending SNMP traps, working with SNMP v3, and many other aspects at all.

For a more detailed story, we invite all habrazhiteley to the webinar Monitoring and management via SNMP, That will take place May 26, 2015 at 11:00 am by Moscow time. In this webinar, we will demonstrate live the entire process described above, as well as many other ways to monitor network, server and non-standard equipment using SNMP.

The SNMP strategy is that network health monitoring at any meaningful level of detail is done primarily by polling from the monitoring center. A limited number of unsolicited messages (trap) provides synchronization and activates polling. Limiting the number of unsolicited messages is consistent with the objectives of keeping the network management system simple and minimizing traffic.

From these quotes, it's pretty clear that TRAP and INFORM requests are not the most commonly used part of SNMP. It would be more appropriate to illustrate an article for beginners with examples of the use of much more common GET requests.

In general, I highly recommend reading all RFCs related to SNMP before getting started. Some aspects of SNMP are not obvious and it makes sense to get an idea about them from the original source. You can start familiarizing yourself with the material from the wiki.

The first steps

In addition to the obligatory familiarization with the documentation, it is important to understand why we are doing all this. In the practice of telecom, the following tasks are most often encountered:
  1. Polling equipment via SNMP (accounting, monitoring)
  2. Equipment management via SNMP (activation)
The tasks associated with interrogating equipment are reduced to the formation of GET (and, as will be shown below, GETNEXT) requests. Equipment management is reduced to sending SET requests that change the state of the corresponding variables on the equipment (for example, in this way, you can disable any interface).

The task of SNMP monitoring stands out from the general background by the requirement that there is a lot or a lot of equipment to be polled. Let's assume that this is the problem we have to solve.

Let's start writing code. In the test example, we will contact our own host via SNMP and read the value of the variable specified by OID 1.3.6.1.2.1.1.3.0 and containing the host's uptime value:

Single GET request

package com.acme.ae.tests.snmp; import java.io.IOException; import org.snmp4j.CommunityTarget; import org.snmp4j.PDU; import org.snmp4j.snmp; import org.snmp4j.Target; import org.snmp4j.TransportMapping; import org.snmp4j.event.ResponseEvent; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultUdpTransportMapping; public class Test( private final static String SNMP_COMMUNITY = "public"; private final static int SNMP_RETRIES = 3; private final static long SNMP_TIMEOUT = 1000L; private Snmp snmp = null; private TransportMapping transport = null; private void test() throws IOException( Target t = getTarget("udp:127.0.0.1/161"); String r = send(t, "1.3.6.1.2.1.1.3.0"); System.out.println(r); ) private String send( Target target, String oid) throws IOException ( PDU pdu = new PDU(); pdu.add(new VariableBinding(new OID(oid))); pdu.setType(PDU.GET); ResponseEvent event = snmp.send(pdu, target, null); if (event != null) ( return event.getResponse().get(0).toString(); ) else ( return "Timeout exceeded"; ) ) private Target getTarget(String address) ( Address targetAddress = GenericAddress.parse(address); CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString(SNMP_COMMUNITY)); target.setAddress(targetAddress); target.setRetries(SNMP_RETRIES); target .setTimeout(SNMP_TIMEOUT); target.setVersion(SnmpConstants.version1); return target; ) private void start() throws IOException ( transport = new DefaultUdpTransportMapping(); snmp = new Snmp(transport); transport.listen(); ) private void stop() throws IOException ( try ( if (transport != null) ( transport .close(); transport = null; ) ) finally ( if (snmp != null) ( snmp.close(); snmp = null; ) ) ) public static void main(String args) ( Test t = new Test() ; try ( try ( t.start(); t.test(); ) finally ( t.stop(); ) ) catch (IOException e) ( System.out.println(e.toString()); ) ) )


After making sure that the SNMP service on our host is running and running the code for execution, we will get the desired uptime value (the time the host has been up and running since the last boot):

1.3.6.1.2.1.1.3.0 = 2:28:55.06
Using this value, you can monitor. If we find that the value has decreased, then the host has managed to reboot since the next poll. If the host hasn't responded within the given timeout (after a few automatic attempts), it most likely means that the host is down. Is everything simple?

Counted - wept

Not really. We remember that we have to fulfill a lot of requests. Let's measure how many requests we can execute per second? Let's make a small correction to the code:

Private void test() throws IOException ( Target t = getTarget("udp:127.0.0.1/161"); Long timestamp = System.currentTimeMillis(); for (int i = 0; i< 1000; i++) { send(t, "1.3.6.1.2.1.1.3.0"); } System.out.println(1000000L /(System.currentTimeMillis() - timestamp)); }
And run it for execution:

2463
Almost two and a half thousand requests per second! Not bad?

Let's not rush. We send requests to the Loopback interface, and it works somewhat faster than the local network. Let's see how many requests per second we can execute to another host in our network:

182
We don't even make it to 200. Generally speaking, perhaps this will be enough. Everything depends on the task. But we took measurements under the condition that the polled host is available. What happens if the host does not respond?

There will be several access attempts (in our code we have set 3) separated by a timeout (1000 ms). This means that in a second we will not have time to complete a single request. Since a non-responsive host is not that uncommon, this can be a big problem in a real project.

I'm going for the record

What can be done about it? If we were dealing with some kind of synchronous protocol (for example, telnet), we would not have much choice. In order to increase performance, we would have to execute many threads at the same time. But SNMP is asynchronous in nature! No need to forcibly squeeze it into a synchronous frame.

How to switch to asynchronous option? In our case, it's quite simple:

Asynchronous requests

package com.acme.ae.tests.snmp; import java.io.IOException; import org.snmp4j.CommunityTarget; import org.snmp4j.PDU; import org.snmp4j.snmp; import org.snmp4j.Target; import org.snmp4j.TransportMapping; import org.snmp4j.event.ResponseEvent; import org.snmp4j.event.ResponseListener; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultUdpTransportMapping; public class Test implements ResponseListener ( private final static String SNMP_COMMUNITY = "public"; private final static int SNMP_RETRIES = 3; private final static long SNMP_TIMEOUT = 1000L; private Snmp snmp = null; private TransportMapping transport = null; public void onResponse(ResponseEvent event ) ( response PDU = event.getResponse(); if (response != null) ( System.out.println(response.get(0).toString()); return; ) ) private void test() throws IOException ( Target t = getTarget("udp:192.168.131.253/161"); Long timestamp = System.currentTimeMillis(); for (int i = 0; i< 1000; i++) { send(t, "1.3.6.1.2.1.1.3.0"); } System.out.println(1000000L /(System.currentTimeMillis() - timestamp)); } private void send(Target target, String oid) throws IOException { PDU pdu = new PDU(); pdu.add(new VariableBinding(new OID(oid))); pdu.setType(PDU.GET); snmp.send(pdu, target, null, this); } private Target getTarget(String address) { Address targetAddress = GenericAddress.parse(address); CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString(SNMP_COMMUNITY)); target.setAddress(targetAddress); target.setRetries(SNMP_RETRIES); target.setTimeout(SNMP_TIMEOUT); target.setVersion(SnmpConstants.version1); return target; } private void start() throws IOException { transport = new DefaultUdpTransportMapping(); snmp = new Snmp(transport); transport.listen(); } private void stop() throws IOException { try { if (transport != null) { transport.close(); transport = null; } } finally { if (snmp != null) { snmp.close(); snmp = null; } } } public static void main(String args) { Test t = new Test(); try { try { t.start(); t.test(); } finally { t.stop(); } } catch (IOException e) { System.out.println(e.toString()); } } }


7142
Requests are like falling into a bottomless barrel! Of course, the answers will come with a delay, but they will also come pretty quickly. But how do we know that the host has not responded?

Very simply, after a specified number of attempts and timeouts, SNMP4J will return an event to us, the response in which will be null:

Corrected version

requests = new HashSet (); private Long firstTimestamp = null; private long lastTimestamp; public void onResponse(ResponseEvent event) ( Integer32 requestId = event.getRequest().getRequestID(); PDU response = event.getResponse(); if (response != null) ( lastTimestamp = System.currentTimeMillis(); if (firstTimestamp = = null) ( firstTimestamp = lastTimestamp; ) return; ) else ( synchronized (requests) ( if (requests.contains(requestId)) ( System.out.println("Timeout exceeded"); ) ) ) synchronized (requests) ( requests .remove(requestId); ) ) private void test() throws IOException ( Target t = getTarget("udp:192.168.131.253/161"); Long timestamp = System.currentTimeMillis(); for (int i = 0; i< 1000; i++) { send(t, "1.3.6.1.2.1.1.3.0"); } System.out.println(1000000L /(System.currentTimeMillis() - timestamp)); while (!requests.isEmpty()) { try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } if (firstTimestamp != null) { System.out.println(1000000L /(lastTimestamp - firstTimestamp)); } } private void send(Target target, String oid) throws IOException { PDU pdu = new PDU(); pdu.add(new VariableBinding(new OID(oid))); pdu.setType(PDU.GET); snmp.send(pdu, target, null, this); synchronized (requests) { requests.add(pdu.getRequestID()); } } private Target getTarget(String address) { Address targetAddress = GenericAddress.parse(address); CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString(SNMP_COMMUNITY)); target.setAddress(targetAddress); target.setRetries(SNMP_RETRIES); target.setTimeout(SNMP_TIMEOUT); target.setVersion(SnmpConstants.version1); return target; } private void start() throws IOException { transport = new DefaultUdpTransportMapping(); snmp = new Snmp(transport); transport.listen(); } private void stop() throws IOException { try { if (transport != null) { transport.close(); transport = null; } } finally { if (snmp != null) { snmp.close(); snmp = null; } } } public static void main(String args) { Test t = new Test(); try { try { t.start(); t.test(); } finally { t.stop(); } } catch (IOException e) { System.out.println(e.toString()); } } }


Let's analyze the result of execution:

9174 283
We manage to generate 9174 requests per second, and the polled device manages to process requests at a speed of 283 requests per second. It does not have time to respond to most of the requests (accordingly, “Timeout exceeded” messages remain in the log). Of course, this will not be a problem when we start polling a large number of devices with a reasonable interval between requests.

We go further

We have learned how to get the values ​​of scalar variables via SNMP. But, in addition to them, SNMP also has tables (for example, a table of interfaces on a device). How are they arranged? Let's see the MIB browser:

In OID mgmt.interfaces (1.3.6.1.2.1.2) we see a scalar variable ifNumber (1.3.6.1.2.1.2.1) containing the number of interfaces in the table, as well as a set of columns. Each of the columns has its own OID. For example, the column containing the numeric index ifIndex of the interface has OID = 1.3.6.1.2.1.2.2.1.1.

In order to get the value of this variable, you need to add the interface index to the OID (for example, for an interface with index 123, OID = 1.3.6.1.2.1.2.2.1.1.123). But how do we get interface indexes? They don't have to be in order! For example, on my machine, the interface table looks like this:

It is for this purpose that the GETNEXT query was invented. By passing the OID prefix to this request, we get the OID and the value of the next (in lexicographical order) variable following this prefix. This means that by passing the prefixes of the OIDs of the columns of the table, we will get the OIDs and values ​​of its first row. To get the next row, you need to execute another request, passing the OIDs received by the previous request into it. And so on until we look at the entire table.

Of course, taking into account all the above, we should minimize the number of requests (this is also necessary, taking into account the fact that within one request, according to the RFC, consistent data is provided, if we request the index and interface name in two consecutive requests, they may not correspond each other). As part of the 1st version of SNMP, we must read the entire row of the table in one request.

It should be noted that it is quite convenient that the OIDs of scalar variables are also prefixes. For example, for the sysUpTime OID variable, it is actually 1.3.6.1.2.1.1.3. We can pass it to a GETNEXT request and get OID = 1.3.6.1.2.1.1.3.0 along with the corresponding value. This makes it possible to query scalar values ​​along with table column values ​​in a single query.

Viewing the first row of a table

package com.acme.ae.tests.snmp; import java.io.IOException; import java.util.HashSet; import java.util.Set; import org.snmp4j.CommunityTarget; import org.snmp4j.PDU; import org.snmp4j.snmp; import org.snmp4j.Target; import org.snmp4j.TransportMapping; import org.snmp4j.event.ResponseEvent; import org.snmp4j.event.ResponseListener; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.Integer32; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultUdpTransportMapping; public class Test implements ResponseListener ( private final static String SNMP_COMMUNITY = "public"; private final static int SNMP_RETRIES = 3; private final static long SNMP_TIMEOUT = 1000L; private Snmp snmp = null; private TransportMapping transport = null; private Set requests = new HashSet (); public void onResponse(ResponseEvent event) ( Integer32 requestId = event.getRequest().getRequestID(); PDU response = event.getResponse(); if (response != null) ( System.out.println(response.toString()) ; return; ) else ( synchronized (requests) ( if (requests.contains(requestId)) ( System.out.println("Timeout exceeded"); ) ) ) synchronized (requests) ( requests.remove(requestId); ) ) private void test() throws IOException ( Target t = getTarget("udp:127.0.0.1/161"); send(t, new String ("1.3.6.1.2.1.1.3", "1.3.6.1.2.1.2.2. 1.1", "1.3.6.1.2.1.2.2.1.2")); ) private void send(Target target, String oids) throws IOException ( PDU pdu = new PDU(); for (String oid: oids) ( pdu.add (new VariableBinding(new OID(oid))); ) pdu.setType(PDU.GETNEXT); ResponseEvent event = snmp.send(pdu, target, null); synchronized (requests) ( requests.add(pdu.getRequestID() ); ) onResponse(event); ) private Target getTarget(String address) ( Address targetAddress = GenericAddress.pars e(address); CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString(SNMP_COMMUNITY)); target.setAddress(targetAddress); target.setRetries(SNMP_RETRIES); target.setTimeout(SNMP_TIMEOUT); target.setVersion(SnmpConstants.version1); return target; ) private void start() throws IOException ( transport = new DefaultUdpTransportMapping(); snmp = new Snmp(transport); transport.listen(); ) private void stop() throws IOException ( try ( if (transport != null) ( transport .close(); transport = null; ) ) finally ( if (snmp != null) ( snmp.close(); snmp = null; ) ) ) public static void main(String args) ( Test t = new Test() ; try ( try ( t.start(); t.test(); ) finally ( t.stop(); ) ) catch (IOException e) ( System.out.println(e.toString()); ) ) )


Running this code for execution, we will get the following response:

RESPONSE]
We got the uptime value, the index of the first interface, and its name, encoded as a hexadecimal octet string. In order to get the next rows, we must execute successive requests, passing the previously obtained OIDs.

Given the need to support the possibility of asynchronous processing, this can become a non-trivial (but quite solvable) task. Fortunately, bulk requests were added in SNMP version 2, which automates the fetching of tabular data and minimizes the number of requests sent. Let's make the necessary changes to the code:

BULK request

package com.acme.ae.tests.snmp; import java.io.IOException; import java.util.HashSet; import java.util.Set; import org.snmp4j.CommunityTarget; import org.snmp4j.PDU; import org.snmp4j.snmp; import org.snmp4j.Target; import org.snmp4j.TransportMapping; import org.snmp4j.event.ResponseEvent; import org.snmp4j.event.ResponseListener; import org.snmp4j.mp.SnmpConstants; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.Integer32; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultUdpTransportMapping; public class Test implements ResponseListener ( private final static String SNMP_COMMUNITY = "public"; private final static int SNMP_RETRIES = 3; private final static long SNMP_TIMEOUT = 1000L; private final static int BULK_SIZE = 50; private Snmp snmp = null; private TransportMapping transport = null;private Set requests = new HashSet (); public void onResponse(ResponseEvent event) ( Integer32 requestId = event.getRequest().getRequestID(); PDU response = event.getResponse(); if (response != null) ( System.out.println(response.toString()) ; return; ) else ( synchronized (requests) ( if (requests.contains(requestId)) ( System.out.println("Timeout exceeded"); ) ) ) synchronized (requests) ( requests.remove(requestId); ) ) private void test() throws IOException ( Target t = getTarget("udp:127.0.0.1/161"); send(t, new String ("1.3.6.1.2.1.1.3", "1.3.6.1.2.1.2.2. 1.1", "1.3.6.1.2.1.2.2.1.2")); ) private void send(Target target, String oids) throws IOException ( PDU pdu = new PDU(); for (String oid: oids) ( pdu.add (new VariableBinding(new OID(oid))); ) pdu.setType(PDU.GETBULK); pdu.setMaxRepetitions(BULK_SIZE); pdu.setNonRepeaters(1); ResponseEvent event = snmp.send(pdu, target, null); synchronized (requests) ( requests.add(pdu.getRequestID()); ) onResponse(event); ) private Target getTarget(St ring address) ( Address targetAddress = GenericAddress.parse(address); CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString(SNMP_COMMUNITY)); target.setAddress(targetAddress); target.setRetries(SNMP_RETRIES); target.setTimeout(SNMP_TIMEOUT); target.setVersion(SnmpConstants.version2c); return target; ) private void start() throws IOException ( transport = new DefaultUdpTransportMapping(); snmp = new Snmp(transport); transport.listen(); ) private void stop() throws IOException ( try ( if (transport != null) ( transport .close(); transport = null; ) ) finally ( if (snmp != null) ( snmp.close(); snmp = null; ) ) ) public static void main(String args) ( Test t = new Test() ; try ( try ( t.start(); t.test(); ) finally ( t.stop(); ) ) catch (IOException e) ( System.out.println(e.toString()); ) ) )


By executing this query, we get all the rows of the table in one query:

Lots of data

RESPONSE]


Of course, if the table contains more than the requested 50 rows, again (as for the 1st version of SNMP) it will be necessary to form requests to receive subsequent rows, passing in them the OIDs received for the last row.

What didn't I say?

In this article, I haven't covered much. I didn't talk about how to change the values ​​of some (not all) variables with SET statements. I did not talk about what TRAPs are and what they are for. I didn't say a word about how to develop SNMP agents. And I did not say a single word about the 3rd version of SNMP and the changes introduced to it.

But even what I said is enough to understand that SNMP is not easy.

Introduction

As the number of networks grows, networks are combined in various ways (routers from different vendors, hosts with built-in routing functions, terminal servers, and so on), the task of managing these systems becomes very important. This chapter discusses the standards that are used within the Internet protocol family to manage the network.

Network management in internetworked TCP/IP networks is based on the interaction between the network management station (manager) and network elements. Network elements can be any objects that use the TCP/IP protocol family: hosts, routers, X terminals, terminal servers, printers, and so on. Network elements must be running software called an agent. Control stations are usually workstations with a color monitor and a graphic display that display what is happening with the elements (which ones work and which do not, the amount of traffic on various channels per unit of time, and so on).

Communication is usually two-way: the manager asks the agent to tell him a certain value (for example, "how many ICMP port unreachable errors were generated?"), or the agent tells the manager about some important event ("the connected interface is down"). The manager should be able to set variables in the agent ("change the default TTL to 64"), in addition to being able to read variables from the agent.

TCP/IP network management consists of three parts.

  1. A Management Information Base (MIB) that specifies which variables in the network elements need to be maintained (information that can be requested and set by a manager). RFC 1213 defines a second version called MIB-II.
  2. Sets the general structure and identification scheme used to access variables in the MIB. This is called the Structure of Management Information (SMI) and is described in RFC 1155. For example, SMI specifies that Counter is a non-negative integer that goes from 0 to 4294967295 and then back to 0.
  3. The protocol that functions between the manager and the element is called the Simple Network Management Protocol (SNMP). RFC 1157 [Case et al. 1990] describes this protocol. It also describes in detail the format of the packages with which the exchange is carried out. Although different protocols can be used as transport protocols, UDP is usually used with SNMP.

These RFCs define what is currently called SNMPv1, or simply SNMP, which is what we will discuss in this chapter. During 1993, additional RFCs were published that describe SNMP Version 2 (SNMPv2), which we will describe in a section of this chapter.

In this chapter, we will look at the protocol that is used to communicate between the manager and the client, first, and then we will see what variables the agent uses. We will describe the information database maintained by the agent (MIB), consider the groups that we have already described in the text: IP, UDP, TCP, and so on. Let's look at examples corresponding to each description, and as we go along, we'll refer to the concept of the protocols described in the previous chapters.

Protocol

SNMP defines a total of five types of messages that are exchanged between a manager and a client.

Get the value of one or more variables: get-request statement. Get the next variable after this or more specified variables: get-next-request statement. (We'll describe what we mean by "next" later in this chapter.) Set the value of one or more variables: the set-request statement. Return the value of one or more variables: get-response statement. This message is returned by the agent to the manager in response to the get-request, get-next-request, and set-request statements. Notify the manager when something has happened to the agent: trap statement.

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

Since four out of five SNMP messages are implemented in a simple request-response sequence (the manager sends a request and the agent returns a response), SNMP uses UDP. This means that a request from the manager may not arrive at the agent, and a response from the agent may not arrive at the manager. In this case, the manager may time out and retransmit.

Figure 25.1 Five SNMP operators.

The manager sends these three requests to UDP port 161. The agent sends traps to UDP port 162. Since two different ports are used, one system can act as manager and agent at the same time. (See at the end of the chapter.)

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

Figure 25.2 Format of five SNMP messages.

In this figure, we have indicated in bytes only the size of the IP and UDP headers. This is because SNMP messages use an encoding - called ASN.1 and BER, which we will describe later in this chapter - depending on the type of variables and their values.

The value of the version field is 0. This value is actually the version number minus one. (The version of SNMP we're describing is called SNMPv1.)

Figure 25.3 shows the value for the PDU type. (A PDU is a Protocol Data Unit, commonly referred to as a "packet".)

get request
get-next-request
set request
get-response
trap

Figure 25.3 SNMP message PDU types.

Community (community) is a character string that contains the password in clear text. The password is used when communicating between the manager and the agent. The usual value is the 6-character public string.

In the get, get-next, and set statements, the manager sets the request ID, which is returned by the agent in the get-response message. We have seen this type of variable in other UDP applications. (Remember the DNS identification field on and the transaction ID field on .) This allows the client (the manager in this case) to match responses from the server (agent) with requests that were sent by the client. This field also allows the manager to issue multiple requests to one or more agents and then sort the responses received.

The error status is an integer returned to agents indicating an error. Figure 25.4 shows the meanings, names, and descriptions of the errors.

error status

Description

noError everything is fine
too Big client cannot fit response into one SNMP message
noSuchName operator points to a non-existent variable
badValue an invalid value was used in the setup operation or a syntax error was made
readOnly the manager tried to change a variable that is marked read-only
genErr unidentified error

Figure 25.4 SNMP error status values.

If an error occurs, the error index is an integer offset indicating which variable the error occurred in. This value is set by the agent only for noSuchName (no such name), badValue (invalid value), and readOnly (read-only) errors.

The list of variable names and values ​​follows in get, get-next and set requests. The value section is ignored in the get and get-next statements.

For a trap statement (PDU type is 4), the format of the SNMP message is changed. We will describe the trap header fields when we describe this operator in a section of this chapter.

Control information structure

SNMP uses a small number of different data types. In this chapter, we will look at these types, but we will not look at how this data is actually encoded (bit patterns are used to store data).

  • INTEGER (integer). Some variables are declared as integers with no restrictions (for example, the MTU for an interface), some are defined with specific values ​​(for example, the IP redirect flag is set to 1 if redirect is enabled, or 2 if redirect is disabled), and others are defined with their minimum values. and maximum values ​​(for example, TCP and UDP port numbers range from 0 to 65535).
  • OCTET STRING (octal string). A string of 0 or more 8-bit bytes. Each byte has a value between 0 and 255. In the BER encoding used for these data types and for the next one, the count of the number of bytes per line is before the line itself. These strings are not null-terminated.
  • DisplayString. A string of 0 or more 8-bit bytes, each byte must be a character from the ASCII NVT set. All variables of this type in MIB-II must contain no more than 255 characters. (A string of zero length is acceptable.)
  • OBJECT IDENTIFIER (object identifier). We will describe them in the next section.
  • NULL (zero). Means that the corresponding variable has no value. Used, for example, as all values ​​for variables in get or get-next requests, as long as those variables are requested and not set.
  • IpAddress (IP address). OCTET STRING (octal string) of length 4, with 1 byte per byte of the IP address.
  • PhysAddress (physical address). OCTET STRING (octal string), contains the physical address (for example, a 6-byte Ethernet address).
  • Counter (counter). A non-negative integer whose value increases monotonically from 0 to 232-1 (4.294.967.295) and then back to 0.
  • Gauge (criteria). A non-negative integer between 0 and 232-1 that can increase or decrease in value, but stop changing when the maximum value is reached. This means that if the value reaches 232-1, the criterion will remain at that value until it is reset. An example is the tcpCurrEstab MIB variable: this is the number of TCP connections currently in the ESTABLISHED (established) or CLOSE_WAIT (waiting to close) state.
  • TimeTicks (time ticks). A counter that counts time in hundredths of a second from some starting point. Different variables may indicate the start of counting from different starting points, the starting point used for each variable of that type and is specified when the variable is declared in the MIB. For example, the sysUpTime variable is the number of hundredths of a second the agent has been up.
  • SEQUENCE (sequence). Reminiscent of a structure in the C programming language. For example, we will look at how a sequence (SEQUENCE) is defined in the MIB, which is called UdpEntry and which contains information about the activity of UDP agent endpoints. (By activity, we mean the ports that the application is currently using.) There are two entries in this structure:
  1. udpLocalAddress, of type IpAddress, containing the local IP address.
  2. udpLocalPort, of type INTEGER, in the range 0 to 65535, which contains the local port number.
  • SEQUENCE OF (sequence of what). This is the definition of a vector with all elements that are of the same data type. If each element is of a simple data type, such as an integer, we have a simple vector (one-dimensional array). However, we will see that SNMP uses these data types with each element of the vector, which is a SEQUENCE (struct). Therefore, we can think of them as two-dimensional arrays or a table. For example, the UDP listener table is called udpTable, and is a SEQUENCE OF of the 2-element UdpEntry structure we just described. Figure 25.5 shows a two-dimensional array.

Figure 25.5 The UDP listener table (udpTable), which is represented as a two-dimensional SNMP array.

The number of rows in this table is not determined by SNMP, but we will see that the manager, using the get-next statement (section of this chapter), can determine that the last row of the table has been received. Also, in the section we will see how the manager specifies which row of the table he wants to get or set.

Object IDs

An object identifier is a data type that points to an authoritatively named object. By "authorized" we mean that these identifiers are not assigned randomly, but are assigned by some organization that is responsible for a group of identifiers.

The object identifier is a sequence of integer decimal numbers separated by dots. These integers are in a tree structure, reminiscent of DNS() or the Unix file system. At the top where the object identifier tree starts, there is an unnamed root.

Figure 25.6 shows the tree structure. All variables in the MIB start with the object identifier 1.3.6.1.2.1.

Each node in the tree also has a text name. The name corresponding to object identifier 1.3.6.1.2.1 is iso.org.dod.internet.mgmt.mib. This form of writing names is used for readability. The MIB variable names used in the exchange of packets between the manager and the agent (Figure 25.2) are numeric object identifiers starting with 1.3.6.1.2.1.

Figure 25.6 Object identifiers in the management infobase.

In addition to the mib IDs shown in Figure 25.6, we have also provided another iso.org.dod.internet.private.enterprises (1.3.5.1.4.1). This location hosts MIBs from various manufacturers. The Assigned Numbers RFC lists about 400 identifiers registered below this node.

Introduction to the Management Information Base (MIB)

Management Information Base (MIB - Management Information Base) is an information database that is maintained by the agent, and the manager can request information from this database or write information to this database. We will look at what is called MIB-II and is described in RFC 1213.

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

In this section, we will only describe the variables that are in the UDP group. This is a simple group with few variables and one table. In the following sections, using this group as an example, we will show how identification is carried out, the construction of a lexicographic order, and some simple examples of these characteristics. After that, in section , we will return to the MIB and describe some of the other groups in the MIB.

In Figure 25.6 we have shown a group called udp below the mib. Figure 25.7 shows the structure of a UDP group.

Figure 25.7 Tree structure of the IP address table.

As we said earlier, the UDP group contains four variables, and one table of two variables. Figure 25.8 shows four variables.

Data type

Description

udpInDatagrams Counter The number of UDP datagrams delivered to user processes.
udpNoPorts Counter The number of delivered UDP datagrams that did not have a user process on the destination port.
udpInErrors Counter The number of undelivered UDP datagrams not due to no application on the destination port (for example, a UDP checksum error).
udpOutDatagrams Counter The number of UDP datagrams sent.

Figure 25.8 Variables in the udp group.

We will use this format when describing all MIB variables in this chapter. The column labeled "R/W" is empty if the variable is read-only, or contains a dot (face=Symbol>·) if the variable is read-write. We will always include this column, even if all variables in the group are read-only (as we saw in the udp group), to remind you that none of the variables can be set by the manager. In case the data type is INTEGER (integer) with a limit, we will indicate the upper and lower limits, as is done for the UDP port number in the following figure.

Figure 25.9 describes two variables in udpTable.

Figure 25.9 Variables in udpTable.

Whenever we declare variables in an SNMP table, the first row of the figure contains the "index" value used to refer to each row in the table. We will show some examples of how this is done in the next section.

Dependency Diagrams

Here is the relationship between the first three counters described in Figure 25.8. Dependency diagrams illustrate the relationship between different MIB variables in a given group. Figure 25.10 shows a dependency diagram for a UDP group.

Figure 25.10 Dependency diagram for UDP group.

This chart shows that the number of UDP datagrams delivered to an application (udpInDatagrams) can be obtained as the number of UDP datagrams delivered from IP to UDP, minus udpInErrors, minus udpNoPorts. The number of UDP datagrams delivered to IP (udpOutDatagrams) is the number sent in UDP from the application. It can be deduced that udpInDatagrams does not include udpInErrors or udpNoPorts.

These diagrams were used during the MIB development process to verify that all data paths for a packet were taken into account. [Rose 1994] shows dependency diagrams for all groups in the MIB.

Identification examples

Each variable in the MIB must be identified when SNMP accesses it to get or set its value. First, only leaf nodes are accessed (a leaf node in a tree structure is any element farthest from the root). SNMP does not work with entire rows or columns in a table. Returning to Figure 25.7, we see that the leaf nodes of the tree are the four we described in Figure 25.8 and the two in Figure 25.9. The mib, udp, udpTable, and udpEntry nodes are not leaf nodes.

Simple Variables

That this variable is simple is indicated by ".0" appended to the variable's object identifier. For example, the counter udpInDatagrams shown in Figure 25.8, with object ID 1.3.6.1.2.1.7.1, can be accessed as 1.3.6.1.2.1.7.1.0. The text name for such a call will be iso.org.dod.internet.mgmt.mib.udp.udpInDatagrams.0.

However, references to this variable are usually made in the abbreviated form, udpInDatagrams.0, we will 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.

Consider the identification of table items in more detail. Let's go back to the UDP listening process table (Figure 25.7).

Each table in the MIB has one or more indexes. For the UDP listening process table, the MIB defines an index as a combination of two variables udpLocalAddress (local IP address) and udpLocalPort (local UDP port), the index in this case is an integer. (We have shown this index in the top row in Figure 25.9.)

Imagine that there are three rows in the table of a UDP listening process: the first 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.

Figure 25.11 A simple UDP listener process table.

The table shows that the system is ready to receive UDP datagrams from any interface for ports 67 (BOOTP server), 161 (SNMP) and 520 (RIP). Three rows in the table can be accessed as shown in figure 25.12.

Lexicographic order

The order in the MIB is based on the location of the object identifiers. All entries in the MIB table are arranged lexicographically according to their object identifiers. This means that the six variables shown in Figure 25.12 are arranged in the MIB as shown in Figure 25.13. As a result, two rules can be declared.

Row (row)

Object ID

Short name

Meaning


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

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
1.3.6.1.2.1.7.5.1.1.0.0.0.0.520
udpLocalAddress.0.0.0.0.520
udpLocalPort.0.0.0.0.520

Figure 25.12 An example of identifying rows in a UDP listening process table.

Object identifier (in lexicographical order)

Short name

Meaning

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

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 table order of the UDP listening process.

  1. Since the udpLocalAddress variable always appears before the next variable (udpLocalPort) appears in the same table, this means that the table is accessed in column-row order. This is the result of the lexicographic ordering of object identifiers, not human-readable names.
  2. The order in which rows appear in a table depends on the index values ​​for the table. In Figure 25.13, 67 is lexicographically less than 161, which in turn is lexicographically less than 520.

Figure 25.14 shows the row-column order for our example UDP listener table.

Figure 25.14 UDP listening process table, shown in column-by-row order.

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

Simple examples

In this chapter, we will show some simple examples of how you can get variable values ​​from an SNMP agent. The software used to interrogate the agent is called snmpi and is taken from the ISODE system. Both are briefly described in [Rose 1994].

Simple Variables

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

sun % snmpi -a gateway -c secret

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

snmpi> quit

The -a option specifies the agent we want to talk to, and the -c option specifies the SNMP community. This is a password set by the client (snmpi in this case) and if the server (the agent on the gateway system) recognizes the community name, it will respond to the manager's request. An agent can allow clients belonging to one community to read-only its variables, while clients from another community can be read-write.

The program displays the snmpi> prompt, after which we can, for example, enter the get command, which will be converted into an SNMP get-request message. We then type quit. (In all the following examples, the last quit command is removed.) Figure 25.15 shows two lines of tcpdump output for this example.

1 0.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

2 0.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 a simple SNMP request.

The request for two variables is sent in one UDP datagram, the response also arrives in one UDP datagram.

We have shown the variables as their respective object IDs because that is what was sent in the SNMP messages. We had to specify these two variables as 0. Note that the name of the variable (object identifier) ​​is always returned in the response. We'll see below that this is necessary for the get-next operator to work.

get-next operator

The operation of the get-next operator is based on the MIB lexicographic order. We'll start the next example by asking for the next object ID after udp (without specifying an object, since it's not a leaf object). This will return the first UDP group object. We then request the next record, the second record will be returned. And finally, we repeat this one more time to get the third entry:

sun % snmpi -a gateway -c secret

snmpi> next udp
udpInDatagrams.0=616318

snmpi> next udpInDatagrams.0
udpNoPorts.0=33

snmpi> next udpNoPorts.0
udpInErrors.0=0

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

When using the get-next operator, the manager performs a cyclic poll of all variables supported by the agent (the cycle starts from the beginning of the MIB). Another use of this operator is to look up tables.

Table Access

We can verify that the table is column-row organized by using the program that sends queries to traverse the table of the UDP listening process. We'll start by asking for the next variable after udpTable. Since it's not a leaf object, we can't specify the object, but the get-next statement still returns the next object in the table. We then continue moving through the table as the agent returns the following 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.520=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 here we have finished looking up the table of the UDP listening process

We see that the order returned in this example matches the order shown in Figure 25.14.

How can a manager determine that he has reached the end of the table? Since the response to the get-next statement contains the name of the next item in the MIB after the table, the manager can tell when the name has changed. In our example, the last entry in the UDP listener table follows the snmpInPkts variable.

Management Information Base (continued)

And now we will return to the description of MIB. Let's describe the following groups: system (system identification), if (interfaces), at (address translation), ip, icmp and tcp. Additional groups are also defined.

system group

The system group is fairly simple; it consists of seven simple variables (there are no tables in this group). Figure 25.16 shows their names, data types, and descriptions.

Data type

Description

sysDescr DisplayString Text description of the item.
sysObjectID Object ID Vendor ID in subtree 1.3.6.1.4.1.
sysUpTime TimeTicks Time in hundredths of seconds since the part of the system responsible for network management was restarted.
sysContact DisplayString The name of the person to contact and how to find them.
sysname DisplayString The host's fully qualified domain name (FQDN).
sysLocation DisplayString The physical location of the node.
sysServices A value indicating which services are provided by the node. This is the sum of the OSI model layers supported by the node. The following values ​​are added together depending on which services are supported: 0x01 (physical), 0x02 (link), 0x04 (network), 0x08 (point-to-point), 0x40 (application).

Figure 25.16 Simple variables of the system group.

We can query the netb router to get some of these variables:

sun % snmpi -a netb -c secret

snmpi> get sysDescr.0 sysObjectID.0 sysUpTime.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

The system object ID is in the internet.private.enterprises group (1.3.6.1.4.1), as shown in Figure 25.6. From the Assigned Numbers RFC, we can determine that the following object ID (12) is assigned to the manufacturer (Epilogue).

We can also see that the sysServices variable is the sum of 4 and 8: this network element (netb) supports the IP layer (routing) and the transport layer (point to point).

interface group

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

Figure 25.17 A simple variable in the if group.

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

Interface table, index =< IfIndex >

Data type

Description

ifIndex INTEGER Interface index, ranges between one and ifNumber.
ifDescr DisplayString Text description of the interface.
ifType INTEGER Type, for example: 6 = Ethernet, 7 = 802.3 Ethernet, 9 = 802.5 Token ring, 23 = PPP, 28 = SLIP and many other variables.
ifMtu INTEGER Interface MTU (Maximum Transmission Unit).
ifSpeed gauge Speed ​​in bits per second.
ifPhysAddress PhysAddress Physical address or zero-length string for interfaces without a physical address (for example, serial links).
ifAdminStatus Desired interface state: 1=active, 2=off, 3=testing.
ifOperStatus The current state of the interface is: 1=active, 2=off, 3=testing.
ifLastChange TimeTicks The value of sysUpTime at the time the interface entered the current state of operation.
ifInOctets Counter The total number of bytes received, including framing characters.
ifInUcastPkts Counter The number of personal packages delivered to upper levels.
ifInNUcastPkts Counter The number of non-personal (broadcast or multicast) packets delivered to upper layers.
ifInDiscards Counter The number of packets received and dropped, even if no error (buffer overflow) was detected in the packet.
ifInErrors Counter The number of packets received and dropped due to errors.
ifInUnknownProtos Counter The number of packets received and dropped because they belonged to an unknown protocol.
ifOutOctets Counter The number of bytes transferred, including framing characters.
ifOutUcastPkts Counter The number of private packets received from upper layers.
ifOutNUcastPkts Counter The number of non-personal (broadcast or multicast) packets received from upper layers.
ifOutDiscards Counter The number of outgoing packets that were dropped, even if no error (buffer overflow) was detected in the packets.
ifOutErrors Counter The number of outgoing packets dropped due to errors.
ifOutQLen gauge The number of packets in the output queue.
ifSpecific Object ID A reference to the MIB definition specifically for that media type.

Figure 25.18 Variables in the interface table: ifTable.

We can query host sun for some of these variables for all of its interfaces. We expect to see three interfaces (see Chapter 3, section ) if the SLIP interface is enabled:

sun % snmpi -a sun

snmpi> next ifTable first, we see what the index of the first interface is
ifIndex.1=1

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

snmpi> next ifDescr.1 ifType.1 ifMtu.1 ifSpeed.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 ifSpeed.2 ifPhysAddress.2
ifDescr.3="lo0"
ifType.3=softwareLoopback(24)
ifMtu.3=1536
ifSpeed.3=0
ifPhysAddress.3=0x00:00:00:00:00:00

First, we got the five variables for the first interface using the get statement, and then we got the same five variables for the second interface using the get-next statement. The last command gets the same five variables for the third interface, again using the get-next command.

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

It is very important to understand the relationship between the get-next operator and the row-column order of information in a table. When we specify next ifDescr.1, the next row in the table for that variable is returned, not the next variable on the same row. However, if the tables were stored in row-column order, we could similarly jump to the next occurrence of the given variable.

at group

The address translation group is supported on all systems, but its value has been greatly reduced by the introduction of MIB-II. With MIB-II, each group of network protocols (such as IP) maintains its own address translation table. For IP, this is ipNetToMediaTable.

Within the at group, only one table of three rows is defined, as shown in Figure 25.19.

We can use the new command that exists in the snmpi program to get the contents of the table as a whole. We will ask the router named kinetics (which provides routes between the TCP/IP network and the AppleTalk network) to issue a full ARP cache. This output will be in lexicographic order as the items in the table:

Address translation table, index = .1.

Data type

Description

atIfIndex INTEGER Interface number: ifIndex.
atPhysAddress PhysAddress Physical adress. Setting this parameter to a zero-length string causes the item to be considered invalid.
atNetAddress NetworkAddress IP address

Figure 25.19 Address translation table: atTable.

sun % snmpi -a kinetics -c secret dump at

atIfIndex.1.1.140.252.1.4=1
atIfIndex.1.1.140.252.1.22=1
atIfIndex.1.1.140.252.1.183=1
atIfIndex.2.1.140.252.6.4=2
atIfIndex.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

Using tcpdump you can see the following. To get the complete table, snmpi first issues get-next on the table name (at in this example) to get the first item. It then prints the first item and issues get-next. This continues until the entire table has been retrieved.

Figure 25.20 shows such a table.

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

Figure 25.20 An example of an at table (ARP cache).

AppleTalk physical addresses with an interface number of 2 have 32-bit values ​​instead of the 48-bit ones found in traditional Ethernet addresses. Also note that there is an entry for our router (netb is at 140.252.1.183) because kinetics and netb are on the same Ethernet cable (140.252.1) and kinetics must use ARP to send us SNMP response.

ip group

The ip group defines a large number of variables and three tables. Figure 25.21 shows simple variables.

Data type

Description

ipForwarding 1 means the system is forwarding the IP datagram, and 2 means it is not forwarding.
ipDefaultTTL INTEGER The default TTL value when the transport layer does not provide one.
ipInReceives Counter Total number of IP datagrams received from all interfaces.
ipInHdrErrors Counter The number of IP datagrams discarded due to header errors (for example, checksum error, version number mismatch, TTL expiration, and so on).
ipInAddrErrors Counter Number of IP datagrams discarded due to bad destination address.
IpForwDatagrams Counter The number of IP datagrams for which an attempt was made to redirect.
ipInUnknownProtos Counter The number of locally addressed IP datagrams that had an invalid protocol field.
ipInDiscards Counter Number of received IP datagrams discarded due to insufficient buffer size.
ipInDelivers Counter The number of IP datagrams delivered to the corresponding protocol module.
ipOutRequests Counter The total number of IP datagrams sent to the IP layer for transmission. This does not include those that were counted in ipForwDatagrams.
ipOutDiscards Counter The number of outgoing IP datagrams that were discarded due to lack of buffer space.
ipOutNoRoutes Counter The number of IP datagrams that were dropped because no route was found.
ipReasmTimeout INTEGER The maximum number of seconds that received fragments wait to be reassembled.
ipReasmReqds Counter The number of received IP fragments to be collected.
ipReasmOKs Counter The number of successfully collected IP datagrams.
ipReasmFails Counter Number of failures in the IP reassembly algorithm.
ipFragOKs Counter The number of successfully fragmented IP datagrams.
ipFragFails Counter The number of IP datagrams to be fragmented, but this was not done because the "don't fragment" flag was set.
ipFragCreates Counter The number of IP fragments that were received during fragmentation.
ipRoutingDiscards Counter The number of routing points selected for destruction, even if they existed and were correct.

Figure 25.21 Simple ip group variables.

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

Table of IP addresses, index =

Data type

Description

ipAdEntAddr IpAddress The IP address for this line.
ipAdEntIfIndex INTEGER Corresponding interface number: ifIndex.
ipAdEntNetMask IpAddress The subnet mask for this IP address.
ipAdEntBcastAddr The value of the least significant bits in the broadcast IP address. Usually equal to 1.
ipAdEntReasmMaxSize Size of the maximum received IP datagram for this interface that can be reassembled.

Figure 25.22 IP address table: ipAddrTable.

We can query host sun to get a table of IP addresses:

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 loopback interface, lo0
ipAdEntIfIndex.140.252.1.29=2 SLIP interface, sl0
ipAdEntIfIndex.140.252.13.33=1 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 all three use the 1 bit
ipAdEntBcastAddr.140.252.1.29=1 for broadcast address
ipAdEntBcastAddr.140.252.13.33=1

ipAdEntReasmMaxSize.127.0.0.1=65535
ipAdEntReasmMaxSize.140.252.1.29=65535
ipAdEntReasmMaxSize.140.252.13.33=65535

The interface numbers can be compared to the output in Figure 25.18, and the IP addresses and subnet masks can be compared to the values ​​obtained from the output of the ifconfig command in section Chapter 3.

The next table, shown in Figure 25.23, is the IP routing table. (Refer to the description of routing tables in the section in Chapter 9.) The destination IP address is used as an index to access each row in the table.

Figure 25.24 shows the routing table for host sun obtained using snmpi's dump ipRouteTable command. We've removed all five routing metrics since they're all -1, and we've removed the ipRoute prefix for each variable name in the column headings.

IP routing table, index =

Data type

Description

ipRouteDest IpAddress Destination IP address. The value 0.0.0.0 indicates the default item.
ipRouteIfIndex INTEGER Interface number: ifIndex.
ipRouteMetric1 INTEGER The primary indicator of the route. The value of the indicator depends on the routing protocol (ipRouteProto). A value of -1 means that the route is not used.
ipRouteMetric2 INTEGER
ipRouteMetric3 INTEGER Alternative route indicator.
ipRouteMetric4 INTEGER Alternative route indicator.
ipRouteNextHop IpAddress The IP address of the next hop router.
ipRouteType INTEGER Route type: 1=other, 2=inactive route, 3=direct, 4=indirect.
ipRouteProto INTEGER Routing protocol: 1=other, 4=ICMP redirect, 8=RIP, 13=OSPF, 14=BGP and others.
ipRouteAge INTEGER The number of seconds that have passed since the route was last updated or determined to be correct.
ipRouteMask IpAddress A mask that must be logically ANDed to the destination IP address before it is compared to ipRouteDest.
ipRouteMetric5 INTEGER Alternative route indicator.
ipRouteInfo Object ID A reference to a specific MIB definition for this routing protocol.

Figure 25.23 IP Routing Table: ipRouteTable.

0.0.0.0 140.252.1.183

indirect (4)

other (1)

0.0.0.0
127.0.0.1 127.0.0.1

straight (3)

other (1)

255.255.255.255
140.252.1.183 140.252.1.29

straight (3)

other (1)

255.255.255.255
140.252.13.32 140.252.13.33

straight (3)

other (1)

255.255.0.0
140.252.13.65 140.252.13.35

indirect (4)

other (1)

255.255.255.255

Figure 25.24 IP routing table of sun router.

For comparison, here is the IP routing table in the output format of the netstat command (see Chapter 9, section ). In Figure 25.24, the routing table is listed in lexicographical order:

sun % netstat -rn
Routing tables
Destination Gateway Flags Refcnt Use Interface
140.252.13.65 140.252.13.35 UGH 0 115 le0
127.0.0.1 127.0.0.1 UH 1 1107 lo0
140.252.1.183 140.252.1.29 UH 0 86 sl0
default 140.252.1.183 UG 2 1628 sl0
140.252.13.32 140.252.13.33 U 8 68359 le0

And the last table for the ip group is the address translation table shown in Figure 25.25. As we said before, the at group is now largely obsolete (obsolete), and this table replaces it.

IP address translation table, index = .

Name Data type Description
ipNetToMediaIfIndex INTEGER Corresponding interface: ifIndex.
ipNetToMediaPhysAddress PhysAddress Physical adress.
ipNetToMediaNetAddress IpAddress IP address.
ipNetToMediaType Mapping type: 1=other, 2=unused, 3=dynamic, 4=static.

Figure 25.25 IP address translation table: ipNetToMediaTable.

Here we show sun's ARP cache:

Face="Courier New" size=1>

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:

Face="Courier New" size=1>

sun % snmpi -a sun dump ipNetToMediaTable

IpNetToMediaIfIndex.1.140.252.13.34=1
ipNetToMediaIfIndex.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)

icmp group

The icmp group consists of four general counters (the total number of incoming and outgoing ICMP messages and the number of incoming and outgoing ICMP error messages) and 22 counters for different types of ICMP messages: 11 counters for incoming messages and 11 counters for outgoing messages. This is shown in figure 25.26.

For ICMP messages with additional codes (refer to 15 different codes for reporting destination unreachable), a separate counter for each SNMP code is not supported.

tcp group

Figure 25.27 describes simple tcp group variables. Many of these correspond to the TCP states shown in .

Data type

Description

icmpInMsgs Counter The total number of received ICMP messages.
icmpInErrors Counter The number of received ICMP messages with errors (for example, an ICMP checksum error).
icmpInDestUnreaches Counter Number of received ICMP source unreachable messages.
icmpInTimeExcds Counter The number of received ICMP timeout messages.
icmpInParmProbs Counter The number of received ICMP parameter problem messages.
icmpInSrcQuenchs Counter The number of ICMP source suppression messages received.
icmpInRedirects Counter The number of ICMP redirect messages received.
icmpInEchos Counter The number of received ICMP echo request messages.
icmpInEchoReps Counter The number of received ICMP messages with an echo response.
icmpInTimestamps Counter The number of received ICMP timestamp request messages.
icmpInTimestampReps Counter The number of timestamped ICMP messages received.
icmpInAddrMasks Counter The number of received ICMP messages requesting an address mask.
icmpInAddrMaskReps Counter The number of ICMP messages received with an address mask response.
icmpOutMsgs Counter The total number of outgoing ICMP messages.
icmpOutErrors Counter The number of ICMP messages that were not sent due to problems within ICMP (buffer overflows).
icmpOutDestUnreaches Counter The number of ICMP destination unreachable messages sent.
icmpOutTimeExcds Counter The number of ICMP timeout messages sent.
icmpOutParmProbs Counter The number of ICMP messages sent about parameter problems.
icmpOutSrcQuenchs Counter The number of ICMP source suppression messages sent.
icmpOutRedirects Counter The number of ICMP redirect messages sent.
icmpOutEchos Counter The number of ICMP echo request messages sent.
icmpOutEchoReps Counter The number of ICMP echo response messages sent.
icmpOutTimestamps Counter The number of ICMP messages sent requesting a timestamp.
icmpOutTimestampReps Counter The number of timestamped ICMP messages sent.
icmpOutAddrMasks Counter The number of ICMP messages sent requesting an address mask.
icmpOutAddrMaskReps Counter The number of ICMP messages sent with an address mask response.

Figure 25.26 Simple icmp group variables.

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

Face="Courier New" size=1>

sun % snmpi -a sun

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

SunOS 4.1.3 uses the timeout and retransmission algorithm developed by Van Jacobson, with timeouts used ranging from 200 milliseconds to 12.8 seconds, and there is no fixed limit on the number of TCP connections. (The upper limit of the range of 12.8 seconds is incorrect, as most implementations use an upper limit of 64 seconds, as we saw in .)

The tcp group has one table, the TCP connection table shown in Figure 25.28. It contains one line for each connection. Each line contains five variables: connection state, local IP address, local port number, remote IP address, and remote port number.

Data type

Description

tcpRtoAlgorithm INTEGER Algorithm used to calculate timeouts and retransmissions: 1=none, 2=permanent RTO, 3=MIL-STD-1778(), 4=Van Jacobson algorithm.
tcpRtoMin INTEGER Minimum retransmission timeout value, in milliseconds.
tcpRtoMax INTEGER The maximum retransmission timeout value, in milliseconds.
tcpMaxConn INTEGER The maximum number of TCP connections. The value -1 means that this value is determined dynamically.
tcpActiveOpens Counter The number of transitions from the CLOSED state to the SYN_SENT state.
tcpPassiveOpens Counter The number of transitions from the LISTEN state to the SYN_RCVD state.
tcpAttemptFails Counter The number of transitions from the SYN_SENT or SYN_RCVD state to the CLOSED state, plus the number of transitions from the SYN_RCVD state to the LISTEN state.
tcpEstabResets Counter The number of transitions from the ESTABLISHED or CLOSE_WAIT state to the CLOSED state.
tcpCurrEstab gauge The number of connections currently in the ESTABLISHED or CLOSE_WAIT state.
tcpInSegs Counter The total number of received segments.
tcpOutSegs Counter The total number of segments sent, excluding those containing only retransmitted bytes.
tcpRetransSegs Counter The total number of retransmitted segments.
tcpInErrs Counter The total number of segments received with errors (for example, bad checksum).
tcpConnLocalAddress IpAddress Local IP address. 0.0.0.0 indicates that the listener is ready to accept a connection from any interface.
tcpConnLocalPort The local port number.
tcpConnRemAddress IpAddress Remote IP address.
tcpConnRemPort The remote port number.

Figure 25.28 TCP connection table: tcpConnTable.

Let's look at this table on the sun system. We've only shown part of the table because there are so many servers (listening processes in this case) listening for connection requests. Before getting the table, two TCP connections were established:

Face="Courier New" size=1>

sun % rlogin gemini face=Arial size=2>IP address of face="Courier New" size=2>gemini is 140.252.1.11

Face="Courier New" size=1>

sun % telnetlocalhost IP address should be 127.0.0.1

The only listening server, as we have shown, is the FTP server on port 21:

Face="Courier New" size=1>

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

tcpConnRemPort.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

There is only one entry for the rlogin command per gemini host, since gemini is a remote host. We only see the client side of the connection (local port 1023), however, both ends of the Telnet connection (client port 1415 and server port 23) are shown because the connection goes through the loopback interface. We can also see that the listening FTP server has a local IP address of 0.0.0.0, which indicates that it will accept a connection from any interface.

Additional examples

We'll now go back to some of the issues we covered earlier in this book and try to use SNMP to figure out what really happened.

Interface MTU

Let's return to our experiment described in the section of Chapter 11, in which we tried to determine the MTU of the SLIP link from netb to sun. Now we can use SNMP to get this MTU. First, we get the interface number (ipRouteIfIndex) for the SLIP link (140.252.1.29) from the IP routing table. To do this, we get into the interface table and get the MTU (along with the description and type) of the SLIP link:

Face="Courier New" size=1>

sun % snmpi -a netb -c secret

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

We can see that even for a link that is SLIP, the MTU is set to Ethernet to 1500, possibly to avoid fragmentation.

Routing tables

Let's go back to our discussion of address sorting performed by DNS in the section of Chapter 14. We showed how the first IP address returned by the DNS server was one on the same subnet as the client. We also mentioned that using a different IP address may well work, but it will be less efficient in that case. Let's see what happens when using an alternate IP address. We will use SNMP to look up entries in the routing table and try to combine together a few of the concepts we've covered in previous chapters that have to do with IP routing.

The gemini host has several interfaces, two of which are Ethernet interfaces. First, make sure we can get a Telnet connection to both addresses:

Face="Courier New" size=1>

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.

We see that there is no difference in connections between the two addresses. Now let's use traceroute to see if there are different routes to 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) 233ms 228ms 234ms

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) 245ms 212ms 234ms
2 swnrt (140.252.1.6) 233ms 229ms 234ms
3 gemini (140.252.3.54) 234ms 233ms 234ms

We see that when using the subnet address 140.252.3 there is an additional forwarding (the swnrt router is R3 on ). Let's see why this extra forwarding occurs.

Figure 25.29 shows the systems settings. Based on the output of the traceroute command, we can tell that the gemini host and the swnrt router are both connected to two networks: 140.252.1 and 140.252.3.

Figure 25.29 System topology used in the example.

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) 285ms 227ms 234ms
4 netb (140.252.1.183) 263ms 259ms 294ms
5 sun (140.252.13.33) 534ms 498ms 504ms

When loose source routing is used, the swnrt router never responds. If we look at the early output of the traceroute command, without source routing, we can see that swnrt is a second hop. The reason for this may be that the router does not generate ICMP timeout errors when the datagram is set to free source routing. We can see from this output of the traceroute command that the return path from gemini (TTL 3, 4, and 5) goes directly to netb instead of going through the swnrt router.

The question that SNMP should help us answer is what makes a routing table entry in netb such that the destination network is set to 140.252.3? The point is that netb sends packets to swnrt and not directly to gemini. We use the get command to get the value of the next hop router for this destination:

Face="Courier New" size=1>

sun % snmpi -a netb -c secret get ipRouteNextHop.140.252.3.0

IpRouteNextHop.140.252.3.0=140.252.1.6

The routing table entry tells netb to send packets to swnrt, which we see is happening.

Why is gemini sending packets back directly through netb? Because the destination address for packets coming back from gemini is set to 140.252.1.29 and the network 140.252.1 is directly connected.

What we see in this example is the result of policy decisions about routing. The default route to network 140.252.3 goes through the swnrt router because gemini is just a multi-interface host, not a router. This is just an example of a multi-interface host that doesn't want to be a router.

Traps

All the examples that we have considered in this chapter illustrate the transfer of information from a manager to an agent. However, there is a way for the agent to notify the manager that some event has occurred that the manager needs to know about (see Figure 25.1). In this case, the agent sends traps to the manager. Traps are sent to UDP port 162 of the manager.

In Figure 25.2, we have shown the format of the PDU trap. We will review all the fields in this message when we look at the output of the tcpdump command below.

Six traps are defined, the seventh is used by the manufacturer to set his own trap. Figure 25.30 describes the trap type values ​​in the trap message (Figure 25.2).

trap type

Description

0 coldStart The agent initialized itself.
1 warmStart The agent reinitialized itself.
2 linkDown The interface state changed from "enabled" to "disabled" (Figure 25.18). The first variable in the message points to the interface.
3 linkUp The interface state has changed from the "off" state to the "enabled" state (Figure 25.18). The first variable in the message points to the interface.
4 authenticationFailure The message was received from an SNMP manager in the wrong community.
5 egpNeighborLoss EGP node changed its state to "off". The first variable in the message contains the host's IP address.
6 enterpriseSpecific Refer to the specialized codes field for information on this trap.

Figure 25.30 Trap types.

We can see some pitfalls with tcpdump. Let's start the SNMP agent on the sun system and see how it generates the coldStart trap. (The agent knows to send traps to host bsdi. However, bsdi does not have a trap manager running, instead running tcpdump to see the packets being generated. Refer to Figure 25.1, which shows that traps are sent from the agent to the manager, but the manager does not send acknowledgments, so there is no need for the manager to process traps.) Then, using the snmpi program, we send a request that specifies the wrong community name. An authenticationFailure trap should be generated in response to this. Figure 25.31 shows the output.

1 0.0 sun.snmp > bsdi.snmp-trap: C=traps Trap(28)
E:unix.1.2.5 coldStart 20

2 18.86 (18.86) sun.snmp > bsdi.snmp-trap: C=traps Trap(29)
E:unix.1.2.5 authenticationFailure 1907

Figure 25.31 Output of the tcpdump command corresponding to the generation of SNMP traps by the agent.

First, note that both UDP datagrams sent from the SNMP agent (port 161, printed as snmp name) have destination port 162 (printed as snmp-trap name).

The expression C=traps is the name of the community in the trap message. This is a configuration option that is used by the agent in the case of ISODE SNMP.

The next expression, Trap(28) on line 1 and Trap(29) on line 2, is the PDU type and length.

The next output field for both lines is E:unix.1.2.5. This is enterprise: object's system identifier (sysObjectID). It is under node 1.3.6.1.4.1 in the tree shown in Figure 25.6 (iso.org.dod.internet.private.enterprises), so the agent object ID is 1.3.6.1.4.1.4.1.2.5. Its short name is unix.agents.fourBSD-isode.5. The last digit (5) is the release version number of the ISODE agent. This value indicates which agent software generated the trap.

The next field in the output of the tcpdump command is the agent's IP address (140.252.13.33).

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

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

Figure 25.2 shows that the trap message can contain variables that agents want to send to the manager, but these are not present in our examples.

The formal SNMP specification uses an abstract notation (ASN.1 - Abstract Syntax Notation 1), and bit encoding in SNMP messages (Figure 25.2) based on basic encoding rules (BER - Basic Encoding Rules). Unlike most publications that describe SNMP, we deliberately left the discussion of ASN.1 and BER to the very end. If you talk about them at the very beginning, the reader may misunderstand the real purpose of SNMP - network management. In this section, we will only give a brief overview of these two topics. Chapter 8 of [Rose 1990] describes ASN.1 and BER in more detail.

ASN.1 is a formal language that describes data and data characteristics. It does not define how this data is stored or encoded. All fields in MIB and SNMP messages are described using ASN.1. For example, the ASN.1 data type definition of IpAddress from SMI is as follows:

IpAddress::=
-- in network-byte order
IMPLICIT OCTET STRING (SIZE(4))

Similarly, in the MIB we find the following definition of simple variables:

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 )

Defining tables using SEQUENCE and SEQUENCE OF is more complex.

Using ASN.1-like definitions, there are many ways to encode data into a bitstream on transmission. SNMP uses BER. It takes 3 bytes to represent small integers like 64 using BER. One byte contains the value of the integer, the next byte tells how many bytes are used to store the integer (1), and the last byte contains the binary value.

Fortunately, the details of ASN.1 and BER are only important to SNMP developers. They are not required to understand how the network is managed.

SNMP Version 2 (SNMP Version 2)

During 1993, 11 RFCs were published that defined new SNMP standards. The first of these, RFC 1441 [Case et al. 1993] is an introduction to SNMP version 2 (SNMPv2). Two books also cover SNMPv2. There are currently two implementations available (see Appendix B.3 of [Rose 1994]), however commercial implementations may not be widely available until 1994.

In this section, we will describe the main differences between SNMPv1 and SNMPv2.

The new get-bulk-request packet type allows the manager to process large blocks of data efficiently. Another new packet type, inform-request, allows one manager to send information to another manager. Two new MIBs are defined: the SNMPv2 MIB and the SNMPv2-M2M (manager-to-manager) MIB. SNMPv2 provides improved privacy over SNMPv1. In SNMPv1, the community name is passed from manager to agent in the form of an open password. SNMPv2 provides authentication and extended privacy.

All vendors are starting to implement SNMPv2-compliant agents, and management stations are emerging that can use both standards. [Routhier 1993] describes extensions and enhancements to SNMPv1 that are intended to provide interoperability and support for SNMPv2.

Brief conclusions

SNMP is a simple request and response protocol for communication between an SNMP manager and an SNMP agent. The Management Information Database (MIB) defines the variables that are maintained by the agent, which in turn the manager can either query or set. A limited number of data types are used to define variables.

All variables are identified by object identifiers, using a hierarchical naming scheme that consists of long strings of numbers that are usually shortened into simple names for ease of reading. Concrete variables are built by adding a variable to an object identifier.

Most SNMP variables are contained in tables, with fixed column numbers but variable row numbers. Fundamental to SNMP is the identification scheme used to identify each row in a table (in the case where we don't know how many rows the table contains) and the lexicographic order (column-row order). The SNMP get-next operator is essential for any SNMP manager.

We have described the following groups of SNMP variables: system, interface, address translation, IP, ICMP, TCP, and UDP. Then they showed two examples, one of which allowed to determine the MTU of the interface, and the other - to view the routing table of the router.

We ended the chapter with a look at SNMP traps. This is a way for the agent to notify the manager that something has happened that will be of interest to the manager. ASN.1 and BER are also briefly described here. The last two topics are probably the most complex aspects of SNMP, but they are only necessary for developers.

Exercises

  1. We said that using two different ports (161 and 162) allows the system to run both the manager and the agent. What happens if the same port is used?
  2. How can you get a complete list of the routing table using get-next?

Gathering information about the server and infrastructure is a very important part of being a system administrator. There are many tools for collecting and processing such data, and many of them are based on SNMP technology.

SNMP (simple network management protocol) is a standard protocol for managing devices on IP networks. With it, servers can share information about their current state, and the administrator can change predefined values. The protocol itself is very simple, but the structure of programs based on it can be complex.

This article will introduce you to the basics of the SNMP protocol: basic concepts, methods of operation, use cases, different versions of the protocol, etc.

Basic concepts

The SNMP protocol is implemented at the application layer of the network stack. The protocol was designed to collect information from a wide variety of systems in a consistent manner. SNMP uses standardized methods for requesting information and paths.

There are many different versions of the SNMP protocol. In addition, the protocol is partially implemented by some network hardware devices. The most common version is SNMPv1, but it has many vulnerabilities; in fact, the main reasons for its popularity are its omnipresence and long existence. It is recommended to use the more secure version of SNMPv3 instead.

An SNMP-based network mainly consists of SNMP agents. An agent is a program that collects information about a hardware device, organizes it into predefined records, and responds to queries using the SNMP protocol.

The component that requests data from agents is called an SNMP manager. SNMP managers receive information about all managed devices and can issue queries to collect information and set some properties.

SNMP Managers

An SNMP manager is a machine that queries information collected by SNMP agents. Such a machine is much simpler than clients, because it simply requests data.

The manager can be any machine that can query SNMP agents by providing valid credentials (for example, a monitoring server); sometimes the manager's tasks are performed by the administrator himself with the help of simple utilities for quickly querying data.

Almost all SNMP commands are for the manager. For example:

GetRequest
GetNextRequest
GetBulkRequest
SetRequest
InformRequest
Response

In addition, the manager can respond to Trap and Response.

SNMP agents

SNMP agents do the bulk of the work. They are responsible for collecting data about the local system, storing it in a format convenient for queries, updating the management information base (or simply MIB).

MIB is a hierarchical predefined structure that stores information that can be requested or added. It is available for SNMP requests originating from a host that provided the correct credentials (i.e. an SNMP manager).

The agent determines which managers can access the data. The agent can also act as an intermediary and relay information to devices that are not configured for SNMP traffic.

SNMP agents respond to most protocol commands, including:

GetRequest
GetNextRequest
GetBulkRequest
SetRequest
InformRequest

It can also send Trap messages.

Briefly about MIB

The Management Information Base, or MIB, is perhaps the most complex component of an SNMP system. It is a hierarchical, globally standardized database that follows the standards of the agents and managers of the system.

The simplest way to think of a MIB structure is as a flipped tree. Each branch receives a serial number (starting from 1) and a unique string for this level of the hierarchy.

To refer to a specific node, you need to trace the path to it in the database. Node identifiers (numbers and strings) can be used as an address. Each node in the hierarchy is represented by a dot. Thus, the address contains a series of identification strings or numbers separated by dots. Such an address is called an object identifier (or OID).

The MIB provides standard branches that any device can use. However, when implementing SNMP on your device, you can create custom branches.

All standard branches belong to the same parent structure. This branch defines information for the MIB-2 specification (this is a revised standard for compatible devices).

Base path to this branch:

iso.org.dod.internet.mgmt.mib-2

  • Part 1.3.6.1 or iso.org.dod.internet is an OID that identifies internet resources.
  • 2 or mgmt define control subcategories.
  • 1 or mib-2 define the MIB-2 specification.

When querying for device information, you will notice that most of the addresses start with 1.3.6.1.2.1.

SNMP protocol commands

Part of the popularity of SNMP is due to its simple commands. It performs only a few operations, but they are quite flexible.

The following protocol data blocks describe the exact types of messages that the protocol supports:

  • Get: This message is sent by the manager to the agent to request the value of a specific OID. In response, this request receives a Response message containing all the necessary data.
  • GetNext: This message allows the manager to request the next consecutive object in the MIB. This way you can traverse the MIB structure without using OIDs in queries.
  • Set: This message is sent by the manager to the agent in order to change the value of a variable. With Set, you can manipulate configuration information or otherwise change the state of remote hosts. This is the only write operation supported by the protocol.
  • GetBulk: This request works like multiple GetNext requests. The manager will receive a response with the maximum amount of data (subject to request restrictions).
  • Response: The agent sends this message to the manager to pass the requested data to it. If the requested data cannot be passed, the response will contain an error with additional information. A response message is sent to any of the above requests as well as an Inform message.
  • Trap: This message is typically sent by an agent to a manager to provide information about events that occur on managed devices.
  • Inform: This is the message the manager sends to the agent in response to trap. If the agent does not receive such a message, it will resend traps.

Protocol versions

Since its release, SNMP has gone through many changes. The first implementation of SNMP, now known as SNMPv1, appeared in 1988 and consisted of RFC 1065, RFC 1066, and RFC 1067. This version is still widely supported, but it has many security issues (such as plain text authentication), therefore, its use is highly undesirable, especially for unsecured networks.

Work on version 2 of this protocol began in 1993. This version offers a number of significant improvements to the previously introduced standards. This release introduced a party-based security model that addresses pre-review vulnerabilities. However, the new security model turned out to be quite difficult to implement, so it did not become popular.

Therefore, additional releases of version 2 appeared, each of which retained most of the improvements in version 2, but changed the security model. SNMPv2c resumed the community-based security model (which was used in v1); it was the most popular protocol version v2. Another implementation, SNMPv2u, which is based on a custom security model, has also not caught on.

In 1998, the third version of SNMP (current) was released. It offers a custom security system that allows you to set authentication requirements using one of these models:

  • NoAuthNoPriv: Users connecting at this level do not have authentication credentials; messages sent and received by them are publicly available.
  • AuthNoPriv: At this level, you must be authenticated to connect, but messages will not be encrypted.
  • AuthPriv: mandatory authentication, messages are encrypted.

In addition to new authentication models, an access control mechanism has been implemented that controls user access to branches. Version 3 can also use SSH or TLS security protocols.

Tags: ,
Share: