Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание расширения для net-snmp 
V
    Опции темы
kyzia887
Дата 26.8.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Собственно вопрос возник в следующем:
требуется написать расширение для net-snmp под linux на С++. В этом я новичок и хотел бы попросить у вас совета где и что можно почитать на данную тему. При написании клиента с использование этой библиотеки вопросов особо не возникло, а вот с расширением увы =( Сразу скажу что гуглил и неоднократно (парюсь этим вопросом уже 2й день), но результатов почти ни каких. Варианты с примерами на Перле или Питоне тоже не катят, тк я с ними вообще не работал.

Сама задача заключается в следующем: при запросе по snmp (oid = произвольный набор к примеру задаю) мое расширение опрашивает некую программу и возвращает 1 - если та запущена, и 0 - если нет. Хотелось бы для примера хоть небольшой кусок кода глянуть чтобы понять как все это дело собрать воедино.

Заранее благодарен.
PM MAIL   Вверх
svlary
Дата 29.8.2011, 06:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата
 В этом я новичок 

  В свое время я написал целиком и менеджера и агента для SNMP, но было это очень давно - больше 10 лет назад, так что - увы, почти ничего не помню...
Цитата
При написании клиента

Не очень понятно, что Вы имеете в виду... В SNMP используется терминология :
  • Менеджер - то, что использует сисадмин для настройки удаленных устройств
  • Агент - то, что работает на удаленных устройствах и обслуживает запросы менеджера

Цитата(kyzia887 @  26.8.2011,  14:57 Найти цитируемый пост)
где и что можно почитать на данную тему

 А на официальном сайте смотрели ? net-snmp.org

Цитата
Хотелось бы для примера хоть небольшой кусок кода глянуть чтобы понять как все это дело собрать воедино.


Ну, на sourceforge я, по запросу "snmp"  сразу нашел 376 результатов. smile Пожалуйста - скачивайте и изучайте! Боюсь только, что толку от этого будет немного. Потому,  что SNMP (несмотря на свое название) - штука очень сложная и запутанная.  И никакого "небольшого кусочка кода" просто-напросто не существует.  Насколько я помню, последовательность действий программиста, при необходимости расширения возможностей существующей SNMP системы, выглядит приблизительно так :
  • Выбираете OID для новых сущностей и согласовываете его между агентом и менеджером.
  • Прописываете его в MIB (и там и там...) и компилируете саму MIB для получения ее двоичного варианта.
  • Согласовывает формат ASN.1 кодирования для добавленного OID.
  • В агенте добавляете новую веточку "case <новый OID>:" для обработки запросов GET и GETNEXT
  • В менеджере добавляете возможность работы с новым OID

PM MAIL   Вверх
kyzia887
Дата 29.8.2011, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата

А на официальном сайте смотрели ? net-snmp.org


Да, перелопатил его. Как раз пример клиента / менеджера там неплохо на С описан и немного повозившись все заработало как часы, а вот расширение агента увы у них тока на перле.

Цитата

Ну, на sourceforge я, по запросу "snmp"  сразу нашел 376 результатов.


Спасибо за инфу, щас буду разбираться что к чему  smile 
PM MAIL   Вверх
kyzia887
Дата 30.8.2011, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Разобрался с проблемой  smile 

Net-SNMP поддерживает возможность использовать подгружаемый внешний модуль (далее - библиотека). 
Для того чтобы собрать данную библиотеку следует рассмотреть приведенный пример: http://www.net-snmp.org/wiki/index.php/TUT...Loadable_Object

Опишу мои действия вкратце (может кому-нибудь пригодится еще):

1) Для начала написал как в примере 2 файла (заголовочный и исходного текста С):

Заголовочный файл "SNMPExtended.h"
Код

#ifndef SNMPEXTENDED_H
#define SNMPEXTENDED_H

#ifdef __cplusplus
extern "C" {
#endif

/*
 * function declarations
 */
void init_SNMPExtended(void);

#ifdef __cplusplus
}
#endif

#endif // SNMPEXTENDED_H
  

Файл исходного текста С "SNMPExtended.c"
Код

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "SNMPExtended.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * the variable we want to tie an OID to.  The agent will handle all
 * * GET and SET requests to this variable changing it's value as needed.
 */

static int SNMPExtended = 333;
static oid SNMPExtended_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 4, 1, 1, 333, 0 };

/*
 * our initialization routine, automatically called by the agent
 * (to get called, the function name must match init_FILENAME())
 */


void init_SNMPExtended(void)
{
   /*
    * a debugging statement.  Run the agent with -DnstAgentPluginObject to see
    * the output of this debugging statement.
    */
    DEBUGMSGTL(("SNMPExtended",
                "Initializing the SNMPExtended module\n"));


   /*
    * the line below registers our variables defined above as
    * accessible and makes it writable.  A read only version of any
    * of these registration would merely call
    * register_read_only_int_instance() instead.  The functions
    * called below should be consistent with your MIB, however.
    *
    * If we wanted a callback when the value was retrieved or set
    * (even though the details of doing this are handled for you),
    * you could change the NULL pointer below to a valid handler
    * function.
    */
    DEBUGMSGTL(("SNMPExtended",
                "Initalizing SNMPExtended scalar integer.  Default value = %d\n",
                SNMPExtended));

    netsnmp_register_int_instance("SNMPExtended",
                                  SNMPExtended_oid,
                                  OID_LENGTH(SNMPExtended_oid),
                                  &SNMPExtended, NULL);

    DEBUGMSGTL(("SNMPExtended",
                "Done initalizing SNMPExtended module\n"));
}


void deinit_SNMPExtended(void)
{
    unregister_mib(SNMPExtended_oid,OID_LENGTH(SNMPExtended_oid));
}

#ifdef __cplusplus
}
#endif



2) Далее собираю все это дело в нашу библиотеку:
Код

gcc -Wall -fPIC -c SNMPExtended.c
gcc -shared -o SNMPExtended.so SNMPExtended.o -ldl


3) Проверяем конфигурацию net-snmp:
Открываем файл /etc/snmp/snmpd.conf
В моем случае он имеет следующий вид:
Код

syslocation Server Room
syscontact Sysadmin (root@localhost)
rocommunity public 127.0.0.1
rwcommunity private 127.0.0.1


4) Далее создаем свой MIB-файл (отталкивался от примера):
NET-SNM-ITELECT-MIB.txt
Код

NET-SNMP-INTELECT-MIB DEFINITIONS ::= BEGIN

IMPORTS
    netSnmpExamples                FROM NET-SNMP-EXAMPLES-MIB
    OBJECT-TYPE, Integer32,
    MODULE-IDENTITY                FROM SNMPv2-SMI
    MODULE-COMPLIANCE, OBJECT-GROUP        FROM SNMPv2-CONF;

netSnmpIntelectMIB MODULE-IDENTITY
    LAST-UPDATE  "201108300000Z"        --30 august 2011
    ORGANIZATION "zzzz"
    CONTACT-INFO "zzzz"

    DESCRIPTION "Mib for intelect."

    ::= { netSnmpExamples 5 }

nstIntelectMibObjects        OBJECT IDENTIFIER ::= { netSnmpIntelectMIB 1 }

nstIntelectAgentModules        OBJECT IDENTIFIER ::= { nstIntelectMibObjects 1 }

SNMPExtended OBJECT-TYPE
    SYNTAX        Integer32
    MAX-ACCESS    read-write
    STATUS        current
    DESCRIPTION
          "This is test object for intelect"
    DEFVAL { 333 }
    ::= { nstIntelectAgentModules 1 }

END


И закидываем наш новый MIB к остальным MIB-файлам:
/usr/share/snmp/mibs/

После чего перезапускаем агент net-snmp:
cd /etc/init.d/
./snmpd restart


5) Проверяем структуру нашего нового MIB-файла:
cd /usr/bin
./snmptranslate -M+. -mNET-SNMP-INTELECT-MIB -Tp -IR netSnmpIntelectMIB


Получаем что-то вроде этого:
Код

+--netSnmpIntelectMIB(5)
      |
     +-- nstIntelectMibObjects(1)
            |
            +--nstIntelectAgentModules(1)
                  |
                  +-- -RW- Integer32 SNMPExtended(1)


6) После всего выше перечисленного можно пойти двумя путями добавления нашей новой библиотеки в агент:
     - прописать ее в конфигурационном файле snmpd.conf (я выбрал этот вариант) (не нужно каждый раз регать наш 
        внешний модуль)

     - выполнить 7 пунктов, описанных в мануале (ссылка вначале сообщения) (данный вариант работает только до   
        тех пор, пока не перезагрузим агент net-snmp! После перезагрузки все настройки слетают!
)

В моем случае отредактированный конфигурационный файл стал выглядеть так:
/etc/snmp/snmpd.conf
Код

syslocation Server Room
syscontact Sysadmin (root@localhost)
rocommunity public 127.0.0.1
rwcommunity private 127.0.0.1
dlmod SNMPExtended /home/intelect/soft/SNMPExtended.so


7) Перезапускаем агент net-snmp и запрашиваем необходимую нам информацию:
cd /usr/bin
./snmpget -c public -v 2c localhost .1.3.6.1.4.1.8072.2.4.1.1.333.0

Получим:
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.333.0 = INTEGER: 333

Это сообщение отредактировал(а) kyzia887 - 30.8.2011, 14:52
PM MAIL   Вверх
svlary
Дата 31.8.2011, 05:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Лично мне Ваше сообщение было очень интересным. Вспомнил - сколько сам мучился с этим делом,  когда никакой net-snmp не было ! smile
Один момент не понял. Вот вы регистрируете функцию-обработчик данного OID:

Цитата(kyzia887 @  30.8.2011,  14:51 Найти цитируемый пост)
   netsnmp_register_int_instance("SNMPExtended",
                                  SNMPExtended_oid,
                                  OID_LENGTH(SNMPExtended_oid),
                                  &SNMPExtended, NULL);


Но где сама функция ? (SNMPExtended)
Т.е. каким образом получается значение объекта { 1, 3, 6, 1, 4, 1, 8072, 2, 4, 1, 1, 333, 0 } и каким образом агент вызывает эту функцию ? При чтении и при записи...

PM MAIL   Вверх
kyzia887
Дата 31.8.2011, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(svlary @ 31.8.2011,  05:54)
Но где сама функция ? (SNMPExtended)
Т.е. каким образом получается значение объекта { 1, 3, 6, 1, 4, 1, 8072, 2, 4, 1, 1, 333, 0 } и каким образом агент вызывает эту функцию ? При чтении и при записи...

Как описывается в мануале, мы описываем инициализацию нашей библиотеки по средствам 
Код

void init_SNMPExtended(void)
{
...
}


и должны описать выгрузку нашей библиотеки по окончании работы
Код

void deinit_SNMPExtended(void)
{
...
}


т.е. общая структура получается void init_Название нашей библиотеки (void); и void deinit_Название (void);

При запуске самого net-snmp (если в его конфигурационном файле прописано подключение нашей библиотеки) наша библиотека регистрируется и присваивает новому инстансу заданный в ней OID (естественно MIB файл тоже должен присутствовать как я писал ранее).

После того как net-snmp запуститься можно обращаться к нашему новому элементу двумя способами:
  •  ./snmpget -c public -v 2c localhost .1.3.6.1.4.1.8072.2.4.1.1.333.0
  •  ./snmpget -c public -v 2c localhost NET-SNMP-INTELECT-MIB::SNMPExtended.0
В обоих вариантах получим один и тот же ответ.

Лично я дописал несколько строк кода для вывода конкретного значения по запросу:
SNMPExtebded.cpp
Код

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "SNMPExtended.h"

#include <QtSql>
#include <QFile>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * the variable we want to tie an OID to.  The agent will handle all
 * * GET and SET requests to this variable changing it's value as needed.
 */

static int SNMPExtended = 0;
static oid SNMPExtended_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 4, 1, 1, 333, 0 };

/*
 * our initialization routine, automatically called by the agent
 * (to get called, the function name must match init_FILENAME())
 */


void init_SNMPExtended(void)
{

    QFile file;
    file.setFileName("SNMPExtended_LOG.txt");
    QTextStream out(&file);
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    out << "-> Init - Ok\nSNMPExtended = " << SNMPExtended << endl;
    file.close();


   /*
    * a debugging statement.  Run the agent with -DnstAgentPluginObject to see
    * the output of this debugging statement.
    */
    DEBUGMSGTL(("SNMPExtended",
                "Initializing the SNMPExtended module\n"));


    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> DEBUGMSGTL - Ok" << endl;
    file.close();

    /** Database connect **/
    int sizeOnDisk = 0;

    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    db.setDatabaseName("bagira");
    db.setHostName("127.0.0.1");
    db.setUserName("postgres");
    db.setPassword("12345");
    if(!db.open())
    {
        /*
        QSqlError sqlError;
        sqlError = db.lastError();
        qDebug() << "DB connection failed! ERROR: " << sqlError.text();
        */
    }
    else
    {
        file.open(QIODevice::Append | QIODevice::Text);
        out << "-> DB open - Ok" << endl;
        file.close();

        QSqlQuery query;
        if(!query.exec("SELECT * FROM db_size_on_disk;"))
        {
            //qDebug() << "\nNot possible to read the table";
        }
        else
        {
            QSqlRecord rec = query.record();
            while(query.next())
            {
                sizeOnDisk = query.value(rec.indexOf("KB")).toInt();

                file.open(QIODevice::Append | QIODevice::Text);
                out << "-> DB size on disk = " << sizeOnDisk << endl;
                file.close();
            }
            SNMPExtended = sizeOnDisk;
        }
    }
    db.close();
    /** End database connect **/

    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> DB close\nSNMPExtended = " << SNMPExtended << endl;
    file.close();

   /*
    * the line below registers our variables defined above as
    * accessible and makes it writable.  A read only version of any
    * of these registration would merely call
    * register_read_only_int_instance() instead.  The functions
    * called below should be consistent with your MIB, however.
    *
    * If we wanted a callback when the value was retrieved or set
    * (even though the details of doing this are handled for you),
    * you could change the NULL pointer below to a valid handler
    * function.
    */
    DEBUGMSGTL(("SNMPExtended",
                "Initalizing SNMPExtended scalar integer.  Default value = %d\n",
                SNMPExtended));

    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> DEBUGMSGTL - Ok  Default value = " << SNMPExtended << endl;
    file.close();

    netsnmp_register_int_instance("SNMPExtended",
                                  SNMPExtended_oid,
                                  OID_LENGTH(SNMPExtended_oid),
                                  &SNMPExtended, NULL);

    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> netsnmp_register_int_instance - Ok" << endl;
    file.close();

    DEBUGMSGTL(("SNMPExtended",
                "Done initalizing SNMPExtended module\n"));

    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> DEBUGMSGTL - Done" << endl;
    file.close();
}


void deinit_SNMPExtended(void)
{
    unregister_mib(SNMPExtended_oid,OID_LENGTH(SNMPExtended_oid));

    QFile file;
    file.setFileName("SNMPExtended_LOG.txt");
    QTextStream out(&file);
    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> unregister_mib - Ok" << endl;
    file.close();
}

#ifdef __cplusplus
}
#endif



Записывать значение так же как получать  smile 

Единственный минус - я пока что не знаю как сделать эти данные обновляемыми, т.е. в моем случае размер БД запишется в переменную только при инициализации библиотеки и все, и если мы к примеру при старте не смогли подключиться к БД то в значении будет висеть 0 и он уже не обновиться даже если подключение вновь появится =( Может конечно нужно настраивать сам net-snmp, пока не знаю... Думаю над этим вопросом. Тут еще возникает необходимость в обработке netsnmpset, т.е. чтобы не ставить это значение в переменную. а производить какие-то манипуляции скажем с БД и не более (значение инстанса при этом должно остаться прежним)...

Это сообщение отредактировал(а) kyzia887 - 31.8.2011, 10:06
PM MAIL   Вверх
fish9370
Дата 31.8.2011, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 2
Всего: 1



kyzia887, спасибо, интересная статья.. плюсанул..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
svlary
Дата 1.9.2011, 05:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата(kyzia887 @  31.8.2011,  09:59 Найти цитируемый пост)
размер БД запишется в переменную только при инициализации библиотеки и все

Вот здесь :
Код

SNMPExtended = sizeOnDisk;

Т.е, получается, что Вы регистрируете не функцию доступа, а переменную, хранящую значение для MIB.
Действительно, у Вас она получает значение только при инициализации всей MIB. 
Цитата(kyzia887 @  31.8.2011,  09:59 Найти цитируемый пост)
Думаю над этим вопросом.

Мой вопрос был как раз про это... Насколько я помню,  мне пришлось найти обработчик 
Код
OID=1.3.6.1.4.1.<ID фирмы>

Вставить туда проверку на код нашей фирмы. Если код совпадал, то вызывался мой обработчик оставшейся части OID, который и делал проверку на то, какая именно переменная обрабатывается и что с ней надо делать (код запроса). 
И только после этого реализовывалась семантика запроса.... 
PM MAIL   Вверх
kyzia887
Дата 1.9.2011, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(svlary @ 1.9.2011,  05:49)
Мой вопрос был как раз про это... Насколько я помню,  мне пришлось найти обработчик 
Код
OID=1.3.6.1.4.1.<ID фирмы>

Вставить туда проверку на код нашей фирмы. Если код совпадал, то вызывался мой обработчик оставшейся части OID, который и делал проверку...

Разобрался с обработкой (по крайней мере на данном этапе мне этого должно хватить)  smile 
Пришлось переписать немного код. Теперь он выглядит следующим образом:
SNMPExtended.h
Код

#ifndef SNMPEXTENDED_H
#define SNMPEXTENDED_H

#ifdef __cplusplus
extern "C" {
#endif

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * function declarations
 */
void init_SNMPExtended(void);
int database_size();
int handle_node_snmpExtended(netsnmp_mib_handler          *handler,
                             netsnmp_handler_registration *reginfo,
                             netsnmp_agent_request_info   *reqinfo,
                             netsnmp_request_info         *requests);
void deinit_SNMPExtended(void);

#ifdef __cplusplus
}
#endif

#endif // SNMPEXTENDED_H


SNMPExtended.cpp
Код

#include "SNMPExtended.h"

#include <QtSql>
#include <QFile>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * the variable we want to tie an OID to.  The agent will handle all
 * * GET and SET requests to this variable changing it's value as needed.
 */
static int SNMPExtended = 0;
static oid SNMPExtended_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 5, 1, 1, 1, 0 };

/*
 * our initialization routine, automatically called by the agent
 * (to get called, the function name must match init_FILENAME())
 */

void init_SNMPExtended(void)
{
    // - LOG -
    QFile file;
    file.setFileName("SNMPExtended_LOG.txt");
    QTextStream out(&file);
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    out << "-> Init - Ok\n-> SNMPExtended = " << SNMPExtended << endl;
    file.close();
    // - LOG -

    DEBUGMSGTL(("SNMPExtended",
                "Initializing the SNMPExtended module\n"));


    // - LOG -
    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> DEBUGMSGTL: Initializing the SNMPExtended module - Ok" << endl;
    file.close();
    // - LOG -

    //create handler registration
    netsnmp_handler_registration *my_test;

    my_test = netsnmp_create_handler_registration("Test SNMP Extended",
                                                  handle_node_snmpExtended,
                                                  SNMPExtended_oid,
                                                  OID_LENGTH(SNMPExtended_oid),
                                                  HANDLER_CAN_RWRITE);
    //register new instance
    netsnmp_register_instance(my_test);

    DEBUGMSGTL(("SNMPExtended",
                "Done initalizing SNMPExtended module\n"));

    // - LOG -
    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> DEBUGMSGTL: Done initalizing SNMPExtended module." << endl;
    file.close();
    // - LOG -
}

int database_size()
{
    // - LOG -
    QFile file;
    file.setFileName("SNMPExtended_LOG.txt");
    QTextStream out(&file);
    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> Init DataBase size func - Done" << endl;
    file.close();
    // - LOG -

    int sizeOnDisk = -1;

    /** Database connect **/
    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    db.setDatabaseName("bagira");
    db.setHostName("192.168.16.38");
    db.setUserName("postgres");
    db.setPassword("12345678");
    if(!db.open())
    {
        // - LOG -
        file.open(QIODevice::Append | QIODevice::Text);
        out << "-> DataBase open - Error!" << endl;
        file.close();
        // - LOG -
    }
    else
    {
        // - LOG -
        file.open(QIODevice::Append | QIODevice::Text);
        out << "-> DataBase open - Ok" << endl;
        file.close();
        // - LOG -

        QSqlQuery query;
        if(!query.exec("SELECT * FROM db_size_on_disk;"))
        {
            // - LOG -
            file.open(QIODevice::Append | QIODevice::Text);
            out << "-> DataBase - Not possible to read the table!" << endl;
            file.close();
            // - LOG -
        }
        else
        {
            QSqlRecord rec = query.record();
            while(query.next())
            {
                sizeOnDisk = query.value(rec.indexOf("KB")).toInt();

                // - LOG -
                file.open(QIODevice::Append | QIODevice::Text);
                out << "-> DataBase size on disk = " << sizeOnDisk << endl;
                file.close();
                // - LOG -
            }
        }
    }
    db.close();

    // - LOG -
    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> DataBase close - Ok  Return value = " << sizeOnDisk << endl;
    file.close();
    // - LOG -
    /** End database connect **/

    return sizeOnDisk;
}

int handle_node_snmpExtended(netsnmp_mib_handler          *handler,
                             netsnmp_handler_registration *reginfo,
                             netsnmp_agent_request_info   *reqinfo,
                             netsnmp_request_info         *requests)
{
    struct snmp_pdu *response;
    struct variable_list *vars;

    u_long bytesWaiting = -12345;

    DEBUGMSGTL(("SNMPExtended",
                "Initalizing SNMPExtended scalar integer.  Default value = %d\n",
                SNMPExtended));

    QFile file;
    file.setFileName("SNMPExtended_LOG.txt");
    QTextStream out(&file);

    //       ->> snmpget -c public -v 2c localhost .1.3.6.1.4.1.8072.2.5.1.1.1.0
    //return ->> NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.0 = INTEGER: 38048
    if (reqinfo->mode == MODE_GET)
    {
        // - LOG -
        file.open(QIODevice::Append | QIODevice::Text);
        out << "\n---> handle_node_snmpExtended Init - Ok\n-> DEBUGMSGTL - Ok  Default value = " << SNMPExtended << endl;
        file.close();
        // - LOG -

        SNMPExtended = database_size(); //get database size

        bytesWaiting = (u_long) SNMPExtended;
        snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *) & bytesWaiting, sizeof(int)); //set value

        // - LOG -
        file.open(QIODevice::Append | QIODevice::Text);
        out << "-> MODE_GET - Ok  Value = " << bytesWaiting << endl;
        file.close();
        // - LOG -

        return SNMP_ERR_NOERROR;
    }

    //       ->> snmpset -c private -v 2c localhost .1.3.6.1.4.1.8072.2.5.1.1.1.0 i 12345
    //return ->> NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.0 = INTEGER: 12345
    //----------------------------------- ore --------------------------------------------
    //       ->> snmpset -c private -v 2c localhost .1.3.6.1.4.1.8072.2.5.1.1.1.0 i 111
    //return ->> NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.0 = INTEGER: 2
    if (reqinfo->mode == MODE_SET_COMMIT)
    {
        // - LOG -
        file.open(QIODevice::Append | QIODevice::Text);
        out << "\n---> handle_node_snmpExtended Init - Ok\n-> DEBUGMSGTL - Ok  Default value = " << SNMPExtended << endl;
        file.close();
        // - LOG -

        response = reqinfo->asp->orig_pdu;
        vars = response->variables;

        int varInt = -111;

        if(vars->type == ASN_INTEGER)
        {
            varInt = (int) *vars->val.integer;

            if(111 == varInt)
            {
                bytesWaiting = 2;
            }
            else
            {
                bytesWaiting = (u_long) varInt;
            }
        }
        else
            return SNMP_ERR_GENERR;

        SNMPExtended = (int) bytesWaiting; //save default value
        snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *) & bytesWaiting, sizeof(int)); //set value

        // - LOG -
        file.open(QIODevice::Append | QIODevice::Text);
        out << "-> MODE_SET_COMMIT - Ok  Value = " << bytesWaiting << endl;
        file.close();
        // - LOG -

        return SNMP_ERR_NOERROR;
    }
    else
    {
        //if other MODE
        return SNMP_ERR_NOERROR;
    }
}

void deinit_SNMPExtended(void)
{
    unregister_mib(SNMPExtended_oid,OID_LENGTH(SNMPExtended_oid));

    // - LOG -
    QFile file;
    file.setFileName("SNMPExtended_LOG.txt");
    QTextStream out(&file);
    file.open(QIODevice::Append | QIODevice::Text);
    out << "-> Unregister_mib - Ok" << endl;
    file.close();
    // - LOG -
}

#ifdef __cplusplus
}
#endif


Прокомментировал все что могло бы вызвать вопросы в самом коде.
MIB-файл и настройки net-snmp не трогал.
Данный вариант обрабатывает каждый запрос который поступает от клиента/менеджера:

Код

intelect@linux-bf9n:/usr/bin> ./snmpset -c private -v 2c localhost .1.3.6.1.4.1.8072.2.5.1.1.1.0 i 11123
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.0 = INTEGER: 11123

intelect@linux-bf9n:/usr/bin> ./snmpget -c public -v 2c localhost .1.3.6.1.4.1.8072.2.5.1.1.1.0
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.0 = INTEGER: 38048

intelect@linux-bf9n:/usr/bin> ./snmpset -c private -v 2c localhost .1.3.6.1.4.1.8072.2.5.1.1.1.0 i 111
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.0 = INTEGER: 2
 

Надеюсь не зря разгребал эту штуку   smile  и это еще кому-то пригодиться  smile 
PM MAIL   Вверх
svlary
Дата 2.9.2011, 05:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата(kyzia887 @  1.9.2011,  14:35 Найти цитируемый пост)
это еще кому-то пригодиться

  Ну, во всяком случае, мне было очень интересно ! smile Спасибо !
PM MAIL   Вверх
kyzia887
Дата 7.9.2011, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Довинтил во все выше описанное еще создание таблицы. 
MIB-файл теперь имеет следующую структуру:
NET-SNM-ITELECT-MIB.txt
Код

NET-SNMP-INTELECT-MIB DEFINITIONS ::= BEGIN
IMPORTS
    netSnmpExamples                FROM NET-SNMP-EXAMPLES-MIB
    OBJECT-TYPE, Integer32,
    MODULE-IDENTITY                FROM SNMPv2-SMI
    MODULE-COMPLIANCE, OBJECT-GROUP        FROM SNMPv2-CONF;

netSnmpIntelectMIB MODULE-IDENTITY
    LAST-UPDATE  "201108300000Z"        --30 august 2011
    ORGANIZATION "zzzz"
    CONTACT-INFO "zzzz"
    DESCRIPTION "Mib for intelect."
    ::= { netSnmpExamples 5 }

nstIntelectMibObjects        OBJECT IDENTIFIER ::= { netSnmpIntelectMIB 1 }

nstIntelectAgentModules        OBJECT IDENTIFIER ::= { nstIntelectMibObjects 1 }

nstIntelectTables        OBJECT IDENTIFIER ::= { nstIntelectAgentModules 1 }

SNMPExtended OBJECT-TYPE
    SYNTAX        Integer32
    MAX-ACCESS    read-write
    STATUS        current
    DESCRIPTION
          "This is test object for intelect"
    DEFVAL { 333 }
    ::= { nstIntelectAgentModules 1 }

MyTestTables OBJECT-TYPE
    SYNTAX        SEQUENCE OF NSTMyTestTables
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION
        "This test tables"
    ::= { nstIntelectTables 1 }

nstMyTestTables OBJECT-TYPE
    SYNTAX        NSTMyTestTables
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION
        "A row value"
    INDEX { nstTableColumn }
    ::= { MyTestTables 1 }

NSTMyTestTables ::= SEQUENCE {
    nstTableColumn        INTEGER,
    nstTableColumnNext    INTEGER
}

nstTableColumn OBJECT-TYPE
    SYNTAX        INTEGER
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION " "

    ::= { nstMyTestTables 1 }

nstTableColumnNext OBJECT-TYPE
    SYNTAX        INTEGER
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION " "

    ::= { nstMyTestTables 2 }

END


Проверяем структуру нового MIB-файла (см. выше) и должны получить что-то вроде этого:
Код

+--netSnmpIntelectMIB(5)
      |
     +-- nstIntelectMibObjects(1)
            |
            +--nstIntelectAgentModules(1)
                  |
                  +-- -RW- Integer32 SNMPExtended(1)
                  |
                  +--MyTestTables(1)
                  |     |
                  |     +--nstMyTestTables(1)
                  |           |  Index: nstTableColumn
                  |           |
                  |           +-- -R-- INTEGER   nstTableColumn(1)
                  |           +-- -R-- INTEGER   nstTableColumnNext(2)
                  |                  
                  +--nstIntelectTables(1)


Конфигурационный файл Net-SNMP стал выглядеть так (подключаю дополнительный новый модуль, который будет создавать таблицу):
snmpd.conf
Код

syslocation Server Room
syscontact Sysadmin (root@localhost)
rocommunity public 127.0.0.1
rwcommunity private 127.0.0.1
dlmod SNMPExtended /home/intelect/soft/SNMPExtended.so
dlmod MyTestTables     /home/intelect/soft/MyTestTables.so


Сам код имеет следующий вид:
MyTestTables.h
Код

#ifndef MYTESTTABLES_H
#define MYTESTTABLES_H

#ifdef __cplusplus
extern "C" {
#endif

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

// function declarations
void init_MyTestTables(void);
int handle_node_MyTestTables(netsnmp_mib_handler          *handler,
                             netsnmp_handler_registration *reginfo,
                             netsnmp_agent_request_info   *reqinfo,
                             netsnmp_request_info         *requests);
void deinit_MyTestTables(void);

#ifdef __cplusplus
}
#endif

#endif // MYTESTTABLES_H



MyTestTables.cpp
Код

#include "MyTestTables.h"

#ifdef __cplusplus
extern "C" {
#endif

netsnmp_table_data_set *table_set;
oid MyTestTables_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 5, 1, 1, 1 };

void init_MyTestTables(void)
{
    DEBUGMSGTL(("MyTestTables",
                "Initializing the MyTestTables module\n"));

    table_set = netsnmp_create_table_data_set("MyTestTables");

    // allow the creation of new rows via SNMP SETs
    table_set->allow_creation = 1;

    // set up what a row "should" look like, starting with the index
    netsnmp_table_dataset_add_index(table_set, ASN_INTEGER);

    // define what the columns should look like.
    netsnmp_table_set_add_default_row(table_set,
                                      // column 2 = INTEGER,
                                      // writable = 1,
                                      // default value = NULL,
                                      // default value len = 0
                                      2, ASN_INTEGER, 1, NULL, 0);

    // if we wanted to handle specific data in a specific way, or note
    // when requests came in we could change the NULL below to a valid
    // handler method in which we could over ride the default
    // behaviour of the table_dataset helper
    netsnmp_handler_registration *MyTestTablesModule;
    MyTestTablesModule = netsnmp_create_handler_registration("Module MyTestTables",
                                                             handle_node_MyTestTables,
                                                             MyTestTables_oid,
                                                             OID_LENGTH(MyTestTables_oid),
                                                             HANDLER_CAN_RONLY);


    netsnmp_register_table_data_set(MyTestTablesModule,
                                    table_set,
                                    NULL);

    // register the table
    netsnmp_register_auto_data_table(table_set, NULL);

    DEBUGMSGTL(("MyTestTables",
                "Done initalizing MyTestTables module\n"));
}

int handle_node_MyTestTables(netsnmp_mib_handler *handler,
                             netsnmp_handler_registration *reginfo,
                             netsnmp_agent_request_info *reqinfo,
                             netsnmp_request_info *requests)
{
    int numberProc = 5;
    for(int i = 0; i < numberProc; i++)
    {
        //add row in table
        // create the a row for the table, and add the data
        netsnmp_table_row *row;
        row = netsnmp_create_table_data_row();

        // set the index to the table row
        u_long tableIndex = (u_long) i;
        netsnmp_table_row_add_index(row, ASN_INTEGER, (u_char*) & tableIndex, sizeof(int));

        // set column 2 to be the table
        u_long tableValue = (u_long) (numberProc + i);
        netsnmp_set_row_column(row, 2, ASN_INTEGER, (u_char *) & tableValue, sizeof(int));
        netsnmp_mark_row_column_writable(row, 2, 1);  // make writable via SETs

        // add the row to the table
        netsnmp_table_dataset_add_row(table_set, row);
    }

    return SNMP_ERR_NOERROR;
}

void deinit_MyTestTables(void)
{
    netsnmp_table_dataset_remove_and_delete_row(table_set, NULL);
    netsnmp_delete_table_data_set(table_set);
    table_set = NULL;
}

#ifdef __cplusplus
}
#endif


При запросе информации получим следующее:
Код

intelect@linux-bf9n:/usr/bin> ./snmpwalk -c public -v 2c localhost .1.3.6.1.4.1.8072.2.5.1.1.1.1.2
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.1.2.0 = INTEGER: 5
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.1.2.1 = INTEGER: 6
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.1.2.2 = INTEGER: 7
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.1.2.3 = INTEGER: 8
NET-SNMP-EXAMPLES-MIB::netSnmpExamples.5.1.1.1.1.2.4 = INTEGER: 9


Если возникнут вопросы, пишите, попробую объяснить или разбраться что к чему  smile 
PM MAIL   Вверх
kyzia887
Дата 9.9.2011, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Небольшое дополнение по таблицам  smile 
Для того чтобы таблица каждый раз пересоздавала строки переписал код следующим образом:
MyTestTables.cpp
Код

#include "MyTestTables.h"
#ifdef __cplusplus
extern "C" {
#endif

int numberProcessFound = 0; //defaul number process
netsnmp_table_data_set *table_set;
oid MyTestTables_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 5, 1, 1, 1 };
void init_MyTestTables(void)
{
    DEBUGMSGTL(("MyTestTables",
                "Initializing the MyTestTables module\n"));
    table_set = netsnmp_create_table_data_set("MyTestTables");
    // allow the creation of new rows via SNMP SETs
    table_set->allow_creation = 1;
    // set up what a row "should" look like, starting with the index
    netsnmp_table_dataset_add_index(table_set, ASN_INTEGER);
    // define what the columns should look like.
    netsnmp_table_set_add_default_row(table_set,
                                      // column 2 = INTEGER,
                                      // writable = 1,
                                      // default value = NULL,
                                      // default value len = 0
                                      2, ASN_INTEGER, 1, NULL, 0);
    // if we wanted to handle specific data in a specific way, or note
    // when requests came in we could change the NULL below to a valid
    // handler method in which we could over ride the default
    // behaviour of the table_dataset helper
    netsnmp_handler_registration *MyTestTablesModule;
    MyTestTablesModule = netsnmp_create_handler_registration("Module MyTestTables",
                                                             handle_node_MyTestTables,
                                                             MyTestTables_oid,
                                                             OID_LENGTH(MyTestTables_oid),
                                                             HANDLER_CAN_RONLY);
    netsnmp_register_table_data_set(MyTestTablesModule,
                                    table_set,
                                    NULL);
    // register the table
    netsnmp_register_auto_data_table(table_set, NULL);
    DEBUGMSGTL(("MyTestTables",
                "Done initalizing MyTestTables module\n"));
}
int handle_node_MyTestTables(netsnmp_mib_handler *handler,
                             netsnmp_handler_registration *reginfo,
                             netsnmp_agent_request_info *reqinfo,
                             netsnmp_request_info *requests)
{
    /** delete all row **/
    if(numberProcessFound != 0)
    {
        netsnmp_table_row *firstRow = netsnmp_table_data_set_get_first_row(table_set);
        while(firstRow != NULL)
        {
            netsnmp_table_row *nextRow = netsnmp_table_data_set_get_next_row(table_set, firstRow);
            netsnmp_table_dataset_remove_row(table_set, firstRow);
            firstRow = nextRow;
        }
    }
    /** -------------- **/

    int numberProc = 5;
    numberProcessFound = numberProc; //set new defaul number process

    for(int i = 0; i < numberProc; i++)
    {
        //add row in table
        // create the a row for the table, and add the data
        netsnmp_table_row *row;
        row = netsnmp_create_table_data_row();
        // set the index to the table row
        u_long tableIndex = (u_long) i;
        netsnmp_table_row_add_index(row, ASN_INTEGER, (u_char*) & tableIndex, sizeof(int));
        // set column 2 to be the table
        u_long tableValue = (u_long) (numberProc + i);
        netsnmp_set_row_column(row, 2, ASN_INTEGER, (u_char *) & tableValue, sizeof(int));
        netsnmp_mark_row_column_writable(row, 2, 1);  // make writable via SETs
        // add the row to the table
        netsnmp_table_dataset_add_row(table_set, row);
    }
    return SNMP_ERR_NOERROR;
}
void deinit_MyTestTables(void)
{
    netsnmp_table_dataset_remove_and_delete_row(table_set, NULL);
    netsnmp_delete_table_data_set(table_set);
    table_set = NULL;
}
#ifdef __cplusplus
}
#endif


Все остальное осталось прежним. Всем успехов  smile 

Это сообщение отредактировал(а) kyzia887 - 9.9.2011, 10:39
PM MAIL   Вверх
azote
Дата 30.10.2012, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 30.10.2012

Репутация: нет
Всего: нет



Спасибо за статью. 
Есть такой вопрос. Могу ли я как-то создать обработчик всех OID'ов начиная с определенного, например, .1.3.6.1.4.1.8072...., и уже в своем обработчике перебирать дочерние номера и решать какому из них какое значение устанавливать?
Ведь, как я понял, у Вас в примере показывается, как обрабатывать определенные значения OID'ов.
И еще вопрос. Могу ли я создать подобное расширение агента без внедрение соответствующего MIB-модуля?
PM MAIL   Вверх
kyzia887
Дата 21.12.2012, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата

Спасибо за статью. 
Есть такой вопрос. Могу ли я как-то создать обработчик всех OID'ов начиная с определенного, например, .1.3.6.1.4.1.8072...., и уже в своем обработчике перебирать дочерние номера и решать какому из них какое значение устанавливать?
Ведь, как я понял, у Вас в примере показывается, как обрабатывать определенные значения OID'ов.
И еще вопрос. Могу ли я создать подобное расширение агента без внедрение соответствующего MIB-модуля? 


Вот на счет первого вопроса к сожалению не подскажу, т.к. сам это задачу не решал, а по поводу внедрения MIB-файла, то вроде бы можно и без него.  smile 
PM MAIL   Вверх
igormat
  Дата 17.9.2013, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 17.9.2013

Репутация: нет
Всего: нет



Добрый день, а никто не может посоветовать литературу по Net-SNMP с точки зрения девелоперов? А то туториалы на официальном сайте очень скудные.
PM MAIL   Вверх
kyzia887
Дата 17.9.2013, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(igormat @ 17.9.2013,  11:33)
Добрый день, а никто не может посоветовать литературу по Net-SNMP с точки зрения девелоперов? А то туториалы на официальном сайте очень скудные.

Лично я, когда занимался этим вопросом, так толком ни чего и не нашел, кроме различных статей и офф. сайта.
PM MAIL   Вверх
igormat
Дата 17.9.2013, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 17.9.2013

Репутация: нет
Всего: нет



Тогда вопрос. Как из запроса вычленить нужную ячейку таблицы и  ответить? Из предыдущего примера не видно где именно задается значение в ОТВЕТЕ. Или же мы просто задаем значение в таблице, а уже сам Net-SNMP достает значение?
PM MAIL   Вверх
igormat
Дата 17.9.2013, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 17.9.2013

Репутация: нет
Всего: нет



И не могли бы привести статьи касаемо обработки таблиц в Net-SNMP?
PM MAIL   Вверх
Vorlon
  Дата 16.10.2013, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.10.2013

Репутация: нет
Всего: нет



kyzia887,  здравствуй.
Если при общении с роутером на основе примера 
Код
net-snmp.org
 при подаче OID snmpget возвращает:
No such Object available on this agent at this OID - с чем это связано?  Что необходимо сделать на уровне кода, чтобы роутер всё-таки ответил?
(Только учусь и страдаю)

Добавлено через 9 минут и 31 секунду
Пример - если необходимо - сразу готов сюда выложить. )
PM MAIL   Вверх
kyzia887
Дата 16.10.2013, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата

Vorlon:
No such Object available on this agent at this OID - с чем это связано?  Что необходимо сделать на уровне кода, чтобы роутер всё-таки ответил?


Скорее всего у вас не подключен MIB файл с OID-ом по которому вы обращаетесь. Посмотрите в начале темы, я там описывал как что делал. Но это все проверялось на локальных машинах. Железки я вообще не трогал, т.к. это не требовалось.

Это сообщение отредактировал(а) kyzia887 - 16.10.2013, 11:12
PM MAIL   Вверх
Vorlon
Дата 16.10.2013, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.10.2013

Репутация: нет
Всего: нет



MIB-файл есть.

Для его подключения надо обязательно создавать SNMPExtended.c и h и собирать в so?

Можно MIB-файл напрямую привязать в snmpd.conf?

Добавлено через 8 минут и 9 секунд
Или по имени и пути MIB-файла привязать его в самом коде, например, в конструкторе?
PM MAIL   Вверх
kyzia887
Дата 16.10.2013, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



MIB файл только описывает что и как запрашивать. Файл библиотеки (*.so - linux, *.dll - windows) собственно и выдает результат.
PM MAIL   Вверх
kyzia887
  Дата 11.2.2014, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Внесу небольшие поправки во все выше описанное. 
Прошло чуть меньше 3-х лет и мне снова пришлось залезть в свои исходники и наклепать очередной модуль для Net-SNMP.
Увы. Он не завелся вот так сразу, что было для меня весьма удивительно, ведь делал все в точности как сам же и писал ранее.

Опишу две основные ошибки:
  • Не корректный MIB файл
  • Не корректный путь к библиотеке в snmpd.conf
Много писать не буду, а выложу исходники и примеры запросов.
PS: Использовал Qt 4.8.4

PhoenixNetSnmpTableModule.pro
Код

QT      -= gui

TARGET   = PhoenixServicesTable
TEMPLATE = lib
DESTDIR  = dist

SOURCES += PhoenixNetSnmpTableModule.cpp

HEADERS += PhoenixNetSnmpTableModule.h


PhoenixNetSnmpTableModule.h
Код

#ifndef PHOENIXNETSNMPTABLEMODULE_H
#define PHOENIXNETSNMPTABLEMODULE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

// function declarations
void init_PhoenixServicesTable(void);

int handle_node_PhoenixNetSnmpTableModule(netsnmp_mib_handler          *handler,
                                                                                         netsnmp_handler_registration *reginfo,
                                                                                         netsnmp_agent_request_info   *reqinfo,
                                                                                         netsnmp_request_info         *requests);

void deinit_PhoenixServicesTable(void);

#ifdef __cplusplus
}
#endif

#endif // PHOENIXNETSNMPTABLEMODULE_H


PhoenixNetSnmpTableModule.cpp
Код

#include "PhoenixNetSnmpTableModule.h"
#include <QProcess>
#include <QTextStream>
#include <QVector>

#ifdef __cplusplus
extern "C" {
#endif

int numberProcessFound = 0;
netsnmp_table_data_set *table_set;
oid PhoenixNetSnmpTableModule_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 5, 1, 1, 1, 1, 2 };

void init_PhoenixServicesTable(void)
{
    DEBUGMSGTL(("PhoenixServicesTable",
                                  "Initializing the PhoenixServicesTable module\n"));

    table_set = netsnmp_create_table_data_set("PhoenixServicesTable");

    // allow the creation of new rows via SNMP SETs
    table_set->allow_creation = 1;

    // set up what a row "should" look like, starting with the index
    netsnmp_table_dataset_add_index(table_set, ASN_OCTET_STR);

    // define what the columns should look like.
    netsnmp_table_set_add_default_row(table_set,
                                                                         // column 2 = ASN_OCTET_STR,
                                                                         // writable = 1,
                                                                         // default value = NULL,
                                                                         // default value len = 0
                                                                         2, ASN_OCTET_STR, 1, NULL, 0);

    // if we wanted to handle specific data in a specific way, or note
    // when requests came in we could change the NULL below to a valid
    // handler method in which we could over ride the default
    // behaviour of the table_dataset helper
    netsnmp_handler_registration *PhoenixNetSnmpTableModule;
    PhoenixNetSnmpTableModule = netsnmp_create_handler_registration("Module PhoenixServicesTable",
                                                                                                                                      handle_node_PhoenixNetSnmpTableModule,
                                                                                                                                      PhoenixNetSnmpTableModule_oid,
                                                                                                                                      OID_LENGTH(PhoenixNetSnmpTableModule_oid),
                                                                                                                                      HANDLER_CAN_RONLY);


    netsnmp_register_table_data_set(PhoenixNetSnmpTableModule,
                                                                    table_set,
                                                                    NULL);

    // register the table
    netsnmp_register_auto_data_table(table_set, NULL);

    DEBUGMSGTL(("PhoenixServicesTable",
                                  "Done initalizing PhoenixServicesTable module\n"));
}

int handle_node_PhoenixNetSnmpTableModule(netsnmp_mib_handler *handler,
                                                                                         netsnmp_handler_registration *reginfo,
                                                                                         netsnmp_agent_request_info *reqinfo,
                                                                                         netsnmp_request_info *requests)
{
    /** delete all row **/
    if(numberProcessFound != 0) {
        netsnmp_table_row *firstRow = netsnmp_table_data_set_get_first_row(table_set);
        while(firstRow != NULL) {
            netsnmp_table_row *nextRow = netsnmp_table_data_set_get_next_row(table_set, firstRow);
            netsnmp_table_dataset_remove_row(table_set, firstRow);
            firstRow = nextRow;
        }
    }
    /** -------------- **/

    QString allProcessMap = "";
    QProcess process;
    QStringList commandProcess;
    commandProcess << "ax";
    process.start("ps", commandProcess);
    if(!process.waitForStarted(30000)) {
        return SNMP_ERR_GENERR;
    }

    QVector <QString> processValue;

    int readStop = 0;
    while(readStop != 1) {
        if(process.waitForReadyRead(30000)) {
            QByteArray processLine = process.readAllStandardOutput();
            QTextStream processOutLocal(processLine);
            allProcessMap = allProcessMap + processOutLocal.readAll();
        } else {
            //qDebug() << "Error Read!";
            readStop = 1;
        }
    }
    process.close();

    QTextStream processOut(&allProcessMap);
    while(!processOut.atEnd()) {
        QString readLine = processOut.readLine();
        QStringList splitReadLine = readLine.split(" ");
        for(int i = 0; i < splitReadLine.size(); i++) {
            QString readLineNext = splitReadLine.operator [](i);
            QStringList splitReadLineNext = readLineNext.split("/");
            for(int j = 0; j < splitReadLineNext.size(); j++) {
                if(splitReadLineNext.operator [](j) == "qtcreator") { //find qtcreator
                    processValue.push_back("qtcreator|ok");
                }
            }
        }
    }

    numberProcessFound = processValue.size(); //save default number process
    if(processValue.size() != 0) {
        for(int i = 0; i < processValue.size(); i++) {
            // add row in table
            // create the a row for the table, and add the data
            netsnmp_table_row *row;
            row = netsnmp_create_table_data_row();

            // set the index to the table row
            u_long tableIndex = (u_long) i;
            netsnmp_table_row_add_index(row, ASN_INTEGER, (u_char*) & tableIndex, sizeof(int));

            // set column 2 to be the table
            QString tableValue = processValue.operator [](i);
            netsnmp_set_row_column(row, 2, ASN_OCTET_STR, (u_char *) tableValue.toStdString().c_str(), tableValue.size());
            netsnmp_mark_row_column_writable(row, 2, 1);  // make writable via SETs

            // add the row to the table
            netsnmp_table_dataset_add_row(table_set, row);
        }
    } else {
        //return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}

void deinit_PhoenixServicesTable(void)
{
    netsnmp_table_dataset_remove_and_delete_row(table_set, NULL);
    netsnmp_delete_table_data_set(table_set);
    table_set = NULL;
}

#ifdef __cplusplus
}
#endif


NET-SNMP-PHOENIX-MIB.txt (копируем в /usr/share/snmp/mibs/)
Код

NET-SNMP-PHOENIX-MIB DEFINITIONS ::= BEGIN

IMPORTS
    netSnmpExamples                FROM NET-SNMP-EXAMPLES-MIB
    OBJECT-TYPE, Integer32,
    MODULE-IDENTITY                FROM SNMPv2-SMI
    MODULE-COMPLIANCE, OBJECT-GROUP        FROM SNMPv2-CONF;

netSnmpPhoenixMIB MODULE-IDENTITY
    LAST-UPDATE  "201402110000Z"        --11 february 2014
    ORGANIZATION " "
    CONTACT-INFO "SPb"

    DESCRIPTION "Mib for phoenix modules."

    ::= { netSnmpExamples 5 }

PhoenixMibObjects        OBJECT IDENTIFIER ::= { netSnmpPhoenixMIB 1 }

PhoenixAgentModules        OBJECT IDENTIFIER ::= { PhoenixMibObjects 1 }

PhoenixTables        OBJECT IDENTIFIER ::= { PhoenixAgentModules 1 }

PhoenixServicesTable OBJECT-TYPE
    SYNTAX        SEQUENCE OF PhoenixServicesDataTable
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION
        "This Phoenix Services tables"
    ::= { PhoenixTables 1 }

PhoenixServicesDataTable OBJECT-TYPE
    SYNTAX        PhoenixServicesDataTable
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION
        "A row value"
    INDEX { PhoenixServicesData }
    ::= { PhoenixServicesTable 1 }

PhoenixServicesDataTable ::= SEQUENCE {
    PhoenixServicesData        OCTET STRING,
    PhoenixServicesDataNumber    INTEGER
}

PhoenixServicesData OBJECT-TYPE
    SYNTAX        OCTET STRING
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION
        "Service Data for Phoenix"

    ::= { PhoenixServicesDataTable 1 }

PhoenixServicesDataNumber OBJECT-TYPE
    SYNTAX        INTEGER
    MAX-ACCESS    read-only
    STATUS        current
    DESCRIPTION
        "Number Service Data for Phoenix"

    ::= { PhoenixServicesDataTable 2 }

END


snmpd.conf (/etc/snmp/snmpd.conf)
Код

syslocation Server Room
syscontact Sysadmin (root@localhost)

rocommunity public 127.0.0.1

dlmod PhoenixServicesTable /home/anton/SnmpDist/libPhoenixServicesTable.so


Теперь главные моменты:
  • Собирал в QtCreator-е (то что он еще до кучи пару тройку символических ссылок делает ни на что не влияет; копипастим куда нужно и не думаем ни о чем)
  • Функции void init_PhoenixServicesTable(void) и void deinit_PhoenixServicesTable(void); init_ИМЯ, КОТОРОЕ УКАЗАЛИ В SNMPD.CONF! deinit_ИМЯ, КОТОРОЕ УКАЗАЛИ В SNMPD.CONF! (если иначе, то просто ни чего не будет работать, т.к. Net-SNMP вряд ли сможет корректно распознать расширение)
  • Так как QtCreator на выходе генерирует библиотеку с префиксом lib, то и его указываем в snmpd.conf (ну нужно ему полное имя и все тут), т.е.: dlmod PhoenixServicesTable /home/anton/SnmpDist/libPhoenixServicesTable.so
В остальном все как и раньше, читайте посты выше.

PS: Если у вас не работает ваш модуль (ошибка из серии: No such Object available on this agent at this OID), то проверить из-за чего можно командой:
Код

./snmptable -c public -v 2c localhost UCD-DLMOD-MIB::dlmodTable

SNMP table: UCD-DLMOD-MIB::dlmodTable

            dlmodName                                       dlmodPath dlmodError dlmodStatus
 PhoenixServicesTable /home/anton/SnmpDist/libPhoenixServicesTable.so                 loaded


Если расширение не загрузилось, то будет хоть как-то описана причина. Например:
Код

./snmptable -c public -v 2c localhost UCD-DLMOD-MIB::dlmodTable

SNMP table: UCD-DLMOD-MIB::dlmodTable

            dlmodName                                        dlmodPath                                                                                                                 dlmodError dlmodStatus
 PhoenixServicesTable /home/anton/SnmpDist/libPhoenixServicesTable1.so dlopen failed: /home/anton/SnmpDist/libPhoenixServicesTable1.so: cannot open shared object file: No such file or directory       error


Может возникнуть косяк из-за того что Net-SNMP не подгрузит MIB. Выполняем следующее:
Код

./snmptranslate -M+. -mNET-SNMP-PHOENIX-MIB -Tp -IR netSnmpPhoenixMIB                                                                                                                                                                                                                   
                                                                                                                                                                                                                                                                                                                                                                                                                                                              Expected LAST-UPDATED (LAST-UPDATE): At line 10 in /usr/share/snmp/mibs/NET-SNMP-PHOENIX-MIB.txt                                                                                                                                                   
+--netSnmpPhoenixMIB(5)                                                                                                                                                                                                                            
   |                                                                                                                                                                                                                                               
   +--PhoenixMibObjects(1)
      |
      +--PhoenixAgentModules(1)
         |
         +--PhoenixTables(1)
            |
            +--PhoenixServicesTable(1)
               |
               +--PhoenixServicesDataTable(1)
                  |  Index: PhoenixServicesData
                  |
                  +-- -R-- String    PhoenixServicesData(1)
                  +-- -R-- INTEGER   PhoenixServicesDataNumber(2)


Ниже прикладываю исходники (мало ли что)  smile 

Это сообщение отредактировал(а) kyzia887 - 11.2.2014, 12:53

Присоединённый файл ( Кол-во скачиваний: 27 )
Присоединённый файл  PhoenixNetSnmpTableModule.zip 3,85 Kb
PM MAIL   Вверх
mchertz
Дата 23.6.2014, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 23.6.2014

Репутация: нет
Всего: нет



Спасибо автору=)

Это сообщение отредактировал(а) mchertz - 27.6.2014, 21:35
PM MAIL   Вверх
WOLFY17
Дата 26.4.2017, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 26.4.2017

Репутация: нет
Всего: нет



kyzia887, спасибо за подробное описание.
Не могу понять некоторых вещей: 
1. Для чего мы создаём пункты таблицы в MIB, если мы её создаём на уровне кода?
2. В каком случае должен вызываться обработчик, к которому привязана таблица (т. е. после какой команды из консоли). я думал что после snmpset или snmpget того OIDа, на котором висит таблица, но это не работает. Вообще не очень понимаю по какому принципу работает таблица
Поясни, если не тяжело)

PM MAIL   Вверх
kyzia887
Дата 27.4.2017, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(WOLFY17 @ 26.4.2017,  13:34)
kyzia887, спасибо за подробное описание.
Не могу понять некоторых вещей: 
1. Для чего мы создаём пункты таблицы в MIB, если мы её создаём на уровне кода?
2. В каком случае должен вызываться обработчик, к которому привязана таблица (т. е. после какой команды из консоли). я думал что после snmpset или snmpget того OIDа, на котором висит таблица, но это не работает. Вообще не очень понимаю по какому принципу работает таблица
Поясни, если не тяжело)

1. Для чего мы создаём пункты таблицы в MIB - для себя и для сторонних разработчиков, если они захотят запросить ваши данные (ведь MIB содержит описание возвращаемых данных)
2. В каком случае должен вызываться обработчик, к которому привязана таблица - после запроса snmpwalk или snmpgetnext

В том примере, который я описал, таблица не имеет постоянного размера (может быть 1 или N строк в зависимости от конфигурационного файла самого модуля), поэтому в своем коде я запрашивал эти данные командой snmpwalk, 
т.к. она выгрузит вам все дочерние элементы этой таблицы.

Например oid таблицы = .1.2.3.4.5, тогда все строки которые вы создадите будут имет oid-ы:
1 -  .1.2.3.4.5.1
2 -  .1.2.3.4.5.2
N - .1.2.3.4.5.N

Пример запроса таблицы:
Код

snmpwalk -v 2c -c public 127.0.0.1 .1.2.3.4.5 


А вот уже единичное значение (например sysname oid = 1.3.6.1.2.1.1.5 ) нужно запрашивать через snmpget.
Пример запроса sysname:
Код

snmpget -v 2c -c public 127.0.0.1 .1.3.6.1.2.1.1.5.0


К слову, если углубиться в код команды snmpwalk, то это лишь запросы snmpgetnext, выполняющиеся до тех пор, пока возвращаемые данные являются дочерними элементами таблицы.

Это сообщение отредактировал(а) kyzia887 - 27.4.2017, 15:48
PM MAIL   Вверх
WOLFY17
Дата 2.5.2017, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 26.4.2017

Репутация: нет
Всего: нет



kyzia887
Спасибо за ответ, не думал, что дождусь ответа через 3 года после активности в теме))

А почему мы в коде пишем oid таблицы 1.3.6.1.4.1.8072.2.5.1.1.1.1.2, если, судя по MIB, она будет иметь oid 1.3.6.1.4.1.8072.2.5.1.1.1.1, что означает последняя двойка в записи oid в коде?

Кстати, при запросе получаю следующие значения
Код

snmpwalk -v 2c -c public 127.0.0.1 .1.3.6.1.4.1.8072.2
iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.0 = INTEGER: 5
iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.1 = INTEGER: 6
iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.2 = INTEGER: 7
iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.3 = INTEGER: 8
iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.4 = INTEGER: 9

iso.3.6.1.4.1.8072.2.5.1.1.1.1.2 - это oid таблицы из кода;
предпоследняя цифра 2 -это, я так понимаю, столбец, который мы заполняем в строке;
последние цифры 0-4 это, наверное, индексы (кстати, вы не могли бы пояснить что они означают? ведь мы указали таблицу, создали запись в ней(строку), указали поле (столбец), что же тогда обозначает этот индекс?)
А вот откуда появилась единица между oid'ом таблицы и номером столбца (iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.0) я понять никак не могу)) Может это порядковый номер записи? Если так, то как тогда создать вторую запись в таблице?

А как в данном случае запрашивать конкретное значение из таблицы? Команда snmpget по oid не работает:
Код

snmpget -v 2c -c public 127.0.0.1 iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.2
iso.3.6.1.4.1.8072.2.5.1.1.1.1.2.1.2.2 = No Such Instance currently exists at this OID


Заранее спасибо за ответ)

Это сообщение отредактировал(а) WOLFY17 - 2.5.2017, 15:38
PM MAIL   Вверх
katenka141
Дата 19.5.2017, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 18.5.2017

Репутация: нет
Всего: нет



Есть такой вопрос. Могу ли я как-то создать обработчик всех OID'ов начиная с определенного, например, .1.3.6.1.4.1.8072...., и уже в своем обработчике перебирать дочерние номера и решать какому из них какое значение устанавливать?
Ведь, как я понял, у Вас в примере показывается, как обрабатывать определенные значения OID'ов.
И еще вопрос. Могу ли я создать подобное расширение агента без внедрение соответствующего MIB-модуля? 

ege.org.ru
ege.net.ru
PM MAIL   Вверх
kyzia887
Дата 19.5.2017, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(WOLFY17 @  2.5.2017,  11:37 Найти цитируемый пост)
WOLFY17


Боюсь что конкретное значение врядли получиться запросить, либо пробовать команду snmpgetnext.

А для более точного понимания что и как происходит попробуйте воспользоваться каким-нибудь MIB-браузером (qtmib, oid view и т.д.), он вам более детально все должен показать.

Это сообщение отредактировал(а) kyzia887 - 19.5.2017, 16:14
PM MAIL   Вверх
kyzia887
Дата 19.5.2017, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(katenka141 @ 19.5.2017,  00:13)
Есть такой вопрос. Могу ли я как-то создать обработчик всех OID'ов начиная с определенного, например, .1.3.6.1.4.1.8072...., и уже в своем обработчике перебирать дочерние номера и решать какому из них какое значение устанавливать?
Ведь, как я понял, у Вас в примере показывается, как обрабатывать определенные значения OID'ов.
И еще вопрос. Могу ли я создать подобное расширение агента без внедрение соответствующего MIB-модуля? 

ege.org.ru
ege.net.ru

1. Могу ли я как-то создать обработчик всех OID'ов начиная с определенного - могу ошибаться, но вроде бы нет. Тут более точно можно сказать, если детально изучить интерфейсы, которые предоставляет net-snmp.
2. Могу ли я создать подобное расширение агента без внедрение соответствующего MIB-модуля? - если я не ошибаюсь, то да, можете. Вроде бы net-snmp служба (snmpd) не лезет в MIB-файл, а зачитывает OID из модуля при его регистрации.
PM MAIL   Вверх
WOLFY17
Дата 16.8.2017, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 26.4.2017

Репутация: нет
Всего: нет



kyzia887, У меня почему-то оба примера (MyTestTables и PhoenixServicesTable) выдают данные только начиная со второго запроса snmpwalk. На первом выдают ошибку "No Such Object available on this agent at this OID". С первого запроса данные выдаются только если таблица заполнялась в функции инициализации, сразу при создании таблицы. И то такое ощущение, что выдаются те данные, которые были записаны при инициализации, а не те, которые были записаны уже в обработчике запроса. У тебя не возникало такой проблемы?
PM MAIL   Вверх
kyzia887
Дата 17.8.2017, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(WOLFY17 @ 16.8.2017,  15:52)
kyzia887, У меня почему-то оба примера (MyTestTables и PhoenixServicesTable) выдают данные только начиная со второго запроса snmpwalk. 
На первом выдают ошибку "No Such Object available on this agent at this OID". С первого запроса данные выдаются только если таблица заполнялась в функции инициализации, 
сразу при создании таблицы. И то такое ощущение, что выдаются те данные, которые были записаны при инициализации, а не те, которые были записаны уже в обработчике запроса. 
У тебя не возникало такой проблемы?


У меня была аналогичная ситуация, и если честно, то я ее не исправил, т.к. не было времени разбираться. Буду признателен, если ты найдешь решение и опишешь его тут.
PM MAIL   Вверх
WOLFY17
Дата 21.8.2017, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 26.4.2017

Репутация: нет
Всего: нет



Цитата(kyzia887 @  17.8.2017,  11:05 Найти цитируемый пост)
У меня была аналогичная ситуация, и если честно, то я ее не исправил, т.к. не было времени разбираться. Буду признателен, если ты найдешь решение и опишешь его тут. 

Я пока понял, что таблице нужна первоначальная, если можно так выразиться, "инициализация", то есть до запроса. Если её не сделать (то есть на заполнить таблицу чем либо), то будет происходить то, что происходит. Я пока делаю так - в функции init_<> создаю таблицу, заполняю её какими-либо данными и после этого в обработчике запросов всё работает корректно.
Но появилась другая проблема: команда snmpwalk просто выполняет последовательные запросы командами GET и GETNEXT для каждого отдельного поля: есть 10  полей-будет 10 запросов разных OIDов. То есть сама по себе таблица как таковая не запрашивается, просто все запросы сводятся к одному обработчику. Отсюда возникает небольшая сложность, касающаяся того как же заполнять таблицу? Строка (row) формируется целиком и уже после формирования добавляется в таблицу. А растягивать её формирование на несколько запросов, в каждом их которых будет заполняться одно поле-не очень хорошая идея. С другой стороны, и перезаписывать всю таблицу с одними и теми же данными 10 раз в каждом из запросов тоже не есть хорошо + в этом случае нужно следить за актуальностью данных. 

Это сообщение отредактировал(а) WOLFY17 - 21.8.2017, 09:21
PM MAIL   Вверх
kyzia887
Дата 22.12.2017, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(WOLFY17 @  21.8.2017,  09:19 Найти цитируемый пост)
Но появилась другая проблема: команда snmpwalk просто выполняет последовательные запросы командами GET и GETNEXT для каждого отдельного поля: есть 10  полей-будет 10 запросов разных OIDов. То есть сама по себе таблица как таковая не запрашивается, просто все запросы сводятся к одному обработчику.


Это нормальное поведение, ведь snmpwalk выпоняет последовательно GETNEXT запросы, пока не выберет все данные из таблицы.

PM MAIL   Вверх
WOLFY17
Дата 13.2.2019, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 26.4.2017

Репутация: нет
Всего: нет



kyzia887, попробую ещё раз возродить тему)) Вы не пробовали не отвечать на запросы с помощью net-snmp, а наоборот - самому запрашивать данные у устройства в своём приложении? То есть, может быть есть у net-snmp какой-то API для пользовательского кода, аналог snmpget. Если вы сталкивались с такой задачей буду очень благодарен, если поделитесь информацией))
PM MAIL   Вверх
kyzia887
Дата 24.11.2020, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 26.8.2011

Репутация: 1
Всего: 1



Цитата(WOLFY17 @ 13.2.2019,  14:16)
kyzia887, попробую ещё раз возродить тему)) Вы не пробовали не отвечать на запросы с помощью net-snmp, а наоборот - самому запрашивать данные у устройства в своём приложении? То есть, может быть есть у net-snmp какой-то API для пользовательского кода, аналог snmpget. Если вы сталкивались с такой задачей буду очень благодарен, если поделитесь информацией))

Добрый день. Прошло много времени, но я отвечу)) Библиотека net-snmp позволяет выполнять весь спектр клиентских запросов. Пример использования проще всего посмотреть в исходниках где реализованы клиенты (snmpget, snmpwalk и тд). Могу сказать сразу, что библиотека net-snmp не поддерживаем многопоточность в рамках клиентских запросов. Эти факторы нужно учитывать заранее.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.3115 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.