Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- originally written by Moshe Levi
- http://blog-moshe.blogspot.com/2012/10/boost-asio-with-net-snmp.html
- compile:
- $ g++ source.cpp -lboost_system -lsnmp
- */
- #include <iostream>
- #include <string>
- #include <boost/asio.hpp>
- #include <boost/bind.hpp>
- #include <boost/function.hpp>
- #include <net-snmp/net-snmp-config.h>
- #include <net-snmp/net-snmp-includes.h>
- typedef boost::function<void(std::string)> SnmpHandler;
- class SnmpConnection {
- private:
- boost::asio::ip::udp::socket m_boost_sock;
- void* m_netsnmp_handle;
- void handle_snmp_req(
- const boost::system::error_code& ec
- , size_t bytes_transferred
- , struct snmp_pdu* pdu
- , SnmpHandler handler
- );
- void handle_snmp_res(
- const boost::system::error_code& ec
- , size_t bytes_transferred
- , SnmpHandler handler
- );
- static int async_response(
- int operation
- , struct snmp_session* sp
- , int reqid
- , struct snmp_pdu* pdu
- , void* magic
- );
- public:
- SnmpConnection(boost::asio::io_service& io_service)
- : m_boost_sock(io_service)
- , m_netsnmp_handle(NULL)
- {};
- ~SnmpConnection() {
- snmp_sess_close(m_netsnmp_handle);
- }
- void connect(
- long version
- , const std::string& peername
- , const std::string& community
- );
- void async_snmp_get(
- const std::string& snmp_oid
- , SnmpHandler handler
- );
- void async_snmp_set(
- const std::string& snmp_oid
- , const int type
- , const std::string& value
- , SnmpHandler handler
- );
- };
- void SnmpConnection::connect(
- long version
- , const std::string& peername
- , const std::string& community
- ){
- struct snmp_session sess;
- //initialize session
- snmp_sess_init(&sess);
- sess.version = version;
- sess.peername = strdup(peername.c_str());
- sess.community = reinterpret_cast<u_char*>(strdup(community.c_str()));
- sess.community_len = community.size();
- sess.callback = async_response;
- m_netsnmp_handle = snmp_sess_open(&sess);
- free(sess.peername);
- free(sess.community);
- netsnmp_transport* transport = snmp_sess_transport(m_netsnmp_handle);
- m_boost_sock.assign(boost::asio::ip::udp::v4(), transport->sock);
- //put the socket into non-blocking mode
- boost::asio::ip::udp::socket::non_blocking_io non_blocking_io(true);
- m_boost_sock.io_control(non_blocking_io);
- }
- void SnmpConnection::async_snmp_get(
- const std::string& snmp_oid
- , SnmpHandler handler
- ) {
- struct snmp_pdu* pdu = NULL;
- oid anOID[MAX_OID_LEN];
- size_t anOID_len = MAX_OID_LEN;
- pdu = snmp_pdu_create(SNMP_MSG_GET);
- if (!snmp_parse_oid(snmp_oid.c_str(), anOID, &anOID_len)) {
- snmp_perror(snmp_oid.c_str());
- std::cout << "error snmp_parse_oid" << std::endl;
- }
- snmp_add_null_var(pdu, anOID, anOID_len);
- m_boost_sock.async_send(
- boost::asio::null_buffers(),
- boost::bind(
- &SnmpConnection::handle_snmp_req
- , this
- , boost::asio::placeholders::error
- , boost::asio::placeholders::bytes_transferred
- , pdu
- , handler
- )
- );
- }
- void SnmpConnection::handle_snmp_req(
- const boost::system::error_code& ec
- , size_t bytes_transferred
- , struct snmp_pdu* pdu
- , SnmpHandler handler
- ) {
- if (!m_boost_sock.is_open()) {
- return;
- }
- if (ec) {
- std::cout << "error SnmpConnection::handle_snmp_req" << std::endl;
- } else {
- //notify net-snmp library that it can perform a write
- snmp_sess_send(m_netsnmp_handle, pdu);
- m_boost_sock.async_receive(
- boost::asio::null_buffers(),
- boost::bind(
- &SnmpConnection::handle_snmp_res
- , this
- , boost::asio::placeholders::error
- , boost::asio::placeholders::bytes_transferred
- , handler
- )
- );
- }
- }
- void SnmpConnection::handle_snmp_res(
- const boost::system::error_code& ec
- , size_t bytes_transferred
- , SnmpHandler handler
- ) {
- if (!m_boost_sock.is_open()) {
- return;
- }
- if (ec) {
- std::cout << "error SnmpConnection::handle_snmp_res" << std::endl;
- } else {
- fd_set snmp_fds;
- FD_ZERO(&snmp_fds);
- FD_SET(m_boost_sock.native(), &snmp_fds);
- snmp_sess_read(m_netsnmp_handle, &snmp_fds);
- // handler(snmp_response);//wtf?!
- }
- }
- //--------------------
- int SnmpConnection::async_response(
- int operation
- , struct snmp_session* sp
- , int reqid
- , struct snmp_pdu* pdu
- , void* magic
- ) {
- if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
- char buf[1024];
- if (pdu->errstat == SNMP_ERR_NOERROR) {
- if (pdu->variables) {
- print_variable(pdu->variables->name, pdu->variables->name_length, pdu->variables);
- /*
- snprint_variable(
- buf
- , sizeof(buf)
- , pdu->variables->name
- , pdu->variables->name_length
- , pdu->variables
- );
- SnmpConnection::response_ = buf;
- // */
- }
- }
- }
- return 1;
- }
- //--------------------
- void snmp_print(
- std::string result
- , int num
- ) {
- std::cout << "result " << result << std::endl;
- std::cout << "num " << num << std::endl;
- }
- int main() {
- boost::asio::io_service snmp_service;
- SnmpConnection snmp_conn(snmp_service);
- snmp_conn.connect(SNMP_VERSION_2c, std::string("192.168.1.1"), std::string("public"));
- snmp_conn.async_snmp_get(std::string(".1.3.6.1.2.1.1.4.0"), boost::bind(snmp_print, _1, 3));
- snmp_service.run();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement