mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-12-25 01:29:53 +03:00
v4.19-9582-beta
This commit is contained in:
parent
3c8abd60ed
commit
4e862a7e40
@ -556,6 +556,16 @@ BRIDGE *BrNewBridge(HUB *h, char *name, POLICY *p, bool local, bool monitor, boo
|
||||
return b;
|
||||
}
|
||||
|
||||
// Raw IP bridge is supported only on Linux
|
||||
bool IsRawIpBridgeSupported()
|
||||
{
|
||||
#ifdef UNIX_LINUX
|
||||
return true;
|
||||
#else // UNIX_LINUX
|
||||
return false;
|
||||
#endif // UNIX_LINUX
|
||||
}
|
||||
|
||||
|
||||
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
|
||||
// Department of Computer Science has dozens of overly-enthusiastic geeks.
|
||||
|
@ -126,6 +126,9 @@
|
||||
|
||||
#endif // OS_WIN32
|
||||
|
||||
// Constants
|
||||
#define BRIDGE_SPECIAL_IPRAW_NAME "ipv4_rawsocket_virtual_router"
|
||||
|
||||
// Bridge
|
||||
struct BRIDGE
|
||||
{
|
||||
@ -171,6 +174,7 @@ bool DeleteLocalBridge(CEDAR *c, char *hubname, char *devicename);
|
||||
bool IsBridgeSupported();
|
||||
bool IsNeedWinPcap();
|
||||
UINT GetEthDeviceHash();
|
||||
bool IsRawIpBridgeSupported();
|
||||
|
||||
#endif // BRIDGE_H
|
||||
|
||||
|
@ -374,7 +374,7 @@ TOKEN_LIST *GetEthListSolaris()
|
||||
|
||||
#ifdef UNIX_LINUX
|
||||
// Get Ethernet device list on Linux
|
||||
TOKEN_LIST *GetEthListLinux()
|
||||
TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
TOKEN_LIST *t;
|
||||
@ -383,6 +383,11 @@ TOKEN_LIST *GetEthListLinux()
|
||||
LIST *o;
|
||||
char name[MAX_SIZE];
|
||||
|
||||
if (enum_normal == false && enum_rawip)
|
||||
{
|
||||
return ParseToken(BRIDGE_SPECIAL_IPRAW_NAME, NULL);
|
||||
}
|
||||
|
||||
o = NewListFast(CompareStr);
|
||||
|
||||
s = UnixEthOpenRawSocket();
|
||||
@ -431,7 +436,7 @@ TOKEN_LIST *GetEthListLinux()
|
||||
Sort(o);
|
||||
|
||||
t = ZeroMalloc(sizeof(TOKEN_LIST));
|
||||
t->NumTokens = LIST_NUM(o);
|
||||
t->NumTokens = LIST_NUM(o) + (enum_rawip ? 1 : 0);
|
||||
t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
|
||||
|
||||
for (i = 0;i < LIST_NUM(o);i++)
|
||||
@ -440,6 +445,11 @@ TOKEN_LIST *GetEthListLinux()
|
||||
t->Token[i] = name;
|
||||
}
|
||||
|
||||
if (enum_rawip)
|
||||
{
|
||||
t->Token[t->NumTokens - 1] = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
|
||||
}
|
||||
|
||||
ReleaseList(o);
|
||||
|
||||
return t;
|
||||
@ -542,11 +552,15 @@ TOKEN_LIST *GetEthListBpf()
|
||||
|
||||
// Enumerate Ethernet devices
|
||||
TOKEN_LIST *GetEthList()
|
||||
{
|
||||
return GetEthListEx(NULL, true, false);
|
||||
}
|
||||
TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip)
|
||||
{
|
||||
TOKEN_LIST *t = NULL;
|
||||
|
||||
#if defined(UNIX_LINUX)
|
||||
t = GetEthListLinux();
|
||||
t = GetEthListLinux(enum_normal, enum_rawip);
|
||||
#elif defined(UNIX_SOLARIS)
|
||||
t = GetEthListSolaris();
|
||||
#elif defined(BRIDGE_PCAP)
|
||||
@ -575,6 +589,11 @@ ETH *OpenEthLinux(char *name, bool local, bool tapmode, char *tapaddr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (StrCmpi(name, BRIDGE_SPECIAL_IPRAW_NAME) == 0)
|
||||
{
|
||||
return OpenEthLinuxIpRaw();
|
||||
}
|
||||
|
||||
if (tapmode)
|
||||
{
|
||||
#ifndef NO_VLAN
|
||||
@ -732,6 +751,10 @@ UINT EthGetMtu(ETH *e)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (e->IsRawIpMode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (e->CurrentMtu != 0)
|
||||
{
|
||||
@ -802,6 +825,10 @@ bool EthSetMtu(ETH *e, UINT mtu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (e->IsRawIpMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mtu == 0)
|
||||
{
|
||||
@ -865,6 +892,11 @@ bool EthIsChangeMtuSupported(ETH *e)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e->IsRawIpMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else // defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
|
||||
return false;
|
||||
@ -1526,6 +1558,13 @@ void CloseEth(ETH *e)
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->IsRawIpMode)
|
||||
{
|
||||
CloseEthLinuxIpRaw(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->Tap != NULL)
|
||||
{
|
||||
#ifndef NO_VLAN
|
||||
@ -1647,6 +1686,11 @@ UINT EthGetPacketLinux(ETH *e, void **data)
|
||||
return INFINITE;
|
||||
}
|
||||
|
||||
if (e->IsRawIpMode)
|
||||
{
|
||||
return EthGetPacketLinuxIpRaw(e, data);
|
||||
}
|
||||
|
||||
if (e->Tap != NULL)
|
||||
{
|
||||
#ifndef NO_VLAN
|
||||
@ -1949,6 +1993,11 @@ void EthPutPacket(ETH *e, void *data, UINT size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (e->IsRawIpMode)
|
||||
{
|
||||
EthPutPacketLinuxIpRaw(e, data, size);
|
||||
return;
|
||||
}
|
||||
if (size < 14 || size > MAX_PACKET_SIZE)
|
||||
{
|
||||
Free(data);
|
||||
@ -2017,6 +2066,745 @@ void EthPutPacket(ETH *e, void *data, UINT size)
|
||||
Free(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Open ETH by using IP raw packets
|
||||
ETH *OpenEthLinuxIpRaw()
|
||||
{
|
||||
ETH *e;
|
||||
|
||||
if (IsRawIpBridgeSupported() == false)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e = ZeroMalloc(sizeof(ETH));
|
||||
|
||||
e->IsRawIpMode = true;
|
||||
|
||||
e->RawTcp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_TCP), NULL);
|
||||
e->RawUdp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_UDP), NULL);
|
||||
e->RawIcmp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_ICMP), NULL);
|
||||
|
||||
if (e->RawTcp == NULL || e->RawUdp == NULL || e->RawIcmp == NULL)
|
||||
{
|
||||
ReleaseSock(e->RawTcp);
|
||||
ReleaseSock(e->RawUdp);
|
||||
ReleaseSock(e->RawIcmp);
|
||||
|
||||
Free(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ClearSockDfBit(e->RawTcp);
|
||||
ClearSockDfBit(e->RawUdp);
|
||||
ClearSockDfBit(e->RawIcmp);
|
||||
|
||||
SetRawSockHeaderIncludeOption(e->RawTcp, true);
|
||||
SetRawSockHeaderIncludeOption(e->RawUdp, true);
|
||||
SetRawSockHeaderIncludeOption(e->RawIcmp, true);
|
||||
|
||||
e->Name = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
|
||||
e->Title = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
|
||||
e->Cancel = NewCancel();
|
||||
|
||||
UnixDeletePipe(e->Cancel->pipe_read, e->Cancel->pipe_write);
|
||||
e->Cancel->pipe_read = e->Cancel->pipe_write = -1;
|
||||
|
||||
UnixSetSocketNonBlockingMode(e->RawTcp->socket, true);
|
||||
UnixSetSocketNonBlockingMode(e->RawUdp->socket, true);
|
||||
UnixSetSocketNonBlockingMode(e->RawIcmp->socket, true);
|
||||
|
||||
e->Cancel->SpecialFlag = true;
|
||||
e->Cancel->pipe_read = e->RawTcp->socket;
|
||||
e->Cancel->pipe_special_read2 = e->RawUdp->socket;
|
||||
e->Cancel->pipe_special_read3 = e->RawIcmp->socket;
|
||||
|
||||
e->RawIpMyMacAddr[2] = 0x01;
|
||||
e->RawIpMyMacAddr[5] = 0x01;
|
||||
|
||||
SetIP(&e->MyIP, 10, 171, 7, 253);
|
||||
SetIP(&e->YourIP, 10, 171, 7, 254);
|
||||
|
||||
e->RawIpSendQueue = NewQueueFast();
|
||||
|
||||
e->RawIP_TmpBufferSize = 67000;
|
||||
e->RawIP_TmpBuffer = Malloc(e->RawIP_TmpBufferSize);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
// Close ETH by using IP raw packets
|
||||
void CloseEthLinuxIpRaw(ETH *e)
|
||||
{
|
||||
if (e == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
BUF *buf = GetNext(e->RawIpSendQueue);
|
||||
if (buf == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
FreeBuf(buf);
|
||||
}
|
||||
ReleaseQueue(e->RawIpSendQueue);
|
||||
|
||||
Free(e->Name);
|
||||
Free(e->Title);
|
||||
|
||||
ReleaseSock(e->RawTcp);
|
||||
ReleaseSock(e->RawUdp);
|
||||
ReleaseSock(e->RawIcmp);
|
||||
|
||||
ReleaseCancel(e->Cancel);
|
||||
|
||||
Free(e->RawIP_TmpBuffer);
|
||||
|
||||
Free(e);
|
||||
}
|
||||
|
||||
// Receive an IP raw packet
|
||||
UINT EthGetPacketLinuxIpRaw(ETH *e, void **data)
|
||||
{
|
||||
UINT r;
|
||||
BUF *b;
|
||||
// Validate arguments
|
||||
if (e == NULL || data == NULL)
|
||||
{
|
||||
return INFINITE;
|
||||
}
|
||||
if (e->RawIp_HasError)
|
||||
{
|
||||
return INFINITE;
|
||||
}
|
||||
|
||||
b = GetNext(e->RawIpSendQueue);
|
||||
if (b != NULL)
|
||||
{
|
||||
UINT size;
|
||||
|
||||
*data = b->Buf;
|
||||
size = b->Size;
|
||||
|
||||
Free(b);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
r = EthGetPacketLinuxIpRawForSock(e, data, e->RawTcp, IP_PROTO_TCP);
|
||||
if (r == 0)
|
||||
{
|
||||
r = EthGetPacketLinuxIpRawForSock(e, data, e->RawUdp, IP_PROTO_UDP);
|
||||
if (r == 0)
|
||||
{
|
||||
r = EthGetPacketLinuxIpRawForSock(e, data, e->RawIcmp, IP_PROTO_ICMPV4);
|
||||
}
|
||||
}
|
||||
|
||||
if (r == INFINITE)
|
||||
{
|
||||
e->RawIp_HasError = true;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Receive an IP raw packet for the specified socket
|
||||
UINT EthGetPacketLinuxIpRawForSock(ETH *e, void **data, SOCK *s, UINT proto)
|
||||
{
|
||||
UCHAR *tmp;
|
||||
UINT r;
|
||||
IP src_addr;
|
||||
UINT src_port;
|
||||
UINT ret = INFINITE;
|
||||
UCHAR *retbuf;
|
||||
PKT *p;
|
||||
bool ok = false;
|
||||
// Validate arguments
|
||||
if (e == NULL || data == NULL)
|
||||
{
|
||||
return INFINITE;
|
||||
}
|
||||
|
||||
tmp = e->RawIP_TmpBuffer;
|
||||
|
||||
LABEL_RETRY:
|
||||
*data = NULL;
|
||||
|
||||
r = RecvFrom(s, &src_addr, &src_port, tmp, e->RawIP_TmpBufferSize);
|
||||
if (r == SOCK_LATER)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
if (s->IgnoreRecvErr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return INFINITE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 14 + r;
|
||||
retbuf = Malloc(ret);
|
||||
*data = retbuf;
|
||||
|
||||
Copy(retbuf, e->RawIpYourMacAddr, 6);
|
||||
Copy(retbuf + 6, e->RawIpMyMacAddr, 6);
|
||||
retbuf[12] = 0x08;
|
||||
retbuf[13] = 0x00;
|
||||
Copy(retbuf + 14, tmp, r);
|
||||
|
||||
// Mangle packet
|
||||
p = ParsePacket(retbuf, ret);
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p->TypeL3 == L3_IPV4)
|
||||
{
|
||||
IPV4_HEADER *ip;
|
||||
IP original_dest_ip;
|
||||
|
||||
ip = p->L3.IPv4Header;
|
||||
|
||||
UINTToIP(&original_dest_ip, ip->DstIP);
|
||||
|
||||
if (IsZeroIP(&e->MyPhysicalIPForce) == false && CmpIpAddr(&e->MyPhysicalIPForce, &original_dest_ip) == 0 ||
|
||||
(IsIPMyHost(&original_dest_ip) && IsLocalHostIP(&original_dest_ip) == false && IsHostIPAddress4(&original_dest_ip)))
|
||||
{
|
||||
if (IsZeroIP(&e->MyPhysicalIPForce) && CmpIpAddr(&e->MyPhysicalIP, &original_dest_ip) != 0)
|
||||
{
|
||||
// Update MyPhysicalIP
|
||||
Copy(&e->MyPhysicalIP, &original_dest_ip, sizeof(IP));
|
||||
// Debug("e->MyPhysicalIP = %r\n", &e->MyPhysicalIP);
|
||||
}
|
||||
|
||||
if (IsZeroIP(&e->MyPhysicalIPForce) == false)
|
||||
{
|
||||
Copy(&e->MyPhysicalIP, &e->MyPhysicalIPForce, sizeof(IP));
|
||||
}
|
||||
|
||||
ip->DstIP = IPToUINT(&e->YourIP);
|
||||
ip->Checksum = 0;
|
||||
ip->Checksum = IpChecksum(ip, IPV4_GET_HEADER_LEN(ip) * 5);
|
||||
|
||||
if (p->TypeL4 == L4_TCP)
|
||||
{
|
||||
TCP_HEADER *tcp = p->L4.TCPHeader;
|
||||
/*
|
||||
if (Endian16(tcp->SrcPort) == 80)
|
||||
{
|
||||
IP a, b;
|
||||
UINTToIP(&a, ip->SrcIP);
|
||||
UINTToIP(&b, ip->DstIP);
|
||||
Debug("%r %r %u %u\n", &a, &b, Endian16(tcp->SrcPort), Endian16(tcp->DstPort));
|
||||
}*/
|
||||
|
||||
ok = true;
|
||||
}
|
||||
else if (p->TypeL4 == L4_UDP)
|
||||
{
|
||||
UDP_HEADER *udp = p->L4.UDPHeader;
|
||||
|
||||
udp->Checksum = 0;
|
||||
|
||||
ok = true;
|
||||
}
|
||||
else if (p->TypeL4 == L4_ICMPV4)
|
||||
{
|
||||
ICMP_HEADER *icmp = p->L4.ICMPHeader;
|
||||
|
||||
if (icmp->Type == ICMP_TYPE_DESTINATION_UNREACHABLE || icmp->Type == ICMP_TYPE_TIME_EXCEEDED)
|
||||
{
|
||||
// Rewrite the Src IP of the IPv4 header of the ICMP response packet
|
||||
UINT size = p->PacketSize - ((UCHAR *)icmp - (UCHAR *)p->PacketData);
|
||||
UCHAR *data = (UCHAR *)icmp;
|
||||
IPV4_HEADER *orig_ipv4 = (IPV4_HEADER *)(((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
|
||||
UINT orig_ipv4_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
|
||||
|
||||
UINT orig_ipv4_header_size = GetIpHeaderSize((UCHAR *)orig_ipv4, orig_ipv4_size);
|
||||
|
||||
if (orig_ipv4_header_size >= sizeof(IPV4_HEADER) && orig_ipv4_size >= orig_ipv4_header_size)
|
||||
{
|
||||
if (orig_ipv4->Protocol == IP_PROTO_ICMPV4)
|
||||
{
|
||||
// Search the inner ICMP header
|
||||
UINT inner_icmp_size = orig_ipv4_size - orig_ipv4_header_size;
|
||||
|
||||
if (inner_icmp_size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
|
||||
{
|
||||
ICMP_HEADER *inner_icmp = (ICMP_HEADER *)(((UCHAR *)data) +
|
||||
sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + orig_ipv4_header_size);
|
||||
|
||||
if (inner_icmp->Type == ICMP_TYPE_ECHO_REQUEST)
|
||||
{
|
||||
ICMP_ECHO *inner_echo = (ICMP_ECHO *)(((UCHAR *)inner_icmp) + sizeof(ICMP_HEADER));
|
||||
|
||||
inner_icmp->Checksum = 0;
|
||||
orig_ipv4->SrcIP = IPToUINT(&e->YourIP);
|
||||
orig_ipv4->Checksum = 0;
|
||||
orig_ipv4->Checksum = IpChecksum(orig_ipv4, orig_ipv4_header_size);
|
||||
|
||||
// Rewrite the outer ICMP header
|
||||
if (true)
|
||||
{
|
||||
UCHAR *payload;
|
||||
UINT payload_size;
|
||||
ICMP_ECHO *echo;
|
||||
|
||||
// Echo Response
|
||||
echo = (ICMP_ECHO *)(((UCHAR *)data) + sizeof(ICMP_HEADER));
|
||||
|
||||
if (size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
|
||||
{
|
||||
payload = ((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
|
||||
payload_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
|
||||
|
||||
// Rewrite the header
|
||||
icmp->Checksum = 0;
|
||||
icmp->Checksum = IpChecksum(icmp, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
icmp->Checksum = 0;
|
||||
icmp->Checksum = IpChecksum(icmp, p->PayloadSize);
|
||||
|
||||
ok = true;
|
||||
}
|
||||
else if (p->TypeL4 == L4_FRAGMENT)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreePacket(p);
|
||||
}
|
||||
|
||||
if (ok == false)
|
||||
{
|
||||
Free(*data);
|
||||
*data = NULL;
|
||||
|
||||
goto LABEL_RETRY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Send internal IP packet (insert into the send queue)
|
||||
void EthSendIpPacketInnerIpRaw(ETH *e, void *data, UINT size, USHORT protocol)
|
||||
{
|
||||
BUF *b;
|
||||
if (e == NULL || data == NULL || size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->RawIpSendQueue->num_item >= 1024)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
b = NewBuf();
|
||||
WriteBuf(b, e->RawIpYourMacAddr, 6);
|
||||
WriteBuf(b, e->RawIpMyMacAddr, 6);
|
||||
WriteBufShort(b, protocol);
|
||||
WriteBuf(b, data, size);
|
||||
SeekBufToBegin(b);
|
||||
|
||||
InsertQueue(e->RawIpSendQueue, b);
|
||||
}
|
||||
|
||||
// Process the packet internal if necessary
|
||||
bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p)
|
||||
{
|
||||
bool ret = false;
|
||||
if (e == NULL || p == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p->TypeL3 == L3_ARPV4)
|
||||
{
|
||||
// ARP processing
|
||||
ARPV4_HEADER *arp = p->L3.ARPv4Header;
|
||||
|
||||
if (Endian16(arp->HardwareType) == ARP_HARDWARE_TYPE_ETHERNET &&
|
||||
Endian16(arp->ProtocolType) == MAC_PROTO_IPV4 &&
|
||||
arp->HardwareSize == 6 && arp->ProtocolType == 4)
|
||||
{
|
||||
if (IPToUINT(&e->MyIP) == arp->TargetIP)
|
||||
{
|
||||
if (Endian16(arp->Operation) == ARP_OPERATION_REQUEST)
|
||||
{
|
||||
ARPV4_HEADER r;
|
||||
|
||||
Zero(&r, sizeof(r));
|
||||
r.HardwareType = Endian16(ARP_HARDWARE_TYPE_ETHERNET);
|
||||
r.ProtocolType = Endian16(MAC_PROTO_IPV4);
|
||||
r.HardwareSize = 6;
|
||||
r.ProtocolSize = 4;
|
||||
r.Operation = Endian16(ARP_OPERATION_RESPONSE);
|
||||
Copy(r.SrcAddress, e->RawIpMyMacAddr, 6);
|
||||
Copy(r.TargetAddress, arp->SrcAddress, 6);
|
||||
r.SrcIP = IPToUINT(&e->MyIP);
|
||||
r.TargetIP = arp->SrcIP;
|
||||
|
||||
EthSendIpPacketInnerIpRaw(e, &r, sizeof(ARPV4_HEADER), MAC_PROTO_ARPV4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (p->TypeL3 == L3_IPV4 && p->TypeL4 == L4_UDP && p->TypeL7 == L7_DHCPV4)
|
||||
{
|
||||
// DHCP processing
|
||||
DHCPV4_HEADER *dhcp;
|
||||
UCHAR *data;
|
||||
UINT size;
|
||||
UINT dhcp_header_size;
|
||||
UINT dhcp_data_offset;
|
||||
UINT tran_id;
|
||||
UINT magic_cookie = Endian32(DHCP_MAGIC_COOKIE);
|
||||
bool ok;
|
||||
DHCP_OPTION_LIST *opt;
|
||||
|
||||
dhcp = p->L7.DHCPv4Header;
|
||||
tran_id = Endian32(dhcp->TransactionId);
|
||||
|
||||
// Get the DHCP data and size
|
||||
dhcp_header_size = sizeof(DHCPV4_HEADER);
|
||||
dhcp_data_offset = (UINT)(((UCHAR *)p->L7.DHCPv4Header) - ((UCHAR *)p->MacHeader) + dhcp_header_size);
|
||||
data = ((UCHAR *)dhcp) + dhcp_header_size;
|
||||
size = p->PacketSize - dhcp_data_offset;
|
||||
if (dhcp_header_size < 5)
|
||||
{
|
||||
// Data size is invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search for Magic Cookie
|
||||
ok = false;
|
||||
while (size >= 5)
|
||||
{
|
||||
if (Cmp(data, &magic_cookie, sizeof(magic_cookie)) == 0)
|
||||
{
|
||||
// Found
|
||||
data += 4;
|
||||
size -= 4;
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
data++;
|
||||
size--;
|
||||
}
|
||||
|
||||
if (ok == false)
|
||||
{
|
||||
// The packet is invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse DHCP options list
|
||||
opt = ParseDhcpOptionList(data, size);
|
||||
if (opt == NULL)
|
||||
{
|
||||
// The packet is invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dhcp->OpCode == 1 && (opt->Opcode == DHCP_DISCOVER || opt->Opcode == DHCP_REQUEST || opt->Opcode == DHCP_INFORM))
|
||||
{
|
||||
// Operate as the server
|
||||
UINT ip = IPToUINT(&e->YourIP);
|
||||
if (ip != 0 || opt->Opcode == DHCP_INFORM)
|
||||
{
|
||||
// Respond if there is providable IP address
|
||||
DHCP_OPTION_LIST ret;
|
||||
LIST *o;
|
||||
UINT hw_type;
|
||||
UINT hw_addr_size;
|
||||
UINT new_ip = ip;
|
||||
IP default_dns;
|
||||
|
||||
Zero(&default_dns, sizeof(default_dns));
|
||||
|
||||
Zero(&ret, sizeof(ret));
|
||||
|
||||
ret.Opcode = (opt->Opcode == DHCP_DISCOVER ? DHCP_OFFER : DHCP_ACK);
|
||||
ret.ServerAddress = IPToUINT(&e->MyIP);
|
||||
ret.LeaseTime = 3600;
|
||||
if (opt->Opcode == DHCP_INFORM)
|
||||
{
|
||||
ret.LeaseTime = 0;
|
||||
}
|
||||
|
||||
ret.SubnetMask = SetIP32(255, 255, 255, 252);
|
||||
|
||||
if (UnixGetDefaultDns(&default_dns) && IsZeroIp(&default_dns) == false)
|
||||
{
|
||||
ret.DnsServer = IPToUINT(&default_dns);
|
||||
ret.DnsServer2 = SetIP32(8, 8, 8, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.DnsServer = SetIP32(8, 8, 8, 8);
|
||||
ret.DnsServer2 = SetIP32(8, 8, 4, 4);
|
||||
}
|
||||
|
||||
ret.Gateway = IPToUINT(&e->MyIP);
|
||||
|
||||
if (opt->Opcode != DHCP_INFORM)
|
||||
{
|
||||
char client_mac[MAX_SIZE];
|
||||
char client_ip[64];
|
||||
IP ips;
|
||||
BinToStr(client_mac, sizeof(client_mac), p->MacAddressSrc, 6);
|
||||
UINTToIP(&ips, ip);
|
||||
IPToStr(client_ip, sizeof(client_ip), &ips);
|
||||
Debug("IP_RAW: DHCP %s : %s given %s\n",
|
||||
ret.Opcode == DHCP_OFFER ? "DHCP_OFFER" : "DHCP_ACK",
|
||||
client_mac, client_ip);
|
||||
}
|
||||
|
||||
// Build a DHCP option
|
||||
o = BuildDhcpOption(&ret);
|
||||
if (o != NULL)
|
||||
{
|
||||
BUF *b = BuildDhcpOptionsBuf(o);
|
||||
if (b != NULL)
|
||||
{
|
||||
UINT dest_ip = p->L3.IPv4Header->SrcIP;
|
||||
UINT blank_size = 128 + 64;
|
||||
UINT dhcp_packet_size;
|
||||
UINT magic = Endian32(DHCP_MAGIC_COOKIE);
|
||||
DHCPV4_HEADER *dhcp;
|
||||
void *magic_cookie_addr;
|
||||
void *buffer_addr;
|
||||
|
||||
if (dest_ip == 0)
|
||||
{
|
||||
dest_ip = 0xffffffff;
|
||||
}
|
||||
|
||||
// Calculate the DHCP packet size
|
||||
dhcp_packet_size = blank_size + sizeof(DHCPV4_HEADER) + sizeof(magic) + b->Size;
|
||||
|
||||
if (dhcp_packet_size < DHCP_MIN_SIZE)
|
||||
{
|
||||
// Padding
|
||||
dhcp_packet_size = DHCP_MIN_SIZE;
|
||||
}
|
||||
|
||||
// Create a header
|
||||
dhcp = ZeroMalloc(dhcp_packet_size);
|
||||
|
||||
dhcp->OpCode = 2;
|
||||
dhcp->HardwareType = hw_type;
|
||||
dhcp->HardwareAddressSize = hw_addr_size;
|
||||
dhcp->Hops = 0;
|
||||
dhcp->TransactionId = Endian32(tran_id);
|
||||
dhcp->Seconds = 0;
|
||||
dhcp->Flags = 0;
|
||||
dhcp->YourIP = new_ip;
|
||||
dhcp->ServerIP = IPToUINT(&e->MyIP);
|
||||
Copy(dhcp->ClientMacAddress, p->MacAddressSrc, 6);
|
||||
|
||||
// Calculate the address
|
||||
magic_cookie_addr = (((UCHAR *)dhcp) + sizeof(DHCPV4_HEADER) + blank_size);
|
||||
buffer_addr = ((UCHAR *)magic_cookie_addr) + sizeof(magic);
|
||||
|
||||
// Magic Cookie
|
||||
Copy(magic_cookie_addr, &magic, sizeof(magic));
|
||||
|
||||
// Buffer
|
||||
Copy(buffer_addr, b->Buf, b->Size);
|
||||
|
||||
if (true)
|
||||
{
|
||||
UCHAR *data = ZeroMalloc(sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size);
|
||||
IPV4_HEADER *ipv4 = (IPV4_HEADER *)(data);
|
||||
UDP_HEADER *udp = (UDP_HEADER *)(data + sizeof(IPV4_HEADER));
|
||||
|
||||
Copy(data + sizeof(IPV4_HEADER) + sizeof(UDP_HEADER), dhcp, dhcp_packet_size);
|
||||
|
||||
IPV4_SET_VERSION(ipv4, 4);
|
||||
IPV4_SET_HEADER_LEN(ipv4, 5);
|
||||
ipv4->TotalLength = Endian16(sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size);
|
||||
ipv4->TimeToLive = 63;
|
||||
ipv4->Protocol = IP_PROTO_UDP;
|
||||
ipv4->SrcIP = IPToUINT(&e->MyIP);
|
||||
ipv4->DstIP = dest_ip;
|
||||
ipv4->Checksum = IpChecksum(ipv4, sizeof(IPV4_HEADER));
|
||||
|
||||
udp->SrcPort = Endian16(NAT_DHCP_SERVER_PORT);
|
||||
udp->DstPort = Endian16(NAT_DHCP_CLIENT_PORT);
|
||||
udp->PacketLength = Endian16(sizeof(UDP_HEADER) + dhcp_packet_size);
|
||||
udp->Checksum = CalcChecksumForIPv4(ipv4->SrcIP, ipv4->DstIP, IP_PROTO_UDP,
|
||||
dhcp, dhcp_packet_size, 0);
|
||||
if (udp->Checksum == 0)
|
||||
{
|
||||
udp->Checksum = 0xffff;
|
||||
}
|
||||
|
||||
EthSendIpPacketInnerIpRaw(e, data, sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size, MAC_PROTO_IPV4);
|
||||
|
||||
Free(data);
|
||||
}
|
||||
|
||||
// Release the memory
|
||||
Free(dhcp);
|
||||
FreeBuf(b);
|
||||
}
|
||||
FreeDhcpOptions(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Free(opt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Send an IP raw packet
|
||||
void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size)
|
||||
{
|
||||
PKT *p;
|
||||
// Validate arguments
|
||||
if (e == NULL || data == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (size < 14 || size > MAX_PACKET_SIZE || e->RawIp_HasError)
|
||||
{
|
||||
Free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
p = ParsePacket(data, size);
|
||||
|
||||
if (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0)
|
||||
{
|
||||
if (IsValidUnicastMacAddress(p->MacAddressSrc))
|
||||
{
|
||||
Copy(e->RawIpYourMacAddr, p->MacAddressSrc, 6);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsZero(e->RawIpYourMacAddr, 6) || IsValidUnicastMacAddress(p->MacAddressSrc) == false ||
|
||||
(p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0))
|
||||
{
|
||||
Free(data);
|
||||
FreePacket(p);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
SOCK *s = NULL;
|
||||
|
||||
if (p->TypeL3 == L3_IPV4)
|
||||
{
|
||||
if (p->TypeL4 == L4_TCP)
|
||||
{
|
||||
if (IsZeroIP(&e->MyPhysicalIP) == false)
|
||||
{
|
||||
s = e->RawTcp;
|
||||
}
|
||||
}
|
||||
else if (p->TypeL4 == L4_UDP)
|
||||
{
|
||||
if (EthProcessIpPacketInnerIpRaw(e, p) == false)
|
||||
{
|
||||
s = e->RawUdp;
|
||||
}
|
||||
}
|
||||
else if (p->TypeL4 == L4_ICMPV4)
|
||||
{
|
||||
if (IsZeroIP(&e->MyPhysicalIP) == false)
|
||||
{
|
||||
s = e->RawIcmp;
|
||||
}
|
||||
}
|
||||
else if (p->TypeL4 == L4_FRAGMENT)
|
||||
{
|
||||
if (IsZeroIP(&e->MyPhysicalIP) == false)
|
||||
{
|
||||
s = e->RawIcmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (p->TypeL3 == L3_ARPV4)
|
||||
{
|
||||
EthProcessIpPacketInnerIpRaw(e, p);
|
||||
}
|
||||
|
||||
if (s != NULL && p->L3.IPv4Header->DstIP != 0xffffffff && p->BroadcastPacket == false &&
|
||||
p->L3.IPv4Header->SrcIP == IPToUINT(&e->YourIP))
|
||||
{
|
||||
UCHAR *send_data = p->IPv4PayloadData;
|
||||
UCHAR *head = p->PacketData;
|
||||
UINT remove_header_size = (UINT)(send_data - head);
|
||||
|
||||
if (p->PacketSize > remove_header_size)
|
||||
{
|
||||
IP dest;
|
||||
UINT send_data_size = p->PacketSize - remove_header_size;
|
||||
|
||||
// checksum
|
||||
if (p->TypeL4 == L4_UDP)
|
||||
{
|
||||
p->L4.UDPHeader->Checksum = 0;
|
||||
}
|
||||
else if (p->TypeL4 == L4_TCP)
|
||||
{
|
||||
p->L4.TCPHeader->Checksum = 0;
|
||||
p->L4.TCPHeader->Checksum = CalcChecksumForIPv4(IPToUINT(&e->MyPhysicalIP),
|
||||
p->L3.IPv4Header->DstIP, IP_PROTO_TCP,
|
||||
p->L4.TCPHeader, p->IPv4PayloadSize, 0);
|
||||
}
|
||||
|
||||
UINTToIP(&dest, p->L3.IPv4Header->DstIP);
|
||||
|
||||
if (s->RawIP_HeaderIncludeFlag == false)
|
||||
{
|
||||
SendTo(s, &dest, 0, send_data, send_data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPV4_HEADER *ip = p->L3.IPv4Header;
|
||||
|
||||
ip->SrcIP = IPToUINT(&e->MyPhysicalIP);
|
||||
ip->Checksum = 0;
|
||||
ip->Checksum = IpChecksum(ip, IPV4_GET_HEADER_LEN(ip) * 4);
|
||||
|
||||
SendTo(s, &dest, 0, ip, ((UCHAR *)p->PacketData - (UCHAR *)ip) + p->PacketSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreePacket(p);
|
||||
}
|
||||
|
||||
Free(data);
|
||||
}
|
||||
|
||||
|
||||
#endif // BRIDGE_C
|
||||
|
||||
|
||||
|
@ -162,6 +162,19 @@ struct ETH
|
||||
|
||||
VLAN *Tap; // tap
|
||||
bool Linux_IsAuxDataSupported; // Is PACKET_AUXDATA supported
|
||||
|
||||
bool IsRawIpMode; // RAW IP mode
|
||||
SOCK *RawTcp, *RawUdp, *RawIcmp; // RAW sockets
|
||||
bool RawIp_HasError;
|
||||
UCHAR RawIpMyMacAddr[6];
|
||||
UCHAR RawIpYourMacAddr[6];
|
||||
IP MyIP;
|
||||
IP YourIP;
|
||||
QUEUE *RawIpSendQueue;
|
||||
IP MyPhysicalIP;
|
||||
IP MyPhysicalIPForce;
|
||||
UCHAR *RawIP_TmpBuffer;
|
||||
UINT RawIP_TmpBufferSize;
|
||||
};
|
||||
|
||||
#if defined( BRIDGE_BPF ) || defined( BRIDGE_PCAP )
|
||||
@ -180,7 +193,8 @@ bool IsEthSupportedLinux();
|
||||
bool IsEthSupportedSolaris();
|
||||
bool IsEthSupportedPcap();
|
||||
TOKEN_LIST *GetEthList();
|
||||
TOKEN_LIST *GetEthListLinux();
|
||||
TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip);
|
||||
TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip);
|
||||
TOKEN_LIST *GetEthListSolaris();
|
||||
TOKEN_LIST *GetEthListPcap();
|
||||
ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr);
|
||||
@ -203,6 +217,14 @@ bool EthIsChangeMtuSupported(ETH *e);
|
||||
bool EthGetInterfaceDescriptionUnix(char *name, char *str, UINT size);
|
||||
bool EthIsInterfaceDescriptionSupportedUnix();
|
||||
|
||||
ETH *OpenEthLinuxIpRaw();
|
||||
void CloseEthLinuxIpRaw(ETH *e);
|
||||
UINT EthGetPacketLinuxIpRaw(ETH *e, void **data);
|
||||
UINT EthGetPacketLinuxIpRawForSock(ETH *e, void **data, SOCK *s, UINT proto);
|
||||
void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size);
|
||||
bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p);
|
||||
void EthSendIpPacketInnerIpRaw(ETH *e, void *data, UINT size, USHORT protocol);
|
||||
|
||||
#ifdef UNIX_SOLARIS
|
||||
// Function prototype for Solaris
|
||||
bool DlipAttatchRequest(int fd, UINT devid);
|
||||
|
@ -1356,9 +1356,9 @@ TOKEN_LIST *GetEthList()
|
||||
{
|
||||
UINT v;
|
||||
|
||||
return GetEthListEx(&v);
|
||||
return GetEthListEx(&v, true, false);
|
||||
}
|
||||
TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden)
|
||||
TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip)
|
||||
{
|
||||
TOKEN_LIST *ret;
|
||||
UINT i;
|
||||
@ -1371,6 +1371,11 @@ TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (enum_normal == false)
|
||||
{
|
||||
return NullToken();
|
||||
}
|
||||
|
||||
if (total_num_including_hidden == NULL)
|
||||
{
|
||||
total_num_including_hidden = &dummy_int;
|
||||
@ -2139,7 +2144,7 @@ RELEASE:
|
||||
return false;
|
||||
}
|
||||
|
||||
o = GetEthListEx(&total_num);
|
||||
o = GetEthListEx(&total_num, true, false);
|
||||
if (o == NULL || total_num == 0)
|
||||
{
|
||||
FreeToken(o);
|
||||
|
@ -213,6 +213,12 @@ struct ETH
|
||||
|
||||
SU *Su; // SeLow handle
|
||||
SU_ADAPTER *SuAdapter; // SeLow adapter handle
|
||||
|
||||
// Unused
|
||||
bool IsRawIpMode; // RAW IP mode
|
||||
UCHAR RawIpMyMacAddr[6];
|
||||
UCHAR RawIpYourMacAddr[6];
|
||||
IP MyPhysicalIPForce;
|
||||
};
|
||||
|
||||
// Function prototype
|
||||
@ -221,7 +227,7 @@ void FreeEth();
|
||||
bool IsEthSupported();
|
||||
bool IsEthSupportedInner();
|
||||
TOKEN_LIST *GetEthList();
|
||||
TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden);
|
||||
TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip);
|
||||
ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr);
|
||||
ETH *OpenEthInternal(char *name, bool local, bool tapmode, char *tapaddr);
|
||||
void CloseEth(ETH *e);
|
||||
|
@ -118,6 +118,34 @@ static UINT init_cedar_counter = 0;
|
||||
static REF *cedar_log_ref = NULL;
|
||||
static LOG *cedar_log;
|
||||
|
||||
// Check whether there is any EAP-enabled RADIUS configuration
|
||||
bool CedarIsThereAnyEapEnabledRadiusConfig(CEDAR *c)
|
||||
{
|
||||
bool ret = false;
|
||||
UINT i;
|
||||
if (c == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LockHubList(c);
|
||||
{
|
||||
for (i = 0;i < LIST_NUM(c->HubList);i++)
|
||||
{
|
||||
HUB *hub = LIST_DATA(c->HubList, i);
|
||||
|
||||
if (hub->RadiusConvertAllMsChapv2AuthRequestToEap)
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockHubList(c);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get build date of current code
|
||||
UINT64 GetCurrentBuildDate()
|
||||
{
|
||||
|
@ -138,7 +138,7 @@
|
||||
#define CEDAR_VER 419
|
||||
|
||||
// Build Number
|
||||
#define CEDAR_BUILD 9578
|
||||
#define CEDAR_BUILD 9582
|
||||
|
||||
// Beta number
|
||||
//#define BETA_NUMBER 3
|
||||
@ -153,16 +153,16 @@
|
||||
|
||||
// Specify the location to build
|
||||
#ifndef BUILD_PLACE
|
||||
#define BUILD_PLACE "pc25"
|
||||
#define BUILD_PLACE "pc30"
|
||||
#endif // BUILD_PLACE
|
||||
|
||||
// Specifies the build date
|
||||
#define BUILD_DATE_Y 2015
|
||||
#define BUILD_DATE_M 9
|
||||
#define BUILD_DATE_D 15
|
||||
#define BUILD_DATE_M 10
|
||||
#define BUILD_DATE_D 6
|
||||
#define BUILD_DATE_HO 14
|
||||
#define BUILD_DATE_MI 39
|
||||
#define BUILD_DATE_SE 35
|
||||
#define BUILD_DATE_MI 56
|
||||
#define BUILD_DATE_SE 30
|
||||
|
||||
// Tolerable time difference
|
||||
#define ALLOW_TIMESTAMP_DIFF (UINT64)(3 * 24 * 60 * 60 * 1000)
|
||||
@ -1259,6 +1259,7 @@ UINT CedarGetQueueBudgetConsuming(CEDAR *c);
|
||||
UINT CedarGetFifoBudgetConsuming(CEDAR *c);
|
||||
UINT CedarGetQueueBudgetBalance(CEDAR *c);
|
||||
UINT CedarGetFifoBudgetBalance(CEDAR *c);
|
||||
bool CedarIsThereAnyEapEnabledRadiusConfig(CEDAR *c);
|
||||
|
||||
|
||||
|
||||
|
@ -142,6 +142,16 @@ typedef struct AUTHNT AUTHNT;
|
||||
// ==============================================================
|
||||
|
||||
typedef struct RADIUS_LOGIN_OPTION RADIUS_LOGIN_OPTION;
|
||||
typedef struct RADIUS_PACKET RADIUS_PACKET;
|
||||
typedef struct RADIUS_AVP RADIUS_AVP;
|
||||
typedef struct EAP_CLIENT EAP_CLIENT;
|
||||
typedef struct EAP_MESSAGE EAP_MESSAGE;
|
||||
typedef struct EAP_MSCHAPV2_GENERAL EAP_MSCHAPV2_GENERAL;
|
||||
typedef struct EAP_MSCHAPV2_CHALLENGE EAP_MSCHAPV2_CHALLENGE;
|
||||
typedef struct EAP_MSCHAPV2_RESPONSE EAP_MSCHAPV2_RESPONSE;
|
||||
typedef struct EAP_MSCHAPV2_SUCCESS_SERVER EAP_MSCHAPV2_SUCCESS_SERVER;
|
||||
typedef struct EAP_MSCHAPV2_SUCCESS_CLIENT EAP_MSCHAPV2_SUCCESS_CLIENT;
|
||||
typedef struct EAP_PEAP EAP_PEAP;
|
||||
|
||||
|
||||
// ==============================================================
|
||||
@ -738,6 +748,8 @@ typedef struct MIRROR_SERVER MIRROR_SERVER;
|
||||
// ==============================================================
|
||||
|
||||
typedef struct NATIVE_STACK NATIVE_STACK;
|
||||
typedef struct IPTABLES_STATE IPTABLES_STATE;
|
||||
typedef struct IPTABLES_ENTRY IPTABLES_ENTRY;
|
||||
|
||||
|
||||
// ==============================================================
|
||||
|
@ -18309,6 +18309,7 @@ UINT PsSecureNatStatusGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
CtInsert(ct, _UU("NM_STATUS_DHCP"), tmp);
|
||||
|
||||
CtInsert(ct, _UU("SM_SNAT_IS_KERNEL"), t.IsKernelMode ? _UU("SEC_YES") : _UU("SEC_NO"));
|
||||
CtInsert(ct, _UU("SM_SNAT_IS_RAW"), t.IsRawIpMode ? _UU("SEC_YES") : _UU("SEC_NO"));
|
||||
|
||||
CtFree(ct, c);
|
||||
}
|
||||
|
101
src/Cedar/Hub.c
101
src/Cedar/Hub.c
@ -166,6 +166,103 @@ ADMIN_OPTION admin_options[] =
|
||||
|
||||
UINT num_admin_options = sizeof(admin_options) / sizeof(ADMIN_OPTION);
|
||||
|
||||
|
||||
// Create an EAP client for the specified Virtual Hub
|
||||
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username)
|
||||
{
|
||||
HUB *hub = NULL;
|
||||
EAP_CLIENT *ret = NULL;
|
||||
char radius_servers[MAX_PATH] = {0};
|
||||
UINT radius_port = 0;
|
||||
UINT radius_retry_interval = 0;
|
||||
char radius_secret[MAX_PATH] = {0};
|
||||
char radius_suffix_filter[MAX_PATH] = {0};
|
||||
if (cedar == NULL || hubname == NULL || client_ip_str == NULL || username == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find the Virtual Hub
|
||||
LockHubList(cedar);
|
||||
{
|
||||
hub = GetHub(cedar, hubname);
|
||||
}
|
||||
UnlockHubList(cedar);
|
||||
|
||||
if (hub != NULL)
|
||||
{
|
||||
if (GetRadiusServerEx2(hub, radius_servers, sizeof(radius_servers), &radius_port, radius_secret,
|
||||
sizeof(radius_secret), &radius_retry_interval, radius_suffix_filter, sizeof(radius_suffix_filter)))
|
||||
{
|
||||
bool use_peap = hub->RadiusUsePeapInsteadOfEap;
|
||||
|
||||
if (IsEmptyStr(radius_suffix_filter) || EndWith(username, radius_suffix_filter))
|
||||
{
|
||||
TOKEN_LIST *radius_servers_list = ParseToken(radius_servers, " ,;\t");
|
||||
|
||||
if (radius_servers_list != NULL && radius_servers_list->NumTokens >= 1)
|
||||
{
|
||||
// Try for each of RADIUS servers
|
||||
UINT i;
|
||||
bool finish = false;
|
||||
|
||||
for (i = 0;i < radius_servers_list->NumTokens;i++)
|
||||
{
|
||||
EAP_CLIENT *eap;
|
||||
IP ip;
|
||||
|
||||
if (GetIP(&ip, radius_servers_list->Token[i]))
|
||||
{
|
||||
eap = NewEapClient(&ip, radius_port, radius_secret, radius_retry_interval,
|
||||
RADIUS_INITIAL_EAP_TIMEOUT, client_ip_str, username);
|
||||
|
||||
if (eap != NULL)
|
||||
{
|
||||
if (use_peap == false)
|
||||
{
|
||||
// EAP
|
||||
if (EapClientSendMsChapv2AuthRequest(eap))
|
||||
{
|
||||
eap->GiveupTimeout = RADIUS_RETRY_TIMEOUT;
|
||||
ret = eap;
|
||||
finish = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// PEAP
|
||||
if (PeapClientSendMsChapv2AuthRequest(eap))
|
||||
{
|
||||
eap->GiveupTimeout = RADIUS_RETRY_TIMEOUT;
|
||||
ret = eap;
|
||||
finish = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (finish == false)
|
||||
{
|
||||
ReleaseEapClient(eap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (finish)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeToken(radius_servers_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseHub(hub);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create a user list
|
||||
LIST *NewUserList()
|
||||
{
|
||||
@ -587,6 +684,7 @@ void DataToHubOptionStruct(HUB_OPTION *o, RPC_ADMIN_OPTION *ao)
|
||||
GetHubAdminOptionDataAndSet(ao, "SecureNAT_MaxIcmpSessionsPerIp", &o->SecureNAT_MaxIcmpSessionsPerIp);
|
||||
GetHubAdminOptionDataAndSet(ao, "AccessListIncludeFileCacheLifetime", &o->AccessListIncludeFileCacheLifetime);
|
||||
GetHubAdminOptionDataAndSet(ao, "DisableKernelModeSecureNAT", &o->DisableKernelModeSecureNAT);
|
||||
GetHubAdminOptionDataAndSet(ao, "DisableIpRawModeSecureNAT", &o->DisableIpRawModeSecureNAT);
|
||||
GetHubAdminOptionDataAndSet(ao, "DisableUserModeSecureNAT", &o->DisableUserModeSecureNAT);
|
||||
GetHubAdminOptionDataAndSet(ao, "DisableCheckMacOnLocalBridge", &o->DisableCheckMacOnLocalBridge);
|
||||
GetHubAdminOptionDataAndSet(ao, "DisableCorrectIpOffloadChecksum", &o->DisableCorrectIpOffloadChecksum);
|
||||
@ -598,6 +696,7 @@ void DataToHubOptionStruct(HUB_OPTION *o, RPC_ADMIN_OPTION *ao)
|
||||
GetHubAdminOptionDataAndSet(ao, "SuppressClientUpdateNotification", &o->SuppressClientUpdateNotification);
|
||||
GetHubAdminOptionDataAndSet(ao, "FloodingSendQueueBufferQuota", &o->FloodingSendQueueBufferQuota);
|
||||
GetHubAdminOptionDataAndSet(ao, "AssignVLanIdByRadiusAttribute", &o->AssignVLanIdByRadiusAttribute);
|
||||
GetHubAdminOptionDataAndSet(ao, "DenyAllRadiusLoginWithNoVlanAssign", &o->DenyAllRadiusLoginWithNoVlanAssign);
|
||||
GetHubAdminOptionDataAndSet(ao, "SecureNAT_RandomizeAssignIp", &o->SecureNAT_RandomizeAssignIp);
|
||||
GetHubAdminOptionDataAndSet(ao, "DetectDormantSessionInterval", &o->DetectDormantSessionInterval);
|
||||
GetHubAdminOptionDataAndSet(ao, "NoPhysicalIPOnPacketLog", &o->NoPhysicalIPOnPacketLog);
|
||||
@ -656,6 +755,7 @@ void HubOptionStructToData(RPC_ADMIN_OPTION *ao, HUB_OPTION *o, char *hub_name)
|
||||
Add(aol, NewAdminOption("SecureNAT_MaxIcmpSessionsPerIp", o->SecureNAT_MaxIcmpSessionsPerIp));
|
||||
Add(aol, NewAdminOption("AccessListIncludeFileCacheLifetime", o->AccessListIncludeFileCacheLifetime));
|
||||
Add(aol, NewAdminOption("DisableKernelModeSecureNAT", o->DisableKernelModeSecureNAT));
|
||||
Add(aol, NewAdminOption("DisableIpRawModeSecureNAT", o->DisableIpRawModeSecureNAT));
|
||||
Add(aol, NewAdminOption("DisableUserModeSecureNAT", o->DisableUserModeSecureNAT));
|
||||
Add(aol, NewAdminOption("DisableCheckMacOnLocalBridge", o->DisableCheckMacOnLocalBridge));
|
||||
Add(aol, NewAdminOption("DisableCorrectIpOffloadChecksum", o->DisableCorrectIpOffloadChecksum));
|
||||
@ -667,6 +767,7 @@ void HubOptionStructToData(RPC_ADMIN_OPTION *ao, HUB_OPTION *o, char *hub_name)
|
||||
Add(aol, NewAdminOption("SuppressClientUpdateNotification", o->SuppressClientUpdateNotification));
|
||||
Add(aol, NewAdminOption("FloodingSendQueueBufferQuota", o->FloodingSendQueueBufferQuota));
|
||||
Add(aol, NewAdminOption("AssignVLanIdByRadiusAttribute", o->AssignVLanIdByRadiusAttribute));
|
||||
Add(aol, NewAdminOption("DenyAllRadiusLoginWithNoVlanAssign", o->DenyAllRadiusLoginWithNoVlanAssign));
|
||||
Add(aol, NewAdminOption("SecureNAT_RandomizeAssignIp", o->SecureNAT_RandomizeAssignIp));
|
||||
Add(aol, NewAdminOption("DetectDormantSessionInterval", o->DetectDormantSessionInterval));
|
||||
Add(aol, NewAdminOption("NoPhysicalIPOnPacketLog", o->NoPhysicalIPOnPacketLog));
|
||||
|
@ -265,6 +265,7 @@ struct HUB_OPTION
|
||||
UINT SecureNAT_MaxIcmpSessionsPerIp; // Maximum number of ICMP sessions per IP address
|
||||
UINT AccessListIncludeFileCacheLifetime; // Expiration of the access list external file (in seconds)
|
||||
bool DisableKernelModeSecureNAT; // Disable the kernel mode NAT
|
||||
bool DisableIpRawModeSecureNAT; // Disable the IP Raw Mode NAT
|
||||
bool DisableUserModeSecureNAT; // Disable the user mode NAT
|
||||
bool DisableCheckMacOnLocalBridge; // Disable the MAC address verification in local bridge
|
||||
bool DisableCorrectIpOffloadChecksum; // Disable the correction of checksum that is IP-Offloaded
|
||||
@ -276,6 +277,7 @@ struct HUB_OPTION
|
||||
bool SuppressClientUpdateNotification; // Suppress the update notification function on the VPN Client
|
||||
UINT FloodingSendQueueBufferQuota; // The global quota of send queues of flooding packets
|
||||
bool AssignVLanIdByRadiusAttribute; // Assign the VLAN ID for the VPN session, by the attribute value of RADIUS
|
||||
bool DenyAllRadiusLoginWithNoVlanAssign; // Deny all RADIUS login with no VLAN ID assigned
|
||||
bool SecureNAT_RandomizeAssignIp; // Randomize the assignment IP address for new DHCP client
|
||||
UINT DetectDormantSessionInterval; // Interval (seconds) threshold to detect a dormant VPN session
|
||||
bool NoPhysicalIPOnPacketLog; // Disable saving physical IP address on the packet log
|
||||
@ -434,6 +436,8 @@ struct HUB
|
||||
UINT RadiusRetryInterval; // Radius retry interval
|
||||
BUF *RadiusSecret; // Radius shared key
|
||||
char RadiusSuffixFilter[MAX_SIZE]; // Radius suffix filter
|
||||
bool RadiusConvertAllMsChapv2AuthRequestToEap; // Convert all MS-CHAPv2 auth request to EAP
|
||||
bool RadiusUsePeapInsteadOfEap; // Use PEAP instead of EAP
|
||||
volatile bool Halt; // Halting flag
|
||||
bool Offline; // Offline
|
||||
bool BeingOffline; // Be Doing Offline
|
||||
@ -636,6 +640,7 @@ void CalcTrafficDiff(TRAFFIC *diff, TRAFFIC *old, TRAFFIC *current);
|
||||
bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now);
|
||||
void VgsSetUserAgentValue(char *str);
|
||||
void VgsSetEmbTag(bool b);
|
||||
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username);
|
||||
|
||||
#endif // HUB_H
|
||||
|
||||
|
@ -170,7 +170,7 @@ void EtherIPIpcConnectThread(THREAD *t, void *p)
|
||||
&s->ClientIP, s->ClientPort,
|
||||
&s->ServerIP, s->ServerPort,
|
||||
tmp,
|
||||
s->CryptName, true, mss);
|
||||
s->CryptName, true, mss, NULL);
|
||||
|
||||
if (ipc != NULL)
|
||||
{
|
||||
|
@ -113,6 +113,7 @@
|
||||
|
||||
#include "CedarPch.h"
|
||||
|
||||
//#define RAW_DEBUG
|
||||
|
||||
// Processing of IKE received packet
|
||||
void ProcIKEPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
|
||||
@ -753,7 +754,7 @@ void ProcIPsecEspPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
|
||||
// Transport mode
|
||||
if (next_header == IP_PROTO_UDP)
|
||||
{
|
||||
if (ike->IPsec->Services.L2TP_IPsec)
|
||||
if (ike->IPsec->Services.L2TP_IPsec || ike->IPsec->Services.EtherIP_IPsec)
|
||||
{
|
||||
// An UDP packet has been received
|
||||
ProcIPsecUdpPacketRecv(ike, c, dec_data, dec_size);
|
||||
@ -791,6 +792,19 @@ void ProcIPsecEspPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
|
||||
if (ipsec_sa->PairIPsecSa != NULL)
|
||||
{
|
||||
c->CurrentIpSecSaSend = ipsec_sa->PairIPsecSa;
|
||||
|
||||
if (p->DestPort == IPSEC_PORT_IPSEC_ESP_UDP)
|
||||
{
|
||||
IPSECSA *send_sa = c->CurrentIpSecSaSend;
|
||||
if (send_sa->TransformSetting.CapsuleMode == IKE_P2_CAPSULE_TUNNEL)
|
||||
{
|
||||
send_sa->TransformSetting.CapsuleMode = IKE_P2_CAPSULE_NAT_TUNNEL_1;
|
||||
}
|
||||
else if (send_sa->TransformSetting.CapsuleMode == IKE_P2_CAPSULE_TRANSPORT)
|
||||
{
|
||||
send_sa->TransformSetting.CapsuleMode = IKE_P2_CAPSULE_NAT_TRANSPORT_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
c->LastCommTick = ike->Now;
|
||||
ipsec_sa->LastCommTick = ike->Now;
|
||||
|
@ -133,20 +133,27 @@ bool ParseAndExtractMsChapV2InfoFromPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *pa
|
||||
|
||||
t = ParseTokenWithNullStr(password, ":");
|
||||
|
||||
if (t->NumTokens == 5)
|
||||
if (t->NumTokens == 6)
|
||||
{
|
||||
BUF *b1, *b2, *b3;
|
||||
BUF *b1, *b2, *b3, *b4;
|
||||
|
||||
b1 = StrToBin(t->Token[2]);
|
||||
b2 = StrToBin(t->Token[3]);
|
||||
b3 = StrToBin(t->Token[4]);
|
||||
b4 = StrToBin(t->Token[5]);
|
||||
|
||||
if (IsEmptyStr(t->Token[1]) == false && b1->Size == 16 && b2->Size == 16 && b3->Size == 24)
|
||||
if (IsEmptyStr(t->Token[1]) == false && b1->Size == 16 && b2->Size == 16 && b3->Size == 24
|
||||
&& b4->Size == 8)
|
||||
{
|
||||
UINT64 eap_client_ptr = 0;
|
||||
|
||||
StrCpy(d->MsChapV2_PPPUsername, sizeof(d->MsChapV2_PPPUsername), t->Token[1]);
|
||||
Copy(d->MsChapV2_ServerChallenge, b1->Buf, 16);
|
||||
Copy(d->MsChapV2_ClientChallenge, b2->Buf, 16);
|
||||
Copy(d->MsChapV2_ClientResponse, b3->Buf, 24);
|
||||
Copy(&eap_client_ptr, b4->Buf, 8);
|
||||
|
||||
d->MsChapV2_EapClient = (EAP_CLIENT *)eap_client_ptr;
|
||||
|
||||
ret = true;
|
||||
}
|
||||
@ -154,6 +161,7 @@ bool ParseAndExtractMsChapV2InfoFromPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *pa
|
||||
FreeBuf(b1);
|
||||
FreeBuf(b2);
|
||||
FreeBuf(b3);
|
||||
FreeBuf(b4);
|
||||
}
|
||||
|
||||
FreeToken(t);
|
||||
@ -315,7 +323,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
|
||||
param->UserName, param->Password, error_code, ¶m->ClientIp,
|
||||
param->ClientPort, ¶m->ServerIp, param->ServerPort,
|
||||
param->ClientHostname, param->CryptName,
|
||||
param->BridgeMode, param->Mss);
|
||||
param->BridgeMode, param->Mss, NULL);
|
||||
|
||||
return ipc;
|
||||
}
|
||||
@ -324,7 +332,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
|
||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
|
||||
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
||||
char *client_hostname, char *crypt_name,
|
||||
bool bridge_mode, UINT mss)
|
||||
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client)
|
||||
{
|
||||
IPC *ipc;
|
||||
UINT dummy_int = 0;
|
||||
@ -431,6 +439,14 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
|
||||
PackAddBool(p, "require_monitor_mode", false);
|
||||
PackAddBool(p, "qos", false);
|
||||
|
||||
if (eap_client != NULL)
|
||||
{
|
||||
UINT64 ptr = (UINT64)eap_client;
|
||||
PackAddInt64(p, "release_me_eap_client", ptr);
|
||||
|
||||
AddRef(eap_client->Ref);
|
||||
}
|
||||
|
||||
// Unique ID is determined by the sum of the connecting client IP address and the client_name
|
||||
b = NewBuf();
|
||||
WriteBuf(b, client_ip, sizeof(IP));
|
||||
|
@ -218,12 +218,13 @@ struct IPC_MSCHAP_V2_AUTHINFO
|
||||
UCHAR MsChapV2_ServerChallenge[16]; // MS-CHAPv2 Server Challenge
|
||||
UCHAR MsChapV2_ClientChallenge[16]; // MS-CHAPv2 Client Challenge
|
||||
UCHAR MsChapV2_ClientResponse[24]; // MS-CHAPv2 Client Response
|
||||
EAP_CLIENT *MsChapV2_EapClient; // EAP client
|
||||
};
|
||||
|
||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
|
||||
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
||||
char *client_hostname, char *crypt_name,
|
||||
bool bridge_mode, UINT mss);
|
||||
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client);
|
||||
IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code);
|
||||
IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address);
|
||||
void FreeIPC(IPC *ipc);
|
||||
|
@ -180,7 +180,7 @@ void SendL2TPControlPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, UINT session_id, L
|
||||
|
||||
p->Nr = t->LastNr + 1;
|
||||
|
||||
buf = BuildL2TPPacketData(p);
|
||||
buf = BuildL2TPPacketData(p, t);
|
||||
|
||||
q = ZeroMalloc(sizeof(L2TP_QUEUE));
|
||||
q->Buf = buf;
|
||||
@ -239,15 +239,33 @@ void SendL2TPDataPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s, void
|
||||
else
|
||||
{
|
||||
// L2TPv3
|
||||
buf_size = 4 + size;
|
||||
buf = Malloc(buf_size);
|
||||
if (t->IsYamahaV3 == false)
|
||||
{
|
||||
buf_size = 4 + size;
|
||||
buf = Malloc(buf_size);
|
||||
|
||||
WRITE_UINT(buf, s->SessionId1);
|
||||
WRITE_UINT(buf, s->SessionId1);
|
||||
|
||||
Copy(buf + 4, data, size);
|
||||
Copy(buf + 4, data, size);
|
||||
|
||||
// Transmission
|
||||
p = NewUdpPacket(&t->ServerIp, IPSEC_PORT_L2TPV3_VIRTUAL, &t->ClientIp, IPSEC_PORT_L2TPV3_VIRTUAL, buf, buf_size);
|
||||
// Transmission
|
||||
p = NewUdpPacket(&t->ServerIp, IPSEC_PORT_L2TPV3_VIRTUAL, &t->ClientIp, IPSEC_PORT_L2TPV3_VIRTUAL, buf, buf_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT header = 0x00030000;
|
||||
|
||||
buf_size = 8 + size;
|
||||
buf = Malloc(buf_size);
|
||||
|
||||
WRITE_UINT(buf, header);
|
||||
WRITE_UINT(buf + 4, s->SessionId1);
|
||||
|
||||
Copy(buf + 8, data, size);
|
||||
|
||||
// Transmission
|
||||
p = NewUdpPacket(&t->ServerIp, t->ServerPort, &t->ClientIp, t->ClientPort, buf, buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
L2TPSendUDP(l2tp, p);
|
||||
@ -285,14 +303,14 @@ void L2TPSendUDP(L2TP_SERVER *l2tp, UDPPACKET *p)
|
||||
}
|
||||
|
||||
// Build a L2TP packet
|
||||
BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
|
||||
BUF *BuildL2TPPacketData(L2TP_PACKET *pp, L2TP_TUNNEL *t)
|
||||
{
|
||||
BUF *ret;
|
||||
UCHAR c;
|
||||
USHORT us;
|
||||
UINT ui;
|
||||
// Validate arguments
|
||||
if (pp == NULL)
|
||||
if (pp == NULL || t == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -322,9 +340,12 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
|
||||
|
||||
if (pp->Ver == 3)
|
||||
{
|
||||
// Zero as Session ID
|
||||
ui = 0;
|
||||
WriteBuf(ret, &ui, sizeof(UINT));
|
||||
if (t->IsYamahaV3 == false)
|
||||
{
|
||||
// Zero as Session ID
|
||||
ui = 0;
|
||||
WriteBuf(ret, &ui, sizeof(UINT));
|
||||
}
|
||||
}
|
||||
|
||||
// Flags
|
||||
@ -339,6 +360,11 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
|
||||
c |= L2TP_HEADER_BIT_OFFSET;
|
||||
}
|
||||
|
||||
if (pp->IsControl == false && pp->Ver == 3 && t->IsYamahaV3)
|
||||
{
|
||||
c = 0;
|
||||
}
|
||||
|
||||
WriteBuf(ret, &c, 1);
|
||||
|
||||
// Ver
|
||||
@ -356,6 +382,13 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
|
||||
WriteBuf(ret, &us, sizeof(USHORT));
|
||||
}
|
||||
|
||||
// Reserved
|
||||
if (pp->IsControl == false && pp->Ver == 3 && t->IsYamahaV3)
|
||||
{
|
||||
us = 0;
|
||||
WriteBuf(ret, &us, sizeof(USHORT));
|
||||
}
|
||||
|
||||
// Tunnel ID
|
||||
if (pp->Ver != 3)
|
||||
{
|
||||
@ -387,9 +420,12 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Offset Size = 0
|
||||
us = 0;
|
||||
WriteBuf(ret, &us, sizeof(USHORT));
|
||||
if (!(pp->IsControl == false && pp->Ver == 3 && t->IsYamahaV3))
|
||||
{
|
||||
// Offset Size = 0
|
||||
us = 0;
|
||||
WriteBuf(ret, &us, sizeof(USHORT));
|
||||
}
|
||||
}
|
||||
|
||||
if (pp->IsControl)
|
||||
@ -431,7 +467,8 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
|
||||
if (pp->IsControl)
|
||||
{
|
||||
// Update Length
|
||||
WRITE_USHORT(((UCHAR *)ret->Buf) + 2 + (pp->Ver == 3 ? sizeof(UINT) : 0), (USHORT)(ret->Size - (pp->Ver == 3 ? sizeof(UINT) : 0)));
|
||||
bool l2tpv3_non_yamaha = ((pp->Ver == 3) && (t->IsYamahaV3 == false));
|
||||
WRITE_USHORT(((UCHAR *)ret->Buf) + 2 + (l2tpv3_non_yamaha ? sizeof(UINT) : 0), (USHORT)(ret->Size - (l2tpv3_non_yamaha ? sizeof(UINT) : 0)));
|
||||
}
|
||||
|
||||
SeekBuf(ret, 0, 0);
|
||||
@ -446,6 +483,7 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
|
||||
UCHAR *buf;
|
||||
UINT size;
|
||||
bool is_l2tpv3 = false;
|
||||
bool is_l2tpv3_yamaha = false;
|
||||
// Validate arguments
|
||||
if (p == NULL)
|
||||
{
|
||||
@ -456,17 +494,27 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
|
||||
|
||||
if (p->SrcPort == IPSEC_PORT_L2TPV3_VIRTUAL)
|
||||
{
|
||||
// It is L2TPv3
|
||||
// L2TPv3 (Cisco)
|
||||
is_l2tpv3 = true;
|
||||
}
|
||||
|
||||
buf = p->Data;
|
||||
size = p->Size;
|
||||
|
||||
if (is_l2tpv3)
|
||||
if (size >= 2 && ((buf[1] & L2TP_HEADER_BIT_VER) == 3))
|
||||
{
|
||||
if (p->SrcPort != IPSEC_PORT_L2TPV3_VIRTUAL)
|
||||
{
|
||||
// L2TPv3 (YAMAHA)
|
||||
is_l2tpv3 = true;
|
||||
is_l2tpv3_yamaha = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_l2tpv3 && (is_l2tpv3_yamaha == false))
|
||||
{
|
||||
// L2TPv3 (Cisco)
|
||||
UINT session_id;
|
||||
// In the case of L2TPv3
|
||||
if (size < 4)
|
||||
{
|
||||
goto LABEL_ERROR;
|
||||
@ -590,6 +638,24 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
|
||||
size = ret->Length - 4;
|
||||
}
|
||||
|
||||
if (is_l2tpv3)
|
||||
{
|
||||
if (p->SrcPort != IPSEC_PORT_L2TPV3_VIRTUAL)
|
||||
{
|
||||
if (ret->IsControl == false)
|
||||
{
|
||||
// Reserved
|
||||
if (size < 2)
|
||||
{
|
||||
goto LABEL_ERROR;
|
||||
}
|
||||
|
||||
buf += 2;
|
||||
size -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tunnel ID, Session ID
|
||||
if (size < 4)
|
||||
{
|
||||
@ -616,6 +682,11 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
|
||||
|
||||
// The session ID is not written in the header
|
||||
ret->SessionId = 0;
|
||||
|
||||
if (ret->IsControl == false)
|
||||
{
|
||||
ret->SessionId = ret->TunnelId;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret->HasSequence)
|
||||
@ -742,7 +813,7 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
|
||||
ret->MessageType = READ_USHORT(a->Data);
|
||||
}
|
||||
|
||||
if (ret->Ver == 3)
|
||||
if (ret->Ver == 3 && ret->IsControl)
|
||||
{
|
||||
// Get the Remote Session ID in the case of L2TPv3
|
||||
L2TP_AVP *a = GetAVPValue(ret, L2TP_AVP_TYPE_V3_SESSION_ID_REMOTE);
|
||||
@ -752,6 +823,8 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
|
||||
}
|
||||
}
|
||||
|
||||
ret->IsYamahaV3 = is_l2tpv3_yamaha;
|
||||
|
||||
return ret;
|
||||
|
||||
LABEL_ERROR:
|
||||
@ -783,6 +856,22 @@ L2TP_AVP *GetAVPValueEx(L2TP_PACKET *p, UINT type, UINT vendor_id)
|
||||
}
|
||||
}
|
||||
|
||||
if (vendor_id == 0)
|
||||
{
|
||||
if (type == L2TP_AVP_TYPE_V3_TUNNEL_ID)
|
||||
{
|
||||
return GetAVPValueEx(p, L2TPV3_CISCO_AVP_TUNNEL_ID, L2TP_AVP_VENDOR_ID_CISCO);
|
||||
}
|
||||
else if (type == L2TP_AVP_TYPE_V3_SESSION_ID_LOCAL)
|
||||
{
|
||||
return GetAVPValueEx(p, L2TPV3_CISCO_AVP_SESSION_ID_LOCAL, L2TP_AVP_VENDOR_ID_CISCO);
|
||||
}
|
||||
else if (type == L2TP_AVP_TYPE_V3_SESSION_ID_REMOTE)
|
||||
{
|
||||
return GetAVPValueEx(p, L2TPV3_CISCO_AVP_SESSION_ID_REMOTE, L2TP_AVP_VENDOR_ID_CISCO);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -899,6 +988,9 @@ L2TP_TUNNEL *NewL2TPTunnel(L2TP_SERVER *l2tp, L2TP_PACKET *p, UDPPACKET *udp)
|
||||
{
|
||||
t->IsCiscoV3 = true;
|
||||
}
|
||||
|
||||
// L2TPv3 on YAMAHA
|
||||
t->IsYamahaV3 = p->IsYamahaV3;
|
||||
}
|
||||
|
||||
// Transmission queue
|
||||
@ -965,6 +1057,30 @@ L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClient(L2TP_SERVER *l2tp, IP *client_ip,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClientEx(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id, bool is_v3)
|
||||
{
|
||||
UINT i;
|
||||
// Validate arguments
|
||||
if (l2tp == NULL || client_ip == 0 || tunnel_id == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0;i < LIST_NUM(l2tp->TunnelList);i++)
|
||||
{
|
||||
L2TP_TUNNEL *t = LIST_DATA(l2tp->TunnelList, i);
|
||||
|
||||
if (t->TunnelId1 == tunnel_id && CmpIpAddr(&t->ClientIp, client_ip) == 0)
|
||||
{
|
||||
if (EQUAL_BOOL(t->IsV3, is_v3))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create a new tunnel ID
|
||||
UINT GenerateNewTunnelId(L2TP_SERVER *l2tp, IP *client_ip)
|
||||
@ -1179,14 +1295,23 @@ void L2TPProcessRecvControlPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_PACKET
|
||||
|
||||
if (s->IsV3)
|
||||
{
|
||||
// Pseudowire AVP
|
||||
us = Endian16(s->PseudowireType);
|
||||
Add(pp->AvpList, NewAVP(L2TP_AVP_TYPE_V3_PW_TYPE, true, 0, &us, sizeof(USHORT)));
|
||||
if (t->IsYamahaV3 == false)
|
||||
{
|
||||
// Pseudowire AVP
|
||||
us = Endian16(s->PseudowireType);
|
||||
Add(pp->AvpList, NewAVP(L2TP_AVP_TYPE_V3_PW_TYPE, true, 0, &us, sizeof(USHORT)));
|
||||
}
|
||||
|
||||
if (s->IsCiscoV3)
|
||||
{
|
||||
Add(pp->AvpList, NewAVP(L2TPV3_CISCO_AVP_PW_TYPE, true, L2TP_AVP_VENDOR_ID_CISCO, &us, sizeof(USHORT)));
|
||||
}
|
||||
|
||||
if (t->IsYamahaV3)
|
||||
{
|
||||
us = Endian16(0x0003);
|
||||
Add(pp->AvpList, NewAVP(L2TP_AVP_TYPE_V3_CIRCUIT_STATUS, true, 0, &us, sizeof(USHORT)));
|
||||
}
|
||||
}
|
||||
|
||||
SendL2TPControlPacket(l2tp, t, session_id, pp);
|
||||
@ -1563,18 +1688,21 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
|
||||
// Respond with SCCEP to SCCRQ
|
||||
pp2 = NewL2TPControlPacket(L2TP_MESSAGE_TYPE_SCCRP, t->IsV3);
|
||||
|
||||
// Protocol Version
|
||||
protocol_version[0] = 1;
|
||||
protocol_version[1] = 0;
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_PROTOCOL_VERSION, true, 0, protocol_version, sizeof(protocol_version)));
|
||||
|
||||
// Framing Capabilities
|
||||
Zero(caps_data, sizeof(caps_data));
|
||||
if (t->IsV3 == false)
|
||||
if (t->IsYamahaV3 == false)
|
||||
{
|
||||
caps_data[3] = 3;
|
||||
// Protocol Version
|
||||
protocol_version[0] = 1;
|
||||
protocol_version[1] = 0;
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_PROTOCOL_VERSION, true, 0, protocol_version, sizeof(protocol_version)));
|
||||
|
||||
// Framing Capabilities
|
||||
Zero(caps_data, sizeof(caps_data));
|
||||
if (t->IsV3 == false)
|
||||
{
|
||||
caps_data[3] = 3;
|
||||
}
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_FRAME_CAP, false, 0, caps_data, sizeof(caps_data)));
|
||||
}
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_FRAME_CAP, false, 0, caps_data, sizeof(caps_data)));
|
||||
|
||||
if (t->IsV3 == false)
|
||||
{
|
||||
@ -1593,7 +1721,21 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_HOST_NAME, true, 0, hostname, StrLen(hostname)));
|
||||
|
||||
// Vendor Name
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_VENDOR_NAME, false, 0, L2TP_VENDOR_NAME, StrLen(L2TP_VENDOR_NAME)));
|
||||
if (t->IsYamahaV3 == false)
|
||||
{
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_VENDOR_NAME, false, 0, L2TP_VENDOR_NAME, StrLen(L2TP_VENDOR_NAME)));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *yamaha_str = "YAMAHA Corporation";
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_VENDOR_NAME, false, 0, yamaha_str, StrLen(yamaha_str)));
|
||||
}
|
||||
|
||||
if (t->IsYamahaV3)
|
||||
{
|
||||
UINT zero = 0;
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_V3_ROUTER_ID, true, 0, &zero, sizeof(UINT)));
|
||||
}
|
||||
|
||||
// Assigned Tunnel ID
|
||||
if (t->IsV3 == false)
|
||||
@ -1635,8 +1777,11 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
|
||||
}
|
||||
|
||||
// Recv Window Size
|
||||
us = Endian16(L2TP_WINDOW_SIZE);
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_RECV_WINDOW_SIZE, false, 0, &us, sizeof(USHORT)));
|
||||
if (t->IsYamahaV3 == false)
|
||||
{
|
||||
us = Endian16(L2TP_WINDOW_SIZE);
|
||||
Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_RECV_WINDOW_SIZE, false, 0, &us, sizeof(USHORT)));
|
||||
}
|
||||
|
||||
SendL2TPControlPacket(l2tp, t, 0, pp2);
|
||||
|
||||
@ -1654,7 +1799,7 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
|
||||
L2TP_TUNNEL *t = NULL;
|
||||
L2TP_SESSION *l2tpv3_session = NULL;
|
||||
|
||||
if (pp->Ver != 3 || pp->IsControl)
|
||||
if (pp->IsControl || pp->Ver != 3)
|
||||
{
|
||||
t = GetTunnelFromId(l2tp, &p->SrcIP, pp->TunnelId, pp->Ver == 3);
|
||||
}
|
||||
@ -1767,6 +1912,15 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reply ACK for already-received packets
|
||||
if (pp->IsZLB == false)
|
||||
{
|
||||
// The packet other than ZLB is treated
|
||||
t->StateChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2373,7 +2527,7 @@ void L2TPProcessInterrupts(L2TP_SERVER *l2tp)
|
||||
|
||||
pp->TunnelId = t->TunnelId1;
|
||||
pp->Ns = t->NextNs;
|
||||
q->Buf = BuildL2TPPacketData(pp);
|
||||
q->Buf = BuildL2TPPacketData(pp, t);
|
||||
|
||||
SendL2TPControlPacketMain(l2tp, t, q);
|
||||
|
||||
|
@ -189,6 +189,7 @@
|
||||
#define L2TP_AVP_TYPE_V3_SESSION_ID_LOCAL 63 // Local Session ID
|
||||
#define L2TP_AVP_TYPE_V3_SESSION_ID_REMOTE 64 // Remote Session ID
|
||||
#define L2TP_AVP_TYPE_V3_PW_TYPE 68 // Pseudowire Type
|
||||
#define L2TP_AVP_TYPE_V3_CIRCUIT_STATUS 71
|
||||
|
||||
// Message Type value
|
||||
#define L2TP_MESSAGE_TYPE_SCCRQ 1 // Start-Control-Connection-Request
|
||||
@ -247,6 +248,7 @@ struct L2TP_PACKET
|
||||
bool HasOffset; // Whether there is offset bit
|
||||
bool IsPriority; // Whether priority packet
|
||||
bool IsZLB; // Zero Length Bit
|
||||
bool IsYamahaV3; // L2TPv3 on YAMAHA
|
||||
UINT Ver; // Version
|
||||
UINT Length; // Length
|
||||
UINT TunnelId; // Tunnel ID
|
||||
@ -284,6 +286,7 @@ struct L2TP_TUNNEL
|
||||
{
|
||||
bool IsV3; // L2TPv3
|
||||
bool IsCiscoV3; // L2TPv3 for Cisco
|
||||
bool IsYamahaV3; // L2TPv3 for YAMAHA
|
||||
IP ClientIp; // Client IP address
|
||||
UINT ClientPort; // Client port number
|
||||
IP ServerIp; // Server IP address
|
||||
@ -339,7 +342,7 @@ void FreeL2TPServer(L2TP_SERVER *l2tp);
|
||||
void StopL2TPServer(L2TP_SERVER *l2tp, bool no_wait);
|
||||
void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p);
|
||||
L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p);
|
||||
BUF *BuildL2TPPacketData(L2TP_PACKET *pp);
|
||||
BUF *BuildL2TPPacketData(L2TP_PACKET *pp, L2TP_TUNNEL *t);
|
||||
L2TP_AVP *GetAVPValue(L2TP_PACKET *p, UINT type);
|
||||
L2TP_AVP *GetAVPValueEx(L2TP_PACKET *p, UINT type, UINT vendor_id);
|
||||
L2TP_TUNNEL *NewL2TPTunnel(L2TP_SERVER *l2tp, L2TP_PACKET *p, UDPPACKET *udp);
|
||||
@ -348,6 +351,7 @@ UINT GenerateNewTunnelIdEx(L2TP_SERVER *l2tp, IP *client_ip, bool is_32bit);
|
||||
void FreeL2TPTunnel(L2TP_TUNNEL *t);
|
||||
L2TP_TUNNEL *GetTunnelFromId(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id, bool is_v3);
|
||||
L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClient(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id);
|
||||
L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClientEx(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id, bool is_v3);
|
||||
void SendL2TPControlPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, UINT session_id, L2TP_PACKET *p);
|
||||
void SendL2TPControlPacketMain(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_QUEUE *q);
|
||||
void SendL2TPDataPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s, void *data, UINT size);
|
||||
|
@ -135,6 +135,8 @@ void PPPThread(THREAD *thread, void *param)
|
||||
p->Mru1 = p->Mru2 = PPP_MRU_DEFAULT;
|
||||
p->RecvPacketList = NewList(NULL);
|
||||
|
||||
p->MsChapV2_UseDoubleMsChapV2 = CedarIsThereAnyEapEnabledRadiusConfig(p->Cedar);
|
||||
|
||||
//// Link establishment phase
|
||||
IPToStr(ipstr1, sizeof(ipstr1), &p->ClientIP);
|
||||
IPToStr(ipstr2, sizeof(ipstr2), &p->ServerIP);
|
||||
@ -244,9 +246,96 @@ void PPPThread(THREAD *thread, void *param)
|
||||
|
||||
PPPContinueUntilFinishAllLCPOptionRequestsDetermined(p);
|
||||
|
||||
if (p->MsChapV2_UseDoubleMsChapV2)
|
||||
{
|
||||
// Use the double-MSCHAPv2 technieue
|
||||
GetMachineHostName(machine_name, sizeof(machine_name));
|
||||
MsChapV2Server_GenerateChallenge(p->MsChapV2_ServerChallenge);
|
||||
|
||||
pp = ZeroMalloc(sizeof(PPP_PACKET));
|
||||
pp->Protocol = PPP_PROTOCOL_CHAP;
|
||||
pp->IsControl = true;
|
||||
pp->Lcp = NewPPPLCP(PPP_CHAP_CODE_CHALLENGE, 99);
|
||||
|
||||
b = NewBuf();
|
||||
WriteBufChar(b, 16);
|
||||
WriteBuf(b, p->MsChapV2_ServerChallenge, sizeof(p->MsChapV2_ServerChallenge));
|
||||
WriteBuf(b, machine_name, StrLen(machine_name));
|
||||
pp->Lcp->Data = Clone(b->Buf, b->Size);
|
||||
pp->Lcp->DataSize = b->Size;
|
||||
FreeBuf(b);
|
||||
|
||||
PPPSendPacket(p, pp);
|
||||
|
||||
pp_ret = PPPRecvResponsePacket(p, pp, 0, &pp_ret_protocol, false, true);
|
||||
|
||||
if (pp_ret != NULL)
|
||||
{
|
||||
// Extract the username from the first MS-CHAP v2 packet
|
||||
if (pp_ret->Lcp != NULL && pp_ret->Lcp->DataSize >= 51)
|
||||
{
|
||||
BUF *b;
|
||||
|
||||
b = MemToBuf(pp_ret->Lcp->Data, pp_ret->Lcp->DataSize);
|
||||
|
||||
if (ReadBufChar(b) == 49)
|
||||
{
|
||||
UCHAR client_response_buffer[49];
|
||||
char username_tmp[MAX_SIZE];
|
||||
char id[MAX_SIZE];
|
||||
char hub[MAX_SIZE];
|
||||
char client_ip_tmp[256];
|
||||
EAP_CLIENT *eap;
|
||||
ETHERIP_ID d;
|
||||
|
||||
ReadBuf(b, client_response_buffer, 49);
|
||||
|
||||
Zero(username_tmp, sizeof(username_tmp));
|
||||
ReadBuf(b, username_tmp, sizeof(username_tmp));
|
||||
|
||||
Debug("First MS-CHAPv2: id=%s\n", username_tmp);
|
||||
|
||||
Zero(id, sizeof(id));
|
||||
Zero(hub, sizeof(hub));
|
||||
|
||||
// The user name is divided into the ID and the virtual HUB name
|
||||
Zero(&d, sizeof(d));
|
||||
PPPParseUsername(p->Cedar, username_tmp, &d);
|
||||
|
||||
StrCpy(id, sizeof(id), d.UserName);
|
||||
StrCpy(hub, sizeof(hub), d.HubName);
|
||||
Debug("First MS-CHAPv2: username=%s, hubname=%s\n", id, hub);
|
||||
|
||||
IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP);
|
||||
|
||||
eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id);
|
||||
|
||||
if (eap)
|
||||
{
|
||||
p->EapClient = eap;
|
||||
}
|
||||
}
|
||||
|
||||
FreeBuf(b);
|
||||
}
|
||||
|
||||
FreePPPPacket(pp_ret);
|
||||
}
|
||||
|
||||
FreePPPPacket(pp);
|
||||
}
|
||||
|
||||
// Generate a Server Challenge packet of MS-CHAP v2
|
||||
GetMachineHostName(machine_name, sizeof(machine_name));
|
||||
MsChapV2Server_GenerateChallenge(p->MsChapV2_ServerChallenge);
|
||||
|
||||
if (p->EapClient == NULL)
|
||||
{
|
||||
MsChapV2Server_GenerateChallenge(p->MsChapV2_ServerChallenge);
|
||||
}
|
||||
else
|
||||
{
|
||||
Copy(p->MsChapV2_ServerChallenge, p->EapClient->MsChapV2Challenge.Chap_ChallengeValue, 16);
|
||||
}
|
||||
|
||||
pp = ZeroMalloc(sizeof(PPP_PACKET));
|
||||
pp->Protocol = PPP_PROTOCOL_CHAP;
|
||||
@ -264,7 +353,7 @@ void PPPThread(THREAD *thread, void *param)
|
||||
PPPSendPacket(p, pp);
|
||||
|
||||
pp_ret_protocol = 0;
|
||||
pp_ret = PPPRecvResponsePacket(p, pp, 0, &pp_ret_protocol, false);
|
||||
pp_ret = PPPRecvResponsePacket(p, pp, 0, &pp_ret_protocol, false, false);
|
||||
|
||||
if (pp_ret != NULL)
|
||||
{
|
||||
@ -565,7 +654,7 @@ bool PPPContinueUntilFinishAllLCPOptionRequestsDetermined(PPP_SESSION *p)
|
||||
return false;
|
||||
}
|
||||
|
||||
PPPRecvResponsePacket(p, NULL, PPP_PROTOCOL_LCP, &received_protocol, true);
|
||||
PPPRecvResponsePacket(p, NULL, PPP_PROTOCOL_LCP, &received_protocol, true, false);
|
||||
|
||||
return p->ClientLCPOptionDetermined;
|
||||
}
|
||||
@ -580,7 +669,7 @@ USHORT PPPContinueCurrentProtocolRequestListening(PPP_SESSION *p, USHORT protoco
|
||||
return 0;
|
||||
}
|
||||
|
||||
PPPRecvResponsePacket(p, NULL, protocol, &received_protocol, false);
|
||||
PPPRecvResponsePacket(p, NULL, protocol, &received_protocol, false, false);
|
||||
|
||||
return received_protocol;
|
||||
}
|
||||
@ -634,7 +723,7 @@ bool PPPSendRequest(PPP_SESSION *p, USHORT protocol, PPP_LCP *c)
|
||||
}
|
||||
|
||||
// Receive a corresponding PPP packet
|
||||
pp2 = PPPRecvResponsePacket(p, pp, 0, NULL, false);
|
||||
pp2 = PPPRecvResponsePacket(p, pp, 0, NULL, false, false);
|
||||
|
||||
if (pp2 != NULL)
|
||||
{
|
||||
@ -880,8 +969,10 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
|
||||
char server_challenge_hex[MAX_SIZE];
|
||||
char client_challenge_hex[MAX_SIZE];
|
||||
char client_response_hex[MAX_SIZE];
|
||||
char eap_client_hex[64];
|
||||
ETHERIP_ID d;
|
||||
UINT error_code;
|
||||
UINT64 eap_client_ptr = (UINT64)p->EapClient;
|
||||
|
||||
ReadBuf(b, client_response_buffer, 49);
|
||||
|
||||
@ -913,18 +1004,21 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
|
||||
p->MsChapV2_ClientChallenge, sizeof(p->MsChapV2_ClientChallenge));
|
||||
BinToStr(client_response_hex, sizeof(client_response_hex),
|
||||
p->MsChapV2_ClientResponse, sizeof(p->MsChapV2_ClientResponse));
|
||||
BinToStr(eap_client_hex, sizeof(eap_client_hex),
|
||||
&eap_client_ptr, 8);
|
||||
|
||||
Format(password, sizeof(password), "%s%s:%s:%s:%s",
|
||||
Format(password, sizeof(password), "%s%s:%s:%s:%s:%s",
|
||||
IPC_PASSWORD_MSCHAPV2_TAG,
|
||||
username_tmp,
|
||||
server_challenge_hex,
|
||||
client_challenge_hex,
|
||||
client_response_hex);
|
||||
client_response_hex,
|
||||
eap_client_hex);
|
||||
|
||||
// Attempt to connect with IPC
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
|
||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||
p->ClientHostname, p->CryptName, false, p->AdjustMss);
|
||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient);
|
||||
|
||||
if (ipc != NULL)
|
||||
{
|
||||
@ -1057,7 +1151,7 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
|
||||
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
|
||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||
p->ClientHostname, p->CryptName, false, p->AdjustMss);
|
||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL);
|
||||
|
||||
if (ipc != NULL)
|
||||
{
|
||||
@ -1555,7 +1649,8 @@ bool PPPGetIPAddressValueFromLCP(PPP_LCP *c, UINT type, IP *ip)
|
||||
// (If req == NULL, process on that protocol while the protocol specified in expected_protocol have received.
|
||||
//If other protocols has arrived, without further processing, and then store that packet in the session context once,
|
||||
// return NULL by setting the received_protocol.)
|
||||
PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked)
|
||||
PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked,
|
||||
bool return_mschapv2_response_with_no_processing)
|
||||
{
|
||||
UINT64 giveup_tick = Tick64() + (UINT64)PPP_PACKET_RECV_TIMEOUT;
|
||||
UINT64 next_resend = Tick64() + (UINT64)PPP_PACKET_RESEND_INTERVAL;
|
||||
@ -1618,6 +1713,16 @@ PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expect
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
|
||||
if (return_mschapv2_response_with_no_processing)
|
||||
{
|
||||
// For the double-MSCHAPv2 technique
|
||||
if (pp->IsControl && pp->Protocol == req->Protocol && pp->Lcp->Id == req->Lcp->Id &&
|
||||
pp->Protocol == PPP_PROTOCOL_CHAP && PPP_PAP_CODE_IS_RESPONSE(pp->Lcp->Code))
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return a response immediately without processing if a protocol other than the expected received
|
||||
@ -2357,9 +2462,26 @@ void FreePPPSession(PPP_SESSION *p)
|
||||
FreeIPC(p->Ipc);
|
||||
}
|
||||
|
||||
PPPFreeEapClient(p);
|
||||
|
||||
Free(p);
|
||||
}
|
||||
|
||||
// Free the associated EAP client
|
||||
void PPPFreeEapClient(PPP_SESSION *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->EapClient != NULL)
|
||||
{
|
||||
ReleaseEapClient(p->EapClient);
|
||||
p->EapClient = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the option value
|
||||
PPP_OPTION *GetOptionValue(PPP_LCP *c, UCHAR type)
|
||||
{
|
||||
|
@ -284,6 +284,9 @@ struct PPP_SESSION
|
||||
UCHAR MsChapV2_ClientResponse[24]; // MS-CHAPv2 Client Response
|
||||
UCHAR MsChapV2_ServerResponse[20]; // MS-CHAPv2 Server Response
|
||||
UINT MsChapV2_ErrorCode; // Authentication failure error code of MS-CHAPv2
|
||||
|
||||
bool MsChapV2_UseDoubleMsChapV2; // Use the double-MSCHAPv2 technieue
|
||||
EAP_CLIENT *EapClient; // EAP client
|
||||
};
|
||||
|
||||
// Function prototype
|
||||
@ -316,7 +319,8 @@ bool PPPSetIPAddressValueToLCP(PPP_LCP *c, UINT type, IP *ip, bool only_modify);
|
||||
bool PPPSendRequest(PPP_SESSION *p, USHORT protocol, PPP_LCP *c);
|
||||
USHORT PPPContinueCurrentProtocolRequestListening(PPP_SESSION *p, USHORT protocol);
|
||||
bool PPPContinueUntilFinishAllLCPOptionRequestsDetermined(PPP_SESSION *p);
|
||||
PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked);
|
||||
PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked,
|
||||
bool return_mschapv2_response_with_no_processing);
|
||||
PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req);
|
||||
void PPPSendEchoRequest(PPP_SESSION *p);
|
||||
bool PPPParseUsername(CEDAR *cedar, char *src, ETHERIP_ID *dst);
|
||||
@ -331,6 +335,7 @@ void MsChapV2Client_GenerateResponse(UCHAR *dst, UCHAR *challenge8, UCHAR *nt_pa
|
||||
void MsChapV2Server_GenerateResponse(UCHAR *dst, UCHAR *nt_password_hash_hash, UCHAR *client_response, UCHAR *challenge8);
|
||||
bool MsChapV2VerityPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *password);
|
||||
char *MsChapV2DoBruteForce(IPC_MSCHAP_V2_AUTHINFO *d, LIST *password_list);
|
||||
void PPPFreeEapClient(PPP_SESSION *p);
|
||||
|
||||
#endif // IPSEC_PPP_H
|
||||
|
||||
|
@ -784,6 +784,7 @@ bool NmStatus(HWND hWnd, SM_SERVER *s, void *param)
|
||||
LvInsertAdd(b, ICO_PROTOCOL_DHCP, NULL, 2, _UU("NM_STATUS_DHCP"), tmp);
|
||||
|
||||
LvInsertAdd(b, ICO_MACHINE, NULL, 2, _UU("SM_SNAT_IS_KERNEL"), t.IsKernelMode ? _UU("SEC_YES") : _UU("SEC_NO"));
|
||||
LvInsertAdd(b, ICO_MACHINE, NULL, 2, _UU("SM_SNAT_IS_RAW"), t.IsRawIpMode ? _UU("SEC_YES") : _UU("SEC_NO"));
|
||||
|
||||
LvInsertEnd(b, hWnd, L_STATUS);
|
||||
|
||||
|
@ -596,7 +596,7 @@ UINT NtGetStatus(NAT *n, RPC_NAT_STATUS *t)
|
||||
|
||||
t->NumDhcpClients = LIST_NUM(v->DhcpLeaseList);
|
||||
|
||||
t->IsKernelMode = NnIsActive(v);
|
||||
t->IsKernelMode = NnIsActiveEx(v, &t->IsRawIpMode);
|
||||
}
|
||||
UnlockVirtual(v);
|
||||
}
|
||||
@ -1063,6 +1063,7 @@ void InRpcNatStatus(RPC_NAT_STATUS *t, PACK *p)
|
||||
t->NumDnsSessions = PackGetInt(p, "NumDnsSessions");
|
||||
t->NumDhcpClients = PackGetInt(p, "NumDhcpClients");
|
||||
t->IsKernelMode = PackGetBool(p, "IsKernelMode");
|
||||
t->IsRawIpMode = PackGetBool(p, "IsRawIpMode");
|
||||
PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
|
||||
}
|
||||
void OutRpcNatStatus(PACK *p, RPC_NAT_STATUS *t)
|
||||
@ -1080,6 +1081,7 @@ void OutRpcNatStatus(PACK *p, RPC_NAT_STATUS *t)
|
||||
PackAddInt(p, "NumDnsSessions", t->NumDnsSessions);
|
||||
PackAddInt(p, "NumDhcpClients", t->NumDhcpClients);
|
||||
PackAddBool(p, "IsKernelMode", t->IsKernelMode);
|
||||
PackAddBool(p, "IsRawIpMode", t->IsRawIpMode);
|
||||
}
|
||||
void FreeRpcNatStatus(RPC_NAT_STATUS *t)
|
||||
{
|
||||
|
@ -168,6 +168,7 @@ struct RPC_NAT_STATUS
|
||||
UINT NumDnsSessions; // Number of DNS sessions
|
||||
UINT NumDhcpClients; // Number of DHCP clients
|
||||
bool IsKernelMode; // Whether kernel mode
|
||||
bool IsRawIpMode; // Whether raw IP mode
|
||||
};
|
||||
|
||||
// RPC_NAT_INFO *
|
||||
|
@ -257,6 +257,109 @@ LABEL_RESTART:
|
||||
Disconnect(a->Sock2);
|
||||
}
|
||||
|
||||
// Start the iptables tracking
|
||||
bool NsStartIpTablesTracking(NATIVE_STACK *a)
|
||||
{
|
||||
if (a->IpTablesThread != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
a->IpTablesInitOk = false;
|
||||
|
||||
a->IpTablesHalt = false;
|
||||
|
||||
a->IpTablesHaltEvent = NewEvent();
|
||||
|
||||
a->IpTablesThread = NewThread(NsIpTablesThread, a);
|
||||
|
||||
WaitThreadInit(a->IpTablesThread);
|
||||
|
||||
return a->IpTablesInitOk;
|
||||
}
|
||||
|
||||
// iptables thread
|
||||
void NsIpTablesThread(THREAD *thread, void *param)
|
||||
{
|
||||
IPTABLES_STATE *state;
|
||||
NATIVE_STACK *s;
|
||||
UINT counter = 0;
|
||||
BUF *seed_buf;
|
||||
char exe_name[MAX_PATH];
|
||||
if (thread == NULL || param == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s = (NATIVE_STACK *)param;
|
||||
|
||||
seed_buf = NewBuf();
|
||||
|
||||
WriteBuf(seed_buf, s->MacAddress, 6);
|
||||
|
||||
GetExeName(exe_name, sizeof(exe_name));
|
||||
WriteBufStr(seed_buf, exe_name);
|
||||
|
||||
state = StartAddIpTablesEntryForNativeStack(seed_buf->Buf, seed_buf->Size);
|
||||
|
||||
FreeBuf(seed_buf);
|
||||
|
||||
if (state == NULL)
|
||||
{
|
||||
NoticeThreadInit(thread);
|
||||
return;
|
||||
}
|
||||
|
||||
s->IpTablesInitOk = true;
|
||||
NoticeThreadInit(thread);
|
||||
|
||||
while (true)
|
||||
{
|
||||
UINT wait_interval;
|
||||
|
||||
if (s->IpTablesHalt)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (MaintainAddIpTablesEntryForNativeStack(state))
|
||||
{
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
counter++;
|
||||
wait_interval = NS_CHECK_IPTABLES_INTERVAL_INIT * counter;
|
||||
wait_interval = MIN(wait_interval, NS_CHECK_IPTABLES_INTERVAL_MAX);
|
||||
|
||||
//Debug("NsIpTablesThread: wait for %u\n", wait_interval);
|
||||
Wait(s->IpTablesHaltEvent, wait_interval);
|
||||
}
|
||||
|
||||
EndAddIpTablesEntryForNativeStack(state);
|
||||
}
|
||||
|
||||
// Stop the iptables tracking
|
||||
void NsStopIpTablesTracking(NATIVE_STACK *a)
|
||||
{
|
||||
if (a->IpTablesThread == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
a->IpTablesHalt = true;
|
||||
Set(a->IpTablesHaltEvent);
|
||||
|
||||
WaitThread(a->IpTablesThread, INFINITE);
|
||||
|
||||
ReleaseThread(a->IpTablesThread);
|
||||
ReleaseEvent(a->IpTablesHaltEvent);
|
||||
|
||||
a->IpTablesThread = NULL;
|
||||
a->IpTablesHaltEvent = NULL;
|
||||
a->IpTablesInitOk = false;
|
||||
a->IpTablesHalt = false;
|
||||
}
|
||||
|
||||
// Release the stack
|
||||
void FreeNativeStack(NATIVE_STACK *a)
|
||||
{
|
||||
@ -288,6 +391,8 @@ void FreeNativeStack(NATIVE_STACK *a)
|
||||
CloseEth(a->Eth);
|
||||
FreeIPC(a->Ipc);
|
||||
|
||||
NsStopIpTablesTracking(a);
|
||||
|
||||
ReleaseCancel(a->Cancel);
|
||||
|
||||
ReleaseSock(a->Sock1);
|
||||
@ -312,12 +417,6 @@ NATIVE_STACK *NewNativeStack(CEDAR *cedar, char *device_name, char *mac_address_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cedar == NULL)
|
||||
{
|
||||
cedar = NewCedar(NULL, NULL);
|
||||
release_cedar = true;
|
||||
}
|
||||
|
||||
GetLocalHostIP4(&localhost);
|
||||
|
||||
// Open the Eth device
|
||||
@ -327,6 +426,12 @@ NATIVE_STACK *NewNativeStack(CEDAR *cedar, char *device_name, char *mac_address_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cedar == NULL)
|
||||
{
|
||||
cedar = NewCedar(NULL, NULL);
|
||||
release_cedar = true;
|
||||
}
|
||||
|
||||
a = ZeroMalloc(sizeof(NATIVE_STACK));
|
||||
|
||||
NewSocketPair(&a->Sock1, &a->Sock2, &localhost, 1, &localhost, 1);
|
||||
@ -353,6 +458,8 @@ NATIVE_STACK *NewNativeStack(CEDAR *cedar, char *device_name, char *mac_address_
|
||||
ReleaseCedar(cedar);
|
||||
}
|
||||
|
||||
a->IsIpRawMode = a->Eth->IsRawIpMode;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -440,6 +547,457 @@ void NsGenMacAddress(void *dest, char *mac_address_seed, char *device_name)
|
||||
Copy(dest, mac, 6);
|
||||
}
|
||||
|
||||
// Add the iptables entries for native stack
|
||||
IPTABLES_STATE *StartAddIpTablesEntryForNativeStack(void *seed, UINT seed_size)
|
||||
{
|
||||
IPTABLES_STATE *ret = NULL;
|
||||
bool ok = false;
|
||||
|
||||
if (IsIpTablesSupported())
|
||||
{
|
||||
IPTABLES_ENTRY *e;
|
||||
UINT i;
|
||||
|
||||
ret = ZeroMalloc(sizeof(IPTABLES_STATE));
|
||||
|
||||
ret->EntryList = NewListFast(NULL);
|
||||
|
||||
HashSha1(ret->SeedHash, seed, seed_size);
|
||||
|
||||
// Create a pair of entry
|
||||
e = ZeroMalloc(sizeof(IPTABLES_ENTRY));
|
||||
GenerateDummyIpAndMark(ret->SeedHash, e, 0);
|
||||
StrCpy(e->Chain, sizeof(e->Chain), "OUTPUT");
|
||||
Format(e->ConditionAndArgs, sizeof(e->ConditionAndArgs),
|
||||
"-p tcp --tcp-flags RST RST --sport %u:%u ! -s %r/32 ! -d %r/32 -m connmark ! --mark 0x%x -j DROP",
|
||||
NN_RAW_IP_PORT_START, NN_RAW_IP_PORT_END,
|
||||
&e->DummySrcIp, &e->DummyDestIP, e->DummyMark);
|
||||
Add(ret->EntryList, e);
|
||||
|
||||
e = ZeroMalloc(sizeof(IPTABLES_ENTRY));
|
||||
GenerateDummyIpAndMark(ret->SeedHash, e, 1);
|
||||
StrCpy(e->Chain, sizeof(e->Chain), "OUTPUT");
|
||||
Format(e->ConditionAndArgs, sizeof(e->ConditionAndArgs),
|
||||
"-p icmp --icmp-type 3/3 ! -s %r/32 ! -d %r/32 -m connmark ! --mark 0x%x -j DROP",
|
||||
&e->DummySrcIp, &e->DummyDestIP, e->DummyMark);
|
||||
Add(ret->EntryList, e);
|
||||
|
||||
ok = true;
|
||||
|
||||
// Insert entries if not exists
|
||||
for (i = 0; i < LIST_NUM(ret->EntryList);i++)
|
||||
{
|
||||
UINT j;
|
||||
IPTABLES_ENTRY *e = LIST_DATA(ret->EntryList, i);
|
||||
|
||||
for (j = 0;j < 100;j++)
|
||||
{
|
||||
if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) != 0)
|
||||
{
|
||||
char cmdline[MAX_PATH];
|
||||
|
||||
Format(cmdline, sizeof(cmdline),
|
||||
"iptables -D %s %s",
|
||||
e->Chain, e->ConditionAndArgs);
|
||||
|
||||
system(cmdline);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
|
||||
{
|
||||
char cmdline[MAX_PATH];
|
||||
|
||||
Format(cmdline, sizeof(cmdline),
|
||||
"iptables -I %s %s",
|
||||
e->Chain, e->ConditionAndArgs);
|
||||
|
||||
system(cmdline);
|
||||
|
||||
if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
|
||||
{
|
||||
Debug("Run \"%s\" failed.\n", cmdline);
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug("Run \"%s\" ok.\n", cmdline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok == false)
|
||||
{
|
||||
EndAddIpTablesEntryForNativeStack(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Maintain the iptables
|
||||
bool MaintainAddIpTablesEntryForNativeStack(IPTABLES_STATE *s)
|
||||
{
|
||||
UINT i;
|
||||
bool ret = false;
|
||||
if (s == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->HasError)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Insert entries if not exists
|
||||
for (i = 0; i < LIST_NUM(s->EntryList);i++)
|
||||
{
|
||||
IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
|
||||
|
||||
if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
|
||||
{
|
||||
char cmdline[MAX_PATH];
|
||||
|
||||
Format(cmdline, sizeof(cmdline),
|
||||
"iptables -I %s %s",
|
||||
e->Chain, e->ConditionAndArgs);
|
||||
|
||||
system(cmdline);
|
||||
|
||||
if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
|
||||
{
|
||||
Debug("Run \"%s\" failed.\n", cmdline);
|
||||
s->HasError = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug("Run \"%s\" ok.\n", cmdline);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Stop the iptables management
|
||||
void EndAddIpTablesEntryForNativeStack(IPTABLES_STATE *s)
|
||||
{
|
||||
UINT i;
|
||||
if (s == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete entries
|
||||
for (i = 0; i < LIST_NUM(s->EntryList);i++)
|
||||
{
|
||||
IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
|
||||
UINT j;
|
||||
|
||||
for (j = 0;j < 100;j++)
|
||||
{
|
||||
if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) != 0)
|
||||
{
|
||||
char cmdline[MAX_PATH];
|
||||
|
||||
Format(cmdline, sizeof(cmdline),
|
||||
"iptables -D %s %s",
|
||||
e->Chain, e->ConditionAndArgs);
|
||||
|
||||
system(cmdline);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeIpTablesState(s);
|
||||
}
|
||||
|
||||
// Generate a set of dummy IP addresses and mark
|
||||
void GenerateDummyIpAndMark(void *hash_seed, IPTABLES_ENTRY *e, UINT id)
|
||||
{
|
||||
PRAND *p;
|
||||
BUF *b;
|
||||
if (hash_seed == NULL || e == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
b = NewBuf();
|
||||
WriteBufInt(b, id);
|
||||
WriteBuf(b, hash_seed, SHA1_SIZE);
|
||||
WriteBufStr(b, "20151002");
|
||||
|
||||
p = NewPRand(b->Buf, b->Size);
|
||||
FreeBuf(b);
|
||||
|
||||
GenerateDummyIp(p, &e->DummySrcIp);
|
||||
GenerateDummyIp(p, &e->DummyDestIP);
|
||||
e->DummyMark = GenerateDummyMark(p);
|
||||
|
||||
FreePRand(p);
|
||||
}
|
||||
|
||||
// Generate a dummy iptables mark
|
||||
UINT GenerateDummyMark(PRAND *p)
|
||||
{
|
||||
UINT i;
|
||||
if (p == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
i = PRandInt(p);
|
||||
|
||||
if (i >= 1000000000 && i <= 0x7FFFFFFE)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Generate a dummy IP
|
||||
void GenerateDummyIp(PRAND *p, IP *ip)
|
||||
{
|
||||
UINT i;
|
||||
if (p == NULL || ip == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Zero(ip, sizeof(IP));
|
||||
|
||||
for (i = 1;i < 4;i++)
|
||||
{
|
||||
UINT v = 0;
|
||||
while (true)
|
||||
{
|
||||
v = PRandInt(p) % 256;
|
||||
if (v >= 1 && v <= 254)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ip->addr[i] = (UCHAR)v;
|
||||
}
|
||||
|
||||
ip->addr[0] = 127;
|
||||
}
|
||||
|
||||
// Search an entry
|
||||
IPTABLES_ENTRY *SearchIpTables(IPTABLES_STATE *s, char *chain, IP *src_ip, IP *dest_ip, UINT mark)
|
||||
{
|
||||
char ip_str1[64];
|
||||
char ip_str2[64];
|
||||
char mark_str1[64];
|
||||
char mark_str2[64];
|
||||
UINT i;
|
||||
if (s == NULL || chain == NULL || src_ip == NULL || dest_ip == NULL || mark == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IPToStr(ip_str1, sizeof(ip_str1), src_ip);
|
||||
IPToStr(ip_str2, sizeof(ip_str2), dest_ip);
|
||||
ToStr(mark_str1, mark);
|
||||
Format(mark_str2, sizeof(mark_str2), "%x", mark);
|
||||
|
||||
for (i = 0;i < LIST_NUM(s->EntryList);i++)
|
||||
{
|
||||
IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
|
||||
|
||||
if (StrCmpi(e->Chain, chain) == 0)
|
||||
{
|
||||
if (InStr(e->ConditionAndArgs, ip_str1) &&
|
||||
InStr(e->ConditionAndArgs, ip_str2) &&
|
||||
(InStr(e->ConditionAndArgs, mark_str1) || InStr(e->ConditionAndArgs, mark_str2)))
|
||||
{
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Search an entry and get the line number
|
||||
UINT GetCurrentIpTableLineNumber(char *chain, IP *src_ip, IP *dest_ip, UINT mark)
|
||||
{
|
||||
IPTABLES_STATE *s;
|
||||
IPTABLES_ENTRY *e;
|
||||
UINT ret = 0;
|
||||
|
||||
if (chain == NULL || src_ip == NULL || dest_ip == NULL || mark == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = GetCurrentIpTables();
|
||||
|
||||
e = SearchIpTables(s, chain, src_ip, dest_ip, mark);
|
||||
|
||||
if (e != NULL)
|
||||
{
|
||||
ret = e->LineNumber;
|
||||
}
|
||||
|
||||
FreeIpTablesState(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Free the iptables state
|
||||
void FreeIpTablesState(IPTABLES_STATE *s)
|
||||
{
|
||||
UINT i;
|
||||
if (s == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0;i < LIST_NUM(s->EntryList);i++)
|
||||
{
|
||||
IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
|
||||
|
||||
Free(e);
|
||||
}
|
||||
|
||||
ReleaseList(s->EntryList);
|
||||
|
||||
Free(s);
|
||||
}
|
||||
|
||||
// Get the current iptables state
|
||||
IPTABLES_STATE *GetCurrentIpTables()
|
||||
{
|
||||
IPTABLES_STATE *ret = NULL;
|
||||
TOKEN_LIST *t = NULL;
|
||||
|
||||
#ifdef OS_UNIX
|
||||
t = UnixExec("iptables -L -x -n --line-numbers");
|
||||
#endif // OS_UNIX
|
||||
|
||||
if (t != NULL)
|
||||
{
|
||||
UINT i;
|
||||
UINT tmp_num = 0;
|
||||
|
||||
for (i = 0;i < t->NumTokens;i++)
|
||||
{
|
||||
char *line = t->Token[i];
|
||||
if (StartWith(line, "Chain INPUT") ||
|
||||
StartWith(line, "Chain FORWARD") ||
|
||||
StartWith(line, "Chain OUTPUT"))
|
||||
{
|
||||
tmp_num++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_num >= 3)
|
||||
{
|
||||
char current_chain[64];
|
||||
UINT mode = 0;
|
||||
|
||||
Zero(current_chain, sizeof(current_chain));
|
||||
|
||||
for (i = 0;i < t->NumTokens;i++)
|
||||
{
|
||||
char *line = t->Token[i];
|
||||
|
||||
if (StartWith(line, "Chain"))
|
||||
{
|
||||
TOKEN_LIST *t2 = ParseToken(line, " \t");
|
||||
if (t2 != NULL)
|
||||
{
|
||||
if (t2->NumTokens >= 4)
|
||||
{
|
||||
StrCpy(current_chain, sizeof(current_chain), t2->Token[1]);
|
||||
mode = 1;
|
||||
|
||||
if (ret == NULL)
|
||||
{
|
||||
ret = ZeroMalloc(sizeof(IPTABLES_STATE));
|
||||
ret->EntryList = NewListFast(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
FreeToken(t2);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == 1)
|
||||
{
|
||||
if (StartWith(line, "num"))
|
||||
{
|
||||
mode = 2;
|
||||
}
|
||||
}
|
||||
else if (mode == 2)
|
||||
{
|
||||
TOKEN_LIST *t2 = ParseToken(line, " \t");
|
||||
if (t2 != NULL)
|
||||
{
|
||||
if (t2->NumTokens >= 6 && ToInt(t2->Token[0]) != 0)
|
||||
{
|
||||
IPTABLES_ENTRY *e = ZeroMalloc(sizeof(IPTABLES_ENTRY));
|
||||
|
||||
StrCpy(e->Chain, sizeof(e->Chain), current_chain);
|
||||
e->LineNumber = ToInt(t2->Token[0]);
|
||||
StrCpy(e->ConditionAndArgs, sizeof(e->ConditionAndArgs), line);
|
||||
|
||||
Add(ret->EntryList, e);
|
||||
}
|
||||
|
||||
FreeToken(t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeToken(t);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get whether iptables is supported
|
||||
bool IsIpTablesSupported()
|
||||
{
|
||||
#ifdef UNIX_LINUX
|
||||
IPTABLES_STATE *s = GetCurrentIpTables();
|
||||
if (s != NULL)
|
||||
{
|
||||
FreeIpTablesState(s);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else // UNIX_LINUX
|
||||
return false;
|
||||
#endif // UNIX_LINUX
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
|
||||
|
@ -117,6 +117,10 @@
|
||||
//// Constants
|
||||
#define NS_MAC_ADDRESS_BYTE_1 0xDA // First byte of the MAC address
|
||||
|
||||
#define NS_CHECK_IPTABLES_INTERVAL_INIT (1 * 1000)
|
||||
|
||||
#define NS_CHECK_IPTABLES_INTERVAL_MAX (5 * 60 * 1000)
|
||||
|
||||
//// Type
|
||||
struct NATIVE_STACK
|
||||
{
|
||||
@ -132,6 +136,30 @@ struct NATIVE_STACK
|
||||
SOCK *Sock2; // Sock2 (Used in the IPC side)
|
||||
DHCP_OPTION_LIST CurrentDhcpOptionList; // Current DHCP options list
|
||||
IP DnsServerIP; // IP address of the DNS server
|
||||
IP DnsServerIP2; // IP address of the DNS server #2
|
||||
bool IsIpRawMode;
|
||||
IP MyIP_InCaseOfIpRawMode; // My IP
|
||||
|
||||
THREAD *IpTablesThread;
|
||||
EVENT *IpTablesHaltEvent;
|
||||
bool IpTablesHalt;
|
||||
bool IpTablesInitOk;
|
||||
};
|
||||
|
||||
struct IPTABLES_ENTRY
|
||||
{
|
||||
char Chain[64];
|
||||
UINT LineNumber;
|
||||
char ConditionAndArgs[MAX_SIZE];
|
||||
IP DummySrcIp, DummyDestIP;
|
||||
UINT DummyMark;
|
||||
};
|
||||
|
||||
struct IPTABLES_STATE
|
||||
{
|
||||
UCHAR SeedHash[SHA1_SIZE];
|
||||
LIST *EntryList;
|
||||
bool HasError;
|
||||
};
|
||||
|
||||
|
||||
@ -144,6 +172,24 @@ void NsMainThread(THREAD *thread, void *param);
|
||||
void NsGenMacAddressSignatureForMachine(UCHAR *dst_last_2, UCHAR *src_mac_addr_4);
|
||||
bool NsIsMacAddressOnLocalhost(UCHAR *mac);
|
||||
|
||||
bool NsStartIpTablesTracking(NATIVE_STACK *a);
|
||||
void NsStopIpTablesTracking(NATIVE_STACK *a);
|
||||
void NsIpTablesThread(THREAD *thread, void *param);
|
||||
|
||||
IPTABLES_STATE *GetCurrentIpTables();
|
||||
void FreeIpTablesState(IPTABLES_STATE *s);
|
||||
bool IsIpTablesSupported();
|
||||
IPTABLES_ENTRY *SearchIpTables(IPTABLES_STATE *s, char *chain, IP *src_ip, IP *dest_ip, UINT mark);
|
||||
UINT GetCurrentIpTableLineNumber(char *chain, IP *src_ip, IP *dest_ip, UINT mark);
|
||||
|
||||
IPTABLES_STATE *StartAddIpTablesEntryForNativeStack(void *seed, UINT seed_size);
|
||||
void EndAddIpTablesEntryForNativeStack(IPTABLES_STATE *s);
|
||||
bool MaintainAddIpTablesEntryForNativeStack(IPTABLES_STATE *s);
|
||||
|
||||
void GenerateDummyIpAndMark(void *hash_seed, IPTABLES_ENTRY *e, UINT id);
|
||||
UINT GenerateDummyMark(PRAND *p);
|
||||
void GenerateDummyIp(PRAND *p, IP *ip);
|
||||
|
||||
#endif // NATIVESTACK_H
|
||||
|
||||
|
||||
|
@ -1324,6 +1324,7 @@ bool ServerAccept(CONNECTION *c)
|
||||
char *error_detail = NULL;
|
||||
char *error_detail_2 = NULL;
|
||||
char ctoken_hash_str[64];
|
||||
EAP_CLIENT *release_me_eap_client = NULL;
|
||||
|
||||
// Validate arguments
|
||||
if (c == NULL)
|
||||
@ -1653,6 +1654,7 @@ bool ServerAccept(CONNECTION *c)
|
||||
if (hub->Option != NULL)
|
||||
{
|
||||
radius_login_opt.In_CheckVLanId = hub->Option->AssignVLanIdByRadiusAttribute;
|
||||
radius_login_opt.In_DenyNoVlanId = hub->Option->DenyAllRadiusLoginWithNoVlanAssign;
|
||||
}
|
||||
|
||||
// Get the various flags
|
||||
@ -1674,6 +1676,14 @@ bool ServerAccept(CONNECTION *c)
|
||||
if (c->IsInProc)
|
||||
{
|
||||
char tmp[MAX_SIZE];
|
||||
UINT64 ptr;
|
||||
|
||||
ptr = PackGetInt64(p, "release_me_eap_client");
|
||||
if (ptr != 0)
|
||||
{
|
||||
release_me_eap_client = (EAP_CLIENT *)ptr;
|
||||
}
|
||||
|
||||
PackGetStr(p, "inproc_postfix", c->InProcPrefix, sizeof(c->InProcPrefix));
|
||||
Zero(tmp, sizeof(tmp));
|
||||
PackGetStr(p, "inproc_cryptname", tmp, sizeof(tmp));
|
||||
@ -2203,9 +2213,25 @@ bool ServerAccept(CONNECTION *c)
|
||||
FreePack(p);
|
||||
|
||||
// Check the assigned VLAN ID
|
||||
if (radius_login_opt.Out_VLanId != 0)
|
||||
if (radius_login_opt.Out_IsRadiusLogin)
|
||||
{
|
||||
assigned_vlan_id = radius_login_opt.Out_VLanId;
|
||||
if (radius_login_opt.In_CheckVLanId)
|
||||
{
|
||||
if (radius_login_opt.Out_VLanId != 0)
|
||||
{
|
||||
assigned_vlan_id = radius_login_opt.Out_VLanId;
|
||||
}
|
||||
|
||||
if (radius_login_opt.In_DenyNoVlanId && assigned_vlan_id == 0 || assigned_vlan_id >= 4096)
|
||||
{
|
||||
// Deny this session
|
||||
Unlock(hub->lock);
|
||||
ReleaseHub(hub);
|
||||
c->Err = ERR_ACCESS_DENIED;
|
||||
error_detail = "In_DenyNoVlanId";
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StrCmpi(username, ADMINISTRATOR_USERNAME) != 0)
|
||||
@ -3807,6 +3833,11 @@ CLEANUP:
|
||||
|
||||
SLog(c->Cedar, "LS_CONNECTION_ERROR", c->Name, GetUniErrorStr(c->Err), c->Err);
|
||||
|
||||
if (release_me_eap_client != NULL)
|
||||
{
|
||||
ReleaseEapClient(release_me_eap_client);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
1621
src/Cedar/Radius.c
1621
src/Cedar/Radius.c
File diff suppressed because it is too large
Load Diff
@ -117,15 +117,260 @@
|
||||
#define RADIUS_DEFAULT_PORT 1812 // The default port number
|
||||
#define RADIUS_RETRY_INTERVAL 500 // Retransmission interval
|
||||
#define RADIUS_RETRY_TIMEOUT (10 * 1000) // Time-out period
|
||||
#define RADIUS_INITIAL_EAP_TIMEOUT 1600 // Initial timeout for EAP
|
||||
|
||||
|
||||
// RADIUS attributes
|
||||
#define RADIUS_ATTRIBUTE_VLAN_ID 81
|
||||
#define RADIUS_ATTRIBUTE_USER_NAME 1
|
||||
#define RADIUS_ATTRIBUTE_NAS_IP 4
|
||||
#define RADIUS_ATTRIBUTE_NAS_PORT 5
|
||||
#define RADIUS_ATTRIBUTE_SERVICE_TYPE 6
|
||||
#define RADIUS_ATTRIBUTE_FRAMED_PROTOCOL 7
|
||||
#define RADIUS_ATTRIBUTE_FRAMED_MTU 12
|
||||
#define RADIUS_ATTRIBUTE_STATE 24
|
||||
#define RADIUS_ATTRIBUTE_VENDOR_SPECIFIC 26
|
||||
#define RADIUS_ATTRIBUTE_CALLED_STATION_ID 30
|
||||
#define RADIUS_ATTRIBUTE_CALLING_STATION_ID 31
|
||||
#define RADIUS_ATTRIBUTE_NAS_ID 32
|
||||
#define RADIUS_ATTRIBUTE_PROXY_STATE 33
|
||||
#define RADIUS_ATTRIBUTE_ACCT_SESSION_ID 44
|
||||
#define RADIUS_ATTRIBUTE_NAS_PORT_TYPE 61
|
||||
#define RADIUS_ATTRIBUTE_TUNNEL_TYPE 64
|
||||
#define RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE 65
|
||||
#define RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT 66
|
||||
#define RADIUS_ATTRIBUTE_TUNNEL_SERVER_ENDPOINT 67
|
||||
#define RADIUS_ATTRIBUTE_EAP_MESSAGE 79
|
||||
#define RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR 80
|
||||
#define RADIUS_ATTRIBUTE_VLAN_ID 81
|
||||
|
||||
// RADIUS codes
|
||||
#define RADIUS_CODE_ACCESS_REQUEST 1
|
||||
#define RADIUS_CODE_ACCESS_ACCEPT 2
|
||||
#define RADIUS_CODE_ACCESS_REJECT 3
|
||||
#define RADIUS_CODE_ACCESS_CHALLENGE 11
|
||||
|
||||
// RADIUS vendor ID
|
||||
#define RADIUS_VENDOR_MICROSOFT 311
|
||||
|
||||
// RADIUS MS attributes
|
||||
#define RADIUS_MS_RAS_VENDOR 9
|
||||
#define RADIUS_MS_CHAP_CHALLENGE 11
|
||||
#define RADIUS_MS_VERSION 18
|
||||
#define RADIUS_MS_CHAP2_RESPONSE 25
|
||||
#define RADIUS_MS_RAS_CLIENT_NAME 34
|
||||
#define RADIUS_MS_RAS_CLIENT_VERSION 35
|
||||
#define RADIUS_MS_NETWORK_ACCESS_SERVER_TYPE 47
|
||||
#define RADIUS_MS_RAS_CORRELATION 56
|
||||
|
||||
// EAP code
|
||||
#define EAP_CODE_REQUEST 1
|
||||
#define EAP_CODE_RESPONSE 2
|
||||
#define EAP_CODE_SUCCESS 3
|
||||
#define EAP_CODE_FAILURE 4
|
||||
|
||||
// EAP type
|
||||
#define EAP_TYPE_IDENTITY 1
|
||||
#define EAP_TYPE_LEGACY_NAK 3
|
||||
#define EAP_TYPE_PEAP 25
|
||||
#define EAP_TYPE_MS_AUTH 26
|
||||
|
||||
// MS-CHAPv2 opcodes
|
||||
#define EAP_MSCHAPV2_OP_CHALLENGE 1
|
||||
#define EAP_MSCHAPV2_OP_RESPONSE 2
|
||||
#define EAP_MSCHAPV2_OP_SUCCESS 3
|
||||
|
||||
// EAP-TLS flags
|
||||
#define EAP_TLS_FLAGS_LEN 0x80
|
||||
#define EAP_TLS_FLAGS_MORE_FRAGMENTS 0x40
|
||||
#define EAP_TLS_FLAGS_START 0x20
|
||||
|
||||
|
||||
////////// Modern implementation
|
||||
|
||||
#ifdef OS_WIN32
|
||||
#pragma pack(push, 1)
|
||||
#endif // OS_WIN32
|
||||
|
||||
struct EAP_MESSAGE
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR Id;
|
||||
USHORT Len; // = sizeof(Data) + 5
|
||||
UCHAR Type;
|
||||
UCHAR Data[1500];
|
||||
} GCC_PACKED;
|
||||
|
||||
struct EAP_MSCHAPV2_GENERAL
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR Id;
|
||||
USHORT Len; // = sizeof(Data) + 5
|
||||
UCHAR Type;
|
||||
UCHAR Chap_Opcode;
|
||||
} GCC_PACKED;
|
||||
|
||||
struct EAP_MSCHAPV2_CHALLENGE
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR Id;
|
||||
USHORT Len; // = sizeof(Data) + 5
|
||||
UCHAR Type;
|
||||
UCHAR Chap_Opcode;
|
||||
UCHAR Chap_Id;
|
||||
USHORT Chap_Len;
|
||||
UCHAR Chap_ValueSize; // = 16
|
||||
UCHAR Chap_ChallengeValue[16];
|
||||
char Chap_Name[256];
|
||||
} GCC_PACKED;
|
||||
|
||||
struct EAP_MSCHAPV2_RESPONSE
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR Id;
|
||||
USHORT Len; // = sizeof(Data) + 5
|
||||
UCHAR Type;
|
||||
UCHAR Chap_Opcode;
|
||||
UCHAR Chap_Id;
|
||||
USHORT Chap_Len;
|
||||
UCHAR Chap_ValueSize; // = 49
|
||||
UCHAR Chap_PeerChallange[16];
|
||||
UCHAR Chap_Reserved[8];
|
||||
UCHAR Chap_NtResponse[24];
|
||||
UCHAR Chap_Flags;
|
||||
char Chap_Name[256];
|
||||
} GCC_PACKED;
|
||||
|
||||
struct EAP_MSCHAPV2_SUCCESS_SERVER
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR Id;
|
||||
USHORT Len; // = sizeof(Data) + 5
|
||||
UCHAR Type;
|
||||
UCHAR Chap_Opcode;
|
||||
UCHAR Chap_Id;
|
||||
USHORT Chap_Len;
|
||||
char Message[256];
|
||||
} GCC_PACKED;
|
||||
|
||||
struct EAP_MSCHAPV2_SUCCESS_CLIENT
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR Id;
|
||||
USHORT Len; // = sizeof(Data) + 5
|
||||
UCHAR Type;
|
||||
UCHAR Chap_Opcode;
|
||||
} GCC_PACKED;
|
||||
|
||||
struct EAP_PEAP
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR Id;
|
||||
USHORT Len; // = sizeof(Data) + 5
|
||||
UCHAR Type;
|
||||
UCHAR TlsFlags;
|
||||
} GCC_PACKED;
|
||||
|
||||
#ifdef OS_WIN32
|
||||
#pragma pack(pop)
|
||||
#endif // OS_WIN32
|
||||
|
||||
struct RADIUS_PACKET
|
||||
{
|
||||
UCHAR Code;
|
||||
UCHAR PacketId;
|
||||
LIST *AvpList;
|
||||
UCHAR Authenticator[16];
|
||||
|
||||
UINT Parse_EapAuthMessagePos;
|
||||
UINT Parse_AuthenticatorPos;
|
||||
|
||||
EAP_MESSAGE *Parse_EapMessage;
|
||||
UINT Parse_EapMessage_DataSize;
|
||||
|
||||
UINT Parse_StateSize;
|
||||
UCHAR Parse_State[256];
|
||||
};
|
||||
|
||||
struct RADIUS_AVP
|
||||
{
|
||||
UCHAR Type;
|
||||
UINT VendorId;
|
||||
UCHAR VendorCode;
|
||||
UCHAR Padding[3];
|
||||
UCHAR DataSize;
|
||||
UCHAR Data[256];
|
||||
};
|
||||
|
||||
struct EAP_CLIENT
|
||||
{
|
||||
REF *Ref;
|
||||
|
||||
SOCK *UdpSock;
|
||||
IP ServerIp;
|
||||
UINT ServerPort;
|
||||
char SharedSecret[MAX_SIZE];
|
||||
char ClientIpStr[256];
|
||||
char Username[MAX_USERNAME_LEN + 1];
|
||||
UINT ResendTimeout;
|
||||
UINT GiveupTimeout;
|
||||
UCHAR TmpBuffer[4096];
|
||||
UCHAR NextEapId;
|
||||
UCHAR LastRecvEapId;
|
||||
|
||||
bool PeapMode;
|
||||
|
||||
UCHAR LastState[256];
|
||||
UINT LastStateSize;
|
||||
|
||||
EAP_MSCHAPV2_CHALLENGE MsChapV2Challenge;
|
||||
EAP_MSCHAPV2_SUCCESS_SERVER MsChapV2Success;
|
||||
UCHAR ServerResponse[20];
|
||||
|
||||
SSL_PIPE *SslPipe;
|
||||
UCHAR NextRadiusPacketId;
|
||||
|
||||
BUF *PEAP_CurrentReceivingMsg;
|
||||
UINT PEAP_CurrentReceivingTotalSize;
|
||||
UCHAR RecvLastCode;
|
||||
|
||||
UINT LastRecvVLanId;
|
||||
};
|
||||
|
||||
void FreeRadiusPacket(RADIUS_PACKET *p);
|
||||
BUF *GenerateRadiusPacket(RADIUS_PACKET *p, char *shared_secret);
|
||||
RADIUS_PACKET *ParseRadiusPacket(void *data, UINT size);
|
||||
RADIUS_PACKET *NewRadiusPacket(UCHAR code, UCHAR packet_id);
|
||||
RADIUS_AVP *NewRadiusAvp(UCHAR type, UINT vendor_id, UCHAR vendor_code, void *data, UINT size);
|
||||
RADIUS_AVP *GetRadiusAvp(RADIUS_PACKET *p, UCHAR type);
|
||||
void RadiusTest();
|
||||
|
||||
|
||||
EAP_CLIENT *NewEapClient(IP *server_ip, UINT server_port, char *shared_secret, UINT resend_timeout, UINT giveup_timeout, char *client_ip_str, char *username);
|
||||
void ReleaseEapClient(EAP_CLIENT *e);
|
||||
void CleanupEapClient(EAP_CLIENT *e);
|
||||
bool EapClientSendMsChapv2AuthRequest(EAP_CLIENT *e);
|
||||
bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge);
|
||||
void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e);
|
||||
bool EapSendPacket(EAP_CLIENT *e, RADIUS_PACKET *r);
|
||||
RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r);
|
||||
|
||||
bool PeapClientSendMsChapv2AuthRequest(EAP_CLIENT *eap);
|
||||
bool PeapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge);
|
||||
|
||||
bool StartPeapClient(EAP_CLIENT *e);
|
||||
bool StartPeapSslClient(EAP_CLIENT *e);
|
||||
bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size);
|
||||
bool SendPeapPacket(EAP_CLIENT *e, void *msg, UINT msg_size);
|
||||
bool GetRecvPeapMessage(EAP_CLIENT *e, EAP_MESSAGE *msg);
|
||||
|
||||
|
||||
////////// Classical implementation
|
||||
struct RADIUS_LOGIN_OPTION
|
||||
{
|
||||
bool In_CheckVLanId;
|
||||
bool In_DenyNoVlanId;
|
||||
UINT Out_VLanId;
|
||||
bool Out_IsRadiusLogin;
|
||||
};
|
||||
|
||||
// Function prototype
|
||||
|
@ -268,6 +268,14 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
b = RadiusLogin(c, radius_server_addr, radius_server_port,
|
||||
radius_secret, StrLen(radius_secret),
|
||||
name, password, interval, mschap_v2_server_response_20, opt);
|
||||
|
||||
if (b)
|
||||
{
|
||||
if (opt != NULL)
|
||||
{
|
||||
opt->Out_IsRadiusLogin = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Lock(hub->lock);
|
||||
|
@ -4098,11 +4098,13 @@ void SiLoadHubOptionCfg(FOLDER *f, HUB_OPTION *o)
|
||||
}
|
||||
|
||||
o->DisableKernelModeSecureNAT = CfgGetBool(f, "DisableKernelModeSecureNAT");
|
||||
o->DisableIpRawModeSecureNAT = CfgGetBool(f, "DisableIpRawModeSecureNAT");
|
||||
o->DisableUserModeSecureNAT = CfgGetBool(f, "DisableUserModeSecureNAT");
|
||||
o->DisableCheckMacOnLocalBridge = CfgGetBool(f, "DisableCheckMacOnLocalBridge");
|
||||
o->DisableCorrectIpOffloadChecksum = CfgGetBool(f, "DisableCorrectIpOffloadChecksum");
|
||||
o->SuppressClientUpdateNotification = CfgGetBool(f, "SuppressClientUpdateNotification");
|
||||
o->AssignVLanIdByRadiusAttribute = CfgGetBool(f, "AssignVLanIdByRadiusAttribute");
|
||||
o->DenyAllRadiusLoginWithNoVlanAssign = CfgGetBool(f, "DenyAllRadiusLoginWithNoVlanAssign");
|
||||
o->SecureNAT_RandomizeAssignIp = CfgGetBool(f, "SecureNAT_RandomizeAssignIp");
|
||||
o->DetectDormantSessionInterval = CfgGetInt(f, "DetectDormantSessionInterval");
|
||||
o->NoPhysicalIPOnPacketLog = CfgGetBool(f, "NoPhysicalIPOnPacketLog");
|
||||
@ -4182,6 +4184,7 @@ void SiWriteHubOptionCfg(FOLDER *f, HUB_OPTION *o)
|
||||
CfgAddBool(f, "DropArpInPrivacyFilterMode", o->DropArpInPrivacyFilterMode);
|
||||
CfgAddBool(f, "SuppressClientUpdateNotification", o->SuppressClientUpdateNotification);
|
||||
CfgAddBool(f, "AssignVLanIdByRadiusAttribute", o->AssignVLanIdByRadiusAttribute);
|
||||
CfgAddBool(f, "DenyAllRadiusLoginWithNoVlanAssign", o->DenyAllRadiusLoginWithNoVlanAssign);
|
||||
CfgAddBool(f, "SecureNAT_RandomizeAssignIp", o->SecureNAT_RandomizeAssignIp);
|
||||
CfgAddBool(f, "NoPhysicalIPOnPacketLog", o->NoPhysicalIPOnPacketLog);
|
||||
CfgAddInt(f, "DetectDormantSessionInterval", o->DetectDormantSessionInterval);
|
||||
@ -4201,6 +4204,7 @@ void SiWriteHubOptionCfg(FOLDER *f, HUB_OPTION *o)
|
||||
CfgAddInt(f, "SecureNAT_MaxIcmpSessionsPerIp", o->SecureNAT_MaxIcmpSessionsPerIp);
|
||||
CfgAddInt(f, "AccessListIncludeFileCacheLifetime", o->AccessListIncludeFileCacheLifetime);
|
||||
CfgAddBool(f, "DisableKernelModeSecureNAT", o->DisableKernelModeSecureNAT);
|
||||
CfgAddBool(f, "DisableIpRawModeSecureNAT", o->DisableIpRawModeSecureNAT);
|
||||
CfgAddBool(f, "DisableUserModeSecureNAT", o->DisableUserModeSecureNAT);
|
||||
CfgAddBool(f, "DisableCheckMacOnLocalBridge", o->DisableCheckMacOnLocalBridge);
|
||||
CfgAddBool(f, "DisableCorrectIpOffloadChecksum", o->DisableCorrectIpOffloadChecksum);
|
||||
@ -5005,6 +5009,9 @@ void SiWriteHubCfg(FOLDER *f, HUB *h)
|
||||
CfgAddInt(f, "RadiusServerPort", h->RadiusServerPort);
|
||||
CfgAddInt(f, "RadiusRetryInterval", h->RadiusRetryInterval);
|
||||
CfgAddStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter);
|
||||
|
||||
CfgAddBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap", h->RadiusConvertAllMsChapv2AuthRequestToEap);
|
||||
CfgAddBool(f, "RadiusUsePeapInsteadOfEap", h->RadiusUsePeapInsteadOfEap);
|
||||
}
|
||||
Unlock(h->RadiusOptionLock);
|
||||
|
||||
@ -5171,6 +5178,9 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
|
||||
|
||||
CfgGetStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter, sizeof(h->RadiusSuffixFilter));
|
||||
|
||||
h->RadiusConvertAllMsChapv2AuthRequestToEap = CfgGetBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap");
|
||||
h->RadiusUsePeapInsteadOfEap = CfgGetBool(f, "RadiusUsePeapInsteadOfEap");
|
||||
|
||||
if (interval == 0)
|
||||
{
|
||||
interval = RADIUS_RETRY_INTERVAL;
|
||||
@ -7486,6 +7496,7 @@ void SiCalledUpdateHub(SERVER *s, PACK *p)
|
||||
o.DropArpInPrivacyFilterMode = PackGetBool(p, "DropArpInPrivacyFilterMode");
|
||||
o.SuppressClientUpdateNotification = PackGetBool(p, "SuppressClientUpdateNotification");
|
||||
o.AssignVLanIdByRadiusAttribute = PackGetBool(p, "AssignVLanIdByRadiusAttribute");
|
||||
o.DenyAllRadiusLoginWithNoVlanAssign = PackGetBool(p, "DenyAllRadiusLoginWithNoVlanAssign");
|
||||
o.SecureNAT_RandomizeAssignIp = PackGetBool(p, "SecureNAT_RandomizeAssignIp");
|
||||
o.DetectDormantSessionInterval = PackGetInt(p, "DetectDormantSessionInterval");
|
||||
o.VlanTypeId = PackGetInt(p, "VlanTypeId");
|
||||
@ -7527,6 +7538,7 @@ void SiCalledUpdateHub(SERVER *s, PACK *p)
|
||||
o.AccessListIncludeFileCacheLifetime = ACCESS_LIST_INCLUDE_FILE_CACHE_LIFETIME;
|
||||
}
|
||||
o.DisableKernelModeSecureNAT = PackGetBool(p, "DisableKernelModeSecureNAT");
|
||||
o.DisableIpRawModeSecureNAT = PackGetBool(p, "DisableIpRawModeSecureNAT");
|
||||
o.DisableUserModeSecureNAT = PackGetBool(p, "DisableUserModeSecureNAT");
|
||||
o.DisableCheckMacOnLocalBridge = PackGetBool(p, "DisableCheckMacOnLocalBridge");
|
||||
o.DisableCorrectIpOffloadChecksum = PackGetBool(p, "DisableCorrectIpOffloadChecksum");
|
||||
@ -9329,6 +9341,7 @@ void SiPackAddCreateHub(PACK *p, HUB *h)
|
||||
PackAddBool(p, "DropArpInPrivacyFilterMode", h->Option->DropArpInPrivacyFilterMode);
|
||||
PackAddBool(p, "SuppressClientUpdateNotification", h->Option->SuppressClientUpdateNotification);
|
||||
PackAddBool(p, "AssignVLanIdByRadiusAttribute", h->Option->AssignVLanIdByRadiusAttribute);
|
||||
PackAddBool(p, "DenyAllRadiusLoginWithNoVlanAssign", h->Option->DenyAllRadiusLoginWithNoVlanAssign);
|
||||
PackAddInt(p, "ClientMinimumRequiredBuild", h->Option->ClientMinimumRequiredBuild);
|
||||
PackAddBool(p, "SecureNAT_RandomizeAssignIp", h->Option->SecureNAT_RandomizeAssignIp);
|
||||
PackAddBool(p, "NoPhysicalIPOnPacketLog", h->Option->NoPhysicalIPOnPacketLog);
|
||||
@ -9366,6 +9379,7 @@ void SiPackAddCreateHub(PACK *p, HUB *h)
|
||||
PackAddInt(p, "SecureNAT_MaxIcmpSessionsPerIp", h->Option->SecureNAT_MaxIcmpSessionsPerIp);
|
||||
PackAddInt(p, "AccessListIncludeFileCacheLifetime", h->Option->AccessListIncludeFileCacheLifetime);
|
||||
PackAddBool(p, "DisableKernelModeSecureNAT", h->Option->DisableKernelModeSecureNAT);
|
||||
PackAddBool(p, "DisableIpRawModeSecureNAT", h->Option->DisableIpRawModeSecureNAT);
|
||||
PackAddBool(p, "DisableUserModeSecureNAT", h->Option->DisableUserModeSecureNAT);
|
||||
PackAddBool(p, "DisableCheckMacOnLocalBridge", h->Option->DisableCheckMacOnLocalBridge);
|
||||
PackAddBool(p, "DisableCorrectIpOffloadChecksum", h->Option->DisableCorrectIpOffloadChecksum);
|
||||
|
@ -329,7 +329,7 @@ void NnDeleteSession(NATIVE_NAT *t, NATIVE_NAT_ENTRY *e)
|
||||
break;
|
||||
|
||||
case NAT_ICMP:
|
||||
Debug("NAT ICMP %u Deleted.", e->Id);
|
||||
Debug("NAT ICMP %u Deleted.\n", e->Id);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -509,6 +509,7 @@ void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT siz
|
||||
if (total_size == c->Size)
|
||||
{
|
||||
// Received whole of the IP packet
|
||||
//Debug("Combine: %u\n", total_size);
|
||||
NnIpReceived(t, c->SrcIP, c->DestIP, c->Protocol, c->Data, c->Size, c->Ttl,
|
||||
c->HeadIpHeaderData, c->HeadIpHeaderDataSize, c->MaxL3Size);
|
||||
|
||||
@ -1651,24 +1652,32 @@ UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_po
|
||||
{
|
||||
UINT i;
|
||||
UINT base_port;
|
||||
UINT port_start = 1025;
|
||||
UINT port_end = 65500;
|
||||
// Validate arguments
|
||||
if (t == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
base_port = Rand32() % (65500 - 1025) + 1025;
|
||||
if (t->IsRawIpMode)
|
||||
{
|
||||
port_start = NN_RAW_IP_PORT_START;
|
||||
port_end = NN_RAW_IP_PORT_END;
|
||||
}
|
||||
|
||||
for (i = 0;i < (65500 - 1025);i++)
|
||||
base_port = Rand32() % (port_end - port_start) + port_start;
|
||||
|
||||
for (i = 0;i < (port_end - port_start);i++)
|
||||
{
|
||||
UINT port;
|
||||
NATIVE_NAT_ENTRY tt;
|
||||
NATIVE_NAT *e;
|
||||
|
||||
port = base_port + i;
|
||||
if (port > 65500)
|
||||
if (port > port_end)
|
||||
{
|
||||
port = port - 65500 + 1025;
|
||||
port = port - port_end + port_start;
|
||||
}
|
||||
|
||||
// Is this port vacant?
|
||||
@ -1688,6 +1697,10 @@ UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_po
|
||||
|
||||
// Examine whether the native NAT is available
|
||||
bool NnIsActive(VH *v)
|
||||
{
|
||||
return NnIsActiveEx(v, NULL);
|
||||
}
|
||||
bool NnIsActiveEx(VH *v, bool *is_ipraw_mode)
|
||||
{
|
||||
// Validate arguments
|
||||
if (v == NULL)
|
||||
@ -1705,6 +1718,14 @@ bool NnIsActive(VH *v)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v->NativeNat->Active)
|
||||
{
|
||||
if (is_ipraw_mode != NULL)
|
||||
{
|
||||
*is_ipraw_mode = v->NativeNat->IsRawIpMode;
|
||||
}
|
||||
}
|
||||
|
||||
return v->NativeNat->Active;
|
||||
}
|
||||
|
||||
@ -1745,7 +1766,7 @@ void NnMainLoop(NATIVE_NAT *t, NATIVE_STACK *a)
|
||||
ipc = a->Ipc;
|
||||
|
||||
tubes[num_tubes++] = ipc->Sock->RecvTube;
|
||||
tubes[num_tubes++] = ipc->Sock->SendTube;
|
||||
//tubes[num_tubes++] = ipc->Sock->SendTube; // bug 2015.10.01 remove
|
||||
tubes[num_tubes++] = t->HaltTube;
|
||||
|
||||
Zero(&yahoo_ip, sizeof(yahoo_ip));
|
||||
@ -1757,13 +1778,25 @@ void NnMainLoop(NATIVE_NAT *t, NATIVE_STACK *a)
|
||||
next_dhcp_renew_tick = Tick64() + (UINT64)dhcp_renew_interval;
|
||||
AddInterrupt(interrupt, next_dhcp_renew_tick);
|
||||
|
||||
while (t->Halt == false && t->v->UseNat && ((t->v->HubOption == NULL) || (t->v->HubOption->DisableKernelModeSecureNAT == false)))
|
||||
while (t->Halt == false && t->v->UseNat)
|
||||
{
|
||||
UINT64 now = Tick64();
|
||||
bool call_cancel = false;
|
||||
bool state_changed = false;
|
||||
UINT wait_interval;
|
||||
|
||||
if (t->v->HubOption != NULL)
|
||||
{
|
||||
if (t->IsRawIpMode == false && t->v->HubOption->DisableKernelModeSecureNAT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (t->IsRawIpMode && t->v->HubOption->DisableIpRawModeSecureNAT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IPCFlushArpTable(ipc);
|
||||
call_cancel = false;
|
||||
|
||||
@ -1774,7 +1807,7 @@ LABEL_RESTART:
|
||||
{
|
||||
BUF *dns_query;
|
||||
|
||||
dns_src_port = NnGenSrcPort();
|
||||
dns_src_port = NnGenSrcPort(a->IsIpRawMode);
|
||||
dns_tran_id = Rand16();
|
||||
|
||||
// Start a connectivity check periodically
|
||||
@ -1877,7 +1910,7 @@ LABEL_RESTART:
|
||||
// DNS response has been received
|
||||
no_store = true;
|
||||
|
||||
tcp_src_port = NnGenSrcPort();
|
||||
tcp_src_port = NnGenSrcPort(a->IsIpRawMode);
|
||||
|
||||
// Generate a TCP connection attempt packet
|
||||
tcp_seq = Rand32();
|
||||
@ -2347,22 +2380,47 @@ LABEL_CLEANUP:
|
||||
bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
||||
{
|
||||
BUF *dns_query;
|
||||
BUF *dns_query2;
|
||||
bool ok = false;
|
||||
USHORT dns_tran_id = Rand16();
|
||||
UINT64 next_send_tick = 0;
|
||||
UINT64 giveup_time;
|
||||
IPC *ipc;
|
||||
UINT src_port = NnGenSrcPort();
|
||||
UINT src_port = NnGenSrcPort(a->IsIpRawMode);
|
||||
INTERRUPT_MANAGER *interrupt;
|
||||
TUBE *tubes[3];
|
||||
UINT num_tubes = 0;
|
||||
IP yahoo_ip;
|
||||
IP my_priv_ip;
|
||||
UINT num_send_dns = 0;
|
||||
IP using_dns;
|
||||
// Validate arguments
|
||||
if (a == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Copy(&using_dns, &a->DnsServerIP, sizeof(IP));
|
||||
|
||||
// Get my physical IP
|
||||
if (a->IsIpRawMode)
|
||||
{
|
||||
if (GetMyPrivateIP(&my_priv_ip, false) == false)
|
||||
{
|
||||
Debug("NnTestConnectivity: GetMyPrivateIP failed.\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug("NnTestConnectivity: GetMyPrivateIP ok: %r\n", &my_priv_ip);
|
||||
|
||||
if (a->Eth != NULL)
|
||||
{
|
||||
Copy(&a->Eth->MyPhysicalIPForce, &my_priv_ip, sizeof(IP));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipc = a->Ipc;
|
||||
interrupt = NewInterruptManager();
|
||||
|
||||
@ -2381,6 +2439,10 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
||||
IPToUINT(&ipc->ClientIPAddress), src_port, IPToUINT(&a->DnsServerIP), 53),
|
||||
IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP), IP_PROTO_UDP, 0);
|
||||
|
||||
dns_query2 = NnBuildIpPacket(NnBuildUdpPacket(NnBuildDnsQueryPacket(NN_CHECK_HOSTNAME, dns_tran_id),
|
||||
IPToUINT(&ipc->ClientIPAddress), src_port, IPToUINT(&a->DnsServerIP), 53),
|
||||
IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP2), IP_PROTO_UDP, 0);
|
||||
|
||||
giveup_time = Tick64() + NN_CHECK_CONNECTIVITY_TIMEOUT;
|
||||
AddInterrupt(interrupt, giveup_time);
|
||||
while (true)
|
||||
@ -2401,7 +2463,16 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
||||
|
||||
AddInterrupt(interrupt, next_send_tick);
|
||||
|
||||
IPCSendIPv4(ipc, dns_query->Buf, dns_query->Size);
|
||||
if ((num_send_dns % 2) == 0)
|
||||
{
|
||||
IPCSendIPv4(ipc, dns_query->Buf, dns_query->Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCSendIPv4(ipc, dns_query2->Buf, dns_query2->Size);
|
||||
}
|
||||
|
||||
num_send_dns++;
|
||||
}
|
||||
|
||||
// Happy processing
|
||||
@ -2424,7 +2495,8 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
||||
if (pkt != NULL)
|
||||
{
|
||||
if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_UDP &&
|
||||
pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) &&
|
||||
(pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) ||
|
||||
pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP2)) &&
|
||||
pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) &&
|
||||
pkt->L4.UDPHeader->SrcPort == Endian16(53) && pkt->L4.UDPHeader->DstPort == Endian16(src_port))
|
||||
{
|
||||
@ -2437,6 +2509,9 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
||||
|
||||
if (NnParseDnsResponsePacket(pkt->Payload, pkt->PayloadSize, &ret_ip))
|
||||
{
|
||||
UINTToIP(&using_dns, pkt->L3.IPv4Header->SrcIP);
|
||||
Debug("NativeStack: Using DNS: %r\n", &using_dns);
|
||||
|
||||
Copy(&yahoo_ip, &ret_ip, sizeof(IP));
|
||||
}
|
||||
}
|
||||
@ -2466,6 +2541,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
||||
}
|
||||
|
||||
FreeBuf(dns_query);
|
||||
FreeBuf(dns_query2);
|
||||
|
||||
if (IsZeroIP(&yahoo_ip) == false)
|
||||
{
|
||||
@ -2589,13 +2665,37 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
|
||||
|
||||
FreeInterruptManager(interrupt);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if (IsZeroIP(&using_dns) == false)
|
||||
{
|
||||
Copy(&a->DnsServerIP, &using_dns, sizeof(IP));
|
||||
}
|
||||
|
||||
if (a->IsIpRawMode)
|
||||
{
|
||||
if (NsStartIpTablesTracking(a) == false)
|
||||
{
|
||||
Debug("NsStartIpTablesTracking failed.\n");
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Generate source port number by a random number
|
||||
UINT NnGenSrcPort()
|
||||
UINT NnGenSrcPort(bool raw_ip_mode)
|
||||
{
|
||||
return 1025 + Rand32() % (65500 - 1025);
|
||||
if (raw_ip_mode == false)
|
||||
{
|
||||
return 1025 + Rand32() % (65500 - 1025);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NN_RAW_IP_PORT_START + Rand32() % (NN_RAW_IP_PORT_END - NN_RAW_IP_PORT_START);
|
||||
}
|
||||
}
|
||||
|
||||
// Get a next good interface for the native NAT
|
||||
@ -2617,7 +2717,9 @@ NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t)
|
||||
t->NextWaitTimeForRetry = NN_NEXT_WAIT_TIME_FOR_DEVICE_ENUM * MIN((t->FailedCount + 1), NN_NEXT_WAIT_TIME_MAX_FAIL_COUNT);
|
||||
|
||||
// Get the device list
|
||||
device_list = GetEthList();
|
||||
device_list = GetEthListEx(NULL,
|
||||
!(t->v->HubOption != NULL && t->v->HubOption->DisableKernelModeSecureNAT),
|
||||
!(t->v->HubOption != NULL && t->v->HubOption->DisableIpRawModeSecureNAT));
|
||||
|
||||
if (device_list == NULL || device_list->NumTokens == 0)
|
||||
{
|
||||
@ -2720,11 +2822,17 @@ NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t)
|
||||
|
||||
// Determine the DNS server to use
|
||||
UINTToIP(&ret->DnsServerIP, opt.DnsServer);
|
||||
UINTToIP(&ret->DnsServerIP2, opt.DnsServer2);
|
||||
if (IsZeroIP(&ret->DnsServerIP))
|
||||
{
|
||||
// Use 8.8.8.8 instead If the DNS is not assigned from the DHCP server
|
||||
SetIP(&ret->DnsServerIP, 8, 8, 8, 8);
|
||||
}
|
||||
if (IsZeroIP(&ret->DnsServerIP2))
|
||||
{
|
||||
// Use 8.8.4.4 instead If the DNS is not assigned from the DHCP server
|
||||
SetIP(&ret->DnsServerIP2, 8, 8, 4, 4);
|
||||
}
|
||||
|
||||
// Connectivity test
|
||||
// (always fail if the default gateway is not set)
|
||||
@ -2773,7 +2881,7 @@ void NativeNatThread(THREAD *thread, void *param)
|
||||
{
|
||||
NATIVE_STACK *a;
|
||||
|
||||
while (t->v->UseNat == false || (t->v->HubOption != NULL && t->v->HubOption->DisableKernelModeSecureNAT))
|
||||
while (t->v->UseNat == false || t->v->HubOption == NULL || (t->v->HubOption->DisableKernelModeSecureNAT && t->v->HubOption->DisableIpRawModeSecureNAT))
|
||||
{
|
||||
if (t->Halt)
|
||||
{
|
||||
@ -2802,6 +2910,8 @@ void NativeNatThread(THREAD *thread, void *param)
|
||||
// Acquisition success
|
||||
Debug("NnGetNextInterface Ok: %s\n", a->DeviceName);
|
||||
|
||||
t->IsRawIpMode = a->IsIpRawMode;
|
||||
|
||||
Lock(t->Lock);
|
||||
{
|
||||
if (a->Sock1 != NULL)
|
||||
@ -2830,6 +2940,8 @@ void NativeNatThread(THREAD *thread, void *param)
|
||||
NnMainLoop(t, a);
|
||||
Debug("NnMainLoop End.\n");
|
||||
|
||||
t->IsRawIpMode = false;
|
||||
|
||||
t->Active = false;
|
||||
t->PublicIP = 0;
|
||||
|
||||
@ -7425,6 +7537,8 @@ void VirtualIcmpEchoRequestReceived(VH *v, UINT src_ip, UINT dst_ip, void *data,
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug("ICMP: %u\n", size);
|
||||
|
||||
if (NnIsActive(v))
|
||||
{
|
||||
// Process by the Native NAT
|
||||
|
@ -115,10 +115,13 @@
|
||||
#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 (60 * 1000)
|
||||
#define NN_NEXT_WAIT_TIME_MAX_FAIL_COUNT 15
|
||||
#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-"
|
||||
@ -191,6 +194,7 @@ struct NATIVE_NAT
|
||||
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
|
||||
@ -643,7 +647,7 @@ 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();
|
||||
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);
|
||||
@ -656,6 +660,7 @@ 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);
|
||||
|
@ -1,4 +1,4 @@
|
||||
BUILD_NUMBER 9578
|
||||
BUILD_NUMBER 9582
|
||||
VERSION 419
|
||||
BUILD_NAME beta
|
||||
BUILD_DATE 20150915_143935
|
||||
BUILD_DATE 20151006_145630
|
||||
|
@ -423,6 +423,7 @@ typedef struct STRMAP_ENTRY STRMAP_ENTRY;
|
||||
typedef struct SHARED_BUFFER SHARED_BUFFER;
|
||||
typedef struct HASH_LIST HASH_LIST;
|
||||
typedef struct HASH_ENTRY HASH_ENTRY;
|
||||
typedef struct PRAND PRAND;
|
||||
|
||||
// Str.h
|
||||
typedef struct TOKEN_LIST TOKEN_LIST;
|
||||
|
@ -134,6 +134,70 @@
|
||||
|
||||
static UINT fifo_current_realloc_mem_size = FIFO_REALLOC_MEM_SIZE;
|
||||
|
||||
// New PRand
|
||||
PRAND *NewPRand(void *key, UINT key_size)
|
||||
{
|
||||
PRAND *r;
|
||||
UCHAR dummy[256];
|
||||
if (key == NULL || key_size == 0)
|
||||
{
|
||||
key = "DUMMY";
|
||||
key_size = 5;
|
||||
}
|
||||
|
||||
r = ZeroMalloc(sizeof(PRAND));
|
||||
|
||||
HashSha1(r->Key, key, key_size);
|
||||
|
||||
r->Rc4 = NewCrypt(key, key_size);
|
||||
|
||||
Zero(dummy, sizeof(dummy));
|
||||
|
||||
Encrypt(r->Rc4, dummy, dummy, 256);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Free PRand
|
||||
void FreePRand(PRAND *r)
|
||||
{
|
||||
if (r == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FreeCrypt(r->Rc4);
|
||||
|
||||
Free(r);
|
||||
}
|
||||
|
||||
// Generate PRand
|
||||
void PRand(PRAND *p, void *data, UINT size)
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Zero(data, size);
|
||||
|
||||
Encrypt(p->Rc4, data, data, size);
|
||||
}
|
||||
|
||||
// Generate UINT PRand
|
||||
UINT PRandInt(PRAND *p)
|
||||
{
|
||||
UINT r;
|
||||
if (p == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRand(p, &r, sizeof(UINT));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Check whether the specified key item is in the hash list
|
||||
bool IsInHashListKey(HASH_LIST *h, UINT key)
|
||||
{
|
||||
@ -2368,6 +2432,28 @@ UINT PeekFifo(FIFO *f, void *p, UINT size)
|
||||
return read_size;
|
||||
}
|
||||
|
||||
// Read all data from FIFO
|
||||
BUF *ReadFifoAll(FIFO *f)
|
||||
{
|
||||
BUF *buf;
|
||||
UCHAR *tmp;
|
||||
UINT size;
|
||||
if (f == NULL)
|
||||
{
|
||||
return NewBuf();
|
||||
}
|
||||
|
||||
size = FifoSize(f);
|
||||
tmp = Malloc(size);
|
||||
ReadFifo(f, tmp, size);
|
||||
|
||||
buf = MemToBuf(tmp, size);
|
||||
|
||||
Free(tmp);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Read from the FIFO
|
||||
UINT ReadFifo(FIFO *f, void *p, UINT size)
|
||||
{
|
||||
@ -3128,6 +3214,21 @@ bool WriteBufInt(BUF *b, UINT value)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write a short integer in the the buffer
|
||||
bool WriteBufShort(BUF *b, USHORT value)
|
||||
{
|
||||
// Validate arguments
|
||||
if (b == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = Endian16(value);
|
||||
|
||||
WriteBuf(b, &value, sizeof(USHORT));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write a UCHAR to the buffer
|
||||
bool WriteBufChar(BUF *b, UCHAR uc)
|
||||
{
|
||||
@ -3194,6 +3295,23 @@ UINT ReadBufInt(BUF *b)
|
||||
return Endian32(value);
|
||||
}
|
||||
|
||||
// Read a short integer from the buffer
|
||||
USHORT ReadBufShort(BUF *b)
|
||||
{
|
||||
USHORT value;
|
||||
// Validate arguments
|
||||
if (b == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ReadBuf(b, &value, sizeof(USHORT)) != sizeof(USHORT))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return Endian16(value);
|
||||
}
|
||||
|
||||
// Write the buffer to a buffer
|
||||
void WriteBufBuf(BUF *b, BUF *bb)
|
||||
{
|
||||
@ -3459,6 +3577,23 @@ BUF *ReadRemainBuf(BUF *b)
|
||||
return ReadBufFromBuf(b, size);
|
||||
}
|
||||
|
||||
// Get the length of the rest
|
||||
UINT ReadBufRemainSize(BUF *b)
|
||||
{
|
||||
// Validate arguments
|
||||
if (b == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (b->Size < b->Current)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return b->Size - b->Current;
|
||||
}
|
||||
|
||||
// Clone the buffer
|
||||
BUF *CloneBuf(BUF *b)
|
||||
{
|
||||
|
@ -236,6 +236,13 @@ struct HASH_LIST
|
||||
LIST *AllList;
|
||||
};
|
||||
|
||||
// PRAND
|
||||
struct PRAND
|
||||
{
|
||||
UCHAR Key[20];
|
||||
CRYPT *Rc4;
|
||||
};
|
||||
|
||||
// Function prototype
|
||||
HASH_LIST *NewHashList(GET_HASH *get_hash_proc, COMPARE *compare_proc, UINT bits, bool make_list);
|
||||
void ReleaseHashList(HASH_LIST *h);
|
||||
@ -250,6 +257,11 @@ void UnlockHashList(HASH_LIST *h);
|
||||
bool IsInHashListKey(HASH_LIST *h, UINT key);
|
||||
void *HashListKeyToPointer(HASH_LIST *h, UINT key);
|
||||
|
||||
PRAND *NewPRand(void *key, UINT key_size);
|
||||
void FreePRand(PRAND *r);
|
||||
void PRand(PRAND *p, void *data, UINT size);
|
||||
UINT PRandInt(PRAND *p);
|
||||
|
||||
LIST *NewCandidateList();
|
||||
void FreeCandidateList(LIST *o);
|
||||
int ComapreCandidate(void *p1, void *p2);
|
||||
@ -310,11 +322,13 @@ void FreeBuf(BUF *b);
|
||||
bool BufToFile(IO *o, BUF *b);
|
||||
BUF *FileToBuf(IO *o);
|
||||
UINT ReadBufInt(BUF *b);
|
||||
USHORT ReadBufShort(BUF *b);
|
||||
UINT64 ReadBufInt64(BUF *b);
|
||||
UCHAR ReadBufChar(BUF *b);
|
||||
bool WriteBufInt(BUF *b, UINT value);
|
||||
bool WriteBufInt64(BUF *b, UINT64 value);
|
||||
bool WriteBufChar(BUF *b, UCHAR uc);
|
||||
bool WriteBufShort(BUF *b, USHORT value);
|
||||
bool ReadBufStr(BUF *b, char *str, UINT size);
|
||||
bool WriteBufStr(BUF *b, char *str);
|
||||
void WriteBufLine(BUF *b, char *str);
|
||||
@ -332,10 +346,12 @@ BUF *CloneBuf(BUF *b);
|
||||
BUF *MemToBuf(void *data, UINT size);
|
||||
BUF *RandBuf(UINT size);
|
||||
BUF *ReadRemainBuf(BUF *b);
|
||||
UINT ReadBufRemainSize(BUF *b);
|
||||
bool CompareBuf(BUF *b1, BUF *b2);
|
||||
|
||||
UINT PeekFifo(FIFO *f, void *p, UINT size);
|
||||
UINT ReadFifo(FIFO *f, void *p, UINT size);
|
||||
BUF *ReadFifoAll(FIFO *f);
|
||||
void ShrinkFifoMemory(FIFO *f);
|
||||
UCHAR *GetFifoPointer(FIFO *f);
|
||||
UCHAR *FifoPtr(FIFO *f);
|
||||
|
@ -5842,6 +5842,11 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_SINGLE_DH_USE);
|
||||
}
|
||||
|
||||
if (server_mode == false)
|
||||
{
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
||||
}
|
||||
|
||||
ssl = SSL_new(ssl_ctx);
|
||||
}
|
||||
Unlock(openssl_lock);
|
||||
@ -8907,10 +8912,36 @@ void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
|
||||
if (c1 != NULL)
|
||||
{
|
||||
reads[num_read++] = p1 = c1->pipe_read;
|
||||
|
||||
if (c1->SpecialFlag)
|
||||
{
|
||||
if (c1->pipe_special_read2 != -1 && c1->pipe_special_read2 != 0)
|
||||
{
|
||||
reads[num_read++] = c1->pipe_special_read2;
|
||||
}
|
||||
|
||||
if (c1->pipe_special_read3 != -1 && c1->pipe_special_read3 != 0)
|
||||
{
|
||||
reads[num_read++] = c1->pipe_special_read3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c2 != NULL)
|
||||
{
|
||||
reads[num_read++] = p2 = c2->pipe_read;
|
||||
|
||||
if (c2->SpecialFlag)
|
||||
{
|
||||
if (c2->pipe_special_read2 != -1 && c2->pipe_special_read2 != 0)
|
||||
{
|
||||
reads[num_read++] = c2->pipe_special_read2;
|
||||
}
|
||||
|
||||
if (c2->pipe_special_read3 != -1 && c2->pipe_special_read3 != 0)
|
||||
{
|
||||
reads[num_read++] = c2->pipe_special_read3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the select
|
||||
@ -8991,6 +9022,8 @@ CANCEL *UnixNewCancel()
|
||||
|
||||
UnixNewPipe(&c->pipe_read, &c->pipe_write);
|
||||
|
||||
c->pipe_special_read2 = c->pipe_special_read3 = -1;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -12307,6 +12340,36 @@ SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR ra
|
||||
return NewUDPEx2Rand(ipv6, ip, hash, sizeof(hash), num_retry);
|
||||
}
|
||||
|
||||
// Set the DF bit of the socket
|
||||
void ClearSockDfBit(SOCK *s)
|
||||
{
|
||||
#ifdef IP_PMTUDISC_DONT
|
||||
#ifdef IP_MTU_DISCOVER
|
||||
UINT value = IP_PMTUDISC_DONT;
|
||||
if (s == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setsockopt(s->socket, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&value, sizeof(value));
|
||||
#endif // IP_MTU_DISCOVER
|
||||
#endif // IP_PMTUDISC_DONT
|
||||
}
|
||||
|
||||
// Set the header-include option
|
||||
void SetRawSockHeaderIncludeOption(SOCK *s, bool enable)
|
||||
{
|
||||
UINT value = BOOL_TO_INT(enable);
|
||||
if (s == NULL || s->IsRawSocket == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setsockopt(s->socket, IPPROTO_IP, IP_HDRINCL, (char *)&value, sizeof(value));
|
||||
|
||||
s->RawIP_HeaderIncludeFlag = enable;
|
||||
}
|
||||
|
||||
// Create and initialize the UDP socket
|
||||
// If port is specified as 0, system assigns a certain port.
|
||||
SOCK *NewUDP(UINT port)
|
||||
|
@ -313,6 +313,7 @@ struct SOCK
|
||||
UINT Reverse_MyServerPort; // Self port number when using the reverse socket
|
||||
UCHAR Ssl_Init_Async_SendAlert[2]; // Initial state of SSL send_alert
|
||||
bool AcceptOnlyTls; // Accept only TLS (disable SSLv3)
|
||||
bool RawIP_HeaderIncludeFlag;
|
||||
|
||||
#ifdef ENABLE_SSL_LOGGING
|
||||
// SSL Logging (for debug)
|
||||
@ -371,6 +372,7 @@ struct CANCEL
|
||||
void *hEvent; // Pointer to a Win32 event handle
|
||||
#else // OS_WIN32
|
||||
int pipe_read, pipe_write; // Pipe
|
||||
int pipe_special_read2, pipe_special_read3;
|
||||
#endif // OS_WIN32
|
||||
};
|
||||
|
||||
@ -1323,6 +1325,8 @@ SOCK *NewUDP4(UINT port, IP *ip);
|
||||
SOCK *NewUDP6(UINT port, IP *ip);
|
||||
SOCK *NewUDPEx2Rand(bool ipv6, IP *ip, void *rand_seed, UINT rand_seed_size, UINT num_retry);
|
||||
SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR rand_port_id);
|
||||
void ClearSockDfBit(SOCK *s);
|
||||
void SetRawSockHeaderIncludeOption(SOCK *s, bool enable);
|
||||
UINT GetNewAvailableUdpPortRand();
|
||||
UINT NewRandPortByMachineAndExePath(UINT start_port, UINT end_port, UINT additional_int);
|
||||
void DisableUDPChecksum(SOCK *s);
|
||||
|
@ -2874,6 +2874,7 @@ bool ParsePacketIPv4(PKT *p, UCHAR *buf, UINT size)
|
||||
{
|
||||
// Quit analysing since this is fragmented
|
||||
p->TypeL4 = L4_FRAGMENT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -158,13 +158,14 @@ UINT64 Tick64ToTime64(UINT64 tick)
|
||||
}
|
||||
LockList(tk64->AdjustTime);
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0;i < LIST_NUM(tk64->AdjustTime);i++)
|
||||
INT i;
|
||||
for (i = ((INT)LIST_NUM(tk64->AdjustTime) - 1); i >= 0; i--)
|
||||
{
|
||||
ADJUST_TIME *t = LIST_DATA(tk64->AdjustTime, i);
|
||||
if (t->Tick <= tick)
|
||||
{
|
||||
ret = t->Time + (tick - t->Tick);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@
|
||||
#define TICK64_H
|
||||
|
||||
// Maximum number of correction list entries
|
||||
#define MAX_ADJUST_TIME 5000
|
||||
#define MAX_ADJUST_TIME 1024
|
||||
|
||||
// Correction list entry
|
||||
struct ADJUST_TIME
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -559,6 +559,7 @@ HUB_AO_DropArpInPrivacyFilterMode Drop ARP packets if the both source and dest
|
||||
HUB_AO_SuppressClientUpdateNotification Suppress the update notification screen on the VPN Client.
|
||||
HUB_AO_FloodingSendQueueBufferQuota Specify the quota limitation value (in bytes) of the sending queue buffer size which the flooding operation on the Virtual Hub can consume. The quota value is applied on the total length of sending queues of all active VPN sessions. Specify '0' to disable the quota. This option is effective to solve the out-of-memory problem on the network where there are many flooding packets.
|
||||
HUB_AO_AssignVLanIdByRadiusAttribute Enable the VLAN ID dynamic assignment function. Each VPN session will be assigned its own VLAN ID by the RADIUS attribute value when the user is authenticated by the external RADIUS server unless the user object has a VLAN ID security policy. The RADIUS attribute with the name "Tunnel-Pvt-Group-ID" (ID = 81) will be used as the VLAN ID. The data type must be STRING.
|
||||
HUB_AO_DenyAllRadiusLoginWithNoVlanAssign If you set this option to non-zero value, then all users, which RADIUS server returns no "Tunnel-Pvt-Group-ID" (ID = 81) value, will be denied to connect to the Virtual Hub. (Only if the values of AssignVLanIdByRadiusAttribute is non-zero value.)
|
||||
HUB_AO_SecureNAT_RandomizeAssignIp If you set this option to non-zero value, then the Virtual DHCP Server of the SecureNAT function will choose an unused IP address randomly from the DHCP pool while the default behavior is to choose the first unused IP address.
|
||||
HUB_AO_DetectDormantSessionInterval If you set this option to non-zero value, then the Virtual Hub will treat the VPN sessions, which have transmitted no packets for the last specified intervals (in seconds), as Dormant Sessions. The Virtual Hub will not flood packets, which should be flood, to any Dormant Sessions.
|
||||
HUB_AO_NoPhysicalIPOnPacketLog If you set this option to non-zero value, then the physical IP addresses of VPN clients of either the source VPN session or the destination VPN session will not be recorded on the packet log file.
|
||||
@ -1498,6 +1499,7 @@ SM_SNAT_STATUS SecureNAT 运行状态
|
||||
SM_SNAT_NUM_SESSION %u 个会话
|
||||
SM_SNAT_NUM_CLIENT %u 个客户端
|
||||
SM_SNAT_IS_KERNEL 内核模式 NAT 功能是活跃的
|
||||
SM_SNAT_IS_RAW Raw IP mode NAT 功能是活跃的
|
||||
SM_BRIDGE_TOO_OLD_VER 当前连接的 VPN Server 版本不支持本地网桥功能。\r\n请更新到最新版本。
|
||||
SM_BRIDGE_UNSUPPORTED 当前连接的 VPN Server 运行的操作系统无法使用本地网桥功能。请参阅 VPN Server 在线文档以获得支持本地网桥功能的操作系统列表。
|
||||
SM_BRIDGE_WPCAP_REMOTE 为在此 VPN Server 上使用本地网桥功能,您必须安装 WinPcap 软件。WinPcap 软件当前没有在服务器上安装。\r\n\r\n要进行 WinPcap 软件的安装,您必须在运行 VPN Server 的服务器上启动 SoftEther VPN Server 管理器,然后连接到本机 (您自己计算机的位置),打开本地网桥功能设置窗口。\r\n首先退出此管理会话,然后在此服务器上启动 SoftEther VPN Server 管理器之后,连接到本机并继续设置进程。
|
||||
|
@ -553,6 +553,7 @@ HUB_AO_DropArpInPrivacyFilterMode Drop ARP packets if the both source and dest
|
||||
HUB_AO_SuppressClientUpdateNotification Suppress the update notification screen on the VPN Client.
|
||||
HUB_AO_FloodingSendQueueBufferQuota Specify the quota limitation value (in bytes) of the sending queue buffer size which the flooding operation on the Virtual Hub can consume. The quota value is applied on the total length of sending queues of all active VPN sessions. Specify '0' to disable the quota. This option is effective to solve the out-of-memory problem on the network where there are many flooding packets.
|
||||
HUB_AO_AssignVLanIdByRadiusAttribute Enable the VLAN ID dynamic assignment function. Each VPN session will be assigned its own VLAN ID by the RADIUS attribute value when the user is authenticated by the external RADIUS server unless the user object has a VLAN ID security policy. The RADIUS attribute with the name "Tunnel-Pvt-Group-ID" (ID = 81) will be used as the VLAN ID. The data type must be STRING.
|
||||
HUB_AO_DenyAllRadiusLoginWithNoVlanAssign If you set this option to non-zero value, then all users, which RADIUS server returns no "Tunnel-Pvt-Group-ID" (ID = 81) value, will be denied to connect to the Virtual Hub. (Only if the values of AssignVLanIdByRadiusAttribute is non-zero value.)
|
||||
HUB_AO_SecureNAT_RandomizeAssignIp If you set this option to non-zero value, then the Virtual DHCP Server of the SecureNAT function will choose an unused IP address randomly from the DHCP pool while the default behavior is to choose the first unused IP address.
|
||||
HUB_AO_DetectDormantSessionInterval If you set this option to non-zero value, then the Virtual Hub will treat the VPN sessions, which have transmitted no packets for the last specified intervals (in seconds), as Dormant Sessions. The Virtual Hub will not flood packets, which should be flood, to any Dormant Sessions.
|
||||
HUB_AO_NoPhysicalIPOnPacketLog If you set this option to non-zero value, then the physical IP addresses of VPN clients of either the source VPN session or the destination VPN session will not be recorded on the packet log file.
|
||||
@ -1488,6 +1489,7 @@ SM_SNAT_STATUS SecureNAT Operating Status
|
||||
SM_SNAT_NUM_SESSION %u Session
|
||||
SM_SNAT_NUM_CLIENT %u Client
|
||||
SM_SNAT_IS_KERNEL Kernel-mode NAT is Active
|
||||
SM_SNAT_IS_RAW Raw IP mode NAT is Active
|
||||
SM_BRIDGE_TOO_OLD_VER The Local Bridge function is not supported by the version of the VPN Server that is currently connected. \r\nTry update to a new version.
|
||||
SM_BRIDGE_UNSUPPORTED Unable to use the Local Bridge function with the operating system that this VPN Server is operating on. For the list of operating system that the Local Bridge function can be used on, refer to the online documentation of the VPN Server.
|
||||
SM_BRIDGE_WPCAP_REMOTE In order to use the Local Bridge function on this VPN Server, you must install the WinPcap software. The software WinPcap is currently not installed on the server computer. \r\n\r\nTo continue the installation of the WinPcap software, you must start SoftEther VPN Server Manager on the server computer that is running VPN Server and then while connected to localhost (location of your own computer), have the Local Bridge Function Setting window displayed. \r\nTo continue, first exit this management session, and then, after starting SoftEther VPN Server Manager on the server computer, connect to localhost and continue the setting process.
|
||||
|
@ -574,6 +574,7 @@ HUB_AO_DropArpInPrivacyFilterMode 送信元および宛先の両方のセッ
|
||||
HUB_AO_SuppressClientUpdateNotification VPN Client のアップデート通知画面の表示を抑制します。
|
||||
HUB_AO_FloodingSendQueueBufferQuota パケットの仮想 HUB 内におけるフラッディング動作時において消費することを許容する送信キューのバッファサイズの制限値 (バイト数) を指定します。クオータは、すべての接続中の VPN セッションの送信キューの合計長さに対してグローバルに適用されます。0 を指定すると無制限になります。このオプションは、フラッディングパケットが多発するネットワークにおいてメモリ消費量が増大する問題を解決するために利用できます。
|
||||
HUB_AO_AssignVLanIdByRadiusAttribute VLAN ID の動的割り当て機能を有効にします。VPN 接続するユーザーオブジェクトのセキュリティポリシーに VLAN ID が指定されていない場合は、各 VPN セッションはユーザー認証を行った RADIUS サーバーから返却される RADIUS 属性の値に基づき VLAN が割当てられます。RADIUS 属性のうち、 "Tunnel-Pvt-Group-ID" (ID = 81) の値が使用されます。データ型は文字列である必要があります。
|
||||
HUB_AO_DenyAllRadiusLoginWithNoVlanAssign この項目が 1 (有効) の場合は、RADIUS サーバーが "Tunnel-Pvt-Group-ID" (ID = 81) の値を返却しなかった場合は VPN 接続が拒否されます。(AssignVLanIdByRadiusAttribute の値が 1 の場合に限ります。)
|
||||
HUB_AO_SecureNAT_RandomizeAssignIp この項目が 1 (有効) の場合は、SecureNAT 機能における仮想 DHCP サーバーは、DHCP クライアントに対して割当てる IP アドレスを指定された IP アドレスプール内の未使用アドレスからランダムに選択するようになります。なお、既定の動作は、未使用アドレスのうち最初のアドレスを割当てるようになっています。
|
||||
HUB_AO_DetectDormantSessionInterval この項目が 0 以外の場合は、指定された秒数無通信であった VPN セッションをドーマント状態 (休止状態) として識別します。ドーマント状態の VPN セッションに対しては、仮想 HUB 内でフラッディングされるべきパケットがフラッディングされなくなります。
|
||||
HUB_AO_NoPhysicalIPOnPacketLog この項目が 0 (有効) の場合は、パケットログに送信元および宛先 VPN セッションの物理的な接続元 VPN クライアントの IP アドレスが記録されないようになります。
|
||||
@ -1492,6 +1493,7 @@ SM_SNAT_STATUS SecureNAT の動作状況
|
||||
SM_SNAT_NUM_SESSION %u セッション
|
||||
SM_SNAT_NUM_CLIENT %u クライアント
|
||||
SM_SNAT_IS_KERNEL カーネルモード NAT で動作中
|
||||
SM_SNAT_IS_RAW Raw IP モード NAT で動作中
|
||||
SM_BRIDGE_TOO_OLD_VER 現在接続している VPN Server のバージョンでは、ローカルブリッジ機能はサポートされていません。\r\n新しいバージョンにアップデートしてみてください。
|
||||
SM_BRIDGE_UNSUPPORTED この VPN Server が動作しているオペレーティングシステム上では、ローカルブリッジ機能を使用することはできません。ローカルブリッジ機能が使用できるオペレーティングシステムの一覧については、VPN Server のオンラインドキュメントを参照してください。
|
||||
SM_BRIDGE_WPCAP_REMOTE この VPN Server 上でローカルブリッジ機能を使用するためには、WinPcap ソフトウェアをインストールする必要があります。現在、サーバー コンピュータ上には WinPcap ソフトウェアがインストールされていません。\r\n\r\nWinPcap ソフトウェアのインストールを続行するためには、VPN Server が動作しているサーバー コンピュータ上で SoftEther VPN サーバー管理マネージャを起動し、localhost (自分自身) に対して接続した状態で、ローカルブリッジ機能設定画面を表示する必要があります。\r\n続行するには、一旦この管理セッションを終了し、サーバー コンピュータ上で SoftEther VPN サーバー管理マネージャを起動してから、localhost に対して接続して、設定を続行してください。
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,7 +4,7 @@
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 7.00.0500 */
|
||||
/* at Tue Sep 15 14:39:53 2015
|
||||
/* at Tue Oct 06 14:56:43 2015
|
||||
*/
|
||||
/* Compiler settings for .\vpnweb.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 7.00.0500 */
|
||||
/* at Tue Sep 15 14:39:53 2015
|
||||
/* at Tue Oct 06 14:56:43 2015
|
||||
*/
|
||||
/* Compiler settings for .\vpnweb.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 7.00.0500 */
|
||||
/* at Tue Sep 15 14:39:53 2015
|
||||
/* at Tue Oct 06 14:56:43 2015
|
||||
*/
|
||||
/* Compiler settings for .\vpnweb.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
|
Loading…
Reference in New Issue
Block a user