diff --git a/apps/snmp/snmp_handler.c b/apps/snmp/snmp_handler.c index aafec1aa..d30b6f42 100644 --- a/apps/snmp/snmp_handler.c +++ b/apps/snmp/snmp_handler.c @@ -178,7 +178,7 @@ snmp_scalar_return(cxobj *xs, } if (type_yang2asn1(ys, &asn1type, 1) < 0) goto done; - if ((ret = type_xml2snmp(xmlstr, &asn1type, &snmpval, &snmplen, &reason)) < 0) + if ((ret = type_xml2snmp(xmlstr, ys, &asn1type, &snmpval, &snmplen, &reason)) < 0) goto done; if (ret == 0){ clixon_debug(CLIXON_DBG_SNMP, "%s", reason); @@ -298,7 +298,7 @@ snmp_scalar_get(clixon_handle h, } goto ok; } - if ((ret = type_xml2snmp(xmlstr, &asn1type, &snmpval, &snmplen, &reason)) < 0) + if ((ret = type_xml2snmp(xmlstr, ys, &asn1type, &snmpval, &snmplen, &reason)) < 0) goto done; if (ret == 0){ clixon_debug(CLIXON_DBG_SNMP, "%s", reason); diff --git a/apps/snmp/snmp_lib.c b/apps/snmp/snmp_lib.c index 1758f08b..3481f66f 100644 --- a/apps/snmp/snmp_lib.c +++ b/apps/snmp/snmp_lib.c @@ -611,6 +611,12 @@ type_yang2asn1(yang_stmt *ys, (strcmp(display_hint, "255a")==0 || strcmp(display_hint, "255t")==0)) at = CLIXON_ASN_FIXED_STRING; + + /* Special case for bits type because netsnmp lib returns ASN_OCTET_STRING. In this case + we have to define an extended type to be able to handle bits type correctly later on. */ + if (strcmp(restype, "bits") == 0){ + at = CLIXON_ASN_BIT_STRING; + } } if (asn1_type) *asn1_type = at; @@ -648,6 +654,7 @@ type_snmp2xml(yang_stmt *ys, char *restype = NULL; /* resolved type */ char *origtype = NULL; /* original type */ yang_stmt *yrestype = NULL; + cbuf *cb = NULL; int ret; clixon_debug(CLIXON_DBG_SNMP, ""); @@ -706,6 +713,20 @@ type_snmp2xml(yang_stmt *ys, case ASN_GAUGE: // 0x42 cv_uint32_set(cv, *requestvb->val.integer); break; + case CLIXON_ASN_BIT_STRING:{ /* special case for bit string */ + if ((cb = cbuf_new()) == NULL){ + clixon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } + if ((ret = yang_val2bitsstr(yrestype, requestvb->val.bitstring, requestvb->val_len, cb)) < 0) + goto done; + if (ret == 0){ + clixon_debug(CLIXON_DBG_DEFAULT, "Invalid bits value"); + goto fail; + } + cv_strncpy(cv, cbuf_get(cb), cbuf_len(cb)); + break; + } case ASN_IPADDRESS:{ struct in_addr addr; memcpy(&addr.s_addr, requestvb->val.string, 4); @@ -753,6 +774,8 @@ type_snmp2xml(yang_stmt *ys, free(origtype); if (cv) cv_free(cv); + if (cb) + cbuf_free(cb); return retval; fail: retval = 0; @@ -849,6 +872,7 @@ type_xml2snmp_pre(char *xmlstr0, /*! Given snmp string value (as translated from XML) parse into snmp value * * @param[in] snmpstr SNMP type string + * @param[in] ys YANG node * @param[in,out] asn1type ASN.1 type id * @param[out] snmpval Malloc:ed snmp type * @param[out] snmplen Length of snmp type @@ -861,18 +885,24 @@ type_xml2snmp_pre(char *xmlstr0, */ int type_xml2snmp(char *snmpstr, + yang_stmt *ys, int *asn1type, u_char **snmpval, size_t *snmplen, char **reason) { - int retval = -1; - int ret; + int retval = -1; + int ret; + yang_stmt *yrestype; /* resolved type */ if (snmpval == NULL || snmplen == NULL){ clixon_err(OE_UNIX, EINVAL, "snmpval or snmplen is NULL"); goto done; } + + if (snmp_yang_type_get(ys, NULL, NULL, &yrestype, NULL)) // XXX yrestype + goto done; + switch (*asn1type){ case CLIXON_ASN_ROWSTATUS: *asn1type = ASN_INTEGER; @@ -978,6 +1008,15 @@ type_xml2snmp(char *snmpstr, } *asn1type = ASN_OCTET_STR; break; + case CLIXON_ASN_BIT_STRING: + if ((ret = yang_bitsstr2val(yrestype, snmpstr, snmpval, snmplen)) < 0) + goto done; + if (ret == 0){ + clixon_debug(CLIXON_DBG_DEFAULT, "Invalid bits valstr %s", snmpstr); + goto fail; + } + *asn1type = ASN_OCTET_STR; + break; default: assert(0); } diff --git a/apps/snmp/snmp_lib.h b/apps/snmp/snmp_lib.h index 406f94c9..602d2aee 100644 --- a/apps/snmp/snmp_lib.h +++ b/apps/snmp/snmp_lib.h @@ -54,6 +54,7 @@ extern "C" { * Must be back to proper net-snmp ASN_ types in type_snmp2xml and type_xml2snmp * before calling netsnmp API */ +#define CLIXON_ASN_BIT_STRING 252 /* Special case used to identify a bit string data type */ #define CLIXON_ASN_EXTRAS 253 /* Special case clixon address >= this */ #define CLIXON_ASN_PHYS_ADDR 253 /* Special case phy-address */ #define CLIXON_ASN_FIXED_STRING 254 /* RFC2578 Sec 7.7: String-valued, fixed-length */ @@ -101,7 +102,7 @@ int type_snmp2xml(yang_stmt *ys, netsnmp_request_info *requests, char **valstr); int type_xml2snmp_pre(char *xmlstr, yang_stmt *ys, char **snmpstr); -int type_xml2snmp(char *snmpstr, int *asn1type, u_char **snmpval, size_t *snmplen, char **reason); +int type_xml2snmp(char *snmpstr, yang_stmt *ys, int *asn1type, u_char **snmpval, size_t *snmplen, char **reason); int snmp_yang2xpath(yang_stmt *ys, cvec *keyvec, char **xpath); int snmp_str2oid(char *str, yang_stmt *yi, oid *objid, size_t *objidlen); int snmp_oid2str(oid **oidi, size_t *oidilen, yang_stmt *yi, cg_var *cv); diff --git a/test/mibs/CLIXON-TYPES-MIB.txt b/test/mibs/CLIXON-TYPES-MIB.txt index 4523d6cb..0ec52928 100644 --- a/test/mibs/CLIXON-TYPES-MIB.txt +++ b/test/mibs/CLIXON-TYPES-MIB.txt @@ -223,6 +223,50 @@ ifIpAddr OBJECT-TYPE DESCRIPTION "IP address example." ::= { clixonExampleScalars 13 } +bitTest OBJECT-TYPE + SYNTAX BITS { + bit00 (0), + bit01 (1), + bit02 (2), + bit03 (3), + bit04 (4), + bit05 (5), + bit06 (6), + bit07 (7), + bit08 (8), + bit09 (9), + bit10 (10), + bit11 (11), + bit12 (12), + bit13 (13), + bit14 (14), + bit15 (15), + bit16 (16), + bit17 (17), + bit18 (18), + bit19 (19), + bit20 (20), + bit21 (21), + bit22 (22), + bit23 (23), + bit24 (24), + bit25 (25), + bit26 (26), + bit27 (27), + bit28 (28), + bit29 (29), + bit30 (30), + bit31 (31), + bit32 (32), + bit33 (33), + bit34 (34), + bit35 (35) + } + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "Simple bits value used for testing." + ::= { clixonExampleScalars 14 } -- -- Example Tables diff --git a/test/test_snmp_get.sh b/test/test_snmp_get.sh index 2cd2981f..87a8b2bf 100755 --- a/test/test_snmp_get.sh +++ b/test/test_snmp_get.sh @@ -68,6 +68,7 @@ cat < $fstate true 1234567890 active + bit00 bit12 bit22 bit35 @@ -160,17 +161,20 @@ OID9="${MIB}.1.9.0" # ifHCInOctets 4294967296 OID10="${MIB}.1.10.0" # ifPromiscuousMode true(1) OID11="${MIB}.1.11.0" # ifCounterDiscontinuityTime 1234567890 TimeStamp OID12="${MIB}.1.12.0" # ifStackStatus active(1) -OID13="${MIB}.2.1" # netSnmpIETFWGTable -OID14="${MIB}.2.1.1" # netSnmpIETFWGEntry -OID15="${MIB}.2.1.1.1.42" # nsIETFWGName -OID16="${MIB}.2.1.1.2.42" # nsIETFWGChair1 -OID17="${MIB}.2.1.1.3.42" # nsIETFWGChair2 -OID18="${MIB}.2.2" # netSnmpHostsTable -OID19="${MIB}.2.2.1.1.4.116.101.115.116" # netSnmpHostName -OID20="${MIB}.2.2.1.2.4.116.101.115.116" # netSnmpHostAddressType -OID21="${MIB}.2.2.1.3" # netSnmpHostAddress -OID22="${MIB}.2.2.1.4" # netSnmpHostStorage -OID23="${MIB}.2.2.1.5" # netSnmpHostRowStatus +OID13="${MIB}.1.13.0" # ifIpAddr +OID14="${MIB}.1.14.0" # bitTest bit00(0) bit12(12) bit22(22) bit35(35) + +OID15="${MIB}.2.1" # netSnmpIETFWGTable +OID16="${MIB}.2.1.1" # netSnmpIETFWGEntry +OID17="${MIB}.2.1.1.1.42" # nsIETFWGName +OID18="${MIB}.2.1.1.2.42" # nsIETFWGChair1 +OID19="${MIB}.2.1.1.3.42" # nsIETFWGChair2 +OID20="${MIB}.2.2" # netSnmpHostsTable +OID21="${MIB}.2.2.1.1.4.116.101.115.116" # netSnmpHostName +OID22="${MIB}.2.2.1.2.4.116.101.115.116" # netSnmpHostAddressType +OID23="${MIB}.2.2.1.3" # netSnmpHostAddress +OID24="${MIB}.2.2.1.4" # netSnmpHostStorage +OID25="${MIB}.2.2.1.5" # netSnmpHostRowStatus NAME1="CLIXON-TYPES-MIB::clixonExampleInteger.0" NAME2="CLIXON-TYPES-MIB::clixonExampleSleeper.0" @@ -184,17 +188,20 @@ NAME9="CLIXON-TYPES-MIB::ifHCInOctets.0" NAME10="CLIXON-TYPES-MIB::ifPromiscuousMode.0" NAME11="CLIXON-TYPES-MIB::ifCounterDiscontinuityTime.0" NAME12="CLIXON-TYPES-MIB::ifStackStatus.0" -NAME13="CLIXON-TYPES-MIB::netSnmpIETFWGTable" -NAME14="CLIXON-TYPES-MIB::netSnmpIETFWGEntry" -NAME15="CLIXON-TYPES-MIB::nsIETFWGName" -NAME16="CLIXON-TYPES-MIB::nsIETFWGChair1" -NAME17="CLIXON-TYPES-MIB::nsIETFWGChair2" -NAME18="CLIXON-TYPES-MIB::netSnmpHostsTable" -NAME19="CLIXON-TYPES-MIB::netSnmpHostName" -NAME20="CLIXON-TYPES-MIB::netSnmpHostAddressType" -NAME21="CLIXON-TYPES-MIB::netSnmpHostAddress" -NAME22="CLIXON-TYPES-MIB::netSnmpHostStorage" -NAME23="CLIXON-TYPES-MIB::netSnmpHostRowStatus" +NAME13="CLIXON-TYPES-MIB::ifIpAddr.0" +NAME14="CLIXON-TYPES-MIB::bitTest.0" + +NAME15="CLIXON-TYPES-MIB::netSnmpIETFWGTable" +NAME16="CLIXON-TYPES-MIB::netSnmpIETFWGEntry" +NAME17="CLIXON-TYPES-MIB::nsIETFWGName" +NAME18="CLIXON-TYPES-MIB::nsIETFWGChair1" +NAME19="CLIXON-TYPES-MIB::nsIETFWGChair2" +NAME20="CLIXON-TYPES-MIB::netSnmpHostsTable" +NAME21="CLIXON-TYPES-MIB::netSnmpHostName" +NAME22="CLIXON-TYPES-MIB::netSnmpHostAddressType" +NAME23="CLIXON-TYPES-MIB::netSnmpHostAddress" +NAME24="CLIXON-TYPES-MIB::netSnmpHostStorage" +NAME25="CLIXON-TYPES-MIB::netSnmpHostRowStatus" new "$snmpget" @@ -269,26 +276,30 @@ new "Get ifStackStatus" validate_oid $OID12 $OID12 "INTEGER" 1 validate_oid $NAME12 $NAME12 "INTEGER" "active(1)" +new "Get bitTest" +validate_oid $OID14 $OID14 "Hex-STRING" "80 08 02 00 10" +validate_oid $NAME14 $NAME14 "BITS" "80 08 02 00 10 bit00(0) bit12(12) bit22(22) bit35(35)" + new "Get bulk OIDs" expectpart "$($snmpbulkget $OID1)" 0 "$OID2 = INTEGER: -1" "$OID3 = STRING: \"This is not default\"" "$OID4 = Timeticks: (12345) 0:02:03.45" "$OID5 = INTEGER: 48" "$OID6 = Gauge32: 123123123" "$OID7 = INTEGER: 3" "$OID8 = Counter32: 123456" "$OID9 = Counter64: 4294967296" "$OID10 = INTEGER: 1" "$OID11 = Timeticks: (1234567890) 142 days, 21:21:18.90" new "Test SNMP getnext netSnmpIETFWGTable" -validate_oid $OID15 $OID15 "INTEGER" 42 +validate_oid $OID17 $OID17 "INTEGER" 42 new "Test SNMP get nsIETFWGName" -validate_oid $OID15 $OID15 "INTEGER" 42 +validate_oid $OID17 $OID17 "INTEGER" 42 new "Test SNMP getnext nsIETFWGName" -expectpart "$($snmpgetnext $OID15)" 0 "STRING: \"Name1\"" +expectpart "$($snmpgetnext $OID17)" 0 "STRING: \"Name1\"" new "Test SNMP getnext netSnmpHostsTable" -expectpart "$($snmpgetnext $OID18)" 0 "$OID19 = STRING: \"test\"" +expectpart "$($snmpgetnext $OID20)" 0 "$OID21 = STRING: \"test\"" new "Test SNMP get netSnmpHostName" -expectpart "$($snmpget $OID19)" 0 "$OID19 = STRING: \"test\"" +expectpart "$($snmpget $OID21)" 0 "$OID21 = STRING: \"test\"" new "Test SNMP getnext netSnmpHostName" -expectpart "$($snmpgetnext $OID19)" 0 "$OID20 = INTEGER: 1" +expectpart "$($snmpgetnext $OID21)" 0 "$OID22 = INTEGER: 1" new "Negative test: Try to set object" expectpart "$($snmpset $OID1 i 4 2> /dev/null)" 2 "^$" diff --git a/test/test_snmp_set.sh b/test/test_snmp_set.sh index a00c68b0..0efc860d 100755 --- a/test/test_snmp_set.sh +++ b/test/test_snmp_set.sh @@ -174,7 +174,7 @@ function testrun() "STRING") set_type="s" ;; - "HEX STRING") + "Hex-STRING") set_type="x" ;; "TIMETICKS") @@ -195,23 +195,28 @@ function testrun() esac new "Set $name via SNMP" - if [ $type == "STRING" ]; then + if [ "$type" == "STRING" ]; then echo "$snmpset $oid_in $set_type $value" expectpart "$($snmpset $oid_in $set_type $value)" 0 "$type:" "$value" + elif [ "$type" == "Hex-STRING" ]; then + echo "$snmpset $oid_in $set_type \"$value\"" + expectpart "$($snmpset $oid_in $set_type "$value")" 0 "$type:" ""$value"" else echo "$snmpset $oid_in $set_type $value2" - expectpart "$($snmpset $oid_in $set_type $value)" 0 "$type: $value2" + expectpart "$($snmpset $oid_in $set_type $value)" 0 "$type: $value2" fi new "Check $name via SNMP" if [ "$type" == "STRING" ]; then expectpart "$($snmpget $oid_out)" 0 "$type:" "$value" + elif [ "$type" == "Hex-STRING" ]; then + expectpart "$($snmpget $oid_out)" 0 "$type:" ""$value"" else expectpart "$($snmpget $oid_out)" 0 "$type: $value2" fi new "Check $name via CLI" - expectpart "$($clixon_cli -1 -f $cfg show config xml)" 0 "<$name>$xvalue" + expectpart "$($clixon_cli -1 -f $cfg show config xml)" 0 "<$name>$xvalue" } function testexit(){ @@ -241,6 +246,7 @@ testrun clixonExampleSleeper INTEGER -1 -1 -1 ${MIB}.1.2.0 ${MIB}.1.2.0 testrun clixonExampleString STRING foobar foobar foobar ${MIB}.1.3.0 ${MIB}.1.3.0 testrun ifPromiscuousMode INTEGER 1 1 true ${MIB}.1.10.0 ${MIB}.1.10.0 # boolean testrun ifIpAddr IPADDRESS 1.2.3.4 1.2.3.4 1.2.3.4 ${MIB}.1.13.0 ${MIB}.1.13.0 # InetAddress +testrun bitTest "Hex-STRING" "00 20 00 00 00" "00 20 00 00 00" "bit10" ${MIB}.1.14.0 ${MIB}.1.14.0 # bitTest # XXX It was supposed to test writing hardware address type, but it is also read-only #testrun ifPhysAddress STRING ff:ee:dd:cc:bb:aa ff:ee:dd:cc:bb:aa ff:ee:dd:cc:bb:aa ${IFMIB}.2.2.1.6.1