📄 natipsecptalg.c
字号:
/* Reset the translation entry timer */ sptr_esp_translation_entry->esp_translation_entry_timer = ISAKMP_ESTABLISHED_TIMEOUT; /* Translate the destination address.... */ address = htonl(sptr_esp_translation_entry->local_address); checksum_fixup ((BYTE *) &checksum, (BYTE *) &sptr_esp_packet->ip_header.destination_address, sizeof (IP_ADDRESS), (BYTE *) &address, sizeof (IP_ADDRESS)); sptr_esp_packet->ip_header.destination_address = address; sptr_esp_packet->ip_header.header_checksum = checksum; return(TRUE); }}/*****************************************************************************************Function: natIPSecPTInitDescription: ******************************************************************************************/STATUS natIPSecPTInit(u_short isakmp_port){ STATUS status; int optval; semTake (natInitSync, WAIT_FOREVER); /* wait for event */ nat_printf(NAT_PRINTF_INIT, "IPSec Pass-Thru initialization: port = %u\n", isakmp_port); memset(&nat_id, 0, sizeof(nat_id)); /* Get the NAT instance ID */ status = natGetID(&nat_id); if (status != NAT_OK) { nat_printf(NAT_PRINTF_ERROR, "natIPSecPTInit: natGetID failed with error %d\n", status); return(status); } memset(&isakmp_agent_info, 0, sizeof(isakmp_agent_info)); /* Register for the ISAKMP packets, UDP port 500, do the full translation in agent */ isakmp_agent_info.type = NAT_AGENT_TYPE_ALG; isakmp_agent_info.flags = NAT_FLAG_NO_XLAT; isakmp_agent_info.session_tag.protocol = IPPROTO_UDP; isakmp_agent_info.session_tag.transport = isakmp_port; isakmp_agent_info.packet_callback = natIsakmpPacket; sprintf(isakmp_agent_info.desc, "%.*s", (int)(sizeof(isakmp_agent_info.desc)-1), isakmp_alg_desc); sprintf(isakmp_agent_info.name, "%.*s", (int)(sizeof(isakmp_agent_info.name)-1), isakmp_alg_name); status = natRegisterAgent(nat_id.id, &isakmp_agent_info); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natIPSecPTInit: natRegisterAgent failed for ISAKMP with error %d\n", status); return(status); } nat_printf(NAT_PRINTF_INIT, "ISAKMP IPSec Pass-Thru ALG registered with NAT\n"); isakmpListLock = semMCreate(SEM_DELETE_SAFE | SEM_INVERSION_SAFE | SEM_Q_PRIORITY); memset(&esp_agent_info, 0, sizeof(esp_agent_info)); /* Register for the ESP packets, IP Protocol 50, do the full translation in agent */ esp_agent_info.type = NAT_AGENT_TYPE_ALG; esp_agent_info.flags = NAT_FLAG_NO_XLAT; esp_agent_info.session_tag.protocol = IPSEC_ESP_PROTOCOL; esp_agent_info.session_tag.transport = 0; esp_agent_info.packet_callback = natEspPacket; sprintf(esp_agent_info.desc, "%.*s", (int)(sizeof(esp_agent_info.desc)-1), esp_alg_desc); sprintf(esp_agent_info.name, "%.*s", (int)(sizeof(esp_agent_info.name)-1), esp_alg_name); status = natRegisterAgent(nat_id.id, &esp_agent_info); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natIPSecPTInit: natRegisterAgent failed for ESP with error %d\n", status); return(status); } nat_printf(NAT_PRINTF_INIT, "ESP IPSec Pass-Thru ALG registered with NAT\n"); espListLock = semMCreate(SEM_DELETE_SAFE | SEM_INVERSION_SAFE | SEM_Q_PRIORITY); /* start a 1 second timer that checks for timeouts in the ISAKMP and ESP table entries */ ipSecTimerId = natTimerEvtCreate(1000,(FUNCPTR)nat_ipsec_timer,0); if (ipSecTimerId == NULL) { nat_printf(NAT_PRINTF_ERROR,"fail to create IPSEC timer\n"); return ERROR; } if (natEvtActivate(ipSecTimerId) == ERROR) { nat_printf(NAT_PRINTF_ERROR,"fail to activate IPSEC timer\n"); return ERROR; } /* Open the raw socket used for packet cloning in the ESP packet handling routine */ espRawFd = socket(AF_INET, SOCK_RAW, 0); optval = 1; setsockopt(espRawFd, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval)); semGive(natInitSync); return(OK);}/*****************************************************************************************Function: natIPSecPTEndDescription: ******************************************************************************************/STATUS natIPSecPTEnd(){ STATUS status; nat_printf(NAT_PRINTF_INIT, "Stopping IPSec Pass-Thru\n"); /* remove the IPSEC timer */ if (ipSecTimerId != NULL) natEvtRemove(ipSecTimerId); status = natUnregisterAgent(nat_id.id, isakmp_agent_info.id); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natIPSecPTEnd: natUnregisterAgent failed for ISAKMP with error %d\n", status); return(status); } status = natUnregisterAgent(nat_id.id, esp_agent_info.id); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natIPSecPTEnd: natUnregisterAgent failed for ESP with error %d\n", status); return(status); } clear_isakmp_translation_entry_list (&isakmp_translation_list); clear_esp_translation_entry_list (&esp_translation_list); semDelete(isakmpListLock); semDelete(espListLock); close(espRawFd); return(OK);}/*****************************************************************************************Function: new_isakmp_translation_entryDescription: ******************************************************************************************/LOCAL ISAKMP_TRANSLATION_ENTRY *new_isakmp_translation_entry ( ISAKMP_TRANSLATION_HEADER *sptr_isakmp_translation_list, ULONG64 initiator_cookie, ULONG64 responder_cookie, IP_ADDRESS local_address, IP_ADDRESS remote_address) { ISAKMP_TRANSLATION_ENTRY *sptr_isakmp_translation_entry; nat_printf (NAT_PRINTF_TRACE, "new_isakmp_translation_entry: " "local addr/init cookie = %08lx:%08lx%08lx\n\t remote addr/resp cookie = %08lx:%08lx%08lx\n", local_address, *((unsigned long *) &initiator_cookie), *(((unsigned long *) &initiator_cookie) + 1), remote_address, *((unsigned long *) &responder_cookie), *(((unsigned long *) &responder_cookie) + 1)); sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) calloc (1, sizeof (ISAKMP_TRANSLATION_ENTRY)); if (sptr_isakmp_translation_entry == NULL) { nat_printf (NAT_PRINTF_ERROR, "new_isakmp_translation_entry: NAT failed calloc\n"); return (NULL); } sptr_isakmp_translation_entry->isakmp_translation_entry_timer = ISAKMP_INIT_TIMEOUT; sptr_isakmp_translation_entry->initiator_cookie = initiator_cookie; sptr_isakmp_translation_entry->responder_cookie = responder_cookie; sptr_isakmp_translation_entry->local_address = local_address; sptr_isakmp_translation_entry->remote_address = remote_address; dllAdd ((DL_LIST *) sptr_isakmp_translation_list, (DL_NODE *) sptr_isakmp_translation_entry); return (sptr_isakmp_translation_entry); }/*****************************************************************************Function: match_outbound_cookies_with_isakmp_entryDescription:Look for ISAKMP entry with matching initiator cookie, responder cookie,and remote address.*****************************************************************************/LOCAL ISAKMP_TRANSLATION_ENTRY *match_outbound_cookies_with_isakmp_entry ( ULONG64 initiator_cookie, ULONG64 responder_cookie, IP_ADDRESS local_address, IP_ADDRESS remote_address, ISAKMP_TRANSLATION_HEADER *sptr_isakmp_translation_list) { ISAKMP_TRANSLATION_ENTRY *sptr_isakmp_translation_entry; semTake (isakmpListLock, WAIT_FOREVER); for (sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_isakmp_translation_list); sptr_isakmp_translation_entry != NULL; sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_isakmp_translation_entry)) { if ((sptr_isakmp_translation_entry->initiator_cookie == initiator_cookie) && (sptr_isakmp_translation_entry->responder_cookie == responder_cookie) && (sptr_isakmp_translation_entry->local_address == local_address) && (sptr_isakmp_translation_entry->remote_address == remote_address)) { nat_printf (NAT_PRINTF_TRACE, "Found match for local addr/init cookie = %08lx:%08lx%08lx\n\t remote addr/resp cookie = %08lx:%08lx%08lx in ISAKMP list\n", local_address, *((unsigned long *) &initiator_cookie), *(((unsigned long *) &initiator_cookie) + 1), remote_address, *((unsigned long *) &responder_cookie), *(((unsigned long *) &responder_cookie) + 1)); semGive (isakmpListLock); return (sptr_isakmp_translation_entry); } } nat_printf (NAT_PRINTF_TRACE, "No match for local addr/init cookie = %08lx:%08lx%08lx\n\t remote addr/resp cookie = %08lx:%08lx%08lx in ISAKMP list\n", local_address, *((unsigned long *) &initiator_cookie), *(((unsigned long *) &initiator_cookie) + 1), remote_address, *((unsigned long *) &responder_cookie), *(((unsigned long *) &responder_cookie) + 1)); semGive (isakmpListLock); return (NULL); }/*****************************************************************************Function: match_inbound_cookies_with_isakmp_entryDescription:Look for ISAKMP entry with matching initiator cookie, responder cookie,and remote address.*****************************************************************************/LOCAL ISAKMP_TRANSLATION_ENTRY *match_inbound_cookies_with_isakmp_entry ( ULONG64 initiator_cookie, ULONG64 responder_cookie, IP_ADDRESS remote_address, ISAKMP_TRANSLATION_HEADER *sptr_isakmp_translation_list) { ISAKMP_TRANSLATION_ENTRY *sptr_isakmp_translation_entry; semTake (isakmpListLock, WAIT_FOREVER); for (sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_isakmp_translation_list); sptr_isakmp_translation_entry != NULL; sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_isakmp_translation_entry)) { if ((sptr_isakmp_translation_entry->initiator_cookie == initiator_cookie) && (sptr_isakmp_translation_entry->responder_cookie == responder_cookie) && (sptr_isakmp_translation_entry->remote_address == remote_address)) { nat_printf (NAT_PRINTF_TRACE, "Found match for init cookie = %08lx%08lx\n\t remote addr/resp cookie = %08lx:%08lx%08lx in ISAKMP list\n", *((unsigned long *) &initiator_cookie), *(((unsigned long *) &initiator_cookie) + 1), remote_address, *((unsigned long *) &responder_cookie), *(((unsigned long *) &responder_cookie) + 1)); semGive (isakmpListLock); return (sptr_isakmp_translation_entry); } } nat_printf (NAT_PRINTF_TRACE, "No match for init cookie = %08lx%08lx\n\t remote addr/resp cookie = %08lx:%08lx%08lx in ISAKMP list\n", *((unsigned long *) &initiator_cookie), *(((unsigned long *) &initiator_cookie) + 1), remote_address, *((unsigned long *) &responder_cookie), *(((unsigned long *) &responder_cookie) + 1)); semGive (isakmpListLock); return (NULL); }/*****************************************************************************Function: find_intializing_isakmp_entryDescription:Look for ISAKMP entry with matching remote address, and responder cookie of 0*****************************************************************************/LOCAL ULONG find_active_isakmp_entries ( IP_ADDRESS remote_address, IP_ADDRESS *active_address, ISAKMP_TRANSLATION_HEADER *sptr_isakmp_translation_list) { ISAKMP_TRANSLATION_ENTRY *sptr_isakmp_translation_entry; ULONG number_active = 0; semTake (isakmpListLock, WAIT_FOREVER); for (sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_isakmp_translation_list); sptr_isakmp_translation_entry != NULL; sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_isakmp_translation_entry)) { if (sptr_isakmp_translation_entry->remote_address == remote_address) { active_address[number_active] = sptr_isakmp_translation_entry->local_address; number_active++; /* The number of entries to guess should be less than or equal to * ESP_GUESS_SIZE, otherwise will cause invalid access in array * guess_ip[ESP_GUESS_SIZE] */ if (number_active >= ESP_GUESS_SIZE) { semGive (isakmpListLock); return (ESP_GUESS_SIZE); } } } semGive (isakmpListLock); return (number_active); }/*****************************************************************************Function: match_outbound_cookies_with_isakmp_entryDescription:Look for ISAKMP entry with matching initiator cookie, responder cookie,and remote address.*****************************************************************************/LOCAL void *cleanup_isakmp_list ( ULONG64 initiator_cookie, ULONG64 responder_cookie, IP_ADDRESS local_address, IP_ADDRESS remote_address, ISAKMP_TRANSLATION_HEADER *sptr_isakmp_translation_list) { ISAKMP_TRANSLATION_ENTRY *sptr_isakmp_translation_entry; semTake (isakmpListLock, WAIT_FOREVER); for (sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_isakmp_translation_list); sptr_isakmp_translation_entry != NULL; sptr_isakmp_translation_entry = (ISAKMP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_isakmp_translation_entry)) { if ((sptr_isakmp_translation_entry->local_address == local_address) && (sptr_isakmp_translation_entry->remote_address == remote_address)) { if ((sptr_isakmp_translation_entry->initiator_cookie != initiator_cookie) || (sptr_isakmp_translation_entry->responder_cookie != responder_cookie)) { if (sptr_isakmp_translation_entry->isakmp_translation_entry_timer > ISAKMP_OLD_TIMEOUT) sptr_isakmp_translation_entry->isakmp_translation_entry_timer = ISAKMP_OLD_TIMEOUT; } } } semGive (isakmpListLock); return (NULL); }/*****************************************************************************************Function: new_esp_translation_entryDescription: ******************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -