📄 natpptpptalg.c
字号:
find_outbound_pptp_entry (bind_info.local_addr, ntohl(sptr_pptp_control_packet->ip_header.destination_address), spoofed_call_id, &pptp_translation_list); /* If we found one, then set the call id's to the spoofed ID */ if (sptr_pptp_translation_entry != NULL) { if (msg == PPTP_CALL_CLEAR_REQUEST) /* Call should be done...set to time out more quickly...or reinited if not */ sptr_pptp_translation_entry->pptp_translation_entry_timer = PPTP_QUICK_TIMEOUT; else { /* Calls done (due to disconnect), time out the translation entry quickly */ sptr_pptp_translation_entry->pptp_translation_entry_timer = PPTP_QUICK_TIMEOUT; sptr_pptp_translation_entry->nated_client = FALSE; } spoofed_call_id = htons(sptr_pptp_translation_entry->spoofed_call_id); } checksum_fixup ((BYTE *) &sptr_pptp_control_packet->tcp_header.checksum, (BYTE *) call_id, sizeof (USHORT), (BYTE *) &spoofed_call_id, sizeof (USHORT)); *call_id = spoofed_call_id; return(TRUE); } return(TRUE); } else { /* Get the call ID and peers call ID from the message ... */ switch(msg) { case PPTP_OUT_CALL_REPLY: spoofed_call_id = ntohs(sptr_pptp_control_packet->message.outgoing_call_reply.peers_call_id); peers_call_id = &sptr_pptp_control_packet->message.outgoing_call_reply.peers_call_id; break; case PPTP_IN_CALL_REPLY: spoofed_call_id = ntohs(sptr_pptp_control_packet->message.outgoing_call_reply.peers_call_id); peers_call_id = &sptr_pptp_control_packet->message.outgoing_call_reply.peers_call_id; break; case PPTP_WAN_ERROR_NOTIFY: spoofed_call_id = ntohs(sptr_pptp_control_packet->message.wan_error_notify.peers_call_id); peers_call_id = &sptr_pptp_control_packet->message.wan_error_notify.peers_call_id; break; case PPTP_SET_LINK_INFO: spoofed_call_id = ntohs(sptr_pptp_control_packet->message.set_link_info.peers_call_id); peers_call_id = &sptr_pptp_control_packet->message.set_link_info.peers_call_id; break; default: return(TRUE); } /* Find the translation entry */ sptr_pptp_translation_entry = find_inbound_pptp_entry (ntohl(sptr_pptp_control_packet->ip_header.source_address), spoofed_call_id, &pptp_translation_list); if (sptr_pptp_translation_entry != NULL) { if (msg == PPTP_OUT_CALL_REPLY || msg == PPTP_IN_CALL_REPLY) { /* Store the peers call ID, and set the initial timer */ if (sptr_pptp_translation_entry->peers_call_id != ntohs(sptr_pptp_control_packet->message.outgoing_call_reply.call_id)) { sptr_pptp_translation_entry->peers_call_id = ntohs(sptr_pptp_control_packet->message.outgoing_call_reply.call_id); sptr_pptp_translation_entry->pptp_translation_entry_timer = PPTP_DATA_INIT_TIMEOUT; } } new_call_id = htons(sptr_pptp_translation_entry->call_id); spoofed_call_id = htons(spoofed_call_id); checksum_fixup ((BYTE *) &sptr_pptp_control_packet->tcp_header.checksum, (BYTE *) &spoofed_call_id, sizeof (USHORT), (BYTE *) &new_call_id, sizeof (USHORT)); *peers_call_id = new_call_id; return(TRUE); } else return(FALSE); } }/*****************************************************************************************Function: natPPTPPTInitDescription: ******************************************************************************************/STATUS natPPTPPTInit(){ STATUS status; semTake (natInitSync, WAIT_FOREVER); /* wait for event */ nat_printf(NAT_PRINTF_INIT, "PPTP Pass-Thru initialization\n"); 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, "natPPTPPTInit: natGetID failed with error %d\n", status); return(status); } memset(&pptp_gre_agent_info, 0, sizeof(pptp_gre_agent_info)); /* Register for the GRE packets, IP Protocol 50, do the full translation in agent */ pptp_gre_agent_info.type = NAT_AGENT_TYPE_ALG; pptp_gre_agent_info.flags = NAT_FLAG_NO_XLAT; pptp_gre_agent_info.session_tag.protocol = GRE_PROTOCOL; pptp_gre_agent_info.session_tag.transport = 0; pptp_gre_agent_info.packet_callback = natPPTPGREPacket; sprintf(pptp_gre_agent_info.desc, "%.*s", (int)(sizeof(pptp_gre_agent_info.desc)-1), pptp_gre_alg_desc); sprintf(pptp_gre_agent_info.name, "%.*s", (int)(sizeof(pptp_gre_agent_info.name)-1), pptp_gre_alg_name); status = natRegisterAgent(nat_id.id, &pptp_gre_agent_info); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natPPTPPTInit: natRegisterAgent failed" " for PPTP GRE with error %d\n", status); return(status); } nat_printf(NAT_PRINTF_INIT, "PPTP GRE Pass-Thru ALG registered with NAT\n"); pptpListLock = semMCreate(SEM_DELETE_SAFE | SEM_INVERSION_SAFE | SEM_Q_PRIORITY); memset(&pptp_control_agent_info, 0, sizeof(pptp_control_agent_info)); /* Register for the control packets, TCP Socket 1723, get the packet after NAT translation */ pptp_control_agent_info.type = NAT_AGENT_TYPE_ALG; pptp_control_agent_info.flags = NAT_FLAG_POST_XLAT; pptp_control_agent_info.session_tag.protocol = TCP_PROTOCOL; pptp_control_agent_info.session_tag.transport = 1723; pptp_control_agent_info.packet_callback = natPPTPControlPacket; sprintf(pptp_control_agent_info.desc, "%.*s", (int)(sizeof(pptp_control_agent_info.desc)-1), pptp_control_alg_desc); sprintf(pptp_control_agent_info.name, "%.*s", (int)(sizeof(pptp_control_agent_info.name)-1), pptp_control_alg_name); status = natRegisterAgent(nat_id.id, &pptp_control_agent_info); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natPPTPPTInit: natRegisterAgent failed" " for PPTP Control with error %d\n", status); return(status); } nat_printf(NAT_PRINTF_INIT, "PPTP Control Pass-Thru ALG registered with NAT\n"); next_pptp_spoofed_call_id = LOWER_SPOOFED_CALL_ID_VALUE; /* start a 1 sec timer that checks for timeouts in the PPTP table entries */ pptpTimerId = natTimerEvtCreate(1000,(FUNCPTR)nat_pptp_timer,0); if (pptpTimerId == NULL) { nat_printf(NAT_PRINTF_ERROR,"fail to create IPSEC timer\n"); return ERROR; } if (natEvtActivate(pptpTimerId) == ERROR) { nat_printf(NAT_PRINTF_ERROR,"fail to activate PPTP timer\n"); return ERROR; } semGive(natInitSync); return(OK);}/*****************************************************************************************Function: natPPTPPTEndDescription: ******************************************************************************************/STATUS natPPTPPTEnd(){ STATUS status; nat_printf(NAT_PRINTF_INIT, "Stopping PPTP Pass-Thru\n"); if (pptpTimerId != NULL) natEvtRemove(pptpTimerId); status = natUnregisterAgent(nat_id.id, pptp_gre_agent_info.id); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natPPTPPTEnd: natUnregisterAgent failed" " for PPTP GRE with error %d\n", status); return(status); } clear_pptp_translation_entry_list (&pptp_translation_list); status = natUnregisterAgent(nat_id.id, pptp_control_agent_info.id); if (status != NAT_OK) { nat_printf (NAT_PRINTF_ERROR, "natPPTPPTEnd: natUnregisterAgent failed" " for PPTP Control with error %d\n", status); return(status); } semDelete(pptpListLock); return(OK);}/*****************************************************************************************Function: new_pptp_translation_entryDescription: ******************************************************************************************/LOCAL PPTP_TRANSLATION_ENTRY *new_pptp_translation_entry ( PPTP_TRANSLATION_HEADER *sptr_pptp_translation_list, USHORT call_id, USHORT spoofed_call_id, BOOL nated_client, IP_ADDRESS local_address, IP_ADDRESS remote_address){ PPTP_TRANSLATION_ENTRY *sptr_pptp_translation_entry; nat_printf (NAT_PRINTF_TRACE, "new_pptp_translation_entry: " "local addr = %08lx, remote addr = %08lx\n\t" "call id = %04x spoofed call id = %04x\n" , local_address, remote_address, call_id, spoofed_call_id); sptr_pptp_translation_entry = (PPTP_TRANSLATION_ENTRY *) calloc (1, sizeof (PPTP_TRANSLATION_ENTRY)); if (sptr_pptp_translation_entry == NULL) { nat_printf (NAT_PRINTF_ERROR, "new_pptp_translation_entry: NAT failed calloc\n"); return (NULL); } sptr_pptp_translation_entry->pptp_translation_entry_timer = PPTP_DATA_INIT_TIMEOUT; sptr_pptp_translation_entry->call_id = call_id; sptr_pptp_translation_entry->spoofed_call_id = spoofed_call_id; sptr_pptp_translation_entry->peers_call_id = 0; sptr_pptp_translation_entry->nated_client = nated_client; sptr_pptp_translation_entry->local_address = local_address; sptr_pptp_translation_entry->remote_address = remote_address; dllAdd ((DL_LIST *) sptr_pptp_translation_list, (DL_NODE *) sptr_pptp_translation_entry); return (sptr_pptp_translation_entry); }/*****************************************************************************Function: find_outbound_pptp_entry_peerDescription:Look for PPTP entry with matching peers_call_id, local address and remote address.*****************************************************************************/LOCAL PPTP_TRANSLATION_ENTRY *find_outbound_pptp_entry_peer ( IP_ADDRESS local_address, IP_ADDRESS remote_address, USHORT call_id, PPTP_TRANSLATION_HEADER *sptr_pptp_translation_list){ PPTP_TRANSLATION_ENTRY *sptr_pptp_translation_entry; semTake (pptpListLock, WAIT_FOREVER); for (sptr_pptp_translation_entry = (PPTP_TRANSLATION_ENTRY *) DLL_FIRST ((DL_LIST *) sptr_pptp_translation_list); sptr_pptp_translation_entry != NULL; sptr_pptp_translation_entry = (PPTP_TRANSLATION_ENTRY *) DLL_NEXT ((DL_NODE *) sptr_pptp_translation_entry)) { if ((sptr_pptp_translation_entry->peers_call_id == call_id) && (sptr_pptp_translation_entry->local_address == local_address) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -