Working with SNMP under QT



Four years ago I worked on a multi-platform desktop application, which main purpose was to observe and control various devices on the local network using SNMP. The main questions that had to be solved were :

How to write an application that can run on multiple platforms (like Windows, Linux, Mac OS) How to communicate with the SNMP devices

The client didn't want a web app, so I had to think of other variants. And because I'm a big C++ fan, I decided to utilize a C++ based solution.







What is QT ?

For those of you you have never heard of it, QT is an intuitive, easy to use cross-platform library written entirely in C++, developed by Trolltech but later bought by Nokia with the idea of using QT in platforms like Maemo (which later morphed into MeeGo). It's available on Window, Linux, Mac OS, along with some mobile platforms. You can use it for game development and even create browser plugins with it. But that was few years ago, for a complete list of the currently supported platforms check this link.





What is SNMP ?

The Simple Network Management Protocol (SNMP) is used for observation and management of devices over an IP network. It's basically a tool to monitor availability and performance, among other things.





SNMP libraries

At the time I was working on the project, there weren't so many SNMP libraries available for C++ (and I think this is still the case). So I was left with more or less two options :

SNMP++ (An object-oriented C++ library, which sounded like a good option)

NetSNMP (Library written entirely in C, which I really didn't want to wrap at that time)

Unfortunately, it turned out that SNMP++ was not designed to work under MinGW (which is the GCC port that QT uses on Windows).

So I decided to create my own class to operate the SNMP packets. It uses the QT network module, creating a UDP packet and manually including all the bytes necessary from the Application layer according to the correct SNMP format.

SNMPv1 QT/C++ implementation



I know there are not so many choices when it comes to SNMP management in C++, so I decided to share this code.

The following is a simple class used to communicate using SNMPv1 devices :

/** * @version 1.0 * * @section DESCRIPTION * * The class represents a SNMP session, which provides get and set * operations on SNMP agents. * */ #ifndef SNMPSESSION_H #define SNMPSESSION_H #include <QObject> #include <QHostAddress> #include <QByteArray> #include <QString> #include <QUdpSocket> class SNMPSession : public QObject { Q_OBJECT public: SNMPSession(); SNMPSession(const QString &agentAddress, qint16 agentPort, qint16 socketPort); ~SNMPSession(); // get/set methods QHostAddress *getAgentAddress() const; qint16 getAgentPort() const; qint16 getSocketPort() const; QString getAgentMACAddress() const; void setAgentAddress(const QString &agentAddress); void setAgentPort(qint16 agentPort); void setSocketPort(qint16 socketPort); // SNMP message methods int sendSetRequest(const QString &communityStringParameter, const QString oidParameter, int value); int sendSetRequest(const QString &communityStringParameter, const QString oidParameter, const QString &valueParameter); int sendGetRequest(QString &receivedValue, const QString &communityStringParameter, const QString &oidParameter); // additional public methods private: int getValueFromGetResponse(QString &receivedValue, QByteArray &receivedDatagram, const int &errorIndex, const int &valueTypeIndex, const int &valueIndex, const int &valueLenghtIndex); QByteArray convertIntAccordingToBER(int valueToConvert); void convertOIDAccordingToBER(QByteArray &oid); void convertOIDAccordingToBER(QByteArray &oid); QUdpSocket udpSocket; QHostAddress *agentAddress; qint16 agentPort; qint16 socketPort; }; #endif // SNMPSESSION_H 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 /** * @version 1.0 * * @section DESCRIPTION * * The class represents a SNMP session, which provides get and set * operations on SNMP agents. * */ #ifndef SNMPSESSION_H #define SNMPSESSION_H #include <QObject> #include <QHostAddress> #include <QByteArray> #include <QString> #include <QUdpSocket> class SNMPSession : public QObject { Q_OBJECT public : SNMPSession ( ) ; SNMPSession ( const QString & agentAddress , qint16 agentPort , qint16 socketPort ) ; ~ SNMPSession ( ) ; // get/set methods QHostAddress * getAgentAddress ( ) const ; qint16 getAgentPort ( ) const ; qint16 getSocketPort ( ) const ; QString getAgentMACAddress ( ) const ; void setAgentAddress ( const QString & agentAddress ) ; void setAgentPort ( qint16 agentPort ) ; void setSocketPort ( qint16 socketPort ) ; // SNMP message methods int sendSetRequest ( const QString & communityStringParameter , const QString oidParameter , int value ) ; int sendSetRequest ( const QString & communityStringParameter , const QString oidParameter , const QString & valueParameter ) ; int sendGetRequest ( QString & receivedValue , const QString & communityStringParameter , const QString & oidParameter ) ; // additional public methods private : int getValueFromGetResponse ( QString & receivedValue , QByteArray & receivedDatagram , const int & errorIndex , const int & valueTypeIndex , const int & valueIndex , const int & valueLenghtIndex ) ; QByteArray convertIntAccordingToBER ( int valueToConvert ) ; void convertOIDAccordingToBER ( QByteArray & oid ) ; void convertOIDAccordingToBER ( QByteArray & oid ) ; QUdpSocket udpSocket ; QHostAddress * agentAddress ; qint16 agentPort ; qint16 socketPort ; } ; #endif // SNMPSESSION_H

You can find the .cpp implementation here.

I should warn you that the code should not be used as an example of best coding practices, but it has a clear and understandable interface. And, honestly, sometimes you just need something that works, even if it's not the most clever implementation.

And since I need to set a license here (because if I don't, you'll have practically no rights over the code), I decided to share it under LGPL.

Hope this will help someone somewhere. ;)

Kosta Hristov ( 34 Posts Hi there ! My name is Kosta Hristov and I currently live in London, England. I've been working as a software engineer for the past 6 years on different mobile, desktop and web IT projects. I started this blog almost one year ago with the idea of helping developers from all around the world in their day to day programming tasks, sharing knowledge on various topics. If you find my articles interesting and you want to know more about me, feel free to contact me via the social links below. ;)

Like the article ? Share it ! ;)