Агент SNMP: может ли mib2c генерировать код для типа InetAddress или String (т.е. что-то нецелочисленного типа)

Мне удалось преобразовать 95% выделенного MIB-кода в код C и заставить его работать в субагенте, как описано в последней части этого Руководство по Net-SNMP

Для этого я, естественно, использую mib2c.mfd.conf (я только что прочитал, что mfd расшифровывается как Mib For Dummies... все сказано...)

mib2c -I -c mib2c.mfd.conf my_mib_node

Он сгенерировал длинный файл .c почти со всеми oids, как показано ниже.

Почти не было создано строк для OID VideoInetAddr

//ABSTRACT OF SOURCE FILE GENERATED BY MIB2C
//...

long    VideoFormat = 0;  /* XXX: set default value */
// <<<=== NOTHING GENERATED HERE FOR VideoInetAddr OF TYPE INETADDRESS
// WHEREAS OTHER INTEGERS ARE NORMALLY PRESENT
long    VideoInetPort = 0;  /* XXX: set default value */
//...

void init_my_mib_node(void)
{
 //...

    const oid VideoFormat_oid[] = { 1,3,6,1,4,1,a,b,c,d,e };
    static netsnmp_watcher_info VideoFormat_winfo;
    // <<<=== NO OID GENERATED for VideoInetAddr OF TYPE INETADDRESS
    // WHEREAS OTHER OIDs ARE NORMALLY GENERATED
    static netsnmp_watcher_info VideoInetAddr_winfo; //We have the winfo after all
    const oid VideoInetPort_oid[] = { 1,3,6,1,4,1,a,b,c,d,g };
    static netsnmp_watcher_info VideoInetPort_winfo;

    DEBUGMSGTL(("my_mib_node",
    "Initializing VideoFormat scalar integer.  Default value = %d\n",
                VideoFormat));

    reg = netsnmp_create_handler_registration(
         "VideoFormat", NULL,
          VideoFormat_oid, OID_LENGTH(VideoFormat_oid),
          HANDLER_CAN_RWRITE);

    netsnmp_init_watcher_info(&VideoFormat_winfo, &VideoFormat, 
    sizeof(long),ASN_INTEGER, WATCHER_FIXED_SIZE);

   if (netsnmp_register_watched_scalar( reg, &VideoFormat_winfo ) < 0 ) {
    snmp_log( LOG_ERR, "Failed to register watched VideoFormat" );
   //...
}

Это сработало нормально и потребовало 5 минут (не нужно писать код, просто вызовите функцию init()), я смог ПОЛУЧИТЬ и УСТАНОВИТЬ все... целые числа...

Некоторые oids типа InetAddress не были сгенерированы, как и строки

Вопрос

  • Есть ли файл mib conf, способный генерировать код для каждого типа

Я попробовал mib2c.old-api.conf, который генерирует код и для нецелочисленных oid, но я считаю его не таким удобным. Нужно написать больше шаблонного кода.


person NGI    schedule 26.10.2017    source источник


Ответы (2)


Да, mib2c может генерировать код для IP-адресов. Не могу сказать, что это делает mfd, но определенно это делает какой-то mib2c.iterate.conf (для таблиц).

Тип IP в SNMP - ASN_IPADDRESS, представленный unint32_t в C. Кроме того, вам необходимо убедиться, что в MIB-файле для объекта, который представляет IP, у вас есть " СИНТАКСИС IP-адрес".

Посмотрите: файл MIB с IP-объектом и реализация на C

person Vlad    schedule 07.11.2017
comment
Определение IP, которое у меня есть в моей MIB, — SYNTAX InetAddress. Я не знаю точно, где это определено. В каталоге Net-SNMP есть каталог mibs, где я нашел INET-ADDRESS_MIB.txt. Вот вам и InetAddress ::= TEXTUAL-CONVENTION ... SYNTAX OCTET STRING (SIZE (0..255)). Вот почему в моем собственном ответе на мой вопрос я использую ASN_OCTET_STR. Я нашел ASN_OCTET_STR в Net-SNMP/include/net-snmp/library/asn1.h со значением 0x04. ASN_IPADDRESS находится в Net-SNMP/include/net-snmp/library/libsnmp.h или snmp_impl.h и имеет значение 0x40. - person NGI; 08.11.2017
comment
Файл MIB исходит от третьей стороны, и я думаю, что у меня нет другого выбора, кроме как справиться с ним. Существуют ли «хорошие» и «плохие» типы IP-адресов SNMP? Может быть, с ASN_IPADDRESS mib2c сгенерировал бы специальный код? - person NGI; 08.11.2017
comment
Некоторые oids типа InetAddress не генерировались, как и строки, на которые я раньше не обращал должного внимания. Для того, чтобы mib2c сгенерировал наилучший код, ваш файл MiB должен определить каждый пользовательский тип, используемый в нем, или импортировать их из MiB, который это делает. Вот некоторая информация и примеры кода, который необходимо добавить в MIB (вы можете создать только временную его версию только для генерации кода шаблона) kb.paessler.com/en/topic/ - person Vlad; 08.11.2017
comment
В моем файле MIB уже было IMPORTS ...InetPortNumber, InetAddress FROM INET-ADDRESS-MIB, и я снова проверяю export MIBS=all. Результат тот же. Я думаю, что файл mfd не подходит для моих нынешних нужд, так как он сначала просит вас проверить между 1) кодом в стиле ucd-snmp, который почти неполный, и 2) стилем Net-SNMP код. После выбора 2 вы выбираете 1) вы пишете код для некоторых общих скаляров (что совпадает со стилем ucd-snmp) или 2) волшебным образом связываете целочисленные переменные с целочисленными скалярами. Снова выбрав 2 явно, вы получите только целое число - person NGI; 08.11.2017
comment
да, я знаю :) Прямо сейчас я разрабатываю какой-то SNMP-агент, и поначалу я также использовал mfd. Но, в конце концов, MibsForDummies оказался не для чайников. И мы стали использовать для таблиц mib2c.iterate.conf и для скаляров mib2c.scalar.conf в большинстве случаев. - person Vlad; 08.11.2017
comment
попробуйте запустить mib2c -c mib2c.scalar.conf VideoInetAddr, чтобы посмотреть, даст ли это какой-либо результат (если этот элемент является частью таблицы, тогда mib2c.iterate.conf) - person Vlad; 08.11.2017
comment
mib2c -c mib2c.scalar.conf VideoInetAddr создает более или менее пустую оболочку. Массив oid[] не создается. Никаких netsnmp_init_watcher_info(...) или подобных полезных вещей... - person NGI; 09.11.2017

Часть ответа, но я очень далек от понимания, поэтому побочные проблемы сохраняются

Очень прагматично мне удалось добавить вручную

//I put here ONLY what I added, see question above to complete code
#define STR_LENGTH_IPV4 sizeof("xxx.yyy.zzz.www")
char   VideoInetAddr[STR_LENGTH_IPV4] = "192.168.2.3";
//...
const oid VideoInetAddr_oid[] = { 1,3,6,1,4,1,a,b,c,d,f };

reg = netsnmp_create_handler_registration(
         "VideoInetAddr", NULL,
          VideoInetAddr_oid, OID_LENGTH(VideoInetAddr_oid),
          HANDLER_CAN_RWRITE);

netsnmp_init_watcher_info(&VideoInetAddr_winfo, &VideoInetAddr, sizeof(VideoInetAddr),
              ASN_OCTET_STR,  WATCHER_MAX_SIZE );

if (netsnmp_register_watched_scalar( reg, &VideoInetAddr_winfo ) < 0 ) {
    snmp_log( LOG_ERR, "Failed to register watched VideoInetAddr" );
}

По-прежнему нужно точно понимать вариант типа WATCHER_MAX_SIZE (это хороший вариант?)

person NGI    schedule 26.10.2017