SNMP: Dynamic table fixes
This commit is contained in:
parent
150ad3ab8b
commit
ebfd173e0b
2 changed files with 102 additions and 40 deletions
|
|
@ -140,7 +140,10 @@ snmp_scalar_return(cxobj *xs,
|
||||||
if ((ret = type_xml2snmp_pre(xml_body(xs), ys, &xmlstr)) < 0)
|
if ((ret = type_xml2snmp_pre(xml_body(xs), ys, &xmlstr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGVALUE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_WRONGVALUE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +154,10 @@ snmp_scalar_return(cxobj *xs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_NOSUCHINSTANCE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
if (type_yang2asn1(ys, &asn1type, 1) < 0)
|
if (type_yang2asn1(ys, &asn1type, 1) < 0)
|
||||||
|
|
@ -160,7 +166,10 @@ snmp_scalar_return(cxobj *xs,
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
clicon_debug(1, "%s %s", __FUNCTION__, reason);
|
clicon_debug(1, "%s %s", __FUNCTION__, reason);
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGTYPE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_WRONGTYPE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* see snmplib/snmp_client. somewhat indirect
|
/* see snmplib/snmp_client. somewhat indirect
|
||||||
|
|
@ -245,7 +254,10 @@ snmp_scalar_get(clicon_handle h,
|
||||||
if ((ret = type_xml2snmp_pre(xml_body(x), ys, &xmlstr)) < 0)
|
if ((ret = type_xml2snmp_pre(xml_body(x), ys, &xmlstr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGVALUE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_WRONGVALUE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +268,10 @@ snmp_scalar_get(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_NOSUCHINSTANCE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
if (type_yang2asn1(ys, &asn1type, 1) < 0)
|
if (type_yang2asn1(ys, &asn1type, 1) < 0)
|
||||||
|
|
@ -265,7 +280,10 @@ snmp_scalar_get(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
clicon_debug(1, "%s %s", __FUNCTION__, reason);
|
clicon_debug(1, "%s %s", __FUNCTION__, reason);
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGTYPE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_WRONGTYPE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* see snmplib/snmp_client. somewhat indirect
|
/* see snmplib/snmp_client. somewhat indirect
|
||||||
|
|
@ -371,6 +389,7 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
|
||||||
clixon_snmp_handle *sh = NULL;
|
clixon_snmp_handle *sh = NULL;
|
||||||
int asn1_type;
|
int asn1_type;
|
||||||
netsnmp_variable_list *requestvb = requests->requestvb;
|
netsnmp_variable_list *requestvb = requests->requestvb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
clicon_debug(2, "%s", __FUNCTION__);
|
clicon_debug(2, "%s", __FUNCTION__);
|
||||||
if (snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 0) < 0)
|
if (snmp_common_handler(handler, nhreg, reqinfo, requests, &sh, 0) < 0)
|
||||||
|
|
@ -391,8 +410,10 @@ clixon_snmp_scalar_handler(netsnmp_mib_handler *handler,
|
||||||
goto done;
|
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);
|
clicon_debug(1, "%s Expected type:%d, got: %d", __FUNCTION__, requestvb->type, asn1_type);
|
||||||
netsnmp_set_request_error(reqinfo, requests,
|
if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_WRONGTYPE)) != SNMPERR_SUCCESS){
|
||||||
SNMP_ERR_WRONGTYPE);
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MODE_SET_RESERVE2: /* 1 */
|
case MODE_SET_RESERVE2: /* 1 */
|
||||||
|
|
@ -496,6 +517,7 @@ snmp_table_get(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, errno, "cvec_dup");
|
clicon_err(OE_UNIX, errno, "cvec_dup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
/* read through keys and create cvk */
|
||||||
oidilen = oidslen-(oidtlen+1);
|
oidilen = oidslen-(oidtlen+1);
|
||||||
oidi = oids+oidtlen+1;
|
oidi = oids+oidtlen+1;
|
||||||
/* Add keys */
|
/* Add keys */
|
||||||
|
|
@ -536,8 +558,9 @@ snmp_table_get(clicon_handle h,
|
||||||
* @param[in] ylist Yang of table (of list type)
|
* @param[in] ylist Yang of table (of list type)
|
||||||
* @param[in] oids OID of ultimate scalar value
|
* @param[in] oids OID of ultimate scalar value
|
||||||
* @param[in] oidslen OID length of scalar
|
* @param[in] oidslen OID length of scalar
|
||||||
|
* @retval 1 OK
|
||||||
|
* @retval 0 Failed
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 OK
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
snmp_table_getnext(clicon_handle h,
|
snmp_table_getnext(clicon_handle h,
|
||||||
|
|
@ -563,8 +586,12 @@ snmp_table_getnext(clicon_handle h,
|
||||||
size_t oidclen = MAX_OID_LEN;
|
size_t oidclen = MAX_OID_LEN;
|
||||||
oid oidk[MAX_OID_LEN] = {0,}; /* Key oid */
|
oid oidk[MAX_OID_LEN] = {0,}; /* Key oid */
|
||||||
size_t oidklen = MAX_OID_LEN;
|
size_t oidklen = MAX_OID_LEN;
|
||||||
int getnext = 0;
|
oid oidnext[MAX_OID_LEN] = {0x7fffffff,}; /* Next oid: start with high value */
|
||||||
|
size_t oidnextlen = MAX_OID_LEN;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
cxobj *xnext = NULL;
|
||||||
|
yang_stmt *ynext = NULL;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if ((ys = yang_parent_get(ylist)) == NULL ||
|
if ((ys = yang_parent_get(ylist)) == NULL ||
|
||||||
|
|
@ -606,29 +633,32 @@ snmp_table_getnext(clicon_handle h,
|
||||||
/* Append key oid */
|
/* Append key oid */
|
||||||
if (oid_append(oidc, &oidclen, oidk, oidklen) < 0)
|
if (oid_append(oidc, &oidclen, oidk, oidklen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (getnext){
|
/* Get smallest larger */
|
||||||
found++; /* return this */
|
if (oid_eq(oidc, oidclen, oids, oidslen) > 0 &&
|
||||||
break;
|
oid_eq(oidc, oidclen, oidnext, oidnextlen) < 0){
|
||||||
}
|
memcpy(oidnext, oidc, oidclen*sizeof(*oidnext));
|
||||||
/* Match oidc - key */
|
oidnextlen = oidclen;
|
||||||
if ((ret = oid_eq(oidc, oidclen, oids, oidslen)) == 0){
|
xnext = xcol;
|
||||||
getnext++; /* return next object if any */
|
ynext = ycol;
|
||||||
}
|
found++;
|
||||||
else if (ret > 0){
|
|
||||||
found++; /* return this */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} /* while xcol */
|
} /* while xcol */
|
||||||
if (found)
|
|
||||||
break;
|
|
||||||
} /* while xrow */
|
} /* while xrow */
|
||||||
}
|
}
|
||||||
if (found){
|
if (found){
|
||||||
if (snmp_scalar_return(xcol, ycol, oidc, oidclen, reqinfo, requests) < 0)
|
if (snmp_scalar_return(xnext, ynext, oidnext, oidnextlen, reqinfo, requests) < 0)
|
||||||
|
goto done;
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
oid_cbuf(cb, oidnext, oidnextlen);
|
||||||
|
clicon_debug(1, "%s next: %s", __FUNCTION__, cbuf_get(cb));
|
||||||
|
}
|
||||||
|
retval = found;
|
||||||
done:
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
if (xpath)
|
if (xpath)
|
||||||
free(xpath);
|
free(xpath);
|
||||||
if (xt)
|
if (xt)
|
||||||
|
|
@ -688,17 +718,31 @@ clixon_snmp_table_handler(netsnmp_mib_handler *handler,
|
||||||
requestvb->name, requestvb->name_length,
|
requestvb->name, requestvb->name_length,
|
||||||
reqinfo, requests)) < 0)
|
reqinfo, requests)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0){
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_NOSUCHINSTANCE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
clicon_debug(1, "%s Nosuchinstance", __FUNCTION__);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case MODE_GETNEXT: // 161
|
case MODE_GETNEXT: // 161
|
||||||
#ifdef SNMP_TABLE_DYNAMIC
|
#ifdef SNMP_TABLE_DYNAMIC
|
||||||
/* Register table sub-oid:s of existing entries in clixon */
|
/* Register table sub-oid:s of existing entries in clixon */
|
||||||
if (snmp_table_getnext(sh->sh_h, sh->sh_ys,
|
if ((ret = snmp_table_getnext(sh->sh_h, sh->sh_ys,
|
||||||
requestvb->name, requestvb->name_length,
|
requestvb->name, requestvb->name_length,
|
||||||
reqinfo, requests) < 0)
|
reqinfo, requests)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (ret == 0){
|
||||||
|
// if ((ret = netsnmp_request_set_error(requests, SNMP_NOSUCHOBJECT)) != SNMPERR_SUCCESS){
|
||||||
|
if ((ret = netsnmp_request_set_error(requests, SNMP_NOSUCHOBJECT)) != SNMPERR_SUCCESS){
|
||||||
|
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
clicon_debug(1, "%s No such object", __FUNCTION__);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case MODE_SET_RESERVE1:
|
case MODE_SET_RESERVE1:
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ snmp_msg_int2str(int msg)
|
||||||
* @param[in] objid1len Length of second OID vector
|
* @param[in] objid1len Length of second OID vector
|
||||||
* @retval 0 Equal
|
* @retval 0 Equal
|
||||||
* @retval !=0 Not equal, see man memcmp
|
* @retval !=0 Not equal, see man memcmp
|
||||||
* (Should be netsnmp lib function, cant find it)
|
* Should really be netsnmp lib function, but cant find any?
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
oid_eq(const oid *objid0,
|
oid_eq(const oid *objid0,
|
||||||
|
|
@ -173,12 +173,24 @@ oid_eq(const oid *objid0,
|
||||||
const oid *objid1,
|
const oid *objid1,
|
||||||
size_t objid1len)
|
size_t objid1len)
|
||||||
{
|
{
|
||||||
|
size_t min;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (objid0len < objid1len)
|
||||||
|
min = objid0len;
|
||||||
|
else
|
||||||
|
min = objid1len;
|
||||||
|
/* First compare common prefix */
|
||||||
|
ret = memcmp(objid0, objid1, min*sizeof(*objid0));
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
/* If equal, check lengths */
|
||||||
if (objid0len < objid1len)
|
if (objid0len < objid1len)
|
||||||
return -1;
|
return -1;
|
||||||
else if (objid0len > objid1len)
|
else if (objid0len > objid1len)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return memcmp(objid0, objid1, objid0len*sizeof(*objid0));
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Append a second OID to a first
|
/*! Append a second OID to a first
|
||||||
|
|
@ -470,6 +482,7 @@ type_snmp2xml(yang_stmt *ys,
|
||||||
cg_var *cv = NULL;
|
cg_var *cv = NULL;
|
||||||
char *restype = NULL; /* resolved type */
|
char *restype = NULL; /* resolved type */
|
||||||
yang_stmt *yrestype = NULL;
|
yang_stmt *yrestype = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if (valstr == NULL){
|
if (valstr == NULL){
|
||||||
|
|
@ -540,7 +553,10 @@ type_snmp2xml(yang_stmt *ys,
|
||||||
default:
|
default:
|
||||||
assert(0); // XXX
|
assert(0); // XXX
|
||||||
clicon_debug(1, "%s %s not supported", __FUNCTION__, cv_type2str(cvtype));
|
clicon_debug(1, "%s %s not supported", __FUNCTION__, cv_type2str(cvtype));
|
||||||
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGTYPE);
|
if ((ret = netsnmp_request_set_error(requests, SNMP_ERR_WRONGTYPE)) != SNMPERR_SUCCESS){
|
||||||
|
clicon_err(OE_SNMP, ret, "netsnmp_request_set_error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -934,20 +950,22 @@ snmp_oid2str(oid **oidi,
|
||||||
case ASN_COUNTER:
|
case ASN_COUNTER:
|
||||||
case ASN_IPADDRESS:
|
case ASN_IPADDRESS:
|
||||||
cprintf(enc, "%lu", (*oidi)[i++]);
|
cprintf(enc, "%lu", (*oidi)[i++]);
|
||||||
if (cv_string_set(cv, cbuf_get(enc)) < 0){
|
|
||||||
clicon_err(OE_UNIX, errno, "cv_string_set");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ASN_OCTET_STR: /* decode from N.c.c.c.c */
|
case ASN_OCTET_STR: /* decode from N.c.c.c.c */
|
||||||
len = (*oidi)[i++];
|
len = (*oidi)[i++];
|
||||||
for (; i<len; i++){
|
for (; i<len+1; i++){
|
||||||
cprintf(enc, "%c", (char)((*oidi)[i]&0xff));
|
cprintf(enc, "%c", (char)((*oidi)[i]&0xff));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (cbuf_len(enc)){
|
||||||
|
if (cv_string_set(cv, cbuf_get(enc)) < 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv_string_set");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (i){
|
if (i){
|
||||||
(*oidi) += i;
|
(*oidi) += i;
|
||||||
(*oidilen) -= i;
|
(*oidilen) -= i;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue