📄 ntfy_chk.c
字号:
/* * Copyright 2000-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//* * Copyright 1998 Integrated Systems, Inc. * All rights reserved. *//* * $Log: ntfy_chk.c,v $ * Revision 1.2 2001/11/06 21:20:16 josh * revised new path hacking * * Revision 1.1.1.1 2001/11/05 17:47:43 tneale * Tornado shuffle * * Revision 9.8.4.1 2001/08/07 18:33:58 josh * adding support for SNMPv1/v2c/v3 coexistence to SNMP Notify code * * Revision 9.8 2001/04/11 20:42:57 josh * merge from the kingfisher branch * * Revision 9.7 2001/01/19 22:22:23 paul * Update copyright. * * Revision 9.6 2000/07/12 20:06:00 josh * some functions are no longer static, some only build when * ENVOY_SNMP_V3_NOTIFY is installed. * * Revision 9.5.2.4 2001/03/12 22:08:20 tneale * Updated copyright * * Revision 9.5.2.3 2000/12/13 20:51:08 josh * SNMP_Send_Notify_Name() now obsoletes SNMP_Send_Notify() * logic of SNMP_Send_Notify_Name() is improved to help prevent nesting of * locks and generally smooth out flow of data * * Revision 9.5.2.2 2000/11/30 19:40:06 josh * fixing a few small bugs in the notify code and method routines... * * Revision 9.5.2.1 2000/09/20 21:47:01 josh * bringing branch up to currency with the root tree * * Revision 9.5 2000/03/17 00:19:13 meister * Update copyright message * * Revision 9.4 2000/02/04 21:56:14 josh * functions which are clearly static have been declared as such. * this makes the vxWorks compiler happy. * * Revision 9.3 1999/12/23 15:42:21 josh * a bug in taglist_check() was causing "foobar foo" to not match * with "foo" * * Revision 9.2 1999/11/09 17:56:39 josh * fixing memory leaks and initialization issues * * Revision 9.1 1999/11/04 21:14:05 josh * fixing Purify-related bugs * * Revision 9.0 1999/10/21 20:41:38 josh * updating version stamps * * Revision 1.4 1999/09/27 21:11:46 josh * fixing nits, rewriting engine id <--> address code, adding installation * option * * Revision 1.3 1999/09/21 21:33:13 josh * deal with fact that sysUpTime is first, TrapID is second varbind * * Revision 1.2 1999/09/14 19:29:28 josh * completed code for sending notifies * * Revision 1.1 1999/09/08 18:10:51 josh * functions to build a target list for a given notify * * *//* [clearcase]modification history-------------------01b,18apr05,job update copyright notices01a,24nov03,job update copyright information*/#include <wrn/wm/snmp/engine/asn1.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/view.h>#include <wrn/wm/snmp/engine/buffer.h>#include <wrn/wm/snmp/engine/v3_ntfy.h>#include <wrn/wm/snmp/engine/v3_trgt.h>#include <wrn/wm/snmp/engine/snmpdefs.h>#include <wrn/wm/snmp/engine/objectid.h>#include <wrn/wm/snmp/engine/ntfy_chk.h>/****************************************************************************NAME: taglist_next_tagPURPOSE: Advance a pointer in an EBUFFER_T to point to the next tag in the tag list.PARAMETERS: EBUFFER_T * pointer to the tag list bits8_t * pointer into the tag list RETURNS: Nothing****************************************************************************/static bits8_t * taglist_next_tag(EBUFFER_T *tag_list, bits8_t *tlp){if ((tlp < EBufferStart(tag_list)) || (tlp >= EBufferNext(tag_list))) { return 0; } while ((tlp < EBufferNext(tag_list)) && (!tag_whitespace(*tlp))) tlp++;if (tlp < EBufferNext(tag_list)) { while ((tlp < EBufferNext(tag_list)) && tag_whitespace(*tlp)) tlp++; }if (tlp >= EBufferNext(tag_list)) return 0;return tlp;}/****************************************************************************NAME: taglist_checkPURPOSE: Check to see if a given tag is in a given tag listPARAMETERS: EBUFFER_T * pointer to the tag list EBUFFER_T * pointer to the tagRETURNS: 0 if tag is in list, -1 otherwise****************************************************************************/int taglist_check(EBUFFER_T *tag_list, EBUFFER_T *tag){bits8_t *tlp, *tp;int tag_len, match_len;tag_len = EBufferUsed(tag);for (tlp = EBufferStart(tag_list), tp = EBufferStart(tag), match_len = 0; tlp; tlp = taglist_next_tag(tag_list, tlp), tp = EBufferStart(tag), match_len = 0) { for (; ((tlp < EBufferNext(tag_list)) && (tp < EBufferNext(tag)) && (match_len < tag_len) && (*tlp == *tp)) ; tlp++, tp++, match_len++) ; if ((match_len == tag_len) && ((tlp == EBufferNext(tag_list)) || tag_whitespace(*tlp))) return 0; }return -1;}/****************************************************************************NAME: init_target_listPURPOSE: Initializes all the field in the TARGET_LIST_T structure.PARAMETERS: TARGET_LIST_T * the target list item to be initializedRETURNS: nothing****************************************************************************/void init_target_list(TARGET_LIST_T *target_list){target_list->pktp = 0;target_list->vblp = 0;EBufferInitialize(&(target_list->context));MEMSET(&(target_list->for_addr), 0, sizeof(SNMPADDR_T));target_list->tdomain.num_components = 0;target_list->tdomain.component_list = 0;EBufferInitialize(&(target_list->taddress));target_list->timeout = 0;target_list->retry_count = 0;target_list->mms = 0;target_list->ptype = 0;target_list->mp_model = 0;target_list->sec_model = 0;EBufferInitialize(&(target_list->sec_name));target_list->sec_level = 0;target_list->flags = 0;}/****************************************************************************NAME: clean_target_listPURPOSE: Destroy a target list. However, don't destroy anything that's being used to send a probe.PARAMETERS: TARGET_LIST_T * pointer to the OID to be checkedRETURNS: nothing****************************************************************************/void clean_target_list(TARGET_LIST_T *tlist){TARGET_LIST_T *current;while (tlist) { current = tlist; tlist = tlist->next; if (current->flags & SNMP_TARGET_LIST_SEND_PROBE) { current->next = 0; continue; } Clean_Obj_ID(&(current->tdomain)); EBufferClean(&(current->taddress)); EBufferClean(&(current->context)); EBufferClean(&(current->sec_name)); if (current->vblp) { Clean_vb_list(current->vblp); SNMP_memory_free(current->vblp); } SNMP_memory_free(current); }}#if (INSTALL_ENVOY_SNMP_V3_NOTIFY)/****************************************************************************NAME: filter_subtree_checkPURPOSE: Check to see if a given OID matches a subtree and maskPARAMETERS: OBJ_ID_T * pointer to the OID to be checked OBJ_ID_T * pointer to the subtree EBUFFER_T * pointer to the subtree maskRETURNS: 0 if subtree matches, -1 if not****************************************************************************/static int filter_subtree_check(OBJ_ID_T *check_oid, OBJ_ID_T *filter_subtree, EBUFFER_T *filter_mask){OIDC_T *testoidc, *suboidc;bits8_t *mask;int testlen, sublen, masklen, i;testoidc = check_oid->component_list;suboidc = filter_subtree->component_list;mask = EBufferStart(filter_mask);testlen = check_oid->num_components;sublen = filter_subtree->num_components;masklen = EBufferUsed(filter_mask) * 8;i = 0;while (i < min(testlen, sublen)) { if (*testoidc != *suboidc) { if (i < masklen) { if (mask[i/8] & (0x80 >> (i%8))) break; } else break; } i++; testoidc++; suboidc++; }if (i == sublen) return 0;return -1;} /****************************************************************************NAME: build_target_listPURPOSE: Given a Notify and a VarBindList, construct a list of targets that the Notify can be sent to. NOTE: This function will do tag matching and filter checking, but not view checking.PARAMETERS: SNMP_NOTIFY_T * pointer to notify structure VBL_T * the varbind list to check againstRETURNS: TARGET_LIST_T * the linked list of targets****************************************************************************/TARGET_LIST_T * build_target_list(SNMP_NOTIFY_T *notify, VBL_T *vblp){SNMP_TARGET_ADDR_T *test_addr;SNMP_NOTIFY_FILTER_PROFILE_T *test_profile;SNMP_NOTIFY_FILTER_T *test_filter;TARGET_LIST_T *target_list_head = 0, *target_list;VB_T *vbp;int notify_oid_ok, vb_oids_ok, vb_cnt;if ((vblp->vbl_count < 2) || (vblp->vblist[1].vb_data_flags_n_type != VT_OBJECT)) return 0;/* Step 1: Scan through the SNMP_TARGET_ADDR_T list, looking for * target_addrs that have the notify tag in their tag list. */for (test_addr = root_target_addr; test_addr; test_addr = test_addr->next) { if ((taglist_check(&(test_addr->tag_list), &(notify->notify_tag)) != 0) || (SNMP_Target_Addr_Get_Status(test_addr) != ETC_RS_ACTIVE)) continue; /* We have a target_addr structure that matches this notify's tag. * Now we have to get to the right notify_filter. We do this * by following the target_addr's params field to the notify filter * profile table, and then looking through all the notify filters * associated with that notify filter profile. */ if (((test_profile = SNMP_Notify_Profile_Lookup(SNMP_Target_Addr_Get_Params(test_addr), SNMP_Target_Addr_Get_Params_Len(test_addr))) == 0) || (SNMP_Notify_Profile_Get_Status(test_profile) != ETC_RS_ACTIVE)) { /* no notify filter profile for this target == no filtering */ if ((target_list = SNMP_memory_alloc(sizeof(TARGET_LIST_T))) == 0) { /* memory allocation error */ clean_target_list(target_list_head); return 0; } init_target_list(target_list); target_list->target = test_addr; target_list->next = target_list_head; target_list_head = target_list; continue; } /* We have a notify filter profile object. Now use it to go * through the NotifyFilterTable. This requires two passes. * The first pass is checking the OID of the notify itself * against the possible filters. If no match (or match and * filter blocks it), notify is not sent to this target. */ for (test_filter = root_notify_filter, notify_oid_ok = 0; test_filter; test_filter = SNMP_Notify_Filter_Next_Filter(test_filter)) { if ((SNMP_Notify_Profile_Get_Profile_Len(test_profile) != SNMP_Notify_Filter_Get_Profile_Len(test_filter)) || (MEMCMP(SNMP_Notify_Profile_Get_Profile(test_profile), SNMP_Notify_Filter_Get_Profile(test_filter), SNMP_Notify_Profile_Get_Profile_Len(test_profile)) != 0) || (SNMP_Notify_Filter_Get_Status(test_filter) != ETC_RS_ACTIVE)) /* This filter doesn't match the profile we have, or * it's not active. Not valid to use in either case. */ continue; /* We have a filter that matches our profile. Now we have to * do subtree checking. */ if (filter_subtree_check(&(vblp->vblist[1]).value_u.v_object, &(test_filter->subtree), &(test_filter->filter_mask)) == 0) { /* a subtree match! */ if (SNMP_Notify_Filter_Get_Type(test_filter) == SNMP_NOTIFY_FILTER_INCLUDED) notify_oid_ok = 1; else /* we need to reset this value in case it was set by * a less specific match. */ notify_oid_ok = 0; } } if (notify_oid_ok == 0) continue; /* We've found a filter that applies to the OID of the notify * and includes it. Now we have to make sure that none of the * OIDs for the varbinds being sent are explicitly excluded. * In this case, no matching filter means it's OK, matching filter * with excluded set is the only thing that will block it. */ for (vb_cnt = 0, vbp = &(vblp->vblist[vb_cnt]), vb_oids_ok = 1; (vb_cnt < vblp->vbl_count) && vb_oids_ok; vb_cnt++, vbp = &(vblp->vblist[vb_cnt])) { if (vb_cnt == 1) continue; for (test_filter = root_notify_filter; test_filter; test_filter = SNMP_Notify_Filter_Next_Filter(test_filter)) { if ((SNMP_Notify_Profile_Get_Profile_Len(test_profile) != SNMP_Notify_Filter_Get_Profile_Len(test_filter)) || (MEMCMP(SNMP_Notify_Profile_Get_Profile(test_profile), SNMP_Notify_Filter_Get_Profile(test_filter), SNMP_Notify_Profile_Get_Profile_Len(test_profile)) != 0) || (SNMP_Notify_Filter_Get_Status(test_filter) != ETC_RS_ACTIVE)) /* This filter doesn't match the profile we have, or * it's not active. Not valid to use in either case. */ continue; if (filter_subtree_check(&(vbp->vb_obj_id), &(test_filter->subtree), &(test_filter->filter_mask)) == 0) { /* subtree match! */ if (SNMP_Notify_Filter_Get_Type(test_filter) == SNMP_NOTIFY_FILTER_EXCLUDED) vb_oids_ok = 0; else /* we need to reset this value in case it was * cleared by a less-specific match. */ vb_oids_ok = 1; } } } if (vb_oids_ok == 0) continue; /* If we made it to this point, the target has passed all * necessary tests and is eligible to receive this notification. * Add it to the list. */ if ((target_list = SNMP_memory_alloc(sizeof(TARGET_LIST_T))) == 0) { /* memory allocation error */ clean_target_list(target_list_head); return 0; } init_target_list(target_list); target_list->target = test_addr; target_list->next = target_list_head; target_list_head = target_list; }return target_list_head;}#endif /* #if (INSTALL_ENVOY_SNMP_V3_NOTIFY) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -