SNMP Support for display-hint "255t" for fixed string translation
This commit is contained in:
parent
4cf1d04cb7
commit
d79d0aa933
3 changed files with 61 additions and 35 deletions
|
|
@ -111,10 +111,8 @@ static const map_str2int snmp_type_map[] = {
|
|||
{NULL, -1}
|
||||
};
|
||||
|
||||
//#define CLIXON_ASN_PHYS_ADDR 0x4242 /* Special case phy-address */
|
||||
//#define CLIXON_ASN_ADMIN_STRING 0x4243 /* Special case SnmpAdminString */
|
||||
#define CLIXON_ASN_PHYS_ADDR 253 /* Special case phy-address */
|
||||
#define CLIXON_ASN_ADMIN_STRING 254 /* Special case SnmpAdminString */
|
||||
#define CLIXON_ASN_FIXED_STRING 254 /* RFC2578 Sec 7.7: String-valued, fixed-length */
|
||||
|
||||
/* Map between clixon "orig" resolved type and ASN.1 types.
|
||||
*/
|
||||
|
|
@ -130,7 +128,6 @@ static const map_str2int snmp_orig_map[] = {
|
|||
{"InetAddress", ASN_IPADDRESS}, // 0x40 / 64 (Dont see this being used)
|
||||
{"ipv4-address", ASN_IPADDRESS}, // 0x40 / 64 (This is used instead)
|
||||
{"phys-address", CLIXON_ASN_PHYS_ADDR}, /* Clixon extended string type */
|
||||
{"SnmpAdminString", CLIXON_ASN_ADMIN_STRING}, /* cf extension display-type 255T? */
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
|
|
@ -436,15 +433,16 @@ type_yang2asn1(yang_stmt *ys,
|
|||
char *restype; /* resolved type */
|
||||
char *origtype = NULL; /* original type */
|
||||
int at;
|
||||
yang_stmt *yrestype = NULL;
|
||||
|
||||
/* Get yang type of leaf and translate to ASN.1 */
|
||||
if (snmp_yang_type_get(ys, NULL, &origtype, NULL, &restype) < 0)
|
||||
if (snmp_yang_type_get(ys, NULL, &origtype, &yrestype, &restype) < 0)
|
||||
goto done;
|
||||
/* Translate to asn.1
|
||||
* First try original type, first type
|
||||
*/
|
||||
if ((at = clicon_str2int(snmp_orig_map, origtype)) >= 0 &&
|
||||
(extended || (at != CLIXON_ASN_PHYS_ADDR && at != CLIXON_ASN_ADMIN_STRING))){
|
||||
(extended || (at != CLIXON_ASN_PHYS_ADDR && at != CLIXON_ASN_FIXED_STRING))){
|
||||
;
|
||||
}
|
||||
/* Then try fully resolved type */
|
||||
|
|
@ -453,6 +451,16 @@ type_yang2asn1(yang_stmt *ys,
|
|||
yang_argument_get(ys), restype);
|
||||
goto done;
|
||||
}
|
||||
if (extended && at == ASN_OCTET_STR && yrestype){
|
||||
yang_stmt *yrp;
|
||||
char *display_hint = NULL;
|
||||
yrp = yang_parent_get(yrestype);
|
||||
if (yang_extension_value(yrp, "display-hint", IETF_YANG_SMIV2_NS, NULL, &display_hint) < 0)
|
||||
goto done;
|
||||
/* RFC2578/2579 but maybe all strings with display-hint should use this, eg exist>0? */
|
||||
if (display_hint && strcmp(display_hint, "255t")==0)
|
||||
at = CLIXON_ASN_FIXED_STRING;
|
||||
}
|
||||
if (asn1_type)
|
||||
*asn1_type = at;
|
||||
retval = 0;
|
||||
|
|
@ -550,7 +558,7 @@ type_snmp2xml(yang_stmt *ys,
|
|||
cv_string_set(cv, inet_ntoa(addr));
|
||||
break;
|
||||
}
|
||||
case CLIXON_ASN_ADMIN_STRING:
|
||||
case CLIXON_ASN_FIXED_STRING:
|
||||
cv_string_set(cv, (char*)requestvb->val.string);
|
||||
*asn1type = ASN_OCTET_STR;
|
||||
break;
|
||||
|
|
@ -783,7 +791,7 @@ type_xml2snmp(char *snmpstr,
|
|||
*asn1type = ASN_OCTET_STR;
|
||||
break;
|
||||
}
|
||||
case CLIXON_ASN_ADMIN_STRING: /* OCTET-STRING with decrement length */
|
||||
case CLIXON_ASN_FIXED_STRING: /* OCTET-STRING with decrement length */
|
||||
*snmplen = strlen(snmpstr);
|
||||
if ((*snmpval = (u_char*)strdup((snmpstr))) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "strdup");
|
||||
|
|
@ -951,11 +959,12 @@ snmp_str2oid(char *str,
|
|||
|
||||
/*! Translate from SMI OID representation to name
|
||||
* For ints this is one to one, eg 42 -> 42
|
||||
* But for eg strings this is more comples, eg foo -> 3.6.22.22 (or something,...)
|
||||
* But for eg strings this is more complex, eg foo -> 3.6.22.22 (or something,...)
|
||||
* @param[in,out] oidi ObjID vector
|
||||
* @param[in,out] oidilen Length of ObjID vector
|
||||
* @param[in] yk Yang statement of key
|
||||
* @param[out] cv CLIgen variable string notation as "x.y.z"
|
||||
* @see rfc2578 Section 7.7
|
||||
*/
|
||||
int
|
||||
snmp_oid2str(oid **oidi,
|
||||
|
|
@ -969,7 +978,7 @@ snmp_oid2str(oid **oidi,
|
|||
cbuf *enc = NULL;
|
||||
size_t len;
|
||||
|
||||
if (type_yang2asn1(yk, &asn1_type, 0) < 0)
|
||||
if (type_yang2asn1(yk, &asn1_type, 1) < 0)
|
||||
goto done;
|
||||
if ((enc = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
|
|
@ -984,12 +993,18 @@ snmp_oid2str(oid **oidi,
|
|||
case ASN_IPADDRESS:
|
||||
cprintf(enc, "%lu", (*oidi)[i++]);
|
||||
break;
|
||||
case CLIXON_ASN_PHYS_ADDR: /* XXX may need special mapping: ether_aton() ? */
|
||||
case ASN_OCTET_STR: /* decode from N.c.c.c.c */
|
||||
len = (*oidi)[i++];
|
||||
for (; i<len+1; i++){
|
||||
cprintf(enc, "%c", (char)((*oidi)[i]&0xff));
|
||||
}
|
||||
break;
|
||||
case CLIXON_ASN_FIXED_STRING: // XXX
|
||||
for (; i<7; i++){
|
||||
cprintf(enc, "%c", (char)((*oidi)[i]&0xff));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,9 +155,18 @@ There are also client-cert tests, eg `test_ssl_certs.sh`
|
|||
Clixon snmp frontend tests require a running netsnmpd and converted YANG files from MIB.
|
||||
|
||||
Netsnmpd is 5.9 or later and can be started via systemd. For the tests
|
||||
to run, the systems IFMIB should be disabled: `-I -ifTable,ifNumber,ifXTable`
|
||||
to run, the systems IFMIB should be disabled: `-I -ifTable,ifNumber,ifXTable`, etc.
|
||||
|
||||
Converted YANG files are available at `https://github.com/clicon/mib-yangs` or alternatively use `smidump` version 0.5 or later.
|
||||
Converted YANG files are available at `https://github.com/clicon/mib-yangs` or alternatively use `smidump` version 0.5 or later. Clixon expects them to be at `/usr/local/share/mib-yangs/` by default, or configured by `--with-mib-generated-yang-dir=DIR`.
|
||||
|
||||
You also need to configure a unix socket for agent. Example of /etc/snmp/snmpd.conf:
|
||||
```
|
||||
master agentx
|
||||
agentaddress 127.0.0.1,[::1]
|
||||
rwcommunity public localhost
|
||||
agentXSocket unix:/var/run/snmp.sock
|
||||
agentxperms 777 777
|
||||
```
|
||||
|
||||
## Known issues
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
# snmpset. This requires deviation of MIB-YANG to make write operations
|
||||
# Get default value, set new value via SNMP and check it, set new value via NETCONF and check
|
||||
# Selected types from CLIXON/IF-MIB/ENTITY mib
|
||||
# SNMP table rowstatus tests
|
||||
#
|
||||
|
||||
# Magic line must be first in script (see README.md)
|
||||
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||
|
|
@ -102,34 +101,37 @@ function testrun_createAndGo()
|
|||
{
|
||||
new "createAndGo"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2)" 0 "Error in packet."
|
||||
new "Configuring a value without a row is a failure"
|
||||
echo "$snmpset SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\' = 2"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\' = 2)" 0 "Error in packet."
|
||||
new "RowStatus is active after createAndGo; can configure additional values afterwards"
|
||||
echo "$snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndGo SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndGo SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: createAndGo(4)"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndGo SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: createAndGo(4)"
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: active(1)"
|
||||
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: active(1)"
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2"
|
||||
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 1"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'notify1\' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 1"
|
||||
}
|
||||
|
||||
function testrun_createAndWait()
|
||||
{
|
||||
new "createAndWait"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndWait SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndWait"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndWait SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndWait"
|
||||
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2"
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyTag.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyTag.'notify1' = 2"
|
||||
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: notInService(2)"
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: notInService(2)"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 1"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'notify1\' = 1)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 1"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = active)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = active"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = active)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = active"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 5)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 5"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.\'notify1\' = 5)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyStorageType.'notify1' = 5"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndWait)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndWait"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndWait)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndWait"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify2' = createAndGo)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify2' = createAndGo"
|
||||
|
||||
|
|
@ -137,20 +139,20 @@ function testrun_createAndWait()
|
|||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify3' = active)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify3' = active"
|
||||
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: notInService(2)"
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = INTEGER: notInService(2)"
|
||||
}
|
||||
|
||||
function testrun_removeRows()
|
||||
{
|
||||
new "removeRows"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = createAndGo)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1'"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = createAndGo)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1'"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = destroy)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = destroy"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\' = destroy)" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1' = destroy"
|
||||
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1'"
|
||||
expectpart "$($snmpset SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1'"
|
||||
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.'notify1')" 0 "No Such Instance currently exists at this OID)"
|
||||
expectpart "$($snmpget SNMP-NOTIFICATION-MIB::snmpNotifyRowStatus.\'notify1\')" 0 "No Such Instance currently exists at this OID)"
|
||||
}
|
||||
|
||||
function testexit()
|
||||
|
|
@ -161,7 +163,7 @@ function testexit()
|
|||
new "SNMP tests"
|
||||
testinit
|
||||
|
||||
if [ -n "$SNMP_DEBUG" ]; then
|
||||
if $snmp_debug; then
|
||||
testrun_createAndGo
|
||||
testrun_createAndWait
|
||||
testrun_removeRows
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue