EN 
15.05.2026 Žofie WELCOME IN MY WORLD

This website is originally written in the Czech language. Most content is machine (AI) translated into English. The translation may not be exact and may contain errors.

Tento článek si můžete zobrazit v originální české verzi. You can view this article in the original Czech version.
Informace o portech switche pomocí SNMP a PHP

Switch port information using SNMP and PHP

| Petr Bouška - Samuraj |
In this article I try to present the possibilities of practical use of SNMP in conjunction with the PHP programming language. The example I have chosen is to get information about the ports/interfaces of the switch. No deep knowledge of either SNMP or PHP is needed to achieve interesting functionality. I think the main thing is the idea (or information) of what we can do.
displayed: 26 098x (22 730 CZ, 3 368 EN) | Comments [1]

The described example is based on a practical situation that I am addressing. I use the port description, where I record what is connected to a given port - the socket label (when a socket is connected) or the computer name (if it is directly connected to the port). Then it is easy to find out where the port leads (for example, when I'm tracking a suspicious MAC address on the network), without having to go through the cables. Occasionally, however, I need the opposite, to find the switch and port where a certain socket is connected. For this, I need a list of all ports and switches, which is difficult to maintain manually. And this is where the idea of dynamically obtaining this information using SNMP comes in, which was brought to me by Cacti, where this feature essentially already exists.

PHP and SNMP Support

Note: I am using PHP (and Apache) on Windows, so my description reflects that. Some things are different under Linux.

In the programming language PHP, we have the php_snmp extension, which offers basic SNMP communication commands like snmpget, snmpset, and snmpwalk. Some additional commands are available only from PHP 5 onwards. Detailed description can be found in the documentation https://www.php.net/manual/en/ref.snmp.php.

The limitation is that these commands use only SNMP version 1. I've found various references to undocumented functions like snmp2_get, snmp3_get, etc., which should use SNMPv2c and SNMPv3. But these functions do not work in my PHP version.

PHP has a subdirectory mibs in its directory, which contains common MIB tables. However, it can happen that PHP does not find this directory, and when using SNMP, it displays a warning (and of course, then does not use the MIB database). The solution is to create a system variable (Control Panel - System - Advanced - Environment Variables - System variables) named MIBDIRS and set its value to the path to the directory with MIB files.

Note: For example, in EasyPHP, the directory with MIB files is not included, so it needs to be copied from a regular PHP installation.

The advantage of using MIB tables is that the return values are adjusted according to them, and for example, an enumeration type has the name added (this is the case for the interface type).

In PHP for SNMP, there are also a number of functions that set the behavior of the values, for example, that OIDs are displayed numerically or that the resulting value does not contain additional information (such as the type - Gauge32: 100). Unfortunately, not everything always works correctly.

Another option for using SNMP is to have Net-SNMP installed and call its commands from PHP using the exec function and capture the output. In this case, we can use all versions of SNMP and do not have the problem with PHP versions (which only contain some functions).

SNMP for Interfaces

SNMP values for interfaces are part of the standard MIB table IF-MIB. The value tree starts at OID = 1.3.6.1.2.1.2, written using node names as iso.org.dod.internet.mgmt.mib-2.interfaces. The first value is the number of interfaces.

Name OID Description
ifNumber .1.3.6.1.2.1.2.1.0 Number of interfaces on the device

There is also a table that contains certain properties for each interface. Of interest are, for example:

Name OID Description
ifIndex .1.3.6.1.2.1.2.2.1.1 Interface index number
ifDescr .1.3.6.1.2.1.2.2.1.2 Port name
ifType .1.3.6.1.2.1.2.2.1.3 Port type
ifSpeed .1.3.6.1.2.1.2.2.1.5 Port speed
ifOperStatus .1.3.6.1.2.1.2.2.1.8 Port status (up, down, ...)
ifInUcastPkts .1.3.6.1.2.1.2.2.1.11 Incoming unicast packets

Some additional values can be found in a slightly different location, under OID = 1.3.6.1.2.1.31, iso.org.dod.internet.mgmt.mib-2.ifMIB

Name OID Description
ifName .1.3.6.1.2.1.31.1.1.1.1 Short port name
ifAlias .1.3.6.1.2.1.31.1.1.1.18 Port description (alias)

Information about IP addresses (which can be assigned only in some places, e.g. for VLANs) is under OID = 1.3.6.1.2.1.4, iso.org.dod.internet.mgmt.mib-2.ip

Name OID Description
ipAdEntAddr .1.3.6.1.2.1.4.20.1.2 IP addresses
ipAdEntIfIndex .1.3.6.1.2.1.4.20.1.1 Interface indices for IP addresses

For switches, global information like name and location is also interesting. These are values that can be set for almost any SNMP device during installation (or in the settings). OID = .1.3.6.1.2.1.1, iso.org.dod.internet.mgmt.mib-2.system

Name OID Description
sysName .1.3.6.1.2.1.1.5.0 Device name
sysLocation .1.3.6.1.2.1.1.6.0 Location

Some values, such as the number of interfaces or the device name, are represented by a single value, and we can therefore use the snmpget function. Other values that are specific to each interface are stored in a way that the index of the interface is appended to the given OID, and the value is stored here. Since we usually don't know these interfaces and it's also more efficient, we can use the snmpwalk function, which goes through all the values under the given OID and returns an array of values to us. The better function is snmprealwalk, which also returns the OID for the given value.

We can also use the snmpwalk function in a way that we call it on the OID for the interface and get all the values for all interfaces.

Implementation in PHP

// function that fills the $interfaces array with values from the device at address $ip using the community string $comm
function getInterface(&$interfaces, $ip, $comm) {
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.1", "Index");
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.8", "Status"); 
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.2", "Port_name");
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.31.1.1.1.18", "Descr");
  getInterPart($interfaces, $ip, $comm, ".1.3.6.1.2.1.2.2.1.3", "Type");
  $name = format_snmp_string(snmpget($ip, $comm, ".1.3.6.1.2.1.1.5.0"));
  addInterSwitcheVal($interfaces, "Switch", $name);
}
// adds an item to the array that is the same for all indices
function addInterSwitcheVal(&$interfaces, $valname, $value) {
  foreach($interfaces as $val)
    $interfaces[$val["Index"]][$valname] = $value;
}
// loads one property for all interfaces
function getInterPart(&$interfaces, $ip, $comm, $oid, $name) {
  $array = snmprealwalk($ip, $comm, $oid);
  foreach($array as $key => $val) {
    $index = ereg_replace('.*\.([0-9]+)$', "\\1", $key);  //index is the last number from the OID
    $val = format_snmp_string($val);
    $interfaces[$index][$name] = $val;
  }
}
// prints the interfaces array as a table
function printInterfaces($interfaces) {
  echo "<table>";
  echo "<tr><th>Switch</th><th>Index</th><th>Status</th><th>Port_name</th><th>descr</th><th>Type</th> tr>";
  foreach($interfaces as $val) {
    echo "<tr>";
    echo "<td>".$val["Switch"]."</td>";
    echo "<td>".$val["Index"]."</td>";
    echo "<td>".$val["Status"]."</td>";
    echo "<td>".$val["Port_name"]."</td>";
    echo "<td>".$val["Descr"]."</td>";
    echo "<td>".$val["Type"]."</td>";
    echo "</tr>";
  }
  echo "</table>";
}
// variable where the resulting values are stored, it is a two-dimensional array - all interfaces (by index) and the loaded values (by name)
$interfaces = array();
$ip = "10.0.0.1"; $co = "public";
// device IP address, community string 
getInterface($interfaces, $ip, $co);
printInterface($interfaces);

The example provided is just a sketch of the solution. It needs to be wrapped in HTML tags to be usable as a web page. It would also deserve a number of improvements or could be solved in a completely different way. We could, for example, store the resulting values in a database, which would only need to be done occasionally, as the changes are not too frequent. Normally, the return values are wrapped in a series of unnecessary information (numeric values, MAC address, etc.), so it's appropriate to remove them. For example, Cisco switches return 3 types of interfaces - physical ports, VLANs, and null interfaces. So we might want to display only the ports, which we can filter by ifType.

My example was mainly intended to make you aware of the possibilities and show how simple it is to use SNMP from PHP.

Author:

Related articles:

SNMP

Simple Network Management Protocol (SNMP) is very useful for managing a computer network.

If you want write something about this article use comments.

Comments
  1. [1] jakub

    diky moc ;-)

    Tuesday, 08.05.2007 23:54 | answer
Add comment

Insert tag: strong em link

Help:
  • maximum length of comment is 2000 characters
  • HTML tags are not allowed (they will be removed), you can use only the special tags listed above the input field
  • new line (ENTER) ends paragraph and start new one
  • when you respond to a comment, put the original comment number in squar brackets at the beginning of the paragraph (line)