[AGENT++] help on creating simple agent.

Nicolai G. utromvecherom at gmail.com
Fri Feb 11 13:49:55 CET 2011


On Thu, Feb 10, 2011 at 9:24 PM, Jochen Katz <katz at agentpp.com> wrote:
>
> Hello,
>
> > In my app I'll need a couple of integers (counters for various
> > transactions and transactions per second) to be read-only accessed for
> > managers.
> > Would it be enough to create a number of classes derived from MibLeaf
> > with overriding get_request to retrieve my values?
>
> yes.
>
> > And how to forbid the agent to respond to snmp queries that come
> > without passphrase?
>
> This has to be done with the VACM. Have a look at the calls to
> vacm->addNewAccessEntry.
>
> Regards,
>  Jochen
> _______________________________________________
> AGENTPP mailing list
> AGENTPP at agentpp.org
> http://lists.agentpp.org/mailman/listinfo/agentpp


Ok, I play with access entries, and now I make the agent to answer
only authentificated requests.
But looking at the debug print, seems like lots of critics it has to me :)
So may be somone will look through the code and point me on troubles in it?
Would be very grateful. And here is the code:

#include <stdlib.h>
#include <signal.h>

#include <agent_pp/agent++.h>
#include <agent_pp/snmp_group.h>
#include <agent_pp/system_group.h>
#include <agent_pp/snmp_target_mib.h>
#include <agent_pp/snmp_notification_mib.h>
#include <agent_pp/snmp_community_mib.h>
#include <agent_pp/notification_originator.h>
#include <agent_pp/notification_log_mib.h>
#include <agent_pp/agentpp_simulation_mib.h>
#include <agent_pp/agentpp_config_mib.h>
#include <agent_pp/v3_mib.h>
#include <agent_pp/mib_policy.h>
#include <agent_pp/vacm.h>

#include <snmp_pp/oid_def.h>
#include <snmp_pp/mp_v3.h>
#include <snmp_pp/log.h>


#ifdef SNMP_PP_NAMESPACE
using namespace Snmp_pp;
#endif

#ifdef AGENTPP_NAMESPACE
using namespace Agentpp;
#endif


// table size policies


// globals:

u_short port;
Mib* mib;
RequestList* reqList;
boolean run = TRUE;

const table_size_def table_sizes[4] =
{ table_size_def(oidUsmUserEntry, 30),
  table_size_def(oidVacmSecurityToGroupEntry, 30),
  table_size_def(oidVacmAccessEntry, 30),
  table_size_def(oidVacmViewTreeFamilyEntry, 30)
};
MibTableSizePolicy policy(table_sizes, 4, 5000);


static void sig(int signo)
{
    if ((signo == SIGTERM) || (signo == SIGINT) ||
        (signo == SIGSEGV)) {

        printf ("\n");

        switch (signo) {
        case SIGSEGV: {
            printf ("Segmentation fault, aborting.\n");
            exit(1);
        }
        case SIGTERM:
        case SIGINT: {
                if (run) {
                run = FALSE;
                printf ("User abort\n");
            }
        }
        }
    }
}


void init_signals()
{
    signal (SIGTERM, sig);
    signal (SIGINT, sig);
    signal (SIGSEGV, sig);
}

int xxx = 999;
class test_mib_t
    :
        public MibLeaf
{
    public:
        test_mib_t()
            :
                MibLeaf(
                    "1.3.6.1.4.1.36300.2.99.1.0",
                    READONLY,
                    new SnmpInt32(0) )
            {}
        virtual ~test_mib_t() {}

        virtual void
        get_request(Request* req, int ind)
        {
            *((SnmpUInt32*)value) = xxx++;
            MibLeaf::get_request( req, ind );
        }
};

void init(Mib& mib)
{
    OctetStr sysDescr("sysDescr Sample snmp agent");

    mib.add(new sysGroup(sysDescr.get_printable(),
             "1.3.6.1.4.1.36300", 72));

     mib.add(new snmpGroup());
    mib.add(new TestAndIncr(oidSnmpSetSerialNo));

    mib.add(new test_mib_t());

    mib.add(new snmp_target_mib());

    mib.add(new snmp_community_mib());
    mib.add(new snmp_notification_mib());

    UsmUserTable *uut = new UsmUserTable();

    uut->addNewRow("MD5",
               SNMP_AUTHPROTOCOL_HMACMD5,
               SNMP_PRIVPROTOCOL_NONE,
               "MD5UserAuthPassword", "");

    uut->addNewRow("SHA",
               SNMP_AUTHPROTOCOL_HMACSHA,
               SNMP_PRIVPROTOCOL_NONE,
               "SHAUserAuthPassword", "");

    // add non persistent USM statistics
    mib.add(new UsmStats());
    // add the USM MIB - usm_mib MibGroup is used to
    // make user added entries persistent
    mib.add(new usm_mib(uut));
    // add non persistent SNMPv3 engine object
    mib.add(new V3SnmpEngine());
    mib.add(new MPDGroup());
}

int main (int argc, char* argv[])
{
    if (argc>1)
        port = atoi(argv[1]);
    else
        port = 4700;

#ifndef _NO_LOGGING
    DefaultLog::log()->set_filter(ERROR_LOG, 5);
    DefaultLog::log()->set_filter(WARNING_LOG, 5);
    DefaultLog::log()->set_filter(EVENT_LOG, 5);
    DefaultLog::log()->set_filter(INFO_LOG, 5);
    DefaultLog::log()->set_filter(DEBUG_LOG, 1);
#endif
    int status;
    Snmp::socket_startup();  // Initialize socket subsystem

    // bind localhost only -> agent will not be reachable from
    // outside
    UdpAddress inaddr("127.0.0.1");
    //UdpAddress inaddr("0.0.0.0");
    inaddr.set_port(port);
    Snmpx snmp(status, inaddr);

    if (status == SNMP_CLASS_SUCCESS) {

        LOG_BEGIN(EVENT_LOG | 1);
        LOG("main: SNMP listen port");
        LOG(port);
        LOG_END;
    }
    else {
        LOG_BEGIN(ERROR_LOG | 0);
        LOG("main: SNMP port init failed");
        LOG(status);
        LOG(Snmp::error_msg(status));
        LOG_END;
        exit(1);
    }

    mib = new Mib();

        unsigned int snmpEngineBoots = 0;
        OctetStr engineId(SnmpEngineID::create_engine_id(port));

        // you may use your own methods to load/store this counter
        status = mib->get_boot_counter(engineId, snmpEngineBoots);
        if ((status != SNMPv3_OK) && (status < SNMPv3_FILEOPEN_ERROR)) {
        LOG_BEGIN(ERROR_LOG | 0);
        LOG("main: Error loading snmpEngineBoots counter (status)");
        LOG(status);
        LOG_END;
        exit(1);
    }

        snmpEngineBoots++;
        status = mib->set_boot_counter(engineId, snmpEngineBoots);
        if (status != SNMPv3_OK) {
        LOG_BEGIN(ERROR_LOG | 0);
        LOG("main: Error saving snmpEngineBoots counter (status)");
        LOG(status);
        LOG_END;
        exit(1);
    }

    int stat;
    v3MP *v3mp = new v3MP(engineId, snmpEngineBoots, stat);

    reqList = new RequestList();

    // register v3MP
    reqList->set_v3mp(v3mp);

    // register requestList for outgoing requests
    mib->set_request_list(reqList);

    init_signals();

    // add supported objects
    init(*mib);

    reqList->set_snmp(&snmp);

    // register VACM
    Vacm* vacm = new Vacm(*mib);
    reqList->set_vacm(vacm);

    // initialize security information
        vacm->addNewContext("");
        vacm->addNewContext("other");

        // Add new entries to the SecurityToGroupTable.
        vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "MD5",
                         "testNoPrivGroup", storageType_nonVolatile);
        vacm->addNewGroup(SNMP_SECURITY_MODEL_USM, "SHA",
                         "testNoPrivGroup", storageType_nonVolatile);

        // Set access rights of groups.
        vacm->addNewAccessEntry("testNoPrivGroup", "",
                SNMP_SECURITY_MODEL_USM,
                SNMP_SECURITY_LEVEL_AUTH_NOPRIV,
//SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV,
                match_prefix,
                "testView", "testView",
                "testView", storageType_nonVolatile);

        // Defining Views
        vacm->addNewView("v1ReadView",
             "1.3",
             "",             // Mask "" is same as 0xFFFFFFFFFF...
             view_included,  // alternatively: view_excluded
             storageType_nonVolatile);

        vacm->addNewView("v1WriteView",
             "1.3",
             "",             // Mask "" is same as 0xFFFFFFFFFF...
             view_included,  // alternatively: view_excluded
             storageType_nonVolatile);

        vacm->addNewView("v1NotifyView",
             "1.3",
             "",             // Mask "" is same as 0xFFFFFFFFFF...
             view_included,  // alternatively: view_excluded
             storageType_nonVolatile);

        vacm->addNewView("testView", "1.3.6", "",
             view_included, storageType_nonVolatile);
        vacm->addNewView("internet", "1.3.6.1","",
             view_included, storageType_nonVolatile);
        vacm->addNewView("restricted", "1.3.6.1.2.1.1","",
             view_included, storageType_nonVolatile);
        vacm->addNewView("restricted", "1.3.6.1.2.1.11","",
             view_included, storageType_nonVolatile);
        vacm->addNewView("restricted", "1.3.6.1.6.3.10.2.1","",
             view_included, storageType_nonVolatile);
        vacm->addNewView("restricted", "1.3.6.1.6.3.11.2.1","",
             view_included, storageType_nonVolatile);
        vacm->addNewView("restricted", "1.3.6.1.6.3.15.1.1","",
             view_included, storageType_nonVolatile);

    // register table size policies
    MibTableSizePolicy::register_policy(mib->get_default_context(),
                        &policy);
    // load persitent objects from disk
    mib->init();

    Request* req;
    while (run) {

        req = reqList->receive(2);

        if (req) {
            mib->process_request(req);
        }
        else {
            mib->cleanup();
        }
    }
    delete mib;
    Snmp::socket_cleanup();  // Shut down socket subsystem
    return 0;
}


--
Nicolai Grodzitski



More information about the AGENTPP mailing list