1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-09 19:20:41 +03:00
SoftEtherVPN/src/Cedar/Virtual.h

699 lines
32 KiB
C

// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
//
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
//
// Copyright (c) Daiyuu Nobori.
// Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) SoftEther Corporation.
//
// All Rights Reserved.
//
// http://www.softether.org/
//
// Author: Daiyuu Nobori, Ph.D.
// Comments: Tetsuo Sugiyama, Ph.D.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License version 2
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
//
//
// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
//
// USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS
// YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY
// CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS
// SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE
// SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO
// COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING
// PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR
// CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE
// NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
// INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+
// COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE
// WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY
// COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE
// COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE
// SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR
// COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO
// RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
// RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT
// JUST A STATEMENT FOR WARNING AND DISCLAIMER.
//
//
// SOURCE CODE CONTRIBUTION
// ------------------------
//
// Your contribution to SoftEther VPN Project is much appreciated.
// Please send patches to us through GitHub.
// Read the SoftEther VPN Patch Acceptance Policy in advance:
// http://www.softether.org/5-download/src/9.patch
//
//
// DEAR SECURITY EXPERTS
// ---------------------
//
// If you find a bug or a security vulnerability please kindly inform us
// about the problem immediately so that we can fix the security problem
// to protect a lot of users around the world as soon as possible.
//
// Our e-mail address for security reports is:
// softether-vpn-security [at] softether.org
//
// Please note that the above e-mail address is not a technical support
// inquiry address. If you need technical assistance, please visit
// http://www.softether.org/ and ask your question on the users forum.
//
// Thank you for your cooperation.
//
//
// NO MEMORY OR RESOURCE LEAKS
// ---------------------------
//
// The memory-leaks and resource-leaks verification under the stress
// test has been passed before release this source code.
// Virtual.h
// Header of Virtual.c
#ifndef VIRTUAL_H
#define VIRTUAL_H
#define NN_RAW_IP_PORT_START 61001
#define NN_RAW_IP_PORT_END 65535
#define VIRTUAL_TCP_SEND_TIMEOUT (21 * 1000)
#define NN_NEXT_WAIT_TIME_FOR_DEVICE_ENUM (30 * 1000)
#define NN_NEXT_WAIT_TIME_MAX_FAIL_COUNT 30
#define NN_HOSTNAME_FORMAT "securenat-%s"
#define NN_HOSTNAME_STARTWITH "securenat-"
#define NN_HOSTNAME_STARTWITH2 "securenat_"
#define NN_CHECK_CONNECTIVITY_TIMEOUT (5 * 1000)
#define NN_CHECK_CONNECTIVITY_INTERVAL (1 * 1000)
#define NN_POLL_CONNECTIVITY_TIMEOUT (4 * 60 * 1000 + 10)
#define NN_POLL_CONNECTIVITY_INTERVAL (1 * 60 * 1000)
#define NN_MAX_QUEUE_LENGTH 10000
#define NN_NO_NATIVE_NAT_FILENAME L"@no_native_nat_niclist.txt"
#define NN_TIMEOUT_FOR_UNESTBALISHED_TCP (10 * 1000) // Time-out period of a TCP connection incomplete session
// Destination host name of the connectivity test for the Internet
// (Access the www.yahoo.com. Access the www.baidu.com from China. I am sorry.)
#define NN_CHECK_HOSTNAME (IsEmptyStr(secure_nat_target_hostname) ? (IsUseAlternativeHostname() ? "www.baidu.com" : "www.yahoo.com") : secure_nat_target_hostname)
// Native NAT entry
struct NATIVE_NAT_ENTRY
{
UINT Id; // ID
UINT Status; // Status
UINT Protocol; // Protocol
UINT SrcIp; // Source IP address
UINT SrcPort; // Source port number
UINT DestIp; // Destination IP address
UINT DestPort; // Destination port number
UINT PublicIp; // Public IP address
UINT PublicPort; // Public port number
UINT64 CreatedTime; // Connection time
UINT64 LastCommTime; // Last communication time
UINT64 TotalSent; // Total number of bytes sent
UINT64 TotalRecv; // Total number of bytes received
UINT LastSeq; // Last sequence number
UINT LastAck; // Last acknowledgment number
UINT HashCodeForSend; // Cached hash code (transmit direction)
UINT HashCodeForRecv; // Cached hash code (receive direction)
};
// Native NAT
struct NATIVE_NAT
{
struct VH *v; // Virtual machine
bool Active; // Whether currently available
THREAD *Thread; // Main thread
bool Halt; // Halting flag
TUBE *HaltTube; // Tube to be disconnected in order to stop
TUBE *HaltTube2; // Tube 2 to be disconnected in order to stop
TUBE *HaltTube3; // Tube 3 to be disconnected in order to stop
LOCK *Lock; // Lock
EVENT *HaltEvent; // Halting event
UINT LastInterfaceIndex; // Index number of the interface that is used for attempting last
UINT LastInterfaceDeviceHash; // Hash value of the device list at the time of the last attempted
UINT NextWaitTimeForRetry; // Time for waiting next time for the device list enumeration
UINT FailedCount; // The number of failed searching for the interface
UINT LastHostAddressHash; // Hash of the last host IP address
DHCP_OPTION_LIST CurrentDhcpOptions; // Current DHCP options
QUEUE *SendQueue; // Transmission queue
QUEUE *RecvQueue; // Reception queue
CANCEL *Cancel; // Cancel object (Hit if there is a received packet)
LOCK *CancelLock; // Lock of the cancel object
HASH_LIST *NatTableForSend; // Native NAT table (for transmission)
HASH_LIST *NatTableForRecv; // Native NAT table (for reception)
UINT PublicIP; // Public IP
USHORT NextId; // Next IP packet ID
bool SendStateChanged; // Transmission state changed
LIST *IpCombine; // IP combining list
UINT CurrentIpQuota; // Current IP combining quota
UCHAR CurrentMacAddress[6]; // Current MAC address
bool IsRawIpMode; // Is RAW_IP mode
};
// ARP entry
struct ARP_ENTRY
{
UINT IpAddress; // IP address
UCHAR MacAddress[6]; // MAC address
UCHAR Padding[2];
UINT64 Created; // Creation date and time
UINT64 Expire; // Expiration date
};
// ARP waiting list
struct ARP_WAIT
{
UINT IpAddress; // IP address trying to solve
UINT NextTimeoutTimeValue; // Next time before timing out
UINT64 TimeoutTime; // Current Time-out of transmission
UINT64 GiveupTime; // Time to give up the transmission
};
// IP waiting list
struct IP_WAIT
{
UINT DestIP; // Destination IP address
UINT SrcIP; // Source IP address
UINT64 Expire; // Storage life
void *Data; // Data
UINT Size; // Size
};
// IP partial list
struct IP_PART
{
UINT Offset; // Offset
UINT Size; // Size
};
// IP restore list
struct IP_COMBINE
{
UINT DestIP; // Destination IP address
UINT SrcIP; // Source IP address
USHORT Id; // IP packet ID
UCHAR Ttl; // TTL
UINT64 Expire; // Storage life
void *Data; // Packet data
UINT DataReserved; // Area reserved for data
UINT Size; // Packet size (Total)
LIST *IpParts; // IP partial list
UCHAR Protocol; // Protocol number
bool MacBroadcast; // Broadcast packets at the MAC level
UCHAR *HeadIpHeaderData; // Data of the IP header of the top
UINT HeadIpHeaderDataSize; // Data size of the IP header of the top
bool SrcIsLocalMacAddr; // Source MAC address is on the same machine
UINT MaxL3Size; // Largest L3 size
};
#define IP_COMBINE_INITIAL_BUF_SIZE (MAX_IP_DATA_SIZE) // Initial buffer size
// NAT session table
struct NAT_ENTRY
{
// TCP | UDP common items
struct VH *v; // Virtual machine
UINT Id; // ID
LOCK *lock; // Lock
UINT Protocol; // Protocol
UINT SrcIp; // Source IP address
UINT SrcPort; // Source port number
UINT DestIp; // Destination IP address
UINT DestPort; // Destination port number
UINT PublicIp; // Public IP address
UINT PublicPort; // Public port number
UINT64 CreatedTime; // Connection time
UINT64 LastCommTime; // Last communication time
SOCK *Sock; // Socket
bool DisconnectNow; // Flag to stop immediately
UINT tag1;
bool ProxyDns; // DNS proxy
UINT DestIpProxy; // Proxy DNS address
// ICMP NAT item (only for the calling ICMP API mode)
THREAD *IcmpThread; // ICMP query thread
BLOCK *IcmpQueryBlock; // Block that contains the ICMP query
BLOCK *IcmpResponseBlock; // Block that contains ICMP result
bool IcmpTaskFinished; // Flag indicating that the processing of ICMP has been completed
UCHAR *IcmpOriginalCopy; // Copy of the original ICMP packet
UINT IcmpOriginalCopySize; // The size of the copy of original ICMP packet
// DNS NAT item
THREAD *DnsThread; // DNS query thread
bool DnsGetIpFromHost; // Reverse resolution flag
char *DnsTargetHostName; // Target host name
IP DnsResponseIp; // Response IP address
char *DnsResponseHostName; // Response host name
UINT DnsTransactionId; // DNS transaction ID
bool DnsFinished; // DNS query completion flag
bool DnsOk; // DNS success flag
bool DnsPollingFlag; // DNS polling completion flag
// UDP item
QUEUE *UdpSendQueue; // UDP send queue
QUEUE *UdpRecvQueue; // UDP receive queue
bool UdpSocketCreated; // Whether an UDP socket was created
// TCP items
FIFO *SendFifo; // Transmission FIFO
FIFO *RecvFifo; // Receive FIFO
UINT TcpStatus; // TCP state
bool NatTcpCancelFlag; // TCP connection cancel flag
THREAD *NatTcpConnectThread; // TCP socket connection thread
bool TcpMakeConnectionFailed; // Failed to connect with connection thread
bool TcpMakeConnectionSucceed; // Successfully connected by the connection thread
UINT TcpSendMaxSegmentSize; // Maximum transmission segment size
UINT TcpRecvMaxSegmentSize; // Maximum reception segment size
UINT64 LastSynAckSentTime; // Time which the SYN+ACK was sent last
UINT SynAckSentCount; // SYN + ACK transmission times
UINT TcpSendWindowSize; // Transmission window size
UINT TcpSendCWnd; // Transmission congestion window size (/mss)
UINT TcpRecvWindowSize; // Receive window size
UINT TcpSendTimeoutSpan; // Transmission time-out period
UINT64 TcpLastSentTime; // Time for the last transmitted over TCP
UINT64 LastSentKeepAliveTime; // Time which the keep-alive ACK was sent last
FIFO *TcpRecvWindow; // TCP receive window
LIST *TcpRecvList; // TCP reception list
bool SendAckNext; // Send an ACK at the time of the next transmission
UINT LastSentWindowSize; // My window size that sent the last
UINT64 TcpLastRecvAckTime; // Time that the other party has received the last data in TCP
UINT64 SendSeqInit; // Initial send sequence number
UINT64 SendSeq; // Send sequence number
UINT64 RecvSeqInit; // Initial receive sequence number
UINT64 RecvSeq; // Receive sequence number
UINT FinSentSeq; // Sequence number with the last FIN
bool CurrentSendingMission; // Burst transmission ongoing
UINT SendMissionSize; // Transmission size of this time
bool RetransmissionUsedFlag; // Retransmission using record flag
UINT CurrentRTT; // Current RTT value
UINT64 CalcRTTStartTime; // RTT measurement start time
UINT64 CalcRTTStartValue; // RTT measurement start value
bool TcpFinished; // Data communication end flag of TCP
bool TcpDisconnected; // TCP Disconnect flag
bool TcpForceReset; // TCP connection force reset flag
UINT64 FinSentTime; // Time which the FIN was sent last
UINT FinSentCount; // Number of FIN transmissions
UINT64 test_TotalSent;
};
// TCP options
struct TCP_OPTION
{
UINT MaxSegmentSize; // Maximum segment size
UINT WindowScaling; // Window scaling
};
// Virtual host structure
struct VH
{
REF *ref; // Reference counter
LOCK *lock; // Lock
SESSION *Session; // Session
CANCEL *Cancel; // Cancel object
QUEUE *SendQueue; // Transmission queue
bool Active; // Active flag
volatile bool HaltNat; // NAT halting flag
LIST *ArpTable; // ARP table
LIST *ArpWaitTable; // ARP waiting table
LIST *IpWaitTable; // IP waiting table
LIST *IpCombine; // IP combining table
UINT64 Now; // Current time
UINT64 NextArpTablePolling; // Next time to poll the ARP table
UINT Mtu; // MTU value
UINT IpMss; // Maximum IP data size
UINT TcpMss; // TCP maximum data size
UINT UdpMss; // UDP maximum data size
bool flag1; // Flag 1
bool flag2; // Flag 2
USHORT NextId; // ID of the IP packet
UINT CurrentIpQuota; // IP packet memory quota
LIST *NatTable; // NAT table
SOCK_EVENT *SockEvent; // Socket event
THREAD *NatThread; // NAT thread
void *TmpBuf; // Buffer that can be used temporarily
bool NatDoCancelFlag; // Flag of whether to hit the cancel
UCHAR MacAddress[6]; // MAC address
UCHAR Padding[2];
UINT HostIP; // Host IP
UINT HostMask; // Host subnet mask
UINT NatTcpTimeout; // NAT TCP timeout in seconds
UINT NatUdpTimeout; // NAT UDP timeout in seconds
bool UseNat; // NAT use flag
bool UseDhcp; // DHCP using flag
UINT DhcpIpStart; // Distribution start address
UINT DhcpIpEnd; // Distribution end address
UINT DhcpMask; // Subnet mask
UINT DhcpExpire; // Address distribution expiration date
UINT DhcpGateway; // Gateway address
UINT DhcpDns; // DNS server address 1
UINT DhcpDns2; // DNS server address 2
char DhcpDomain[MAX_HOST_NAME_LEN + 1]; // Assigned domain name
LIST *DhcpLeaseList; // DHCP lease list
UINT64 LastDhcpPolling; // Time which the DHCP list polled last
bool SaveLog; // Save a log
DHCP_CLASSLESS_ROUTE_TABLE PushRoute; // Pushing routing table
COUNTER *Counter; // Session counter
UINT DhcpId; // DHCP ID
UINT64 LastSendBeacon; // Time which the beacon has been sent last
LOG *Logger; // Logger
NAT *nat; // A reference to the NAT object
bool IcmpRawSocketOk; // ICMP RAW SOCKET is available
bool IcmpApiOk; // ICMP API is available
HUB_OPTION *HubOption; // Pointer to the Virtual HUB options
NATIVE_NAT *NativeNat; // Native NAT
};
// Virtual host option
struct VH_OPTION
{
char HubName[MAX_HUBNAME_LEN + 1]; // Target Virtual HUB name
UCHAR MacAddress[6]; // MAC address
UCHAR Padding[2];
IP Ip; // IP address
IP Mask; // Subnet mask
bool UseNat; // Use flag of NAT function
UINT Mtu; // MTU value
UINT NatTcpTimeout; // NAT TCP timeout in seconds
UINT NatUdpTimeout; // NAT UDP timeout in seconds
bool UseDhcp; // Using flag of DHCP function
IP DhcpLeaseIPStart; // Start of IP address range for DHCP distribution
IP DhcpLeaseIPEnd; // End of IP address range for DHCP distribution
IP DhcpSubnetMask; // DHCP subnet mask
UINT DhcpExpireTimeSpan; // DHCP expiration date
IP DhcpGatewayAddress; // Assigned gateway address
IP DhcpDnsServerAddress; // Assigned DNS server address 1
IP DhcpDnsServerAddress2; // Assigned DNS server address 2
char DhcpDomainName[MAX_HOST_NAME_LEN + 1]; // Assigned domain name
bool SaveLog; // Save a log
bool ApplyDhcpPushRoutes; // Apply flag for DhcpPushRoutes
char DhcpPushRoutes[MAX_DHCP_CLASSLESS_ROUTE_TABLE_STR_SIZE]; // DHCP pushing routes
};
// DHCP lease entry
struct DHCP_LEASE
{
UINT Id; // ID
UINT64 LeasedTime; // Leased time
UINT64 ExpireTime; // Expiration date
UCHAR MacAddress[6]; // MAC address
UCHAR Padding[2]; // Padding
UINT IpAddress; // IP address
UINT Mask; // Subnet mask
char *Hostname; // Host name
};
// DNS query
typedef struct NAT_DNS_QUERY
{
REF *ref; // Reference counter
char Hostname[256]; // Host name
bool Ok; // Result success flag
IP Ip; // Result IP address
} NAT_DNS_QUERY;
// Parsed DNS query
struct DNS_PARSED_PACKET
{
UINT TransactionId;
char Hostname[128];
};
// Virtual LAN card of the virtual host
PACKET_ADAPTER *VirtualGetPacketAdapter();
bool VirtualPaInit(SESSION *s);
CANCEL *VirtualPaGetCancel(SESSION *s);
UINT VirtualPaGetNextPacket(SESSION *s, void **data);
bool VirtualPaPutPacket(SESSION *s, void *data, UINT size);
void VirtualPaFree(SESSION *s);
bool VirtualInit(VH *v);
UINT VirtualGetNextPacket(VH *v, void **data);
bool VirtualPutPacket(VH *v, void *data, UINT size);
void Virtual_Free(VH *v);
VH *NewVirtualHost(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, VH_OPTION *vh_option);
VH *NewVirtualHostEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, VH_OPTION *vh_option, NAT *nat);
void LockVirtual(VH *v);
void UnlockVirtual(VH *v);
void ReleaseVirtual(VH *v);
void CleanupVirtual(VH *v);
void StopVirtualHost(VH *v);
void SetVirtualHostOption(VH *v, VH_OPTION *vo);
void GenMacAddress(UCHAR *mac);
void GetVirtualHostOption(VH *v, VH_OPTION *o);
void VirtualLayer2(VH *v, PKT *packet);
bool VirtualLayer2Filter(VH *v, PKT *packet);
void VirtualArpReceived(VH *v, PKT *packet);
void VirtualArpResponseRequest(VH *v, PKT *packet);
void VirtualArpResponseReceived(VH *v, PKT *packet);
void VirtualArpSendResponse(VH *v, UCHAR *dest_mac, UINT dest_ip, UINT src_ip);
void VirtualArpSendRequest(VH *v, UINT dest_ip);
void VirtualIpSend(VH *v, UCHAR *dest_mac, void *data, UINT size);
void VirtualLayer2Send(VH *v, UCHAR *dest_mac, UCHAR *src_mac, USHORT protocol, void *data, UINT size);
void VirtualPolling(VH *v);
void InitArpTable(VH *v);
void FreeArpTable(VH *v);
int CompareArpTable(void *p1, void *p2);
ARP_ENTRY *SearchArpTable(VH *v, UINT ip);
void RefreshArpTable(VH *v);
void PollingArpTable(VH *v);
void InsertArpTable(VH *v, UCHAR *mac, UINT ip);
bool IsMacBroadcast(UCHAR *mac);
bool IsMacInvalid(UCHAR *mac);
void InitArpWaitTable(VH *v);
void FreeArpWaitTable(VH *v);
int CompareArpWaitTable(void *p1, void *p2);
ARP_WAIT *SearchArpWaitTable(VH *v, UINT ip);
void DeleteArpWaitTable(VH *v, UINT ip);
void SendArp(VH *v, UINT ip);
void InsertArpWaitTable(VH *v, ARP_WAIT *w);
void PollingArpWaitTable(VH *v);
void ArpIpWasKnown(VH *v, UINT ip, UCHAR *mac);
void InitIpWaitTable(VH *v);
void FreeIpWaitTable(VH *v);
void InsertIpWaitTable(VH *v, UINT dest_ip, UINT src_ip, void *data, UINT size);
void SendFragmentedIp(VH *v, UINT dest_ip, UINT src_ip, USHORT id, USHORT total_size, USHORT offset, UCHAR protocol, void *data, UINT size, UCHAR *dest_mac, UCHAR ttl);
void SendIp(VH *v, UINT dest_ip, UINT src_ip, UCHAR protocol, void *data, UINT size);
void SendIpEx(VH *v, UINT dest_ip, UINT src_ip, UCHAR protocol, void *data, UINT size, UCHAR ttl);
void PollingIpWaitTable(VH *v);
void DeleteOldIpWaitTable(VH *v);
void SendWaitingIp(VH *v, UCHAR *mac, UINT dest_ip);
void VirtualIpReceived(VH *v, PKT *packet);
void InitIpCombineList(VH *v);
void FreeIpCombineList(VH *v);
int CompareIpCombine(void *p1, void *p2);
void CombineIp(VH *v, IP_COMBINE *c, UINT offset, void *data, UINT size, bool last_packet, UCHAR *head_ip_header_data, UINT head_ip_header_size);
void IpReceived(VH *v, UINT src_ip, UINT dest_ip, UINT protocol, void *data, UINT size, bool mac_broadcast, UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, bool is_local_mac, UINT max_l3_size);
void FreeIpCombine(VH *v, IP_COMBINE *c);
void PollingIpCombine(VH *v);
IP_COMBINE *InsertIpCombine(VH *v, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol, bool mac_broadcast, UCHAR ttl, bool src_is_localmac);
IP_COMBINE *SearchIpCombine(VH *v, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol);
void VirtualIcmpReceived(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size, UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size);
void VirtualIcmpEchoRequestReceived(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size);
void VirtualIcmpEchoRequestReceivedRaw(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size);
void VirtualIcmpEchoSendResponse(VH *v, UINT src_ip, UINT dst_ip, USHORT id, USHORT seq_no, void *data, UINT size);
void VirtualIcmpSend(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size);
void VirtualUdpReceived(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, bool mac_broadcast, bool is_localmac, UINT max_l3_size);
void SendUdp(VH *v, UINT dest_ip, UINT dest_port, UINT src_ip, UINT src_port, void *data, UINT size);
UINT GetNetworkAddress(UINT addr, UINT mask);
UINT GetBroadcastAddress(UINT addr, UINT mask);
void GetBroadcastAddress4(IP *dst, IP *addr, IP *mask);
bool IsInNetwork(UINT uni_addr, UINT network_addr, UINT mask);
void UdpRecvForMe(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size);
void UdpRecvLlmnr(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size);
void UdpRecvForBroadcast(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size);
void UdpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, bool dns_proxy);
void UdpRecvForNetBiosBroadcast(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, bool dns_proxy, bool unicast);
bool IsNetbiosRegistrationPacket(UCHAR *buf, UINT size);
bool ProcessNetBiosNameQueryPacketForMyself(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size);
void EncodeNetBiosName(UCHAR *dst, char *src);
char *CharToNetBiosStr(char c);
void InitNat(VH *v);
void FreeNat(VH *v);
int CompareNat(void *p1, void *p2);
NAT_ENTRY *SearchNat(VH *v, NAT_ENTRY *target);
void SetNat(NAT_ENTRY *n, UINT protocol, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT public_ip, UINT public_port);
void DeleteNatTcp(VH *v, NAT_ENTRY *n);
void DeleteNatUdp(VH *v, NAT_ENTRY *n);
void DeleteNatIcmp(VH *v, NAT_ENTRY *n);
NAT_ENTRY *CreateNatUdp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT dns_proxy_ip);
NAT_ENTRY *CreateNatIcmp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UCHAR *original_copy, UINT original_copy_size);
void NatThread(THREAD *t, void *param);
void NatThreadMain(VH *v);
bool NatTransactUdp(VH *v, NAT_ENTRY *n);
bool NatTransactIcmp(VH *v, NAT_ENTRY *n);
void NatIcmpThreadProc(THREAD *thread, void *param);
void PoolingNat(VH *v);
void PoolingNatUdp(VH *v, NAT_ENTRY *n);
void PollingNatIcmp(VH *v, NAT_ENTRY *n);
void VirtualTcpReceived(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, UINT max_l3_size);
void TcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, TCP_HEADER *tcp, void *data, UINT size, UINT max_l3_size);
NAT_ENTRY *CreateNatTcp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port);
bool NatTransactTcp(VH *v, NAT_ENTRY *n);
void CreateNatTcpConnectThread(VH *v, NAT_ENTRY *n);
void NatTcpConnectThread(THREAD *t, void *p);
void PollingNatTcp(VH *v, NAT_ENTRY *n);
void ParseTcpOption(TCP_OPTION *o, void *data, UINT size);
void SendTcp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT seq, UINT ack, UINT flag, UINT window_size, UINT mss, void *data, UINT size);
void DnsProxy(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size);
bool ParseDnsPacket(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size);
bool ParseDnsPacketEx(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, DNS_PARSED_PACKET *parsed_result);
void SetDnsProxyVgsHostname(char *hostname);
bool NatTransactDns(VH *v, NAT_ENTRY *n);
void NatDnsThread(THREAD *t, void *param);
bool NatGetIP(IP *ip, char *hostname);
void NatGetIPThread(THREAD *t, void *param);
NAT_ENTRY *CreateNatDns(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port,
UINT transaction_id, bool dns_get_ip_from_host, char *dns_target_host_name);
void PollingNatDns(VH *v, NAT_ENTRY *n);
void SendNatDnsResponse(VH *v, NAT_ENTRY *n);
void BuildDnsQueryPacket(BUF *b, char *hostname, bool ptr);
void BuildDnsResponsePacketA(BUF *b, IP *ip);
void BuildDnsResponsePacketPtr(BUF *b, char *hostname);
bool ArpaToIP(IP *ip, char *str);
BUF *BuildDnsHostName(char *hostname);
bool CanCreateNewNatEntry(VH *v);
void VirtualDhcpServer(VH *v, PKT *p);
void InitDhcpServer(VH *v);
void FreeDhcpServer(VH *v);
void PollingDhcpServer(VH *v);
int CompareDhcpLeaseList(void *p1, void *p2);
DHCP_LEASE *NewDhcpLease(UINT expire, UCHAR *mac_address, UINT ip, UINT mask, char *hostname);
void FreeDhcpLease(DHCP_LEASE *d);
DHCP_LEASE *SearchDhcpLeaseByMac(VH *v, UCHAR *mac);
DHCP_LEASE *SearchDhcpLeaseByIp(VH *v, UINT ip);
UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip);
UINT GetFreeDhcpIpAddress(VH *v);
UINT GetFreeDhcpIpAddressByRandom(VH *v, UCHAR *mac);
UINT ServeDhcpRequest(VH *v, UCHAR *mac, UINT request_ip);
void VirtualDhcpSend(VH *v, UINT tran_id, UINT dest_ip, UINT dest_port,
UINT new_ip, UCHAR *client_mac, BUF *b, UINT hw_type, UINT hw_addr_size);
void VLog(VH *v, char *str);
void SendBeacon(VH *v);
void PollingBeacon(VH *v);
HUB_OPTION *NatGetHubOption(VH *v);
UINT GetNumNatEntriesPerIp(VH *v, UINT ip, UINT protocol, bool tcp_syn_sent);
void NatSetHubOption(VH *v, HUB_OPTION *o);
NAT_ENTRY *GetOldestNatEntryOfIp(VH *v, UINT ip, UINT protocol);
void DisconnectNatEntryNow(VH *v, NAT_ENTRY *e);
NATIVE_NAT *NewNativeNat(VH *v);
void FreeNativeNat(NATIVE_NAT *t);
void NativeNatThread(THREAD *thread, void *param);
NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t);
bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube);
void NnMainLoop(NATIVE_NAT *t, NATIVE_STACK *a);
BUF *NnBuildDnsQueryPacket(char *hostname, USHORT tran_id);
BUF *NnBuildUdpPacket(BUF *payload, UINT src_ip, USHORT src_port, UINT dst_ip, USHORT dst_port);
BUF *NnBuildTcpPacket(BUF *payload, UINT src_ip, USHORT src_port, UINT dst_ip, USHORT dst_port, UINT seq, UINT ack, UINT flag, UINT window_size, UINT mss);
BUF *NnBuildIpPacket(BUF *payload, UINT src_ip, UINT dst_ip, UCHAR protocol, UCHAR ttl);
UINT NnGenSrcPort(bool raw_ip_mode);
bool NnParseDnsResponsePacket(UCHAR *data, UINT size, IP *ret_ip);
BUF *NnReadDnsRecord(BUF *buf, bool answer, USHORT *ret_type, USHORT *ret_class);
bool NnReadDnsLabel(BUF *buf);
void NnClearQueue(NATIVE_NAT *t);
int CmpNativeNatTableForSend(void *p1, void *p2);
int CmpNativeNatTableForRecv(void *p1, void *p2);
UINT GetHashNativeNatTableForSend(void *p);
UINT GetHashNativeNatTableForRecv(void *p);
void NnSetNat(NATIVE_NAT_ENTRY *e, UINT protocol, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT pub_ip, UINT pub_port);
bool NnIsActive(VH *v);
bool NnIsActiveEx(VH *v, bool *is_ipraw_mode);
void NnUdpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, UINT max_l3_size);
void NnTcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, TCP_HEADER *old_tcp, void *data, UINT size, UINT max_l3_size);
void NnIcmpEchoRecvForInternet(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size);
UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_port, UINT public_ip);
void NnIpSendForInternet(NATIVE_NAT *t, UCHAR ip_protocol, UCHAR ttl, UINT src_ip, UINT dest_ip, void *data, UINT size, UINT max_l3_size);
void NnIpSendFragmentedForInternet(NATIVE_NAT *t, UCHAR ip_protocol, UINT src_ip, UINT dest_ip, USHORT id, USHORT total_size,
USHORT offset, void *data, UINT size, UCHAR ttl);
void NnPoll(NATIVE_NAT *t);
void NnLayer2(NATIVE_NAT *t, PKT *packet);
void NnFragmentedIpReceived(NATIVE_NAT *t, PKT *packet);
void NnIpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, UINT protocol, void *data, UINT size,
UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size);
void NnUdpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, UINT max_l3_size);
void NnTcpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, UINT max_l3_size);
void NnIcmpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, UINT max_l3_size);
void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT size, bool last_packet, UCHAR *head_ip_header_data, UINT head_ip_header_size);
void NnFreeIpCombine(NATIVE_NAT *t, IP_COMBINE *c);
IP_COMBINE *NnSearchIpCombine(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol);
IP_COMBINE *NnInsertIpCombine(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol, bool mac_broadcast, UCHAR ttl, bool src_is_localmac);
void NnInitIpCombineList(NATIVE_NAT *t);
void NnFreeIpCombineList(NATIVE_NAT *t);
void NnPollingIpCombine(NATIVE_NAT *t);
void NnDeleteOldSessions(NATIVE_NAT *t);
void NnDeleteSession(NATIVE_NAT *t, NATIVE_NAT_ENTRY *e);
NATIVE_NAT_ENTRY *NnGetOldestNatEntryOfIp(NATIVE_NAT *t, UINT ip, UINT protocol);
void NnDeleteOldestNatSession(NATIVE_NAT *t, UINT ip, UINT protocol);
UINT NnGetNumNatEntriesPerIp(NATIVE_NAT *t, UINT src_ip, UINT protocol);
void NnDeleteOldestNatSessionIfNecessary(NATIVE_NAT *t, UINT ip, UINT protocol);
void NnSetSecureNatTargetHostname(char *name);
#endif // VIRTUAL_H