SNMP Frontend, fixed remaining types: phys-addr, timeticks, binary, objectid

This commit is contained in:
Olof hagsand 2022-05-28 10:33:41 +02:00
parent a0541483d4
commit 7bcecc155a
7 changed files with 153 additions and 136 deletions

View file

@ -69,29 +69,34 @@ snmp_common_handler(netsnmp_mib_handler *handler,
{
int retval = -1;
netsnmp_variable_list *requestvb; /* sub of requests */
clixon_snmp_handle *sh;
char oidstr0[MAX_OID_LEN*2] = {0,};
char oidstr1[MAX_OID_LEN*2] = {0,};
char oidstr2[MAX_OID_LEN*2] = {0,};
if (requests == NULL || shp == NULL){
clicon_err(OE_XML, EINVAL, "requests or shp is null");
goto done;
}
requestvb = requests->requestvb;
if (snprint_objid(oidstr0, sizeof(oidstr0),
requestvb->name, requestvb->name_length) < 0){
clicon_err(OE_XML, 0, "snprint_objid buffer too small");
goto done;
}
if ((*shp = (clixon_snmp_handle*)handler->myvoid) == NULL){
clicon_err(OE_XML, 0, "No myvoid handler");
goto done;
}
if ((sh = (clixon_snmp_handle*)handler->myvoid) != NULL){
if (snprint_objid(oidstr1, sizeof(oidstr1),
nhreg->rootoid, nhreg->rootoid_len) < 0){
clicon_err(OE_XML, 0, "snprint_objid buffer too small");
goto done;
}
if (snprint_objid(oidstr2, sizeof(oidstr2),
sh->sh_oid, sh->sh_oidlen) < 0){
(*shp)->sh_oid, (*shp)->sh_oidlen) < 0){
clicon_err(OE_XML, 0, "snprint_objid buffer too small");
goto done;
}
if (shp)
*shp = sh;
if (strcmp(oidstr0, oidstr2) == 0)
clicon_debug(1, "%s \"%s\" %s inclusive:%d %s", __FUNCTION__,
oidstr2,
@ -102,10 +107,6 @@ snmp_common_handler(netsnmp_mib_handler *handler,
oidstr2, oidstr0,
snmp_msg_int2str(reqinfo->mode),
requests->inclusive, tablehandler?"table":"");
}
else{
assert(0);
}
retval = 0;
done:
@ -140,6 +141,7 @@ clixon_snmp_table_handler(netsnmp_mib_handler *handler,
cbuf *cb = NULL;
int ret;
clicon_debug(2, "%s", __FUNCTION__);
if ((ret = snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 1)) < 0)
goto done;
switch(reqinfo->mode){
@ -253,7 +255,7 @@ snmp_scalar_get(clicon_handle h,
}
if (type_yang2asn1(ys, &asn1type) < 0)
goto done;
if ((ret = type_snmpstr2val(snmpstr, asn1type, &snmpval, &snmplen, &reason)) < 0)
if ((ret = type_snmpstr2val(snmpstr, &asn1type, &snmpval, &snmplen, &reason)) < 0)
goto done;
if (ret == 0){
clicon_debug(1, "%s %s", __FUNCTION__, reason);
@ -365,14 +367,10 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
int asn1_type;
netsnmp_variable_list *requestvb = requests->requestvb;
clicon_debug(2, "%s", __FUNCTION__);
if (snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 0) < 0)
goto done;
ys = sh->sh_ys;
#if 0 /* If oid match fails */
netsnmp_set_request_error(reqinfo, requests,
SNMP_NOSUCHOBJECT);
return SNMP_ERR_NOERROR;
#endif
/* see net-snmp/agent/snmp_agent.h / net-snmp/library/snmp.h */
switch (reqinfo->mode) {
case MODE_GET: /* 160 */
@ -387,9 +385,11 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
/* Translate from YANG ys leaf type to SNMP asn1.1 type ids (not value), also cvtype */
if (type_yang2asn1(ys, &asn1_type) < 0)
goto done;
if (requestvb->type != asn1_type)
if (requestvb->type != asn1_type){
clicon_debug(1, "%s Expected type:%d, got: %d", __FUNCTION__, requestvb->type, asn1_type);
netsnmp_set_request_error(reqinfo, requests,
SNMP_ERR_WRONGTYPE);
}
break;
case MODE_SET_RESERVE2: /* 1 */
break;

View file

@ -57,6 +57,7 @@
#include <signal.h>
#include <assert.h>
#include <sys/types.h>
#include <netinet/ether.h> /* ether_aton */
/* net-snmp */
#include <net-snmp/net-snmp-config.h>
@ -101,18 +102,21 @@ static const map_str2int snmp_type_map[] = {
{"enumeration", ASN_INTEGER}, // 2 special case
{"uint32", ASN_GAUGE}, // 0x42 / 66
{"uint32", ASN_COUNTER}, // 0x41 / 65
{"uint32", ASN_TIMETICKS}, // 0x43 / 67
{"uint64", ASN_COUNTER64}, // 0x46 / 70
{"boolean", ASN_INTEGER}, // 2 special case -> enumeration
{NULL, -1}
};
#define CLIXON_ASN_PHYS_ADDR 0x4242
/* Map between SNMP message / mode str and int form
*/
static const map_str2int snmp_msg_map[] = {
{"MODE_SET_RESERVE1", MODE_SET_RESERVE1},
{"MODE_SET_RESERVE2", MODE_SET_RESERVE2},
{"MODE_SET_ACTION", MODE_SET_ACTION},
{"MODE_SET_COMMIT", MODE_SET_COMMIT},
{"MODE_SET_RESERVE1", MODE_SET_RESERVE1}, // 0
{"MODE_SET_RESERVE2", MODE_SET_RESERVE2}, // 1
{"MODE_SET_ACTION", MODE_SET_ACTION}, // 2
{"MODE_SET_COMMIT", MODE_SET_COMMIT}, // 3
{"MODE_SET_FREE", MODE_SET_FREE}, // 4
{"MODE_GET", MODE_GET}, // 160
{"MODE_GETNEXT", MODE_GETNEXT}, // 161
{NULL, -1}
@ -187,6 +191,16 @@ type_yang2asn1(yang_stmt *ys,
else if (strcmp(origtype, "object-identifier-128")==0){
at = ASN_OBJECT_ID;
}
else if (strcmp(origtype, "binary")==0){
at = ASN_OCTET_STR;
}
else if (strcmp(origtype, "timeticks")==0){
at = ASN_TIMETICKS; /* Clixon extended string type */
}
else if (strcmp(origtype, "phys-address")==0){
at = CLIXON_ASN_PHYS_ADDR; /* Clixon extended string type */
}
/* translate to asn.1 */
else if ((at = clicon_str2int(snmp_type_map, restype)) < 0){
clicon_err(OE_YANG, 0, "No snmp translation for YANG %s type:%s",
@ -248,6 +262,7 @@ type_snmp2xml(yang_stmt *ys,
goto done;
}
switch (requestvb->type){
case ASN_TIMETICKS: // 67
case ASN_INTEGER: // 2
if (cvtype == CGV_STRING){ /* special case for enum */
char *xmlstr;
@ -342,9 +357,11 @@ type_xml2snmpstr(char *xmlstr,
if (strcmp(restype, "enumeration") == 0){ /* special case for enum */
if ((ret = yang_enum2valstr(yrestype, xmlstr, &str)) < 0)
goto done;
if (ret == 0)
if (ret == 0){
clicon_debug(1, "Invalid enum valstr %s", xmlstr);
goto fail;
}
}
/* special case for bool: although smidump translates TruthValue to boolean
* and there is an ASN_BOOLEAN constant:
* 1) there is no code for ASN_BOOLEAN and
@ -375,17 +392,19 @@ type_xml2snmpstr(char *xmlstr,
/*! Given snmp string value (as translated frm XML) parse into snmp value
*
* @param[in] snmpstr SNMP type string
* @param[in] asn1type ASN.1 type id
* @param[in,out] asn1type ASN.1 type id
* @param[out] snmpval Malloc:ed snmp type
* @param[out] snmplen Length of snmp type
* @param[out] reason Error reason if retval is 0
* @retval 1 OK
* @retval 0 Invalid
* @retval -1 Error
* @note asn1type can be rewritten from CLIXON_ASN_ to ASN_
* XXX See sprint_realloc_timeticks
*/
int
type_snmpstr2val(char *snmpstr,
int asn1type,
int *asn1type,
u_char **snmpval,
size_t *snmplen,
char **reason)
@ -397,7 +416,7 @@ type_snmpstr2val(char *snmpstr,
clicon_err(OE_UNIX, EINVAL, "snmpval or snmplen is NULL");
goto done;
}
switch (asn1type){
switch (*asn1type){
case ASN_INTEGER: // 2
*snmplen = 4;
if ((*snmpval = malloc(*snmplen)) == NULL){
@ -409,6 +428,7 @@ type_snmpstr2val(char *snmpstr,
if (ret == 0)
goto fail;
break;
case ASN_TIMETICKS:
case ASN_COUNTER: // 0x41
case ASN_GAUGE: // 0x42
*snmplen = 4;
@ -422,7 +442,21 @@ type_snmpstr2val(char *snmpstr,
goto fail;
break;
case ASN_OBJECT_ID: // 6
case ASN_OBJECT_ID:{ // 6
oid oid1[MAX_OID_LEN] = {0,};
size_t sz1 = MAX_OID_LEN;
if (snmp_parse_oid(snmpstr, oid1, &sz1) == NULL){
clicon_debug(1, "Failed to parse OID %s", snmpstr);
goto fail;
}
*snmplen = sizeof(oid)*sz1;
if ((*snmpval = malloc(*snmplen)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
memcpy(*snmpval, oid1, *snmplen);
break;
}
case ASN_OCTET_STR: // 4
*snmplen = strlen(snmpstr)+1;
if ((*snmpval = (u_char*)strdup((snmpstr))) == NULL){
@ -448,6 +482,22 @@ type_snmpstr2val(char *snmpstr,
goto fail;
}
break;
case CLIXON_ASN_PHYS_ADDR:{
struct ether_addr *eaddr;
*snmplen = sizeof(*eaddr);
if ((*snmpval = malloc(*snmplen + 1)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
memset(*snmpval, 0, *snmplen + 1);
if ((eaddr = ether_aton(snmpstr)) == NULL){
clicon_debug(1, "ether_aton(%s)", snmpstr);
goto fail;
}
memcpy(*snmpval, eaddr, sizeof(*eaddr));
*asn1type = ASN_OCTET_STR;
break;
}
default:
assert(0);
}

View file

@ -68,7 +68,7 @@ int type_snmp2xml(yang_stmt *ys,
netsnmp_request_info *requests,
char **valstr);
int type_xml2snmpstr(char *xmlstr, yang_stmt *ys, char **snmpstr);
int type_snmpstr2val(char *snmpstr, int asn1type, u_char **snmpval, size_t *snmplen, char **reason);
int type_snmpstr2val(char *snmpstr, int *asn1type, u_char **snmpval, size_t *snmplen, char **reason);
int yang2xpath(yang_stmt *ys, cvec *keyvec, char **xpath);
#endif /* _SNMP_LIB_H_ */

View file

@ -77,15 +77,17 @@ cat <<EOF > $fstate
<ifLastChange>0</ifLastChange>
<ifInOctets>123</ifInOctets>
<ifInUcastPkts>124</ifInUcastPkts>
<ifInNUcastPkts>124</ifInNUcastPkts>
<ifInDiscards>125</ifInDiscards>
<ifInErrors>126</ifInErrors>
<ifInUnknownProtos>127</ifInUnknownProtos>
<ifOutOctets>128</ifOutOctets>
<ifOutUcastPkts>129</ifOutUcastPkts>
<ifOutNUcastPkts>129</ifOutNUcastPkts>
<ifOutDiscards>130</ifOutDiscards>
<ifOutErrors>131</ifOutErrors>
<ifOutQLen>132</ifOutQLen>
<!-- ifSpecific>SNMPv2-SMI::zeroDotZero</ifSpecific--> <!-- objid type -->
<ifSpecific>SNMPv2-SMI::zeroDotZero</ifSpecific>
</ifEntry>
<ifEntry>
<ifIndex>2</ifIndex>
@ -164,100 +166,76 @@ MIB=".1.3.6.1.2.1"
for (( i=1; i<23; i++ )); do
eval OID${i}="${MIB}.2.2.1.$i.1"
done
if false; then
OID1="${MIB}.2.2.1.1.1"
OID2="${MIB}.2.2.1.2.1"
OID3="${MIB}.2.2.1.3.1"
OID4="${MIB}.2.2.1.4.1"
OID5="${MIB}.2.2.1.5.1"
OID6="${MIB}.2.2.1.6.1"
OID7="${MIB}.2.2.1.7.1"
OID8="${MIB}.2.2.1.8.1"
OID9="${MIB}.2.2.1.9.1"
OID10="${MIB}.2.2.1.10.1"
OID11="${MIB}.2.2.1.11.1"
OID12="${MIB}.2.2.1.12.1"
OID13="${MIB}.2.2.1.13.1"
OID14="${MIB}.2.2.1.14.1"
OID15="${MIB}.2.2.1.15.1"
OID16="${MIB}.2.2.1.16.1"
OID17="${MIB}.2.2.1.17.1"
OID18="${MIB}.2.2.1.18.1"
OID19="${MIB}.2.2.1.19.1"
OID20="${MIB}.2.2.1.20.1"
OID21="${MIB}.2.2.1.21.1"
OID22="${MIB}.2.2.1.22.1"
fi
new "$snmpget"
new "Test SNMP get all entries in ifTable"
new "Test $OID2"
new "Test $OID1 ifIndex"
expectpart "$($snmpget $OID1)" 0 "$OID1 = INTEGER: 1"
new "Test $OID2"
new "Test $OID2 ifDescr"
expectpart "$($snmpget $OID2)" 0 "$OID2 = STRING: Test"
new "Test $OID3"
new "Test $OID3 ifType"
expectpart "$($snmpget $OID3)" 0 "$OID3 = INTEGER: ethernetCsmacd(6)"
new "Test $OID4"
new "Test $OID4 ifMtu"
expectpart "$($snmpget $OID4)" 0 "$OID4 = INTEGER: 1500"
new "Test $OID5"
new "Test $OID5 ifSpeed"
expectpart "$($snmpget $OID5)" 0 "$OID5 = Gauge32: 10000000"
new "Test $OID6"
#expectpart "$($snmpget $OID6)" 0 "$OID6 = STRING: aa.bb:cc:dd:ee:ff"
new "Test $OID6 ifPhysAddress yang:phys-address"
expectpart "$($snmpget $OID6)" 0 "$OID6 = STRING: aa.bb:cc:dd:ee:ff"
new "Test $OID7"
new "Test $OID7 ifAdminStatus"
expectpart "$($snmpget $OID7)" 0 "$OID7 = INTEGER: testing(3)"
new "Test $OID8"
new "Test $OID8 ifOperStatus"
expectpart "$($snmpget $OID8)" 0 "$OID8 = INTEGER: up(1)"
new "Test $OID9"
#expectpart "$($snmpget $OID9)" 0 "$OID9 = Timeticks: (0) 0:00:00.00"
new "Test $OID9 ifLastChange"
expectpart "$($snmpget $OID9)" 0 "$OID9 = Timeticks: (0) 0:00:00.00"
new "Test $OID10"
new "Test $OID10 ifInOctets"
expectpart "$($snmpget $OID10)" 0 "$OID10 = Counter32: 123"
new "Test $OID11"
new "Test $OID11 ifInUcastPkts"
expectpart "$($snmpget $OID11)" 0 "$OID11 = Counter32: 124"
new "Test $OID12"
#expectpart "$($snmpget $OID12)" 0 "$OID12 = Counter32: 125"
new "Test $OID12 ifInNUcastPkts"
expectpart "$($snmpget $OID12)" 0 "$OID12 = Counter32: 124"
new "Test $OID13"
new "Test $OID13 ifInDiscards"
expectpart "$($snmpget $OID13)" 0 "$OID13 = Counter32: 125"
new "Test $OID14"
new "Test $OID14 ifInErrors"
expectpart "$($snmpget $OID14)" 0 "$OID14 = Counter32: 126"
new "Test $OID15"
new "Test $OID15 ifInUnknownProtos"
expectpart "$($snmpget $OID15)" 0 "$OID15 = Counter32: 127"
new "Test $OID16"
new "Test $OID16 ifOutOctets"
expectpart "$($snmpget $OID16)" 0 "$OID16 = Counter32: 128"
new "Test $OID17"
new "Test $OID17 ifOutUcastPkts"
expectpart "$($snmpget $OID17)" 0 "$OID17 = Counter32: 129"
new "Test $OID18"
#expectpart "$($snmpget $OID18)" 0 "$OID18 = Counter32: 130"
new "Test $OID18 ifOutNUcastPkts"
expectpart "$($snmpget $OID18)" 0 "$OID18 = Counter32: 129"
new "Test $OID19"
new "Test $OID19 ifOutDiscards"
expectpart "$($snmpget $OID19)" 0 "$OID19 = Counter32: 130"
new "Test $OID20"
new "Test $OID20 ifOutErrors"
expectpart "$($snmpget $OID20)" 0 "$OID20 = Counter32: 131"
new "Test $OID21"
new "Test $OID21 ifOutQLen"
expectpart "$($snmpget $OID21)" 0 "$OID21 = Gauge32: 132"
new "Test $OID22"
#expectpart "$($snmpget $OID22)" 0 "$OID22 = OID: SNMPv2-SMI::zeroDotZero"
new "Test $OID22 ifSpecific"
expectpart "$($snmpget $OID22)" 0 "$OID22 = OID: .0.0"
new "Cleaning up"
testexit

View file

@ -160,17 +160,17 @@ expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: $VALUE"
NAME=ifTableLastChange
OID=$OID4
VALUE=12345678
TYPE=Gauge32 # TimeTicks
VALUE=12345 # (12345) 0:02:03.45
TYPE=TimeTicks
new "Get $NAME"
expectpart "$($snmpget $OID)" 0 "$OID = No Such Instance currently exists at this OID"
new "Set $NAME $VALUE"
expectpart "$($snmpset $OID u $VALUE)" 0 "$OID = $TYPE: $VALUE"
expectpart "$($snmpset $OID t $VALUE)" 0 "$OID = $TYPE: ($VALUE) 0:02:03.45"
new "Get $NAME $VALUE"
expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: $VALUE"
expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: ($VALUE) 0:02:03.45"
NAME=ifType
OID=$OID5
@ -205,19 +205,6 @@ expectpart "$($snmpset $OID i $VALUE)" 0 "$OID = $TYPE: $VALUE"
new "Get $NAME $VALUE"
expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: $VALUE"
NAME=ifInOctets
OID=$OID8
VALUE=123456
TYPE=Counter32
new "Set $NAME $VALUE"
# XXXYYY
#expectpart "$($snmpset $OID u $VALUE)" 0 "$OID = $TYPE: $VALUE"
new "Get $NAME $VALUE"
# XXXYYY
#expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: $VALUE"
NAME=ifPromiscuousMode
OID=$OID10
VALUE=1 # true(1)

View file

@ -116,11 +116,11 @@ function testexit()
new "SNMP table tests"
testinit
new "Test SNMP table for netSnmpIETFWGTable"
# XXXYYY
#expectpart "$($snmptable $OID)" 0 "SNMP table: NET-SNMP-EXAMPLES-MIB::netSnmpIETFWGTable" "Russ Mundy" "David Harrington"
if false; then # NOT YET
new "Test SNMP table for netSnmpIETFWGTable"
expectpart "$($snmptable $OID)" 0 "SNMP table: NET-SNMP-EXAMPLES-MIB::netSnmpIETFWGTable" "Russ Mundy" "David Harrington"
new "Set new value for one cell"
expectpart "$($snmpset $OID_SET s newstring)" 0 "$OID_SET = STRING: \"newstring\""

View file

@ -62,7 +62,7 @@ cat <<EOF > $fstate
<netSnmpExampleInteger>0x7fffffff</netSnmpExampleInteger>
<netSnmpExampleSleeper>-1</netSnmpExampleSleeper>
<netSnmpExampleString>This is not default</netSnmpExampleString>
<ifTableLastChange>12345678</ifTableLastChange>
<ifTableLastChange>12345</ifTableLastChange>
<ifType>modem</ifType>
<ifSpeed>123123123</ifSpeed>
<ifAdminStatus>testing</ifAdminStatus>
@ -189,12 +189,12 @@ new "Get $NAME $VALUE"
expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: $VALUE"
new "Test SNMP getnext netSnmpExampleString"
expectpart "$($snmpgetnext $OID3)" 0 "$OID4 = Gauge32: 12345678"
expectpart "$($snmpgetnext $OID3)" 0 "$OID4 = Timeticks: (12345) 0:02:03.45"
NAME=ifTableLastChange
OID=$OID4
VALUE=12345678
TYPE=Gauge32 # TimeTicks
VALUE="(12345) 0:02:03.45"
TYPE=TimeTicks
new "Get $NAME $VALUE"
expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: $VALUE"
@ -271,7 +271,7 @@ expectpart "$($snmpgetnext $OID10)" 0 "$OID11 = Gauge32: 1234567890"
NAME=ifCounterDiscontinuityTime
OID=$OID11
VALUE=1234567890
TYPE=Gauge32 # TimeStamp
TYPE=Gauge32 # timestamp
new "Get $NAME $VALUE"
expectpart "$($snmpget $OID)" 0 "$OID = $TYPE: $VALUE"
@ -292,21 +292,23 @@ expectpart "$($snmpgetnext $OID12)" 0 "" # XXX table OID
#----------------- table
# the index/key netSnmpHostName has type binary translates to string
# which requires a transaltion to numeric OID which is NYI
if false; then
new "Test SNMP table netSnmpIETFWGTable"
#XXXYYY
#expectpart "$($snmptable $OID13)" 0 "Name1" "Name2"
expectpart "$($snmptable $OID13)" 0 "Name1" "Name2"
new "Test SNMP getnext netSnmpIETFWGTable"
#XXXYYY
#expectpart "$($snmpgetnext $OID13)" 0 ""
expectpart "$($snmpgetnext $OID13)" 0 ""
new "Test SNMP table netSnmpHostsTable"
#XXXYYY
#expectpart "$($snmptable $OID18)" 0 "10.20.30.40" # Should verify all columns
expectpart "$($snmptable $OID18)" 0 "10.20.30.40" # Should verify all columns
new "Test SNMP getnext netSnmpHostsTable $OID18"
expectpart "$($snmpgetnext $OID18)" 0 ""
fi
new "Cleaning up"
testexit