/************************************************************************/ /* SISCO SOFTWARE MODULE HEADER *****************************************/ /************************************************************************/ /* (c) Copyright Systems Integration Specialists Company, Inc., */ /* 2003 - 2003, All Rights Reserved */ /* */ /* MODULE NAME : acse2dib.c */ /* PRODUCT(S) : MMS-LITE */ /* */ /* MODULE DESCRIPTION : Address matching functions. */ /* */ /* NOTE: !!! If changes are made to this file the same changes */ /* have to be made in the marb_dib.c (MMS-EASE). */ /* */ /* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */ /* */ /* MODIFICATION LOG : */ /* Date Who Rev Comments */ /* -------- --- ------ ------------------------------------------- */ /* 03/28/05 JRB 03 Del suicacse header. */ /* 06/16/03 EJV 02 Renamed m_match.c to acse2dib.c */ /* 06/02/03 MDE 01 Created */ /************************************************************************/ #include "glbtypes.h" #include "sysincs.h" #include "acse2.h" /************************************************************************/ /* For debug version, use a static pointer to avoid duplication of */ /* __FILE__ strings. */ /************************************************************************/ #ifdef DEBUG_SISCO static ST_CHAR *thisFileName = __FILE__; #endif /************************************************************************/ /* Internal Functions */ static ST_VOID _dib_match_ap_title (DIB_MATCH_CTRL *matchCtrl, ST_INT *matchLevel, ST_BOOLEAN ind_pres, MMS_OBJ_ID *ind_apTitle, ST_BOOLEAN dib_pres, MMS_OBJ_ID *dib_apTitle); static ST_VOID _dib_match_ae_int (DIB_MATCH_CTRL *matchCtrl, ST_INT *matchLevel, ST_BOOLEAN ind_pres, ST_INT32 ind_val, ST_BOOLEAN dib_pres, ST_INT32 dib_val, ST_CHAR *itemText); static ST_VOID _dib_match_mem (ST_INT *matchLevel, ST_INT ind_sel_len, ST_UCHAR *ind_sel, ST_INT dib_sel_len, ST_UCHAR *dib_sel, ST_CHAR *sel_text); static ST_VOID _dib_match_ae_present_flag (DIB_MATCH_CTRL *matchCtrl, ST_INT *matchLevelIo, ST_CHAR *aeElText, ST_BOOLEAN dibPres, ST_BOOLEAN remotePres, ST_BOOLEAN *doCompareOut); /************************************************************************/ /* ml_match_remote_ar */ /************************************************************************/ ST_RET dib_match_remote_ar (DIB_MATCH_CTRL *matchCtrl, AARQ_APDU *aarq, DIB_ENTRY **dib_entry_out) { ST_INT i; DIB_ENTRY *de; DIB_ENTRY *closeDe; ST_INT remMatch; ACSELOG_DIB0 ("Matching Remote AR"); closeDe = NULL; for (i = 0; i < num_rem_dib_entries; ++i) { de = &rem_dib_table[i]; ACSELOG_DIB1C (" Remote AR '%s'", de->name); remMatch = dib_cmp_remote_addr (matchCtrl, aarq, de); if (remMatch == DIB_MATCH_EXACT) { *dib_entry_out = de; ACSELOG_DIB1C ("Exact Match: '%s'", de->name); return (SD_SUCCESS); } if (remMatch == DIB_MATCH_CLOSE && closeDe == NULL) closeDe = de; } if (closeDe != NULL) { *dib_entry_out = closeDe; ACSELOG_DIB1C ("Close Match: '%s'", closeDe->name); return (SD_SUCCESS); } return (SD_FAILURE); } /************************************************************************/ /* dib_match_local_ar */ /************************************************************************/ ST_RET dib_match_local_ar (DIB_MATCH_CTRL *matchCtrl, AARQ_APDU *aarq, DIB_ENTRY **dib_entry_out) { ST_INT i; DIB_ENTRY *de; DIB_ENTRY *closeDe; ST_INT locMatch; ACSELOG_DIB0 ("Matching Local AR"); closeDe = NULL; for (i = 0; i < num_loc_dib_entries; ++i) { de = &loc_dib_table[i]; ACSELOG_DIB1C (" Local AR '%s'", de->name); locMatch = dib_cmp_local_addr (matchCtrl,aarq, de); if (locMatch == DIB_MATCH_EXACT) { ACSELOG_DIB1C ("Exact Match: '%s'", de->name); *dib_entry_out = de; return (SD_SUCCESS); } if (locMatch == DIB_MATCH_CLOSE && closeDe == NULL) closeDe = de; } if (closeDe != NULL) { ACSELOG_DIB1C ("Close Match: '%s'", de->name); *dib_entry_out = closeDe; return (SD_SUCCESS); } return (SD_FAILURE); } /************************************************************************/ /************************************************************************/ /* dib_cmp_local_addr */ /************************************************************************/ ST_INT dib_cmp_local_addr (DIB_MATCH_CTRL *matchCtrl, AARQ_APDU *aarq, DIB_ENTRY *dib_entry) { ST_INT matchLevel; /* The best we can do ... */ matchLevel = DIB_MATCH_EXACT; /* Compare local network address with dib entry */ #if 0 if (matchCtrl->match_net_addr) { if (aarq->transport == TCP) { _dib_match_mem (&matchLevel, strlen (aarq->ip_addr), aarq->ip_addr, strlen (dib_entry->ip_addr), dib_entry->ip_addr, "Local IP Address"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } else if (aarq->transport == TP4) { _dib_match_mem (&matchLevel, aarq->net_addr_len,aarq->net_addr, dib_entry->net_addr_len, dib_entry->net_addr, "Local Network Address"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } else { ACSELOG_ERR1 ("Transport type problem: %d", aarq->transport); return (DIB_MATCH_NOT); } } #endif /* Compare selectors with dib entry */ /* PSEL */ if (matchCtrl->match_psel) { _dib_match_mem (&matchLevel, aarq->called_paddr.psel_len, aarq->called_paddr.psel, dib_entry->pres_addr.psel_len, dib_entry->pres_addr.psel, "PSEL"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* SSEL */ if (matchCtrl->match_ssel) { _dib_match_mem (&matchLevel, aarq->called_paddr.ssel_len, aarq->called_paddr.ssel, dib_entry->pres_addr.ssel_len, dib_entry->pres_addr.ssel, "SSEL"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* TSEL */ if (matchCtrl->match_tsel) { _dib_match_mem (&matchLevel, aarq->called_paddr.tsel_len, aarq->called_paddr.tsel, dib_entry->pres_addr.tsel_len, dib_entry->pres_addr.tsel, "TSEL"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* Now compare AE Titles */ /* AP Title */ if (matchCtrl->match_ap_title) { _dib_match_ap_title (matchCtrl,&matchLevel, aarq->called_ae_title.AP_title_pres, &aarq->called_ae_title.AP_title, dib_entry->AP_title_pres, &dib_entry->AP_title); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* AE Qualifier */ if (matchCtrl->match_ae_qualifier) { _dib_match_ae_int (matchCtrl, &matchLevel, aarq->called_ae_title.AE_qual_pres, aarq->called_ae_title.AE_qual, dib_entry->AE_qual_pres, dib_entry->AE_qual, "AE Qualifier"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* AP Invoke ID */ if (matchCtrl->match_ap_invoke) { _dib_match_ae_int (matchCtrl, &matchLevel, aarq->called_ae_title.AP_inv_id_pres, aarq->called_ae_title.AP_inv_id, dib_entry->AP_inv_id_pres, dib_entry->AP_invoke_id, "AP invoke ID"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* AE Invoke ID */ if (matchCtrl->match_ae_invoke) { _dib_match_ae_int (matchCtrl, &matchLevel, aarq->called_ae_title.AE_inv_id_pres, aarq->called_ae_title.AE_inv_id, dib_entry->AE_inv_id_pres, dib_entry->AE_invoke_id, "AE invoke ID"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } return (matchLevel); /* exact */ } /************************************************************************/ /* dib_cmp_remote_addr */ /************************************************************************/ ST_INT dib_cmp_remote_addr (DIB_MATCH_CTRL *matchCtrl, AARQ_APDU *aarq, DIB_ENTRY *dib_entry) { ST_INT matchLevel; /* The best we can do ... */ matchLevel = DIB_MATCH_EXACT; /* Compare partner network address with dib entry */ #if 0 if (matchCtrl->match_net_addr) { if (aarq->transport == TCP) { _dib_match_mem (&matchLevel, strlen (aarq->part_ip_addr), aarq->part_ip_addr, strlen (dib_entry->ip_addr), dib_entry->ip_addr, "Remote IP Address"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } else if (aarq->transport == TP4) { _dib_match_mem (&matchLevel, aarq->part_net_addr_len,aarq->part_net_addr, dib_entry->net_addr_len, dib_entry->net_addr, "Remote Network Address"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } else { ACSELOG_ERR1 ("Transport type problem: %d", aarq->transport); return (DIB_MATCH_NOT); } } #endif /* Compare selectors with dib entry */ /* PSEL */ if (matchCtrl->match_psel) { _dib_match_mem (&matchLevel, aarq->calling_paddr.psel_len, aarq->calling_paddr.psel, dib_entry->pres_addr.psel_len, dib_entry->pres_addr.psel, "PSEL"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* SSEL */ if (matchCtrl->match_ssel) { _dib_match_mem (&matchLevel, aarq->calling_paddr.ssel_len, aarq->calling_paddr.ssel, dib_entry->pres_addr.ssel_len, dib_entry->pres_addr.ssel, "SSEL"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* TSEL */ if (matchCtrl->match_tsel) { _dib_match_mem (&matchLevel, aarq->calling_paddr.tsel_len, aarq->calling_paddr.tsel, dib_entry->pres_addr.tsel_len, dib_entry->pres_addr.tsel, "TSEL"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* Now compare AE Titles */ /* AP Title */ if (matchCtrl->match_ap_title) { _dib_match_ap_title (matchCtrl, &matchLevel, aarq->calling_ae_title.AP_title_pres, &aarq->calling_ae_title.AP_title, dib_entry->AP_title_pres, &dib_entry->AP_title); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* AE Qualifier */ if (matchCtrl->match_ae_qualifier) { _dib_match_ae_int (matchCtrl, &matchLevel, aarq->calling_ae_title.AE_qual_pres, aarq->calling_ae_title.AE_qual, dib_entry->AE_qual_pres, dib_entry->AE_qual, "AE Qualifier"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* AP Invoke ID */ if (matchCtrl->match_ap_invoke) { _dib_match_ae_int (matchCtrl, &matchLevel, aarq->calling_ae_title.AP_inv_id_pres, aarq->calling_ae_title.AP_inv_id, dib_entry->AP_inv_id_pres, dib_entry->AP_invoke_id, "AP invoke ID"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } /* AE Invoke ID */ if (matchCtrl->match_ae_invoke) { _dib_match_ae_int (matchCtrl, &matchLevel, aarq->calling_ae_title.AE_inv_id_pres, aarq->calling_ae_title.AE_inv_id, dib_entry->AE_inv_id_pres, dib_entry->AE_invoke_id, "AE invoke ID"); if (matchLevel == DIB_MATCH_NOT) return (DIB_MATCH_NOT); } return (matchLevel); } /************************************************************************/ /* _dib_match_ap_title */ /************************************************************************/ /* Set match level to DIB_MATCH_NOT, or leave alone */ static ST_VOID _dib_match_ap_title (DIB_MATCH_CTRL *matchCtrl, ST_INT *matchLevel, ST_BOOLEAN ind_pres, MMS_OBJ_ID *ind_apTitle, ST_BOOLEAN dib_pres, MMS_OBJ_ID *dib_apTitle) { ST_CHAR *itemText = "AP Title"; ST_BOOLEAN doCompare; _dib_match_ae_present_flag (matchCtrl, matchLevel, itemText, dib_pres, ind_pres, &doCompare); /* See if we need to compare */ if (doCompare) { if (asn1_objidcmp (ind_apTitle, dib_apTitle)) { ACSELOG_DIB1C (" %s mismatch", itemText); *matchLevel = DIB_MATCH_NOT; return; } } } /************************************************************************/ /* _dib_match_ae_int */ /************************************************************************/ /* Set match level to DIB_MATCH_NOT, or leave alone */ static ST_VOID _dib_match_ae_int (DIB_MATCH_CTRL *matchCtrl, ST_INT *matchLevel, ST_BOOLEAN ind_pres, ST_INT32 ind_val, ST_BOOLEAN dib_pres, ST_INT32 dib_val, ST_CHAR *itemText) { ST_BOOLEAN doCompare; _dib_match_ae_present_flag (matchCtrl, matchLevel, itemText, dib_pres, ind_pres, &doCompare); /* OK, we matched, see if we need to compare */ if (doCompare) { if (ind_val != dib_val) { ACSELOG_DIB1C (" %s mismatch", itemText); *matchLevel = DIB_MATCH_NOT; return; } } } /************************************************************************/ /* _dib_match_mem */ /************************************************************************/ /* Set match level to DIB_MATCH_NOT, or leave alone */ static ST_VOID _dib_match_mem (ST_INT *matchLevel, ST_INT ind_sel_len, ST_UCHAR *ind_sel, ST_INT dib_sel_len, ST_UCHAR *dib_sel, ST_CHAR *sel_text) { /* See if the selectors match */ if (ind_sel_len == dib_sel_len && !memcmp (ind_sel, dib_sel, ind_sel_len)) { return; } ACSELOG_DIB1C (" %s mismatch", sel_text); *matchLevel = DIB_MATCH_NOT; return; } /************************************************************************/ /* _dib_match_ae_present_flag */ /************************************************************************/ /* Set match level to DIB_MATCH_CLOSE or DIB_MATCH_NOT, or leave alone */ static ST_VOID _dib_match_ae_present_flag (DIB_MATCH_CTRL *matchCtrl, ST_INT *matchLevelIo, ST_CHAR *aeElText, ST_BOOLEAN dibPres, ST_BOOLEAN remotePres, ST_BOOLEAN *doCompareOut) { /* If the remote sent the parameter and it is in the DIB, SUCCESS */ if (dibPres == remotePres) { *doCompareOut = dibPres; /* If it is present, then compare it */ return; } *doCompareOut = SD_FALSE; /* Can't compare */ /* OK, this is more complicated. We need to find out what the mismatch */ /* is and what the user wants to do about it. */ if (!remotePres) { if (matchCtrl->match_allow_missing_ae_elements) { ACSELOG_DIB1C (" Remote did not send: %s, ignoring", aeElText); if (*matchLevelIo == DIB_MATCH_EXACT) *matchLevelIo = DIB_MATCH_CLOSE; } else { ACSELOG_DIB1C (" Remote did not send required: %s", aeElText); *matchLevelIo = DIB_MATCH_NOT; } } if (remotePres) { if (matchCtrl->match_allow_extra_ae_elements) { ACSELOG_DIB1C (" Remote sent unexpected: %s, ignoring", aeElText); if (*matchLevelIo == DIB_MATCH_EXACT) *matchLevelIo = DIB_MATCH_CLOSE; } else { ACSELOG_DIB1C (" Remote sent unexpected: %s", aeElText); *matchLevelIo = DIB_MATCH_NOT; } } }