mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-09 19:20:41 +03:00
699 lines
32 KiB
C
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
|
|
|
|
|