📄 agent_registry.c
字号:
{
return register_mib_priority( moduleName, var, varsize, numvars,
mibloc, mibloclen, DEFAULT_MIB_PRIORITY );
}
void
unload_subtree( struct subtree *sub, struct subtree *prev)
{
struct subtree *ptr;
if ( prev != NULL ) { /* non-leading entries are easy */
prev->children = sub->children;
return;
}
/* otherwise, we need to amend our neighbours as well */
if ( sub->children == NULL) { /* just remove this node completely */
for (ptr = sub->prev ; ptr ; ptr=ptr->children )
ptr->next = sub->next;
for (ptr = sub->next ; ptr ; ptr=ptr->children )
ptr->prev = sub->prev;
return;
}
else {
for (ptr = sub->prev ; ptr ; ptr=ptr->children )
ptr->next = sub->children;
for (ptr = sub->next ; ptr ; ptr=ptr->children )
ptr->prev = sub->children;
return;
}
}
int
unregister_mib_range( oid *name, size_t len, int priority,
int range_subid, oid range_ubound)
{
struct subtree *list, *myptr;
struct subtree *prev, *child; /* loop through children */
struct register_parameters reg_parms;
list = find_subtree( name, len, subtrees );
if ( list == NULL )
return MIB_NO_SUCH_REGISTRATION;
for ( child=list, prev=NULL; child != NULL;
prev=child, child=child->children ) {
if (( snmp_oid_compare( child->name, child->namelen, name, len) == 0 )
&& ( child->priority == priority ))
break; /* found it */
}
if ( child == NULL )
return MIB_NO_SUCH_REGISTRATION;
unload_subtree( child, prev );
myptr = child; /* remember this for later */
/*
* Now handle any occurances in the following subtrees,
* as a result of splitting this range. Due to the
* nature of the way such splits work, the first
* subtree 'slice' that doesn't refer to the given
* name marks the end of the original region.
*
* This should also serve to register ranges.
*/
for ( list = myptr->next ; list != NULL ; list=list->next ) {
for ( child=list, prev=NULL; child != NULL;
prev=child, child=child->children ) {
if (( snmp_oid_compare( child->name, child->namelen,
name, len) == 0 )
&& ( child->priority == priority )) {
unload_subtree( child, prev );
free_subtree( child );
break;
}
}
if ( child == NULL ) /* Didn't find the given name */
break;
}
free_subtree( myptr );
reg_parms.name = name;
reg_parms.namelen = len;
reg_parms.priority = priority;
reg_parms.range_subid = range_subid;
reg_parms.range_ubound = range_ubound;
snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREGISTER_OID,
®_parms);
return MIB_UNREGISTERED_OK;
}
int
unregister_mib_priority(oid *name, size_t len, int priority)
{
return unregister_mib_range( name, len, priority, 0, 0 );
}
int
unregister_mib(oid *name,
size_t len)
{
return unregister_mib_priority( name, len, DEFAULT_MIB_PRIORITY );
}
void
unregister_mibs_by_session (struct snmp_session *ss)
{
struct subtree *list, *list2;
struct subtree *child, *prev, *next_child;
for( list = subtrees; list != NULL; list = list2) {
list2 = list->next;
for ( child=list, prev=NULL; child != NULL; child=next_child ) {
next_child = child->children;
if (( (ss->flags & SNMP_FLAGS_SUBSESSION) && child->session == ss ) ||
(!(ss->flags & SNMP_FLAGS_SUBSESSION) &&
child->session->subsession == ss )) {
unload_subtree( child, prev );
free_subtree( child );
}
else
prev = child;
}
}
}
struct subtree *
free_subtree(struct subtree *st)
{
struct subtree *ret = NULL;
if ((snmp_oid_compare(st->name, st->namelen, st->start, st->start_len) == 0)
&& (st->variables != NULL))
free(st->variables);
if (st->next != NULL)
ret = st->next;
free(st);
return ret;
}
/* in_a_view: determines if a given snmp_pdu is allowed to see a
given name/namelen OID pointer
name IN - name of var, OUT - name matched
nameLen IN -number of sub-ids in name, OUT - subid-is in matched name
pi IN - relevant auth info re PDU
cvp IN - relevant auth info re mib module
*/
int
in_a_view(oid *name, /* IN - name of var, OUT - name matched */
size_t *namelen, /* IN -number of sub-ids in name*/
struct snmp_pdu *pdu, /* IN - relevant auth info re PDU */
int type) /* IN - variable type being checked */
{
struct view_parameters view_parms;
view_parms.pdu = pdu;
view_parms.name = name;
if (namelen)
view_parms.namelen = *namelen;
else
view_parms.namelen = 0;
view_parms.errorcode = 0;
if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
return 0; /* Enable bypassing of view-based access control */
/* check for v1 and counter64s, since snmpv1 doesn't support it */
if (pdu->version == SNMP_VERSION_1 && type == ASN_COUNTER64)
return 5;
switch (pdu->version) {
case SNMP_VERSION_1:
case SNMP_VERSION_2c:
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
case SNMP_VERSION_3:
#endif
snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
&view_parms);
return view_parms.errorcode;
}
return 1;
}
/* in_a_view: determines if a given snmp_pdu is ever going to be allowed to do
anynthing or if it's not going to ever be authenticated. */
int
check_access(struct snmp_pdu *pdu) /* IN - pdu being checked */
{
struct view_parameters view_parms;
view_parms.pdu = pdu;
view_parms.name = 0;
view_parms.namelen = 0;
view_parms.errorcode = 0;
if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW)
return 0; /* Enable bypassing of view-based access control */
switch (pdu->version) {
case SNMP_VERSION_1:
case SNMP_VERSION_2c:
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
case SNMP_VERSION_3:
#endif
snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
SNMPD_CALLBACK_ACM_CHECK_INITIAL,
&view_parms);
return view_parms.errorcode;
}
return 1;
}
/* lexicographical compare two object identifiers.
* Returns -1 if name1 < name2,
* 0 if name1 = name2, or name1 matches name2 for length of name2
* 1 if name1 > name2
*
* Note: snmp_oid_compare checks len2 before last return.
*/
int
compare_tree(const oid *in_name1,
size_t len1,
const oid *in_name2,
size_t len2)
{
register int len, res;
register const oid * name1 = in_name1;
register const oid * name2 = in_name2;
/* len = minimum of len1 and len2 */
if (len1 < len2)
len = len1;
else
len = len2;
/* find first non-matching OID */
while(len-- > 0){
res = *(name1++) - *(name2++);
if (res < 0)
return -1;
if (res > 0)
return 1;
}
/* both OIDs equal up to length of shorter OID */
if (len1 < len2)
return -1;
/* name1 matches name2 for length of name2, or they are equal */
return 0;
}
struct subtree *find_subtree_previous(oid *name,
size_t len,
struct subtree *subtree)
{
struct subtree *myptr, *previous = NULL;
if ( subtree )
myptr = subtree;
else
myptr = subtrees; /* look through everything */
for( ; myptr != NULL; previous = myptr, myptr = myptr->next) {
if (snmp_oid_compare(name, len, myptr->start, myptr->start_len) < 0)
return previous;
}
return previous;
}
struct subtree *find_subtree_next(oid *name,
size_t len,
struct subtree *subtree)
{
struct subtree *myptr = NULL;
myptr = find_subtree_previous(name, len, subtree);
if ( myptr != NULL ) {
myptr = myptr->next;
while ( myptr && (myptr->variables == NULL || myptr->variables_len == 0) )
myptr = myptr->next;
return myptr;
}
else if (subtree && snmp_oid_compare(name, len, subtree->start, subtree->start_len) < 0)
return subtree;
else
return NULL;
}
struct subtree *find_subtree(oid *name,
size_t len,
struct subtree *subtree)
{
struct subtree *myptr;
myptr = find_subtree_previous(name, len, subtree);
if (myptr && snmp_oid_compare(name, len, myptr->end, myptr->end_len) < 0)
return myptr;
return NULL;
}
struct snmp_session *get_session_for_oid( oid *name, size_t len)
{
struct subtree *myptr;
myptr = find_subtree_previous(name, len, subtrees);
while ( myptr && myptr->variables == NULL )
myptr = myptr->next;
if ( myptr == NULL )
return NULL;
else
return myptr->session;
}
static struct subtree root_subtrees[] = {
{ { 0 }, 1 }, /* ccitt */
{ { 1 }, 1 }, /* iso */
{ { 2 }, 1 } /* joint-ccitt-iso */
};
void setup_tree (void)
{
#ifdef USING_AGENTX_SUBAGENT_MODULE
int role;
role = ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE);
ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT);
#endif
register_mib("", NULL, 0, 0,
root_subtrees[0].name, root_subtrees[0].namelen);
register_mib("", NULL, 0, 0,
root_subtrees[1].name, root_subtrees[1].namelen);
register_mib("", NULL, 0, 0,
root_subtrees[2].name, root_subtrees[2].namelen);
/* Support for 'static' subtrees (subtrees_old) has now been dropped */
/* No longer necessary to sort the mib tree - this is inherent in
the construction of the subtree structure */
#ifdef USING_AGENTX_SUBAGENT_MODULE
ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, role);
#endif
}
/*
* Initial support for index allocation
*/
extern struct snmp_session *main_session;
char *
register_string_index( oid *name, size_t name_len, char *cp )
{
struct variable_list varbind, *res;
memset( &varbind, 0, sizeof(struct variable_list));
varbind.type = ASN_OCTET_STR;
snmp_set_var_objid( &varbind, name, name_len );
if ( cp != ANY_STRING_INDEX ) {
snmp_set_var_value( &varbind, (u_char *)cp, strlen(cp) );
res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
}
else
res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
if ( res == NULL )
return NULL;
else
return (char *)res->val.string;
}
int
register_int_index( oid *name, size_t name_len, int val )
{
struct variable_list varbind, *res;
memset( &varbind, 0, sizeof(struct variable_list));
varbind.type = ASN_INTEGER;
snmp_set_var_objid( &varbind, name, name_len );
varbind.val.string = varbind.buf;
if ( val != ANY_INTEGER_INDEX ) {
varbind.val_len = sizeof(long);
*varbind.val.integer = val;
res = register_index( &varbind, ALLOCATE_THIS_INDEX, main_session );
}
else
res = register_index( &varbind, ALLOCATE_ANY_INDEX, main_session );
if ( res == NULL )
return -1;
else
return *res->val.integer;
}
struct variable_list *
register_oid_index( oid *name, size_t name_len,
oid *value, size_t value_len )
{
struct variable_list varbind;
memset( &varbind, 0, sizeof(struct variable_list));
varbind.type = ASN_OBJECT_ID;
snmp_set_var_objid( &varbind, name, name_len );
if ( value != ANY_OID_INDEX ) {
snmp_set_var_value( &varbind, (u_char*)value, value_len*sizeof(oid) );
return( register_index( &varbind, ALLOCATE_THIS_INDEX, main_session ));
}
else
return( register_index( &varbind, ALLOCATE_ANY_INDEX, main_session ));
}
struct variable_list*
register_index(struct variable_list *varbind, int flags, struct snmp_session *ss )
{
struct snmp_index *new_index, *idxptr, *idxptr2;
struct snmp_index *prev_oid_ptr, *prev_idx_ptr;
int res, res2, i;
#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING)
if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) == SUB_AGENT )
return( agentx_register_index( ss, varbind, flags ));
#endif
/* Look for the requested OID entry */
prev_oid_ptr = NULL;
prev_idx_ptr = NULL;
res = 1;
res2 = 1;
for( idxptr = snmp_index_head ; idxptr != NULL;
prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) {
if ((res = snmp_oid_compare(varbind->name, varbind->name_length,
idxptr->varbind.name,
idxptr->varbind.name_length)) <= 0 )
break;
}
/* Found the OID - now look at the registered indices */
if ( res == 0 && idxptr ) {
if ( varbind->type != idxptr->varbind.type )
return NULL; /* wrong type */
/*
* If we've been asked for an arbitrary new value,
* then find the end of the list.
* If we've been asked for any arbitrary value,
* then look for an unused entry, and use that.
* If there aren't any, continue as for new.
* Otherwise, locate the given value in the (sorted)
* list of already allocated values
*/
if ( flags & ALLOCATE_ANY_INDEX ) {
for(idxptr2 = idxptr ; idxptr2 != NULL;
prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
if ( flags == ALLOCATE_ANY_INDEX && idxptr2->session == NULL ) {
idxptr2->session = ss ;
return &idxptr2->varbind;
}
}
}
else {
for(idxptr2 = idxptr ; idxptr2 != NULL;
prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) {
switch ( varbind->type ) {
case ASN_INTEGER:
res2 = (*varbind->val.integer - *idxptr2->varbind.val.integer);
break;
case ASN_OCTET_STR:
i = SNMP_MIN(varbind->val_len, idxptr2->varbind.val_len);
res2 = memcmp(varbind->val.string, idxptr2->varbind.val.string, i);
break;
case ASN_OBJECT_ID:
res2 = snmp_oid_compare(varbind->val.objid, varbind->val_len/sizeof(oid),
idxptr2->varbind.val.objid,
idxptr2->varbind.val_len/sizeof(oid));
break;
default:
return NULL; /* wrong type */
}
if ( res2 <= 0 )
break;
}
if ( res2 == 0 )
return NULL; /* duplicate value */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -