📄 commlkup.c
字号:
/* * Copyright 2001-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. *//* * $Log: commlkup.c,v $ * Revision 1.6 2002/07/09 19:28:20 josh * make sure that we only use active entries from the community table * * Revision 1.5 2002/05/17 18:46:49 josh * improve use of MMS in PDU processing * * Revision 1.4 2002/05/13 16:14:49 josh * initialize src_tdomain to {0, 0} * * Revision 1.3 2002/04/08 19:57:43 josh * fix the way masks are used by find_target_by_community() * make sure that we pass the correct value to SNMP_V3_Access_Find() * make sure we return a badCommunityUse error when no view is found * * Revision 1.2 2001/11/06 21:20:06 josh * revised new path hacking * * Revision 1.1.1.1 2001/11/05 17:47:42 tneale * Tornado shuffle * * Revision 1.1.2.3 2001/09/21 19:20:59 josh * make sure we don't reject unknown community strings out of hand * on incoming responses * * Revision 1.1.2.2 2001/08/07 18:33:58 josh * adding support for SNMPv1/v2c/v3 coexistence to SNMP Notify code * * Revision 1.1.2.1 2001/07/20 20:34:36 josh * a community table based validation routine that can * supercede existing community validation routines * * *//* [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/buffer.h>#include <wrn/wm/snmp/engine/objectid.h>#include <wrn/wm/snmp/engine/v3_eng.h>#include <wrn/wm/snmp/engine/v3_acc.h> #include <wrn/wm/snmp/engine/v3_proxy.h>#include <wrn/wm/snmp/engine/v3_comm.h>#include <wrn/wm/snmp/engine/v3_trgt.h>#include <wrn/wm/snmp/engine/ntfy_chk.h>#include <wrn/wm/snmp/engine/snmpdefs.h>#include <wrn/wm/snmp/engine/auxfuncs.h>#include <wrn/wm/snmp/engine/wkobj.h>/********************************************************************** find_target_by_community -- Based on the value of snmpCommunityTransportTag, find a matching entry in the snmpTargetAddrTable. The parameters to this procedure are: EBUFFER_T * transport tag OBJ_ID_T * TDomain EBUFFER_T * TAddress Returns: A pointer to a target_addr object if a matching one exists, 0 otherwise. **********************************************************************//*ARGSUSED*/SNMP_TARGET_ADDR_T * find_target_by_community(EBUFFER_T *transport_tag, OBJ_ID_T *tdomain, EBUFFER_T *taddress){SNMP_TARGET_ADDR_T *test_taddr;ALENGTH_T address_len;int i;bits8_t *taddr_chk, *comm_chk;for (test_taddr = root_target_addr ; test_taddr ; test_taddr = test_taddr->next) { /* Is this an active entry with a matching tag? */ if ((taglist_check(&(test_taddr->tag_list), transport_tag) != 0) || (SNMP_Target_Addr_Get_Status(test_taddr) != ETC_RS_ACTIVE)) continue; /* Do the TDomains match? */ if (oidcmp2(SNMP_Target_Addr_Get_TDomain(test_taddr)->num_components, SNMP_Target_Addr_Get_TDomain(test_taddr)->component_list, tdomain->num_components, tdomain->component_list) != 0) continue; /* Compare TAddress lengths */ address_len = SNMP_Target_Addr_Get_TAddress_Len(test_taddr); if (EBufferUsed(taddress) != address_len) continue; /* Compare TAddress values (modulo TMask) */ for (i = 0, taddr_chk = SNMP_Target_Addr_Get_TAddress(test_taddr), comm_chk = EBufferStart(taddress) ; i < address_len * 8 ; i++) { if (taddr_chk[i/8] != comm_chk[i/8]) { if (i < SNMP_Target_Addr_Get_TMask_Len(test_taddr) * 8) { if (SNMP_Target_Addr_Get_TMask(test_taddr)[i/8] & (0x80 >> (i%8))) break; } else break; } else i += 7; /* Go on to next byte. */ } if (i == address_len * 8) break; }return(test_taddr);}/********************************************************************** lookup_SNMP_community -- Check an operation against the community name using the community table from RFC 2576. The parameters to this procedure are: SNMP_PKT_T * The received packet (decoded format) SNMPADDR_T * Source of the packet SNMPADDR_T * Destination of the packet (most likely the address of the machine on which this code is running.) This procedure should return 0 if a reasonable view can be assigned and 1 if not. **********************************************************************//*ARGSUSED*/int lookup_SNMP_community(SNMP_PKT_T *rp, SNMPADDR_T *pktsrc, SNMPADDR_T *pktdst){SNMP_COMMUNITY_T *comm;SNMP_TARGET_ADDR_T *taddr;SNMP_GROUP_T *group;SNMP_ACCESS_T *access = 0;bits8_t *com_str;ALENGTH_T com_len;OBJ_ID_T src_tdomain;EBUFFER_T src_taddress;int addr_converted = 0;ALENGTH_T id_len;/* Step 1: Perform address validation. */if (SNMP_validate_address(rp, pktsrc, pktdst) != 0) return 1;com_str = EBufferStart(&(rp->community));com_len = EBufferUsed(&(rp->community));/* convert the source address into a TDomain/TAddress pair */EBufferInitialize(&src_taddress);src_tdomain.num_components = 0;src_tdomain.component_list = 0;if (ENVOY_SNMPADDR_TO_TADDRESS(pktsrc, &src_tdomain, &src_taddress) == 0) addr_converted = 1;/* Step 2: Find a matching entry in the snmpCommunityTable */for (comm = root_community ; comm ; comm = comm->next) { /* Is this entry active? */ if (SNMP_Community_Get_Status(comm) != ETC_RS_ACTIVE) continue; /* Does the community string match snmpCommunityName? */ if ((SNMP_Community_Get_Name_Len(comm) != com_len) || (MEMCMP_NULLOK(SNMP_Community_Get_Name(comm), com_str, com_len) != 0)) continue; /* Is the tag field empty? OR Is this a response? */ if ((SNMP_Community_Get_Tag_Len(comm) == 0) || ((rp->pdu_type & (GET_RESPONSE_PDU | REPORT_PDU)) != 0)) break; /* * If we can't convert the SNMPADDR_T to a TDomain/TAddress pair, * then we can't use any entry with a non-empty tag field. */ if (addr_converted == 0) continue; /* We need to find a valid entry in the target addr table. */ taddr = find_target_by_community(&(comm->comm_tag), &src_tdomain, &src_taddress); if (taddr) { rp->msg_max_size = SNMP_Target_Addr_Get_MMS(taddr); rp->maxpkt = max(rp->maxpkt, rp->msg_max_size); break; } }/* Did we find an entry? */EBufferClean (&src_taddress);Clean_Obj_ID (&src_tdomain);if (comm == 0) { /* No community match. Problem only if this is a request that we * might have to process or forward. */ switch (rp->pdu_type) { case GET_REQUEST_PDU: case GET_NEXT_REQUEST_PDU: case SET_REQUEST_PDU: case GET_BULK_REQUEST_PDU: return 2; default: return 0; } } /* We found an entry -- install its name into the packet */EBufferAllocateLoad(BFL_IS_ALLOC, &rp->comm_entry, SNMP_Community_Get_Index(comm), SNMP_Community_Get_Index_Len(comm));/* Check the context engine id. If it's not our own, this may need to be forwarded. */id_len = min(SNMP_Community_Get_Con_ID_Len(comm), v3_my_engine->id_len);if (MEMCMP(SNMP_Community_Get_Con_ID(comm), v3_my_engine->id, id_len) != 0) {#if INSTALL_ENVOY_SNMP_V3_PROXY switch (rp->pdu_type) { case GET_REQUEST_PDU: case GET_NEXT_REQUEST_PDU: case SET_REQUEST_PDU: case GET_BULK_REQUEST_PDU: rp->proxy_routine = (PROXY_ROUTINE_T *) snmpProxyV3Request; break; case INFORM_REQUEST_PDU: case TRAP2_PDU: rp->proxy_routine = (PROXY_ROUTINE_T *) snmpProxyV3Notify; break; case GET_RESPONSE_PDU: case REPORT_PDU: rp->proxy_routine = (PROXY_ROUTINE_T *) snmpProxyV3Response; break; default: rp->proxy_routine = 0; return(2); } return(0); #else /* #if INSTALL_ENVOY_SNMP_V3_PROXY */ /* * contextEngineID doesn't match and we're not doing proxy. If it's a * request, then we have a problem. Other PDU types can just pass * through, though. */ switch (rp->pdu_type) { case GET_REQUEST_PDU: case GET_NEXT_REQUEST_PDU: case SET_REQUEST_PDU: case GET_BULK_REQUEST_PDU: return 2; default: return 0; }#endif /* #if INSTALL_ENVOY_SNMP_V3_PROXY */ }/* We have an appropriate community entry. Look up the corresponding group, if necessary. */switch (rp->pdu_type) { case GET_REQUEST_PDU: case GET_NEXT_REQUEST_PDU: case SET_REQUEST_PDU: case GET_BULK_REQUEST_PDU: group = SNMP_Group_Lookup((rp->snmp_version == SNMP_VERSION_1) ? ETC_SEC_MODEL_V1 : ETC_SEC_MODEL_V2, SNMP_Community_Get_Sec_Name(comm), SNMP_Community_Get_Sec_Name_Len(comm)); if (group && (SNMP_Group_Get_Status(group) == ETC_RS_ACTIVE)) { /* We have a group -- look up the access entry */ access = SNMP_V3_Access_Find(SNMP_Group_Get_Group(group), SNMP_Group_Get_Group_Len(group), SNMP_Community_Get_Con_Name(comm), SNMP_Community_Get_Con_Name_Len(comm), ((rp->snmp_version == SNMP_VERSION_1) ? ETC_SEC_MODEL_V1 : ETC_SEC_MODEL_V2), ETC_SEC_LEVEL_NONE); } if (access) { if (rp->pdu_type == SET_REQUEST_PDU) { EBufferAllocateLoad(BFL_IS_ALLOC, &rp->view_name, SNMP_V3_Access_Get_Write(access), SNMP_V3_Access_Get_Write_Len(access)); if (SNMP_V3_Access_Get_Write_Len(access) == 0) /* No write view */ return 3; } else { EBufferAllocateLoad(BFL_IS_ALLOC, &rp->view_name, SNMP_V3_Access_Get_Read(access), SNMP_V3_Access_Get_Read_Len(access)); if (SNMP_V3_Access_Get_Read_Len(access) == 0) /* No read view */ return 3; } return(0); } return(2); default: /* allow other pdu types through without checking */ return(0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -