From f2fee4d32c1898cfe0e315f50c3f29a6ac3af3fd Mon Sep 17 00:00:00 2001 From: Evengard Date: Tue, 12 May 2020 01:06:59 +0300 Subject: [PATCH] Preliminary implementation of IPv6CP and IPv6 for PPP (untested) --- src/Cedar/BridgeUnix.c | 158 +++---- src/Cedar/CedarType.h | 1 + src/Cedar/IPC.c | 243 ++++++---- src/Cedar/IPC.h | 27 +- src/Cedar/Proto_OpenVPN.c | 177 ++++---- src/Cedar/Proto_PPP.c | 289 +++++++++--- src/Cedar/Proto_PPP.h | 15 +- src/Cedar/Virtual.c | 915 ++++++++++++++++++++------------------ src/Mayaqua/Network.c | 1 + 9 files changed, 1087 insertions(+), 739 deletions(-) diff --git a/src/Cedar/BridgeUnix.c b/src/Cedar/BridgeUnix.c index 95410787..5fa21762 100644 --- a/src/Cedar/BridgeUnix.c +++ b/src/Cedar/BridgeUnix.c @@ -232,12 +232,12 @@ TOKEN_LIST *GetEthListSolaris() lifc.lifc_family = AF_INET; lifc.lifc_flags = 0; lifc.lifc_len = bufsize; - lifc.lifc_buf = (char*) buf; + lifc.lifc_buf = (char *) buf; if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) >= 0) { for (i = 0; iNumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { char *name = LIST_DATA(o, i); t->Token[i] = name; @@ -287,7 +287,7 @@ TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip) if (s != INVALID_SOCKET) { n = 0; - for (i = 0;;i++) + for (i = 0;; i++) { Zero(&ifr, sizeof(ifr)); ifr.ifr_ifindex = i; @@ -332,7 +332,7 @@ TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip) t->NumTokens = LIST_NUM(o) + (enum_rawip ? 1 : 0); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { char *name = LIST_DATA(o, i); t->Token[i] = name; @@ -372,9 +372,9 @@ TOKEN_LIST *GetEthListPcap() if(p != NULL) { int datalink = pcap_datalink(p); - // Debug("type:%s\n",pcap_datalink_val_to_name(datalink)); + // Debug("type:%s\n",pcap_datalink_val_to_name(datalink)); pcap_close(p); - if(datalink == DLT_EN10MB){ + if(datalink == DLT_EN10MB) { // Enumerate only Ethernet type device Add(o, CopyStr(dev->name)); } @@ -388,7 +388,7 @@ TOKEN_LIST *GetEthListPcap() t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { t->Token[i] = LIST_DATA(o, i); } @@ -415,7 +415,7 @@ TOKEN_LIST *GetEthListBpf() struct ifaddrs *ifadr = ifadrs; while(ifadr) { - sockadr = (struct sockaddr_dl*)ifadr->ifa_addr; + sockadr = (struct sockaddr_dl *)ifadr->ifa_addr; if(sockadr->sdl_family == AF_LINK && sockadr->sdl_type == IFT_ETHER) { // Is this Ethernet device? @@ -434,7 +434,7 @@ TOKEN_LIST *GetEthListBpf() t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { t->Token[i] = LIST_DATA(o, i); } @@ -1070,7 +1070,7 @@ bool ParseUnixEthDeviceName(char *dst_devname, UINT dst_devname_size, char *src_ #if defined(BRIDGE_BPF) || defined(BRIDGE_PCAP) // Initialize captured packet data structure -struct CAPTUREBLOCK *NewCaptureBlock(UCHAR *data, UINT size){ +struct CAPTUREBLOCK *NewCaptureBlock(UCHAR *data, UINT size) { struct CAPTUREBLOCK *block = Malloc(sizeof(struct CAPTUREBLOCK)); block->Buf = data; block->Size = size; @@ -1078,7 +1078,7 @@ struct CAPTUREBLOCK *NewCaptureBlock(UCHAR *data, UINT size){ } // Free captured packet data structure -void FreeCaptureBlock(struct CAPTUREBLOCK *block){ +void FreeCaptureBlock(struct CAPTUREBLOCK *block) { Free(block); } #endif // BRIDGE_BPF || BRIDGE_PCAP @@ -1087,7 +1087,7 @@ void FreeCaptureBlock(struct CAPTUREBLOCK *block){ // Callback function to receive arriving packet (Pcap) void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) { - ETH *e = (ETH*) user; + ETH *e = (ETH *) user; struct CAPTUREBLOCK *block; UCHAR *data; @@ -1096,7 +1096,7 @@ void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) block = NewCaptureBlock(data, h->caplen); LockQueue(e->Queue); // Discard arriving packet when queue filled - if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ + if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE) { InsertQueue(e->Queue, block); e->QueueSize += h->caplen; } @@ -1108,7 +1108,7 @@ void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) // Relay thread for captured packet (Pcap) void PcapThread(THREAD *thread, void *param) { - ETH *e = (ETH*)param; + ETH *e = (ETH *)param; pcap_t *p = e->Pcap; int ret; @@ -1116,8 +1116,8 @@ void PcapThread(THREAD *thread, void *param) NoticeThreadInit(thread); // Return -1:Error -2:Terminated externally - ret = pcap_loop(p, -1, PcapHandler, (u_char*) e); - if(ret == -1){ + ret = pcap_loop(p, -1, PcapHandler, (u_char *) e); + if(ret == -1) { e->Socket = INVALID_SOCKET; pcap_perror(p, "capture"); } @@ -1181,7 +1181,7 @@ ETH *OpenEthPcap(char *name, bool local, bool tapmode, char *tapaddr) // Relay thread for captured packet (BPF) void BpfThread(THREAD *thread, void *param) { - ETH *e = (ETH*)param; + ETH *e = (ETH *)param; int fd = e->Socket; int len; int rest; // Rest size in buffer @@ -1196,14 +1196,14 @@ void BpfThread(THREAD *thread, void *param) // Notify initialize completed NoticeThreadInit(thread); - while(1){ + while(1) { // Determining to exit loop - if(e->Socket == INVALID_SOCKET){ + if(e->Socket == INVALID_SOCKET) { break; } rest = read(fd, buf, e->BufSize); - if(rest < 0 && errno != EAGAIN){ + if(rest < 0 && errno != EAGAIN) { // Error close(fd); e->Socket = INVALID_SOCKET; @@ -1213,12 +1213,12 @@ void BpfThread(THREAD *thread, void *param) } next = buf; LockQueue(e->Queue); - while(rest>0){ + while(rest>0) { // Cut out a packet - hdr = (struct bpf_hdr*)next; + hdr = (struct bpf_hdr *)next; // Discard arriving packet when queue filled - if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ + if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE) { data = Malloc(hdr->bh_caplen); Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen); block = NewCaptureBlock(data, hdr->bh_caplen); @@ -1253,31 +1253,31 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr) struct timeval to; // Find unused bpf device and open it - do{ + do { Format(devname, sizeof(devname), "/dev/bpf%d", n++); fd = open (devname, O_RDWR); - if(fd<0){ + if(fd<0) { perror("open"); } - }while(fd < 0 && errno == EBUSY); + } while(fd < 0 && errno == EBUSY); // No free bpf device was found - if(fd < 0){ + if(fd < 0) { Debug("BPF: No minor number are free.\n"); return NULL; } // Enlarge buffer size n = 524288; // Somehow(In libpcap, this size is 32768) - while(true){ + while(true) { // Specify buffer size ioctl(fd, BIOCSBLEN, &n); // Bind to the network device StrCpy(ifr.ifr_name, IFNAMSIZ, name); ret = ioctl(fd, BIOCSETIF, &ifr); - if(ret < 0){ - if(ret == ENOBUFS && n>1500){ + if(ret < 0) { + if(ret == ENOBUFS && n>1500) { // Inappropriate buffer size // Retry with half buffer size // If buffer size is under 1500 bytes, something goes wrong @@ -1287,15 +1287,15 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr) Debug("bpf: binding network failed.\n"); close(fd); return NULL; - }else{ + } else { break; } } bufsize = n; // Set to promiscuous mode - if(local == false){ - if (ioctl(fd, BIOCPROMISC, NULL) < 0){ + if(local == false) { + if (ioctl(fd, BIOCPROMISC, NULL) < 0) { printf("bpf: promisc mode failed.\n"); close(fd); return NULL; @@ -1305,7 +1305,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr) // Set to immediate mode (Return immediately when packet arrives) n = 1; - if (ioctl(fd, BIOCIMMEDIATE, &n) < 0){ + if (ioctl(fd, BIOCIMMEDIATE, &n) < 0) { Debug("BPF: non-block mode failed.\n"); close(fd); return NULL; @@ -1313,7 +1313,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr) // Set receiving self sending packet n = 1; - if (ioctl(fd, BIOCGSEESENT, &n) < 0){ + if (ioctl(fd, BIOCGSEESENT, &n) < 0) { Debug("BPF: see sent mode failed.\n"); close(fd); return NULL; @@ -1321,7 +1321,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr) // Header complete mode (Generate whole header of sending packet) n = 1; - if (ioctl(fd, BIOCSHDRCMPLT, &n) < 0){ + if (ioctl(fd, BIOCSHDRCMPLT, &n) < 0) { Debug("BPF: Header complete mode failed.\n"); close(fd); return NULL; @@ -1330,7 +1330,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr) // Set timeout delay to 1 second to.tv_sec = 1; to.tv_usec = 0; - if (ioctl(fd, BIOCSRTIMEOUT, &to) < 0){ + if (ioctl(fd, BIOCSRTIMEOUT, &to) < 0) { Debug("BPF: Read timeout setting failed.\n"); close(fd); return NULL; @@ -1401,16 +1401,16 @@ ETH *OpenEthBSD(char *name, bool local, bool tapmode, char *tapaddr) return e; #else // NO_VLAN - return NULL: +return NULL: #endif // NO_VLAN } #if defined(BRIDGE_BPF) - return OpenEthBpf(name, local, tapmode, tapaddr); + return OpenEthBpf(name, local, tapmode, tapaddr); #elif defined(BRIDGE_PCAP) - return OpenEthPcap(name, local, tapmode, tapaddr); + return OpenEthPcap(name, local, tapmode, tapaddr); #else - return NULL; + return NULL; #endif } #endif // UNIX_BSD @@ -1471,7 +1471,7 @@ void CloseEth(ETH *e) WaitThread(e->CaptureThread, INFINITE); ReleaseThread(e->CaptureThread); pcap_close(e->Pcap); - while (block = GetNext(e->Queue)){ + while (block = GetNext(e->Queue)) { Free(block->Buf); FreeCaptureBlock(block); } @@ -1488,7 +1488,7 @@ void CloseEth(ETH *e) WaitThread(e->CaptureThread, INFINITE); ReleaseThread(e->CaptureThread); e->Socket = fd; // restore to close after - while (block = GetNext(e->Queue)){ + while (block = GetNext(e->Queue)) { Free(block->Buf); FreeCaptureBlock(block); } @@ -1660,8 +1660,8 @@ UINT EthGetPacketLinux(ETH *e, void **data) USHORT vlan_id = 0; if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct my_tpacket_auxdata)) || - cmsg->cmsg_level != SOL_PACKET || - cmsg->cmsg_type != MY_PACKET_AUXDATA) + cmsg->cmsg_level != SOL_PACKET || + cmsg->cmsg_type != MY_PACKET_AUXDATA) { continue; } @@ -1772,14 +1772,14 @@ UINT EthGetPacketPcap(ETH *e, void **data) LockQueue(e->Queue); block = GetNext(e->Queue); - if(block != NULL){ + if(block != NULL) { e->QueueSize -= block->Size; } UnlockQueue(e->Queue); - if(block == NULL){ + if(block == NULL) { *data = NULL; - if(e->Socket == INVALID_SOCKET){ + if(e->Socket == INVALID_SOCKET) { return INFINITE; } return 0; @@ -1802,14 +1802,14 @@ UINT EthGetPacketBpf(ETH *e, void **data) LockQueue(e->Queue); block = GetNext(e->Queue); - if(block != NULL){ + if(block != NULL) { e->QueueSize -= block->Size; } UnlockQueue(e->Queue); - if(block == NULL){ + if(block == NULL) { *data = NULL; - if(e->Socket == INVALID_SOCKET){ + if(e->Socket == INVALID_SOCKET) { return INFINITE; } return 0; @@ -1826,11 +1826,11 @@ UINT EthGetPacketBpf(ETH *e, void **data) { struct bpf_hdr *hdr; - if(e->Rest<=0){ + if(e->Rest<=0) { e->Rest = read(e->Socket, e->Buffer, e->BufSize); - if(e->Rest < 0){ + if(e->Rest < 0) { *data = NULL; - if(errno != EAGAIN){ + if(errno != EAGAIN) { // Error return INFINITE; } @@ -1840,7 +1840,7 @@ UINT EthGetPacketBpf(ETH *e, void **data) e->Next = e->Buffer; } // Cut out a packet - hdr = (struct bpf_hdr*)e->Next; + hdr = (struct bpf_hdr *)e->Next; *data = Malloc(hdr->bh_caplen); Copy(*data, e->Next+(hdr->bh_hdrlen), hdr->bh_caplen); @@ -1864,7 +1864,7 @@ void EthPutPackets(ETH *e, UINT num, void **datas, UINT *sizes) return; } - for (i = 0;i < num;i++) + for (i = 0; i < num; i++) { EthPutPacket(e, datas[i], sizes[i]); } @@ -1910,7 +1910,7 @@ void EthPutPacket(ETH *e, void *data, UINT size) // Send to device #ifdef BRIDGE_PCAP ret = pcap_inject(e->Pcap, data, size); - if( ret == -1 ){ + if( ret == -1 ) { #ifdef _DEBUG pcap_perror(e->Pcap, "inject"); #endif // _DEBUG @@ -2162,7 +2162,7 @@ LABEL_RETRY: 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))) + (IsIPMyHost(&original_dest_ip) && IsLocalHostIP(&original_dest_ip) == false && IsHostIPAddress4(&original_dest_ip))) { if (IsZeroIP(&e->MyPhysicalIPForce) && CmpIpAddr(&e->MyPhysicalIP, &original_dest_ip) != 0) { @@ -2183,14 +2183,14 @@ LABEL_RETRY: 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)); - }*/ + /* + 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; } @@ -2226,7 +2226,7 @@ LABEL_RETRY: 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); + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + orig_ipv4_header_size); if (inner_icmp->Type == ICMP_TYPE_ECHO_REQUEST) { @@ -2328,8 +2328,8 @@ bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p) 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) + Endian16(arp->ProtocolType) == MAC_PROTO_IPV4 && + arp->HardwareSize == 6 && arp->ProtocolType == 4) { if (IPToUINT(&e->MyIP) == arp->TargetIP) { @@ -2460,8 +2460,8 @@ bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p) 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); + ret.Opcode == DHCP_OFFER ? "DHCP_OFFER" : "DHCP_ACK", + client_mac, client_ip); } // Build a DHCP option @@ -2538,7 +2538,7 @@ bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p) 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); + dhcp, dhcp_packet_size, 0); if (udp->Checksum == 0) { udp->Checksum = 0xffff; @@ -2589,14 +2589,14 @@ void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size) if (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0) { - if (IsValidUnicastMacAddress(p->MacAddressSrc)) + if (IsMacUnicast(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)) + if (IsZero(e->RawIpYourMacAddr, 6) || IsMacUnicast(p->MacAddressSrc) == false || + (p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0)) { Free(data); FreePacket(p); @@ -2641,7 +2641,7 @@ void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size) } if (s != NULL && p->L3.IPv4Header->DstIP != 0xffffffff && p->BroadcastPacket == false && - p->L3.IPv4Header->SrcIP == IPToUINT(&e->YourIP)) + p->L3.IPv4Header->SrcIP == IPToUINT(&e->YourIP)) { UCHAR *send_data = p->IPv4PayloadData; UCHAR *head = p->PacketData; @@ -2661,8 +2661,8 @@ void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size) { 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); + p->L3.IPv4Header->DstIP, IP_PROTO_TCP, + p->L4.TCPHeader, p->IPv4PayloadSize, 0); } UINTToIP(&dest, p->L3.IPv4Header->DstIP); diff --git a/src/Cedar/CedarType.h b/src/Cedar/CedarType.h index 61f8c5b8..620d0291 100644 --- a/src/Cedar/CedarType.h +++ b/src/Cedar/CedarType.h @@ -583,6 +583,7 @@ typedef struct IPC_DHCP_RELEASE_QUEUE IPC_DHCP_RELEASE_QUEUE; typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO; typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA; typedef struct IPC_IPV6_ROUTER_ADVERTISEMENT IPC_IPV6_ROUTER_ADVERTISEMENT; +typedef struct IPC_DHCPV4_AWAIT IPC_DHCPV4_AWAIT; // ============================================================== diff --git a/src/Cedar/IPC.c b/src/Cedar/IPC.c index ed80f64f..899238b5 100644 --- a/src/Cedar/IPC.c +++ b/src/Cedar/IPC.c @@ -147,7 +147,7 @@ void IPCAsyncThreadProc(THREAD *thread, void *param) // Save the options list Copy(&a->L3ClientAddressOption, &cao, sizeof(DHCP_OPTION_LIST)); - a->L3DhcpRenewInterval = t * 1000; + a->L3DhcpRenewInterval = (UINT64)t * (UINT64)1000; // Set the obtained IP address parameters to the IPC virtual host UINTToIP(&ip, cao.ClientAddress); @@ -488,6 +488,10 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char // Create an IPv4 reception queue ipc->IPv4ReceivedQueue = NewQueue(); + ipc->IPv4State = IPC_PROTO_STATUS_CLOSED; + + ipc->DHCPv4Awaiter.IsAwaiting = false; + ipc->DHCPv4Awaiter.DhcpData = NULL; IPCIPv6Init(ipc); @@ -530,6 +534,10 @@ IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address) // Create an IPv4 reception queue ipc->IPv4ReceivedQueue = NewQueue(); + ipc->IPv4State = IPC_PROTO_STATUS_CLOSED; + + ipc->DHCPv4Awaiter.IsAwaiting = false; + ipc->DHCPv4Awaiter.DhcpData = NULL; ipc->FlushList = NewTubeFlushList(); @@ -614,6 +622,8 @@ void FreeIPC(IPC *ipc) ReleaseSharedBuffer(ipc->IpcSessionSharedBuffer); + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + IPCIPv6Free(ipc); Free(ipc); @@ -871,6 +881,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION // Time-out inspection if ((expecting_code != 0) && (now >= giveup_time)) { + ipc->DHCPv4Awaiter.IsAwaiting = false; + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + ipc->DHCPv4Awaiter.DhcpData = NULL; return NULL; } @@ -880,6 +893,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION dhcp_packet = IPCBuildDhcpRequest(ipc, dest_ip, tran_id, opt); if (dhcp_packet == NULL) { + ipc->DHCPv4Awaiter.IsAwaiting = false; + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + ipc->DHCPv4Awaiter.DhcpData = NULL; return NULL; } @@ -889,6 +905,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION if (expecting_code == 0) { + ipc->DHCPv4Awaiter.IsAwaiting = false; + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + ipc->DHCPv4Awaiter.DhcpData = NULL; return NULL; } @@ -898,48 +917,28 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION } // Happy processing + ipc->DHCPv4Awaiter.IsAwaiting = true; + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + ipc->DHCPv4Awaiter.DhcpData = NULL; + ipc->DHCPv4Awaiter.TransCode = tran_id; + ipc->DHCPv4Awaiter.OpCode = expecting_code; IPCProcessL3Events(ipc); - while (true) + if (ipc->DHCPv4Awaiter.DhcpData != NULL) { - // Receive a packet - BLOCK *b = IPCRecvIPv4(ipc); - PKT *pkt; - DHCPV4_DATA *dhcp; - - if (b == NULL) - { - break; - } - - // Parse the packet - pkt = ParsePacketIPv4WithDummyMacHeader(b->Buf, b->Size); - - dhcp = ParseDHCPv4Data(pkt); - - if (dhcp != NULL) - { - if (Endian32(dhcp->Header->TransactionId) == tran_id && dhcp->OpCode == expecting_code) - { - // Expected operation code and transaction ID are returned - FreePacketWithData(pkt); - FreeBlock(b); - - return dhcp; - } - - FreeDHCPv4Data(dhcp); - } - - FreePacketWithData(pkt); - - FreeBlock(b); + DHCPV4_DATA *dhcp = ipc->DHCPv4Awaiter.DhcpData; + ipc->DHCPv4Awaiter.IsAwaiting = false; + ipc->DHCPv4Awaiter.DhcpData = NULL; + return dhcp; } if (IsTubeConnected(ipc->Sock->RecvTube) == false || IsTubeConnected(ipc->Sock->SendTube) == false || (discon_poll_tube != NULL && IsTubeConnected(discon_poll_tube) == false)) { // Session is disconnected + ipc->DHCPv4Awaiter.IsAwaiting = false; + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + ipc->DHCPv4Awaiter.DhcpData = NULL; return NULL; } @@ -947,6 +946,9 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION WaitForTubes(tubes, num_tubes, GetNextIntervalForInterrupt(ipc->Interrupt)); } + ipc->DHCPv4Awaiter.IsAwaiting = false; + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + ipc->DHCPv4Awaiter.DhcpData = NULL; return NULL; } @@ -1301,6 +1303,16 @@ void IPCProcessL3Events(IPC *ipc) { IPCProcessL3EventsEx(ipc, 0); } +void IPCProcessL3EventsIPv4Only(IPC *ipc) +{ + UINT previousStatus4 = IPC_PROTO_GET_STATUS(ipc, IPv4State); + UINT previousStatus6 = IPC_PROTO_GET_STATUS(ipc, IPv6State); + IPC_PROTO_SET_STATUS(ipc, IPv4State, IPC_PROTO_STATUS_OPENED); + IPC_PROTO_SET_STATUS(ipc, IPv6State, IPC_PROTO_STATUS_CLOSED); + IPCProcessL3Events(ipc); + IPC_PROTO_SET_STATUS(ipc, IPv4State, previousStatus4); + IPC_PROTO_SET_STATUS(ipc, IPv6State, previousStatus6); +} void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) { // Validate arguments @@ -1340,6 +1352,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) // If the source MAC address is itselves or invalid address, ignore the packet if (Cmp(src_mac, ipc->MacAddress, 6) != 0 && !IsMacUnicast(src_mac)) { + Debug("Received packed for L3 parsing\n"); if (protocol == MAC_PROTO_ARPV4) { // ARP receiving process @@ -1347,6 +1360,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) } else if (protocol == MAC_PROTO_IPV4) { + Debug("MAC_PROTO_IPV4\n"); // IPv4 receiving process if (b->Size >= (14 + 20)) { @@ -1390,10 +1404,43 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) if (ok) { + // Parse DHCP packets + bool packetConsumed = false; + if (ipc->DHCPv4Awaiter.IsAwaiting) + { + PKT *pkt; + DHCPV4_DATA *dhcp; + + Debug("Parsing for DHCP awaiter\n"); + pkt = ParsePacketIPv4WithDummyMacHeader(data, size); + dhcp = ParseDHCPv4Data(pkt); + + if (dhcp != NULL) + { + if (Endian32(dhcp->Header->TransactionId) == ipc->DHCPv4Awaiter.TransCode && + dhcp->OpCode == ipc->DHCPv4Awaiter.OpCode) + { + FreeDHCPv4Data(ipc->DHCPv4Awaiter.DhcpData); + ipc->DHCPv4Awaiter.DhcpData = dhcp; + packetConsumed = true; + } + else + { + FreeDHCPv4Data(dhcp); + } + } + + FreePacket(pkt); + } + IPCAssociateOnArpTable(ipc, &ip_src, src_mac); - // Place in the reception queue - InsertQueue(ipc->IPv4ReceivedQueue, NewBlock(data, size, 0)); + if (ipc->IPv4State == IPC_PROTO_STATUS_OPENED && !packetConsumed) + { + // Place in the reception queue + InsertQueue(ipc->IPv4ReceivedQueue, NewBlock(data, size, 0)); + } + } else { @@ -1409,8 +1456,9 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) { IP ip_src, ip_dst; bool ndtProcessed = false; + UINT size = p->L3.IPv6Header->PayloadLength + sizeof(IPV6_HEADER); - UCHAR *data = Clone(p->L3.IPv6Header, p->L3.IPv6Header->PayloadLength + sizeof(IPV6_HEADER)); + UCHAR *data = Clone(p->L3.IPv6Header, size); IPv6AddrToIP(&ip_src, &p->IPv6HeaderPacketInfo.IPv6Header->SrcAddress); IPv6AddrToIP(&ip_dst, &p->IPv6HeaderPacketInfo.IPv6Header->DestAddress); @@ -1426,7 +1474,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) // We save the router advertisement data for later use IPCIPv6AddRouterPrefix(ipc, &p->ICMPv6HeaderPacketInfo.OptionList, src_mac, &ip_src); IPCIPv6AssociateOnNDTEx(ipc, &ip_src, src_mac, true); - IPCIPv6AssociateOnNDTEx(ipc, &ip_src, &p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer, true); + IPCIPv6AssociateOnNDTEx(ipc, &ip_src, &p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, true); break; case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT: // We save the neighbor advertisements into NDT @@ -1445,7 +1493,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) } /// TODO: should we or not filter Neighbor Advertisements and/or Neighbor Solicitations? - InsertQueue(ipc->IPv6ReceivedQueue, data); + if (ipc->IPv6State == IPC_PROTO_STATUS_OPENED) + { + InsertQueue(ipc->IPv6ReceivedQueue, NewBlock(data, size, 0)); + } FreePacket(p); } @@ -1948,6 +1999,8 @@ void IPCIPv6Init(IPC *ipc) ipc->IPv6ClientEUI = 0; ipc->IPv6ServerEUI = 0; + + ipc->IPv6State = IPC_PROTO_STATUS_CLOSED; } void IPCIPv6Free(IPC *ipc) { @@ -2113,14 +2166,31 @@ void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now) } } -bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, IP *addr) +// Scan the hub IP Table to try to find the EUI-based link-local address +bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui) { HUB t, *h; - IP_TABLE_ENTRY t, *e; + IP_TABLE_ENTRY i, *e; t.Name = ipc->HubName; + + // Construct link local from eui + ZeroIP6(&i.Ip); + i.Ip.ipv6_addr[0] = 0xFE; + i.Ip.ipv6_addr[1] = 0x80; + WRITE_UINT64(&i.Ip.ipv6_addr[8], &eui); + h = Search(ipc->Cedar->HubList, &t); - //h->IpTable + if (h != NULL) + { + e = Search(h->IpTable, &i); + if (e != NULL) + { + return true; + } + } + + return false; } // RA @@ -2175,45 +2245,66 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER } // Send router solicitation and then eventually populate the info from Router Advertisements -void IPCIPv6SendRouterSolicitation(IPC *ipc) +UINT64 IPCIPv6GetServerEui(IPC *ipc) { - IP senderIP; - IP destIP; - UCHAR destMacAddress[6]; - IPV6_ADDR linkLocal; - BUF *packet; - Zero(&linkLocal, sizeof(IPV6_ADDR)); - - // Generate link local from client's EUI - linkLocal.Value[0] = 0xFE; - linkLocal.Value[1] = 0x80; - WRITE_UINT64(&linkLocal.Value[8], &ipc->IPv6ClientEUI); - - GetAllRouterMulticastAddress6(&destIP); - - // Generate the MAC address from the multicast address - destMacAddress[0] = 0x33; - destMacAddress[1] = 0x33; - WRITE_UINT(&destMacAddress[2], &destIP.ipv6_addr[12]); - - packet = BuildICMPv6RouterSoliciation(senderIP.ipv6_addr, destIP.ipv6_addr, ipc->MacAddress, 0); - - while (LIST_NUM(ipc->IPv6RouterAdvs) == 0) + // It is already configured, nothing to do here + if (ipc->IPv6ServerEUI != 0) { - UINT64 giveup_time = Tick64() + (UINT64)(IPC_IPV6_RA_MAX_RETRIES * IPC_IPV6_RA_INTERVAL); - UINT64 timeout_retry = Tick() + (UINT64)IPC_IPV6_RA_INTERVAL; - IPCIPv6SendWithDestMacAddr(ipc, packet->Buf, packet->Size, destMacAddress); + return ipc->IPv6ServerEUI; + } - AddInterrupt(ipc->Interrupt, timeout_retry); + // If we don't have a valid client EUI, we can't generate a correct link local + if (ipc->IPv6ClientEUI == 0) + { + return ipc->IPv6ServerEUI; + } - if (Tick64() >= giveup_time) + if (LIST_NUM(ipc->IPv6RouterAdvs) == 0) + { + IP senderIP; + IPV6_ADDR senderV6; + IP destIP; + IPV6_ADDR destV6; + UCHAR destMacAddress[6]; + IPV6_ADDR linkLocal; + BUF *packet; + + Zero(&linkLocal, sizeof(IPV6_ADDR)); + + // Generate link local from client's EUI + linkLocal.Value[0] = 0xFE; + linkLocal.Value[1] = 0x80; + WRITE_UINT64(&linkLocal.Value[8], &ipc->IPv6ClientEUI); + + GetAllRouterMulticastAddress6(&destIP); + + // Generate the MAC address from the multicast address + destMacAddress[0] = 0x33; + destMacAddress[1] = 0x33; + WRITE_UINT(&destMacAddress[2], &destIP.ipv6_addr[12]); + + IPToIPv6Addr(&senderV6, &senderIP); + IPToIPv6Addr(&destV6, &destIP); + + packet = BuildICMPv6RouterSoliciation(&senderV6, &destV6, ipc->MacAddress, 0); + + while (LIST_NUM(ipc->IPv6RouterAdvs) == 0) { - // We failed to receive any router advertisements - break; - } + UINT64 giveup_time = Tick64() + (UINT64)(IPC_IPV6_RA_MAX_RETRIES * IPC_IPV6_RA_INTERVAL); + UINT64 timeout_retry = Tick() + (UINT64)IPC_IPV6_RA_INTERVAL; + IPCIPv6SendWithDestMacAddr(ipc, packet->Buf, packet->Size, destMacAddress); - // The processing should populate the received RAs by itself - IPCProcessL3Events(ipc); + AddInterrupt(ipc->Interrupt, timeout_retry); + + if (Tick64() >= giveup_time) + { + // We failed to receive any router advertisements + break; + } + + // The processing should populate the received RAs by itself + IPCProcessL3Events(ipc); + } } // Populating the IPv6 Server EUI for IPV6CP @@ -2222,6 +2313,8 @@ void IPCIPv6SendRouterSolicitation(IPC *ipc) IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, 0); ipc->IPv6ServerEUI = READ_UINT64(&ra->RouterAddress.ipv6_addr[8]); } + + return ipc->IPv6ServerEUI; } // Data flow diff --git a/src/Cedar/IPC.h b/src/Cedar/IPC.h index 02ad2e72..3160f1d1 100644 --- a/src/Cedar/IPC.h +++ b/src/Cedar/IPC.h @@ -30,6 +30,16 @@ #define IPC_IPV6_RA_INTERVAL (4 * 1000) // as per RTR_SOLICITATION_INTERVAL constant of RFC4861 #define IPC_IPV6_RA_MAX_RETRIES 3 // as per MAX_RTR_SOLICITATIONS constant of RFC4861 +// Protocol status +#define IPC_PROTO_STATUS_CLOSED 0x0 +#define IPC_PROTO_STATUS_CONFIG 0x1 +#define IPC_PROTO_STATUS_CONFIG_WAIT 0x2 +#define IPC_PROTO_STATUS_OPENED 0x10 +#define IPC_PROTO_STATUS_REJECTED 0x100 + +#define IPC_PROTO_SET_STATUS(ipc, proto, value) ((ipc) != NULL ? ((ipc->proto) = (value)) : 0) +#define IPC_PROTO_GET_STATUS(ipc, proto) ((ipc) != NULL ? (ipc->proto) : IPC_PROTO_STATUS_REJECTED) + // ARP table entry struct IPC_ARP { @@ -78,6 +88,15 @@ struct IPC_PARAM UINT Layer; }; +// DHCPv4 response awaiter +struct IPC_DHCPV4_AWAIT +{ + bool IsAwaiting; + DHCPV4_DATA *DhcpData; + UINT TransCode; + UINT OpCode; +}; + // IPC_ASYNC object struct IPC_ASYNC { @@ -117,6 +136,8 @@ struct IPC UCHAR Padding[2]; LIST *ArpTable; // ARP table QUEUE *IPv4ReceivedQueue; // IPv4 reception queue + UINT IPv4State; + IPC_DHCPV4_AWAIT DHCPv4Awaiter; TUBE_FLUSH_LIST *FlushList; // Tube Flush List UCHAR MsChapV2_ServerResponse[20]; // Server response DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table @@ -126,6 +147,7 @@ struct IPC // IPv6 stuff QUEUE *IPv6ReceivedQueue; // IPv6 reception queue + UINT IPv6State; LIST *IPv6NeighborTable; // Neighbor Discovery Table LIST *IPv6RouterAdvs; // Router offered prefixes UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf) @@ -166,6 +188,7 @@ void IPCSendIPv4(IPC *ipc, void *data, UINT size); BLOCK *IPCRecvL2(IPC *ipc); BLOCK *IPCRecvIPv4(IPC *ipc); void IPCProcessInterrupts(IPC *ipc); +void IPCProcessL3EventsIPv4Only(IPC *ipc); void IPCProcessL3Events(IPC *ipc); void IPCProcessL3EventsEx(IPC *ipc, UINT64 now); bool IPCSetIPv4Parameters(IPC *ipc, IP *ip, IP *subnet, IP *gw, DHCP_CLASSLESS_ROUTE_TABLE *rt); @@ -202,11 +225,11 @@ void IPCIPv6AssociateOnNDT(IPC *ipc, IP *ip, UCHAR *mac_address); void IPCIPv6AssociateOnNDTEx(IPC *ipc, IP *ip, UCHAR *mac_address, bool isNeighborAdv); void IPCIPv6FlushNDT(IPC *ipc); void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now); -bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, IP *addr); +bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui); // RA void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip); bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA); -void IPCIPv6SendRouterSolicitation(IPC *ipc); +UINT64 IPCIPv6GetServerEui(IPC *ipc); // Data flow BLOCK *IPCIPv6Recv(IPC *ipc); void IPCIPv6Send(IPC *ipc, void *data, UINT size); diff --git a/src/Cedar/Proto_OpenVPN.c b/src/Cedar/Proto_OpenVPN.c index c6acc5fa..fbce1940 100644 --- a/src/Cedar/Proto_OpenVPN.c +++ b/src/Cedar/Proto_OpenVPN.c @@ -259,13 +259,13 @@ void OvsLog(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, char *na if (c == NULL) { UniFormat(prefix, sizeof(prefix), _UU("LO_PREFIX_SESSION"), - se->Id, &se->ClientIp, se->ClientPort, &se->ServerIp, se->ServerPort); + se->Id, &se->ClientIp, se->ClientPort, &se->ServerIp, se->ServerPort); } else { UniFormat(prefix, sizeof(prefix), _UU("LO_PREFIX_CHANNEL"), - se->Id, &se->ClientIp, se->ClientPort, &se->ServerIp, se->ServerPort, - c->KeyId); + se->Id, &se->ClientIp, se->ClientPort, &se->ServerIp, se->ServerPort, + c->KeyId); } } va_start(args, name); @@ -617,10 +617,10 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol) { // Control packet Debug("OvsProceccRecvPacket(): Received control packet. PacketId: %u, OpCode: %u, KeyId: %u, MySessionId: %I64u\n", - recv_packet->PacketId, recv_packet->OpCode, recv_packet->KeyId, recv_packet->MySessionId); + recv_packet->PacketId, recv_packet->OpCode, recv_packet->KeyId, recv_packet->MySessionId); if (recv_packet->OpCode == OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2 || - recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1) + recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1) { // Connection request packet if (c != NULL && c->Status == OPENVPN_CHANNEL_STATUS_ESTABLISHED) @@ -644,19 +644,19 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol) OvsLog(s, se, c, "LO_NEW_CHANNEL"); } } -/* else if (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1) - { - // Response to soft reset request packet - OPENVPN_PACKET *p; + /* else if (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1) + { + // Response to soft reset request packet + OPENVPN_PACKET *p; - p = OvsNewControlPacket(OPENVPN_P_CONTROL_SOFT_RESET_V1, recv_packet->KeyId, se->ServerSessionId, - 0, NULL, 0, 0, 0, NULL); + p = OvsNewControlPacket(OPENVPN_P_CONTROL_SOFT_RESET_V1, recv_packet->KeyId, se->ServerSessionId, + 0, NULL, 0, 0, 0, NULL); - OvsSendPacketNow(s, se, p); + OvsSendPacketNow(s, se, p); - OvsFreePacket(p); - } -*/ + OvsFreePacket(p); + } + */ if (c != NULL) { // Delete the send packet list by looking the packet ID in the ACK list of arrived packet @@ -668,8 +668,8 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol) InsertIntDistinct(c->AckReplyList, recv_packet->PacketId); if ((recv_packet->PacketId > c->MaxRecvPacketId) - || (recv_packet->OpCode == OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2) - || (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1)) + || (recv_packet->OpCode == OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2) + || (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1)) { c->MaxRecvPacketId = recv_packet->PacketId; @@ -743,12 +743,12 @@ void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UI } o = NewListFast(NULL); - for (i = 0;i < num_acks;i++) + for (i = 0; i < num_acks; i++) { UINT ack = acks[i]; UINT j; - for (j = 0;j < LIST_NUM(c->SendControlPacketList);j++) + for (j = 0; j < LIST_NUM(c->SendControlPacketList); j++) { OPENVPN_CONTROL_PACKET *p = LIST_DATA(c->SendControlPacketList, j); @@ -759,7 +759,7 @@ void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UI } } - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { OPENVPN_CONTROL_PACKET *p = LIST_DATA(o, i); @@ -1119,7 +1119,7 @@ UINT OvsPeekStringFromFifo(FIFO *f, char *str, UINT str_size) StrCpy(str, str_size, ""); - for (i = 0;i < MIN(str_size, FifoSize(f));i++) + for (i = 0; i < MIN(str_size, FifoSize(f)); i++) { char c = *(((char *)FifoPtr(f)) + i); @@ -1267,8 +1267,8 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C WriteBuf(b, c->ClientKey.Random1, sizeof(c->ClientKey.Random1)); WriteBuf(b, c->ServerKey.Random1, sizeof(c->ServerKey.Random1)); Enc_tls1_PRF(b->Buf, b->Size, - c->ClientKey.PreMasterSecret, sizeof(c->ClientKey.PreMasterSecret), - c->MasterSecret, sizeof(c->MasterSecret)); + c->ClientKey.PreMasterSecret, sizeof(c->ClientKey.PreMasterSecret), + c->MasterSecret, sizeof(c->MasterSecret)); FreeBuf(b); // Generate an Expansion Key @@ -1279,7 +1279,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C WriteBufInt64(b, se->ClientSessionId); WriteBufInt64(b, se->ServerSessionId); Enc_tls1_PRF(b->Buf, b->Size, c->MasterSecret, sizeof(c->MasterSecret), - c->ExpansionKey, sizeof(c->ExpansionKey)); + c->ExpansionKey, sizeof(c->ExpansionKey)); FreeBuf(b); // Set up the encryption algorithm @@ -1314,13 +1314,13 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C // Generate the response option string Format(c->ServerKey.OptionString, sizeof(c->ServerKey.OptionString), - "V4,dev-type %s,link-mtu %u,tun-mtu %u,proto %s," - "cipher %s,auth %s,keysize %u,key-method 2,tls-server", - (se->Mode == OPENVPN_MODE_L2 ? "tap" : "tun"), - se->LinkMtu, - se->TunMtu, - c->Proto, - cipher_name, md_name, c->CipherEncrypt->KeySize * 8); + "V4,dev-type %s,link-mtu %u,tun-mtu %u,proto %s," + "cipher %s,auth %s,keysize %u,key-method 2,tls-server", + (se->Mode == OPENVPN_MODE_L2 ? "tap" : "tun"), + se->LinkMtu, + se->TunMtu, + c->Proto, + cipher_name, md_name, c->CipherEncrypt->KeySize * 8); FreeEntryList(o); @@ -1482,13 +1482,13 @@ UINT OvsParseKeyMethod2(OPENVPN_KEY_METHOD_2 *ret, UCHAR *data, UINT size, bool { // String if (OvsReadStringFromBuf(b, ret->OptionString, sizeof(ret->OptionString)) && - OvsReadStringFromBuf(b, ret->Username, sizeof(ret->Username)) && - OvsReadStringFromBuf(b, ret->Password, sizeof(ret->Password))) + OvsReadStringFromBuf(b, ret->Username, sizeof(ret->Username)) && + OvsReadStringFromBuf(b, ret->Password, sizeof(ret->Password))) + { + if (!OvsReadStringFromBuf(b, ret->PeerInfo, sizeof(ret->PeerInfo))) { - if (!OvsReadStringFromBuf(b, ret->PeerInfo, sizeof(ret->PeerInfo))) - { - Zero(ret->PeerInfo, sizeof(ret->PeerInfo)); - } + Zero(ret->PeerInfo, sizeof(ret->PeerInfo)); + } read_size = b->Current; } } @@ -1637,7 +1637,7 @@ UINT OvsGetAckReplyList(OPENVPN_CHANNEL *c, UINT *ret) num = MIN(LIST_NUM(c->AckReplyList), OPENVPN_MAX_NUMACK); - for (i = 0;i < num;i++) + for (i = 0; i < num; i++) { UINT *v = LIST_DATA(c->AckReplyList, i); @@ -1651,7 +1651,7 @@ UINT OvsGetAckReplyList(OPENVPN_CHANNEL *c, UINT *ret) ret[i] = *v; } - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { UINT *v = LIST_DATA(o, i); @@ -1682,7 +1682,7 @@ void OvsFreeChannel(OPENVPN_CHANNEL *c) ReleaseIntList(c->AckReplyList); - for (i = 0;i < LIST_NUM(c->SendControlPacketList);i++) + for (i = 0; i < LIST_NUM(c->SendControlPacketList); i++) { OPENVPN_CONTROL_PACKET *p = LIST_DATA(c->SendControlPacketList, i); @@ -1758,7 +1758,7 @@ UINT64 OvsNewServerSessionId(OPENVPN_SERVER *s) continue; } - for (i = 0;i < LIST_NUM(s->SessionList);i++) + for (i = 0; i < LIST_NUM(s->SessionList); i++) { OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i); if (se->ServerSessionId == id) @@ -1882,7 +1882,7 @@ BUF *OvsBuildPacket(OPENVPN_PACKET *p) { UINT i; - for (i = 0;i < num_ack;i++) + for (i = 0; i < num_ack; i++) { WriteBufInt(b, (UCHAR)p->AckPacketId[i]); } @@ -1970,7 +1970,7 @@ OPENVPN_PACKET *OvsParsePacket(UCHAR *data, UINT size) goto LABEL_ERROR; } - for (i = 0;i < ret->NumAck;i++) + for (i = 0; i < ret->NumAck; i++) { UINT ui; @@ -2066,7 +2066,7 @@ UINT OvsGetNumSessionByClientIp(OPENVPN_SERVER *s, IP *ip) return 0; } - for (i = 0;i < LIST_NUM(s->SessionList);i++) + for (i = 0; i < LIST_NUM(s->SessionList); i++) { OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i); @@ -2130,7 +2130,7 @@ OPENVPN_SESSION *OvsNewSession(OPENVPN_SERVER *s, IP *server_ip, UINT server_por IPToStr(server_ip_str, sizeof(server_ip_str), server_ip); IPToStr(client_ip_str, sizeof(client_ip_str), client_ip); Debug("OpenVPN New Session: %s:%u -> %s:%u Proto=%u\n", server_ip_str, server_port, - client_ip_str, client_port, protocol); + client_ip_str, client_port, protocol); OvsLog(s, se, NULL, "LO_NEW_SESSION", (protocol == OPENVPN_PROTOCOL_UDP ? "UDP" : "TCP")); @@ -2159,13 +2159,14 @@ void OvsFreeSession(OPENVPN_SESSION *se) UINTToIP(&dhcp_ip, se->IpcAsync->L3ClientAddressOption.ServerAddress); IPCDhcpFreeIP(se->Ipc, &dhcp_ip); - IPCProcessL3Events(se->Ipc); + IPC_PROTO_SET_STATUS(se->Ipc, IPv6State, IPC_PROTO_STATUS_CLOSED); + IPCProcessL3EventsIPv4Only(se->Ipc); } } } // Release the channel - for (i = 0;i < OPENVPN_NUM_CHANNELS;i++) + for (i = 0; i < OPENVPN_NUM_CHANNELS; i++) { OPENVPN_CHANNEL *c = se->Channels[i]; @@ -2225,7 +2226,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) s->Now = Tick64(); // Process for all sessions - for (i = 0;i < LIST_NUM(s->SessionList);i++) + for (i = 0; i < LIST_NUM(s->SessionList); i++) { OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i); @@ -2240,7 +2241,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) } // Process received packets - for (i = 0;i < LIST_NUM(recv_packet_list);i++) + for (i = 0; i < LIST_NUM(recv_packet_list); i++) { UDPPACKET *p = LIST_DATA(recv_packet_list, i); @@ -2248,7 +2249,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) } // Treat for all sessions and all channels - for (i = 0;i < LIST_NUM(s->SessionList);i++) + for (i = 0; i < LIST_NUM(s->SessionList); i++) { OPENVPN_CHANNEL *latest_channel = NULL; UINT64 max_tick = 0; @@ -2259,11 +2260,11 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) { if (se->Mode == OPENVPN_MODE_L3) { - IPCProcessL3Events(se->Ipc); + IPCProcessL3EventsIPv4Only(se->Ipc); } } - for (j = 0;j < OPENVPN_NUM_CHANNELS;j++) + for (j = 0; j < OPENVPN_NUM_CHANNELS; j++) { OPENVPN_CHANNEL *c = se->Channels[j]; @@ -2320,9 +2321,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) // Return the PUSH_REPLY Format(option_str, sizeof(option_str), - "PUSH_REPLY,ping %u,ping-restart %u", - (OPENVPN_PING_SEND_INTERVAL / 1000), - (OPENVPN_RECV_TIMEOUT / 1000)); + "PUSH_REPLY,ping %u,ping-restart %u", + (OPENVPN_PING_SEND_INTERVAL / 1000), + (OPENVPN_RECV_TIMEOUT / 1000)); if (se->Mode == OPENVPN_MODE_L3) { @@ -2344,26 +2345,26 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) ClearStr(ip_defgw, sizeof(ip_defgw)); IPToStr32(ip_client, sizeof(ip_client), - cao->ClientAddress); + cao->ClientAddress); IPToStr32(ip_subnet_mask, sizeof(ip_subnet_mask), - cao->SubnetMask); + cao->SubnetMask); Format(l3_options, sizeof(l3_options), - ",topology subnet"); + ",topology subnet"); StrCat(option_str, sizeof(option_str), l3_options); Format(l3_options, sizeof(l3_options), - ",ifconfig %s %s", - ip_client, - ip_subnet_mask); + ",ifconfig %s %s", + ip_client, + ip_subnet_mask); StrCat(option_str, sizeof(option_str), l3_options); // Domain name if (IsEmptyStr(cao->DomainName) == false) { Format(l3_options, sizeof(l3_options), - ",dhcp-option DOMAIN %s", cao->DomainName); + ",dhcp-option DOMAIN %s", cao->DomainName); StrCat(option_str, sizeof(option_str), l3_options); } @@ -2373,7 +2374,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer); Format(l3_options, sizeof(l3_options), - ",dhcp-option DNS %s", ip_str); + ",dhcp-option DNS %s", ip_str); StrCat(option_str, sizeof(option_str), l3_options); StrCpy(ip_dns1, sizeof(ip_dns1), ip_str); @@ -2385,7 +2386,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer2); Format(l3_options, sizeof(l3_options), - ",dhcp-option DNS %s", ip_str); + ",dhcp-option DNS %s", ip_str); StrCat(option_str, sizeof(option_str), l3_options); StrCpy(ip_dns2, sizeof(ip_dns2), ip_str); @@ -2397,7 +2398,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer); Format(l3_options, sizeof(l3_options), - ",dhcp-option WINS %s", ip_str); + ",dhcp-option WINS %s", ip_str); StrCat(option_str, sizeof(option_str), l3_options); StrCpy(ip_wins1, sizeof(ip_wins1), ip_str); @@ -2409,7 +2410,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer2); Format(l3_options, sizeof(l3_options), - ",dhcp-option WINS %s", ip_str); + ",dhcp-option WINS %s", ip_str); StrCat(option_str, sizeof(option_str), l3_options); StrCpy(ip_wins2, sizeof(ip_wins2), ip_str); @@ -2421,7 +2422,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->Gateway); Format(l3_options, sizeof(l3_options), - ",route-gateway %s,redirect-gateway def1", ip_str); + ",route-gateway %s,redirect-gateway def1", ip_str); StrCat(option_str, sizeof(option_str), l3_options); StrCpy(ip_defgw, sizeof(ip_defgw), ip_str); @@ -2442,9 +2443,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) IPAnd4(&local_network, &client_ip, &subnet_mask); Format(l3_options, sizeof(l3_options), - ",route %r %r vpn_gateway", - &local_network, - &cao->SubnetMask); + ",route %r %r vpn_gateway", + &local_network, + &cao->SubnetMask); StrCat(option_str, sizeof(option_str), l3_options); #endif @@ -2454,15 +2455,15 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) if (cao->ClasslessRoute.NumExistingRoutes >= 1) { UINT i; - for (i = 0;i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES;i++) + for (i = 0; i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES; i++) { DHCP_CLASSLESS_ROUTE *r = &cao->ClasslessRoute.Entries[i]; if (r->Exists) { Format(l3_options, sizeof(l3_options), - ",route %r %r vpn_gateway", - &r->Network, &r->SubnetMask); + ",route %r %r vpn_gateway", + &r->Network, &r->SubnetMask); StrCat(option_str, sizeof(option_str), l3_options); } @@ -2470,7 +2471,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) } OvsLog(s, se, c, "LP_SET_IPV4_PARAM", - ip_client, ip_subnet_mask, ip_defgw, ip_dns1, ip_dns2, ip_wins1, ip_wins2); + ip_client, ip_subnet_mask, ip_defgw, ip_dns1, ip_dns2, ip_wins1, ip_wins2); } else { @@ -2579,8 +2580,8 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) Debug("RawOut Fifo Size (c=%u): %u\n", c->KeyId, FifoSize(c->SslPipe->RawOut->RecvFifo)); OvsSendControlPacketWithAutoSplit(c, OPENVPN_P_CONTROL_V1, - FifoPtr(c->SslPipe->RawOut->RecvFifo), - FifoSize(c->SslPipe->RawOut->RecvFifo)); + FifoPtr(c->SslPipe->RawOut->RecvFifo), + FifoSize(c->SslPipe->RawOut->RecvFifo)); ReadFifo(c->SslPipe->RawOut->RecvFifo, NULL, FifoSize(c->SslPipe->RawOut->RecvFifo)); } @@ -2594,7 +2595,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) UINT k; // Packet transmission - for (k = 0;k < LIST_NUM(c->SendControlPacketList);k++) + for (k = 0; k < LIST_NUM(c->SendControlPacketList); k++) { OPENVPN_CONTROL_PACKET *cp = LIST_DATA(c->SendControlPacketList, k); @@ -2609,7 +2610,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) num = OvsGetAckReplyList(c, acks); p = OvsNewControlPacket(cp->OpCode, j, se->ServerSessionId, num, acks, - se->ClientSessionId, cp->PacketId, cp->DataSize, cp->Data); + se->ClientSessionId, cp->PacketId, cp->DataSize, cp->Data); OvsSendPacketNow(s, se, p); @@ -2628,7 +2629,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) if (num >= 1) { OPENVPN_PACKET *p = OvsNewControlPacket(OPENVPN_P_ACK_V1, j, se->ServerSessionId, - num, acks, se->ClientSessionId, 0, 0, NULL); + num, acks, se->ClientSessionId, 0, 0, NULL); OvsSendPacketNow(s, se, p); @@ -2656,14 +2657,14 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) } } - IPCProcessL3Events(se->Ipc); + IPCProcessL3EventsIPv4Only(se->Ipc); } IPCProcessInterrupts(se->Ipc); } // Choose the latest channel in all established channels - for (j = 0;j < OPENVPN_NUM_CHANNELS;j++) + for (j = 0; j < OPENVPN_NUM_CHANNELS; j++) { OPENVPN_CHANNEL *c = se->Channels[j]; @@ -2733,7 +2734,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) se->NextPingSendTick = s->Now + (UINT64)(OPENVPN_PING_SEND_INTERVAL); OvsSendDataPacket(latest_channel, latest_channel->KeyId, ++latest_channel->LastDataPacketId, - ping_signature, sizeof(ping_signature)); + ping_signature, sizeof(ping_signature)); //Debug("."); AddInterrupt(s->Interrupt, se->NextPingSendTick); @@ -2765,7 +2766,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) { UINT i; - for (i = 0;i < LIST_NUM(delete_session_list);i++) + for (i = 0; i < LIST_NUM(delete_session_list); i++) { OPENVPN_SESSION *se = LIST_DATA(delete_session_list, i); @@ -2798,7 +2799,7 @@ void OvsSendPacketNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_PACKET *p) if (p->NumAck >= 1) { Debug("Sending ACK Packet IDs (c=%u): ", p->KeyId); - for (i = 0;i < p->NumAck;i++) + for (i = 0; i < p->NumAck; i++) { Debug("%u ", p->AckPacketId[i]); } @@ -2844,14 +2845,14 @@ void OvsSendPacketRawNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, void *data, UIN } u = NewUdpPacket(&se->ServerIp, se->ServerPort, &se->ClientIp, se->ClientPort, - data, size); + data, size); Add(s->SendPacketList, u); } // Create a new OpenVPN control packet OPENVPN_PACKET *OvsNewControlPacket(UCHAR opcode, UCHAR key_id, UINT64 my_channel_id, UINT num_ack, - UINT *ack_packet_ids, UINT64 your_channel_id, UINT packet_id, - UINT data_size, UCHAR *data) + UINT *ack_packet_ids, UINT64 your_channel_id, UINT packet_id, + UINT data_size, UCHAR *data) { OPENVPN_PACKET *p = ZeroMalloc(sizeof(OPENVPN_PACKET)); UINT i; @@ -2861,7 +2862,7 @@ OPENVPN_PACKET *OvsNewControlPacket(UCHAR opcode, UCHAR key_id, UINT64 my_channe p->MySessionId = my_channel_id; p->NumAck = num_ack; - for (i = 0;i < MIN(num_ack, OPENVPN_MAX_NUMACK);i++) + for (i = 0; i < MIN(num_ack, OPENVPN_MAX_NUMACK); i++) { p->AckPacketId[i] = ack_packet_ids[i]; } diff --git a/src/Cedar/Proto_PPP.c b/src/Cedar/Proto_PPP.c index b165c350..c7af4310 100644 --- a/src/Cedar/Proto_PPP.c +++ b/src/Cedar/Proto_PPP.c @@ -12,9 +12,6 @@ void PPPThread(THREAD *thread, void *param) { PPP_SESSION *p = (PPP_SESSION *)param; UINT i; - PPP_LCP *c; - USHORT us; - UINT ui; USHORT next_protocol = 0; bool ret = false; char ipstr1[128], ipstr2[128]; @@ -32,8 +29,6 @@ void PPPThread(THREAD *thread, void *param) Debug("PPP Initialize"); PPPSetStatus(p, PPP_STATUS_CONNECTED); - p->IPv4_State = PPP_PROTO_STATUS_CLOSED; - p->IPv6_State = PPP_PROTO_STATUS_CLOSED; p->Eap_Protocol = PPP_UNSPECIFIED; @@ -181,7 +176,8 @@ void PPPThread(THREAD *thread, void *param) { UINT64 nowL; // Here client to server - if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IP && p->IPv4_State == PPP_PROTO_STATUS_OPENED) + if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IP && + IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED) { receivedPacketProcessed = true; IPCSendIPv4(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize); @@ -190,10 +186,11 @@ void PPPThread(THREAD *thread, void *param) { Debug("Got IPv4 packet before IPv4 ready!\n"); } - else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6 && p->IPv6_State == PPP_PROTO_STATUS_OPENED) + else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6 && + IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_OPENED) { receivedPacketProcessed = true; - Debug("IPv6 to be implemented\n"); + IPCIPv6Send(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize); } else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6) { @@ -318,18 +315,21 @@ void PPPThread(THREAD *thread, void *param) if (p->PPPStatus == PPP_STATUS_NETWORK_LAYER) { UINT64 timeBeforeLoop; - if (p->DhcpAllocated) + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED) { - if (now >= p->DhcpNextRenewTime) + if (p->DhcpAllocated) { - IP ip; + if (now >= p->DhcpNextRenewTime) + { + IP ip; - // DHCP renewal procedure - p->DhcpNextRenewTime = now + p->DhcpRenewInterval; + // DHCP renewal procedure + p->DhcpNextRenewTime = now + p->DhcpRenewInterval; - UINTToIP(&ip, p->ClientAddressOption.ServerAddress); + UINTToIP(&ip, p->ClientAddressOption.ServerAddress); - IPCDhcpRenewIP(p->Ipc, &ip); + IPCDhcpRenewIP(p->Ipc, &ip); + } } } @@ -340,30 +340,73 @@ void PPPThread(THREAD *thread, void *param) while (true) { UINT64 nowL; - BLOCK *b = IPCRecvIPv4(p->Ipc); - PPP_PACKET *pp; - PPP_PACKET tmp; - if (b == NULL) + bool no4packets = false; + bool no6packets = false; + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED) { - break; + BLOCK *b = IPCRecvIPv4(p->Ipc); + if (b == NULL) + { + no4packets = true; + } + else + { + PPP_PACKET *pp; + PPP_PACKET tmp; + + // Since receiving the IP packet, send it to the client by PPP + pp = &tmp; + pp->IsControl = false; + pp->Protocol = PPP_PROTOCOL_IP; + pp->Lcp = NULL; + pp->Data = b->Buf; + pp->DataSize = b->Size; + + PPPSendPacketEx(p, pp, true); + + FreePPPPacketEx(pp, true); + Free(b); + } + } + else + { + no4packets = true; } - // Since receiving the IP packet, send it to the client by PPP - pp = &tmp; - pp->IsControl = false; - pp->Protocol = PPP_PROTOCOL_IP; - pp->Lcp = NULL; - pp->Data = b->Buf; - pp->DataSize = b->Size; + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_OPENED) + { + BLOCK *b = IPCIPv6Recv(p->Ipc); + if (b == NULL) + { + no6packets = true; + } + else + { + PPP_PACKET *pp; + PPP_PACKET tmp; - PPPSendPacketEx(p, pp, true); + // Since receiving the IP packet, send it to the client by PPP + pp = &tmp; + pp->IsControl = false; + pp->Protocol = PPP_PROTOCOL_IPV6; + pp->Lcp = NULL; + pp->Data = b->Buf; + pp->DataSize = b->Size; - FreePPPPacketEx(pp, true); - Free(b); + PPPSendPacketEx(p, pp, true); + + FreePPPPacketEx(pp, true); + Free(b); + } + } + else + { + no6packets = true; + } // Let's break out of the loop once in a while so we don't get stuck here endlessly nowL = Tick64(); - if (nowL > timeBeforeLoop + PPP_PACKET_RESEND_INTERVAL) + if (nowL > timeBeforeLoop + PPP_PACKET_RESEND_INTERVAL || (no4packets && no6packets)) { break; } @@ -743,7 +786,7 @@ bool PPPProcessResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req) return PPPProcessIPCPResponsePacket(p, pp, req); break; case PPP_PROTOCOL_IPV6CP: - Debug("IPv6CP to be implemented\n"); + return PPPProcessIPv6CPResponsePacket(p, pp, req); break; case PPP_PROTOCOL_EAP: return PPPProcessEAPResponsePacket(p, pp, req); @@ -786,11 +829,11 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req USHORT *protocol = pp->Lcp->Data; if (*protocol == PPP_PROTOCOL_IPCP || *protocol == PPP_PROTOCOL_IP) { - p->IPv4_State = PPP_PROTO_STATUS_REJECTED; + IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED); } if (*protocol == PPP_PROTOCOL_IPV6CP || *protocol == PPP_PROTOCOL_IPV6) { - p->IPv6_State = PPP_PROTO_STATUS_REJECTED; + IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED); } } } @@ -1082,7 +1125,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re if (!PPPGetIPAddressValueFromLCP(pp->Lcp, PPP_IPCP_OPTION_IP, &addrStruct) || pp->Lcp->Code == PPP_LCP_CODE_REJECT || pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT) { Debug("Unsupported IPCP protocol"); - p->IPv4_State = PPP_PROTO_STATUS_REJECTED; + IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED); PPPRejectUnsupportedPacketEx(p, pp, true); return false; } @@ -1096,14 +1139,14 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re Debug("Accepted server IP address of %s\n", addrStr); // We already configured client address, now server address is also confirmed, ready for IPv4 data flow - if (p->IPv4_State == PPP_PROTO_STATUS_CONFIG) + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG) { - p->IPv4_State = PPP_PROTO_STATUS_CONFIG_WAIT; + IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG_WAIT); } return true; } - p->IPv4_State = PPP_PROTO_STATUS_CONFIG; + IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG); PPPGetIPAddressValueFromLCP(req->Lcp, PPP_IPCP_OPTION_IP, &prevAddrStruct); prevAddr = IPToUINT(&prevAddrStruct); @@ -1115,7 +1158,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re if (prevAddr == Endian32(0xc0000008)) { Debug("We already tried the fallback IP of 192.0.0.8, giving up\n"); - p->IPv4_State = PPP_PROTO_STATUS_REJECTED; + IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED); PPPRejectUnsupportedPacketEx(p, pp, true); return false; } @@ -1205,6 +1248,31 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req return false; } +// Process IPv6CP responses +bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req) +{ + bool isAccepted = !PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code); + + // If we got a reject or a NACK, we just reject the whole IPv6 configuration, there is no way we can recover even from a NACK as we can't change the link-local address of an already existing router + if (!isAccepted) + { + Debug("Unsupported IPv6CP protocol"); + IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED); + PPPRejectUnsupportedPacketEx(p, pp, true); + return false; + } + + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) != IPC_PROTO_STATUS_CONFIG) + { + Debug("We got an early IPv6CP response, ignoring for now...\n"); + return false; + } + + Debug("Accepted server IPv6CP handshake\n"); + IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG_WAIT); + return true; +} + // Processes request packets bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) @@ -1227,8 +1295,7 @@ bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) return PPPProcessIPCPRequestPacket(p, pp); break; case PPP_PROTOCOL_IPV6CP: - PPPRejectUnsupportedPacketEx(p, pp, true); - Debug("IPv6CP to be implemented\n"); + return PPPProcessIPv6CPRequestPacket(p, pp); break; case PPP_PROTOCOL_EAP: return PPPProcessEAPRequestPacket(p, pp); @@ -1547,9 +1614,8 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) bool ok = true; bool processed = false; bool isEmptyIpAddress = false; - PPP_LCP *c; - if (p->IPv4_State == PPP_PROTO_STATUS_REJECTED) + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_REJECTED) { Debug("We got an IPCP packet after we had it rejected\n"); return PPPRejectUnsupportedPacketEx(p, pp, true); @@ -1823,7 +1889,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) // We will delay this packet ACK and send the server IP first, then wait for a reparse // it is kind of dirty but fixes issues on some clients (namely VPN Client Pro on Android) - if (p->IPv4_State == PPP_PROTO_STATUS_CLOSED && p->ClientAddressOption.ServerAddress != 0 && ok) + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED && p->ClientAddressOption.ServerAddress != 0 && ok) { PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); UINT ui = p->ClientAddressOption.ServerAddress; @@ -1834,7 +1900,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) WHERE; return false; } - p->IPv4_State = PPP_PROTO_STATUS_CONFIG; + IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG); if (!processed) { PPPAddNextPacket(p, pp, 1); @@ -1843,7 +1909,8 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) } // We still haven't received any answer from client about server IP, keep waiting... - if ((p->IPv4_State == PPP_PROTO_STATUS_CONFIG || p->IPv4_State == PPP_PROTO_STATUS_CLOSED) && !processed) + if ((IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG || + IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED) && !processed) { PPPAddNextPacket(p, pp, 1); return false; @@ -1856,9 +1923,9 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) } Debug("ACKed IPCP options ID = 0x%x\n", pp->Lcp->Id); - if (ok && p->IPv4_State == PPP_PROTO_STATUS_CONFIG_WAIT) + if (ok && IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG_WAIT) { - p->IPv4_State = PPP_PROTO_STATUS_OPENED; + IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_OPENED); Debug("IPv4 OPENED\n"); } return ok; @@ -1871,6 +1938,116 @@ bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) return false; } +// Process IPv6CP request packets +bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) +{ + UINT i; + bool processed = false; + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_REJECTED) + { + Debug("We got an IPv6CP packet after we had it rejected\n"); + return PPPRejectUnsupportedPacketEx(p, pp, true); + } + + for (i = 0; i < LIST_NUM(pp->Lcp->OptionList); i++) + { + PPP_OPTION *t = LIST_DATA(pp->Lcp->OptionList, i); + + switch (t->Type) + { + case PPP_IPV6CP_OPTION_EUI: + t->IsSupported = true; + if (t->DataSize == sizeof(UINT64)) + { + UINT64 newValue = 0; + UINT64 value = READ_UINT64(t->Data); + if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, value)) + { + t->IsAccepted = true; + p->Ipc->IPv6ClientEUI = value; + } + else + { + t->IsAccepted = false; + GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress); + if (newValue != value && !IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue)) + { + WRITE_UINT64(t->AltData, newValue); + t->AltDataSize = sizeof(UINT64); + } + else + { + while (true) + { + newValue = Rand64(); + if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue)) + { + WRITE_UINT64(t->AltData, newValue); + t->AltDataSize = sizeof(UINT64); + break; + } + } + } + } + } + break; + default: + t->IsSupported = false; + break; + } + } + + if (PPPRejectLCPOptionsEx(p, pp, processed)) + { + Debug("Rejected IPv6CP options ID = 0x%x\n", pp->Lcp->Id); + processed = true; + } + + if (PPPNackLCPOptionsEx(p, pp, processed)) + { + Debug("NACKed IPv6CP options ID = 0x%x\n", pp->Lcp->Id); + processed = true; + } + + if (p->Ipc->IPv6ClientEUI != 0 && IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CLOSED) + { + PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); + UINT64 serverEui = IPCIPv6GetServerEui(p->Ipc); + if (serverEui != 0 && serverEui != p->Ipc->IPv6ClientEUI) + { + Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &serverEui, sizeof(UINT64))); + } + if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c)) + { + PPPSetStatus(p, PPP_STATUS_FAIL); + WHERE; + return false; + } + + IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG); + } + + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG && !processed) + { + PPPAddNextPacket(p, pp, 1); + return false; + } + + if (!PPPAckLCPOptionsEx(p, pp, processed)) + { + return false; + } + Debug("ACKed IPv6CP options ID = 0x%x\n", pp->Lcp->Id); + + if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG_WAIT) + { + IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_OPENED); + Debug("IPv6 OPENED\n"); + } + + return true; +} + // LCP option based packets utility bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp) { @@ -2128,7 +2305,7 @@ LABEL_LOOP: if (async == false) { - d = TubeRecvSync(p->TubeRecv, p->PacketRecvTimeout); + d = TubeRecvSync(p->TubeRecv, (UINT)p->PacketRecvTimeout); } else { @@ -2241,7 +2418,6 @@ PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p) void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay) { PPP_DELAYED_PACKET *t = ZeroMalloc(sizeof(PPP_DELAYED_PACKET)); - UINT i; if (p->CurrentPacket == pp) { p->CurrentPacket = NULL; @@ -2262,7 +2438,7 @@ void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay) Debug("after sorting delayeds end\n");*/ } -int PPPDelayedPacketsComparator(const void *a, const void *b) +int PPPDelayedPacketsComparator(void *a, void *b) { PPP_DELAYED_PACKET *first = a; PPP_DELAYED_PACKET *second = b; @@ -3009,12 +3185,11 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi UCHAR *dataBuffer; UINT dataSize; UINT tlsLength = 0; - UINT i; bool isFragmented = false; PPP_LCP *lcp; PPP_EAP *eap; UCHAR flags = PPP_EAP_TLS_FLAG_NONE; - UINT64 sizeLeft = 0; + UINT sizeLeft = 0; Debug("Got EAP-TLS size=%i\n", eapTlsSize); if (eapTlsSize == 1) { @@ -3024,7 +3199,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi // We got an ACK to transmit the next fragmented message dataSize = p->Mru1 - 8 - 1 - 1; // Calculating the maximum payload size (without TlsLength) sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferSend); - sizeLeft -= p->Eap_TlsCtx.CachedBufferSendPntr - p->Eap_TlsCtx.CachedBufferSend; + sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferSendPntr - p->Eap_TlsCtx.CachedBufferSend); flags = PPP_EAP_TLS_FLAG_FRAGMENTED; // M flag if (dataSize > sizeLeft) @@ -3035,7 +3210,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi lcp = BuildEAPTlsRequest(p->Eap_PacketId++, dataSize, flags); eap = lcp->Data; Copy(eap->Tls.TlsDataWithoutLength, p->Eap_TlsCtx.CachedBufferSendPntr, dataSize); - p->Eap_TlsCtx.CachedBufferSendPntr += dataSize; + p->Eap_TlsCtx.CachedBufferSendPntr += (UINT64)dataSize; if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) { @@ -3192,7 +3367,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv; } sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv); - sizeLeft -= p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv; + sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv); Copy(p->Eap_TlsCtx.CachedBufferRecvPntr, dataBuffer, MIN(sizeLeft, dataSize)); @@ -3206,7 +3381,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi dataSize = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv); if (dataSize == MAX_BUFFERING_PACKET_SIZE) { - dataSize = p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv; + dataSize = (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv); } } diff --git a/src/Cedar/Proto_PPP.h b/src/Cedar/Proto_PPP.h index 9c261bed..4cf8c9fe 100644 --- a/src/Cedar/Proto_PPP.h +++ b/src/Cedar/Proto_PPP.h @@ -95,7 +95,7 @@ #define PPP_IPCP_OPTION_WINS2 132 // IPV6CP option type -#define PPP_IPV6CP_OPTION_IID 1 +#define PPP_IPV6CP_OPTION_EUI 1 // EAP codes #define PPP_EAP_CODE_REQUEST 1 @@ -135,13 +135,6 @@ #define PPP_STATUS_FAIL 0x1000 #define PPP_STATUS_AUTH_FAIL 0x1010 -// Protocol status -#define PPP_PROTO_STATUS_CLOSED 0x0 -#define PPP_PROTO_STATUS_CONFIG 0x1 -#define PPP_PROTO_STATUS_CONFIG_WAIT 0x2 -#define PPP_PROTO_STATUS_OPENED 0x10 -#define PPP_PROTO_STATUS_REJECTED 0x100 - #define PPP_UNSPECIFIED 0xFFFF //// Type @@ -301,8 +294,6 @@ struct PPP_SESSION UCHAR ClientInterfaceId[8]; // Client IPv6CP Interface Identifier UINT PPPStatus; - UINT IPv4_State; - UINT IPv6_State; // EAP contexts UINT Eap_Protocol; // Current EAP Protocol used @@ -344,12 +335,14 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); +bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); // Request packets bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); +bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); // LCP option based packets utility bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp); @@ -369,7 +362,7 @@ PPP_PACKET *PPPRecvPacket(PPP_SESSION *p, bool async); // Helpers for delaying packets PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p); void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay); -int PPPDelayedPacketsComparator(const void *a, const void *b); +int PPPDelayedPacketsComparator(void *a, void *b); char PPPRelatedPacketComparator(PPP_PACKET *a, PPP_PACKET *b); // PPP utility functions diff --git a/src/Cedar/Virtual.c b/src/Cedar/Virtual.c index 26a27922..d5c88d47 100644 --- a/src/Cedar/Virtual.c +++ b/src/Cedar/Virtual.c @@ -98,7 +98,7 @@ NATIVE_NAT_ENTRY *NnGetOldestNatEntryOfIp(NATIVE_NAT *t, UINT ip, UINT protocol) return NULL; } - for (i = 0;i < LIST_NUM(t->NatTableForRecv->AllList);i++) + for (i = 0; i < LIST_NUM(t->NatTableForRecv->AllList); i++) { NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i); @@ -129,7 +129,7 @@ UINT NnGetNumNatEntriesPerIp(NATIVE_NAT *t, UINT src_ip, UINT protocol) return 0; } - for (i = 0;i < LIST_NUM(t->NatTableForRecv->AllList);i++) + for (i = 0; i < LIST_NUM(t->NatTableForRecv->AllList); i++) { NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i); @@ -160,7 +160,7 @@ void NnDeleteOldSessions(NATIVE_NAT *t) o = NULL; now = t->v->Now; - for (i = 0;i < LIST_NUM(t->NatTableForSend->AllList);i++) + for (i = 0; i < LIST_NUM(t->NatTableForSend->AllList); i++) { NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i); UINT64 timeout; @@ -188,7 +188,7 @@ void NnDeleteOldSessions(NATIVE_NAT *t) if (o != NULL) { - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { NATIVE_NAT_ENTRY *e = LIST_DATA(o, i); @@ -213,7 +213,7 @@ void NnDeleteSession(NATIVE_NAT *t, NATIVE_NAT_ENTRY *e) case NAT_TCP: // Send a RST to the client side SendTcp(t->v, e->DestIp, e->DestPort, e->SrcIp, e->SrcPort, - e->LastAck, e->LastSeq + (e->Status == NAT_TCP_CONNECTING ? 1 : 0), TCP_RST | TCP_ACK, 0, 0, NULL, 0); + e->LastAck, e->LastSeq + (e->Status == NAT_TCP_CONNECTING ? 1 : 0), TCP_RST | TCP_ACK, 0, 0, NULL, 0); NLog(t->v, "LH_NAT_TCP_DELETED", e->Id); break; @@ -246,7 +246,7 @@ void NnPollingIpCombine(NATIVE_NAT *t) // Discard the old combining object o = NULL; - for (i = 0;i < LIST_NUM(t->IpCombine);i++) + for (i = 0; i < LIST_NUM(t->IpCombine); i++) { IP_COMBINE *c = LIST_DATA(t->IpCombine, i); @@ -262,7 +262,7 @@ void NnPollingIpCombine(NATIVE_NAT *t) if (o != NULL) { - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { IP_COMBINE *c = LIST_DATA(o, i); @@ -336,7 +336,7 @@ void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT siz // Check the overlap between the region which is represented by the offset and size of the // existing received list and the region which is represented by the offset and size - for (i = 0;i < LIST_NUM(c->IpParts);i++) + for (i = 0; i < LIST_NUM(c->IpParts); i++) { UINT moving_size; IP_PART *p = LIST_DATA(c->IpParts, i); @@ -393,7 +393,7 @@ void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT siz UINT total_size = 0; UINT i; - for (i = 0;i < LIST_NUM(c->IpParts);i++) + for (i = 0; i < LIST_NUM(c->IpParts); i++) { IP_PART *p = LIST_DATA(c->IpParts, i); @@ -405,7 +405,7 @@ void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT siz // 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); + c->HeadIpHeaderData, c->HeadIpHeaderDataSize, c->MaxL3Size); // Release the combining object NnFreeIpCombine(t, c); @@ -431,7 +431,7 @@ void NnFreeIpCombine(NATIVE_NAT *t, IP_COMBINE *c) Free(c->Data); // Release the partial list - for (i = 0;i < LIST_NUM(c->IpParts);i++) + for (i = 0; i < LIST_NUM(c->IpParts); i++) { IP_PART *p = LIST_DATA(c->IpParts, i); @@ -525,7 +525,7 @@ void NnFreeIpCombineList(NATIVE_NAT *t) return; } - for (i = 0;i < LIST_NUM(t->IpCombine);i++) + for (i = 0; i < LIST_NUM(t->IpCombine); i++) { IP_COMBINE *c = LIST_DATA(t->IpCombine, i); @@ -707,7 +707,7 @@ void NnIcmpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT s ret_echo->SeqNo = echo->SeqNo; Copy((UCHAR *)ret_icmp + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO), - payload, payload_size); + payload, payload_size); ret_icmp->Checksum = IpChecksum(ret_icmp, ret_size); @@ -738,7 +738,7 @@ void NnIcmpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT s 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); + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + orig_ipv4_header_size); if (inner_icmp->Type == ICMP_TYPE_ECHO_REQUEST) { @@ -850,14 +850,14 @@ void NnUdpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT si // Deliver to the client by rewriting the port number SendUdp(t->v, e->SrcIp, e->SrcPort, src_ip, Endian16(udp->SrcPort), - payload, payload_size); + payload, payload_size); } } } // A combined IP packet is received void NnIpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, UINT protocol, void *data, UINT size, - UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size) + UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size) { // Validate arguments if (t == NULL || data == NULL) @@ -939,7 +939,7 @@ void NnFragmentedIpReceived(NATIVE_NAT *t, PKT *packet) // Because this packet has not been fragmented, it can be passed to the upper layer immediately head_ip_header_data = (UCHAR *)packet->L3.IPv4Header; NnIpReceived(t, ip->SrcIP, ip->DstIP, ip->Protocol, data, size, ip->TimeToLive, - head_ip_header_data, head_ip_header_size, l3_size); + head_ip_header_data, head_ip_header_size, l3_size); } else { @@ -964,8 +964,8 @@ void NnFragmentedIpReceived(NATIVE_NAT *t, PKT *packet) { // Create a combining object because it is the first packet c = NnInsertIpCombine( - t, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol, packet->BroadcastPacket, - ip->TimeToLive, false); + t, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol, packet->BroadcastPacket, + ip->TimeToLive, false); if (c != NULL) { c->MaxL3Size = MAX(c->MaxL3Size, l3_size); @@ -1050,7 +1050,7 @@ void NnPoll(NATIVE_NAT *t) // Send a fragmented IP packet to the Internet void NnIpSendFragmentedForInternet(NATIVE_NAT *t, UCHAR ip_protocol, UINT src_ip, UINT dest_ip, USHORT id, USHORT total_size, - USHORT offset, void *data, UINT size, UCHAR ttl) + USHORT offset, void *data, UINT size, UCHAR ttl) { UCHAR *buf; IPV4_HEADER *ip; @@ -1165,7 +1165,7 @@ void NnIpSendForInternet(NATIVE_NAT *t, UCHAR ip_protocol, UCHAR ttl, UINT src_i // Transmit the fragmented packet NnIpSendFragmentedForInternet(t, ip_protocol, src_ip, dest_ip, id, total_size, offset, - buf + offset, size_of_this_packet, ttl); + buf + offset, size_of_this_packet, ttl); if (last_packet) { break; @@ -1211,7 +1211,7 @@ void NnIcmpEchoRecvForInternet(VH *v, UINT src_ip, UINT dest_ip, void *data, UIN { // Respond because it is addressed to me VirtualIcmpEchoSendResponse(v, dest_ip, src_ip, Endian16(old_icmp_echo->Identifier), - Endian16(old_icmp_echo->SeqNo), payload_data, payload_size); + Endian16(old_icmp_echo->SeqNo), payload_data, payload_size); return; } @@ -1562,7 +1562,7 @@ UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_po base_port = Rand32() % (port_end - port_start) + port_start; - for (i = 0;i < (port_end - port_start);i++) + for (i = 0; i < (port_end - port_start); i++) { UINT port; NATIVE_NAT_ENTRY tt; @@ -1706,8 +1706,8 @@ LABEL_RESTART: // Start a connectivity check periodically dns_query = NnBuildIpPacket(NnBuildUdpPacket(NnBuildDnsQueryPacket(NN_CHECK_HOSTNAME, dns_tran_id), - IPToUINT(&ipc->ClientIPAddress), dns_src_port, IPToUINT(&a->DnsServerIP), 53), - IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP), IP_PROTO_UDP, 0); + IPToUINT(&ipc->ClientIPAddress), dns_src_port, IPToUINT(&a->DnsServerIP), 53), + IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP), IP_PROTO_UDP, 0); IPCSendIPv4(ipc, dns_query->Buf, dns_query->Size); @@ -1753,7 +1753,7 @@ LABEL_RESTART: UnlockQueue(t->SendQueue); // Happy processing - IPCProcessL3Events(ipc); + IPCProcessL3EventsIPv4Only(ipc); LockQueue(t->RecvQueue); { @@ -1782,9 +1782,9 @@ LABEL_RESTART: if (wait_for_dns) { if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_UDP && - pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) && - pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) && - pkt->L4.UDPHeader->SrcPort == Endian16(53) && pkt->L4.UDPHeader->DstPort == Endian16(dns_src_port)) + pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) && + pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) && + pkt->L4.UDPHeader->SrcPort == Endian16(53) && pkt->L4.UDPHeader->DstPort == Endian16(dns_src_port)) { DNSV4_HEADER *dns_header = (DNSV4_HEADER *)pkt->Payload; if (pkt->PayloadSize >= sizeof(DNSV4_HEADER)) @@ -1809,8 +1809,8 @@ LABEL_RESTART: // Generate a TCP connection attempt packet tcp_seq = Rand32(); tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), tcp_src_port, - IPToUINT(&yahoo_ip), 80, tcp_seq, 0, TCP_SYN, 8192, 1414), - IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); + IPToUINT(&yahoo_ip), 80, tcp_seq, 0, TCP_SYN, 8192, 1414), + IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); IPCSendIPv4(ipc, tcp_query->Buf, tcp_query->Size); @@ -1824,9 +1824,9 @@ LABEL_RESTART: } if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_TCP && - pkt->L3.IPv4Header->SrcIP == IPToUINT(&yahoo_ip) && - pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) && - pkt->L4.TCPHeader->SrcPort == Endian16(80) && pkt->L4.TCPHeader->DstPort == Endian16(tcp_src_port)) + pkt->L3.IPv4Header->SrcIP == IPToUINT(&yahoo_ip) && + pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) && + pkt->L4.TCPHeader->SrcPort == Endian16(80) && pkt->L4.TCPHeader->DstPort == Endian16(tcp_src_port)) { TCP_HEADER *tcp_header = (TCP_HEADER *)pkt->L4.TCPHeader; if ((tcp_header->Flag & TCP_SYN) && (tcp_header->Flag & TCP_ACK)) @@ -1839,8 +1839,8 @@ LABEL_RESTART: // Send a RST tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), tcp_src_port, - IPToUINT(&yahoo_ip), 80, tcp_seq + 1, recv_seq, TCP_RST | TCP_ACK, 8192, 0), - IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); + IPToUINT(&yahoo_ip), 80, tcp_seq + 1, recv_seq, TCP_RST | TCP_ACK, 8192, 0), + IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); IPCSendIPv4(ipc, tcp_query->Buf, tcp_query->Size); @@ -2220,7 +2220,7 @@ bool NnParseDnsResponsePacket(UCHAR *data, UINT size, IP *ret_ip) UINT num_answers = Endian16(h.AnswerRRs); UINT i; - for (i = 0;i < num_questions;i++) + for (i = 0; i < num_questions; i++) { BUF *r = NnReadDnsRecord(buf, false, NULL, NULL); @@ -2234,7 +2234,7 @@ bool NnParseDnsResponsePacket(UCHAR *data, UINT size, IP *ret_ip) } } - for (i = 0;i < num_answers;i++) + for (i = 0; i < num_answers; i++) { USHORT tp, cl; BUF *r = NnReadDnsRecord(buf, true, &tp, &cl); @@ -2330,12 +2330,12 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) // Try to get an IP address of www.yahoo.com dns_query = NnBuildIpPacket(NnBuildUdpPacket(NnBuildDnsQueryPacket(NN_CHECK_HOSTNAME, dns_tran_id), - IPToUINT(&ipc->ClientIPAddress), src_port, IPToUINT(&a->DnsServerIP), 53), - IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP), IP_PROTO_UDP, 0); + 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); + 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); @@ -2370,7 +2370,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) } // Happy processing - IPCProcessL3Events(ipc); + IPCProcessL3EventsIPv4Only(ipc); while (true) { @@ -2389,10 +2389,10 @@ 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->DnsServerIP2)) && - pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) && - pkt->L4.UDPHeader->SrcPort == Endian16(53) && pkt->L4.UDPHeader->DstPort == Endian16(src_port)) + (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)) { DNSV4_HEADER *dns_header = (DNSV4_HEADER *)pkt->Payload; if (pkt->PayloadSize >= sizeof(DNSV4_HEADER)) @@ -2418,7 +2418,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) } if ((halt_tube != NULL && IsTubeConnected(halt_tube) == false) || - IsTubeConnected(ipc->Sock->SendTube) == false || IsTubeConnected(ipc->Sock->RecvTube) == false) + IsTubeConnected(ipc->Sock->SendTube) == false || IsTubeConnected(ipc->Sock->RecvTube) == false) { // Disconnected break; @@ -2450,8 +2450,8 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) // Generate a TCP packet tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), src_port, - IPToUINT(&yahoo_ip), 80, seq, 0, TCP_SYN, 8192, 1414), - IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); + IPToUINT(&yahoo_ip), 80, seq, 0, TCP_SYN, 8192, 1414), + IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); Debug("Test TCP to %r\n", &yahoo_ip); @@ -2479,7 +2479,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) } // Happy procedure - IPCProcessL3Events(ipc); + IPCProcessL3EventsIPv4Only(ipc); while (true) { @@ -2498,9 +2498,9 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) if (pkt != NULL) { if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_TCP && - pkt->L3.IPv4Header->SrcIP == IPToUINT(&yahoo_ip) && - pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) && - pkt->L4.TCPHeader->SrcPort == Endian16(80) && pkt->L4.TCPHeader->DstPort == Endian16(src_port)) + pkt->L3.IPv4Header->SrcIP == IPToUINT(&yahoo_ip) && + pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) && + pkt->L4.TCPHeader->SrcPort == Endian16(80) && pkt->L4.TCPHeader->DstPort == Endian16(src_port)) { TCP_HEADER *tcp_header = (TCP_HEADER *)pkt->L4.TCPHeader; if ((tcp_header->Flag & TCP_SYN) && (tcp_header->Flag & TCP_ACK)) @@ -2517,7 +2517,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) } if ((halt_tube != NULL && IsTubeConnected(halt_tube) == false) || - IsTubeConnected(ipc->Sock->SendTube) == false || IsTubeConnected(ipc->Sock->RecvTube) == false) + IsTubeConnected(ipc->Sock->SendTube) == false || IsTubeConnected(ipc->Sock->RecvTube) == false) { // Disconnected break; @@ -2542,8 +2542,8 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube) } tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), src_port, - IPToUINT(&yahoo_ip), 80, seq + 1, recv_seq, TCP_RST | TCP_ACK, 8192, 0), - IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); + IPToUINT(&yahoo_ip), 80, seq + 1, recv_seq, TCP_RST | TCP_ACK, 8192, 0), + IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0); IPCSendIPv4(ipc, tcp_query->Buf, tcp_query->Size); @@ -2612,8 +2612,8 @@ NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t) // Get the device list device_list = GetEthListEx(NULL, - !(t->v->HubOption != NULL && t->v->HubOption->DisableKernelModeSecureNAT), - !(t->v->HubOption != NULL && t->v->HubOption->DisableIpRawModeSecureNAT)); + !(t->v->HubOption != NULL && t->v->HubOption->DisableKernelModeSecureNAT), + !(t->v->HubOption != NULL && t->v->HubOption->DisableIpRawModeSecureNAT)); if (device_list == NULL || device_list->NumTokens == 0) { @@ -2703,7 +2703,7 @@ NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t) IPToStr32(gateway_ip, sizeof(gateway_ip), opt.Gateway); Debug("DHCP: client_ip=%s, client_mask=%s, dhcp_ip=%s, gateway_ip=%s\n", - client_ip, client_mask, dhcp_ip, gateway_ip); + client_ip, client_mask, dhcp_ip, gateway_ip); Copy(&ret->CurrentDhcpOptionList, &opt, sizeof(DHCP_OPTION_LIST)); @@ -2731,7 +2731,7 @@ NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t) // Connectivity test // (always fail if the default gateway is not set) if (opt.Gateway != 0 && - NnTestConnectivity(ret, t->HaltTube2)) + NnTestConnectivity(ret, t->HaltTube2)) { // Reset the number of search failures t->FailedCount = 0; @@ -2783,7 +2783,7 @@ void NativeNatThread(THREAD *thread, void *param) } // If the NAT is disabled, wait until it becomes enabled - Wait(t->HaltEvent, 1234); + Wait(t->HaltEvent, 1234); } if (t->Halt) @@ -2829,8 +2829,8 @@ void NativeNatThread(THREAD *thread, void *param) Debug("NnMainLoop Start.\n"); MacToStr(macstr, sizeof(macstr), a->Ipc->MacAddress); NLog(t->v, "LH_KERNEL_MODE_START", a->DeviceName, - &a->Ipc->ClientIPAddress, &a->Ipc->SubnetMask, &a->Ipc->DefaultGateway, &a->Ipc->BroadcastAddress, - macstr, &a->CurrentDhcpOptionList.ServerAddress, &a->DnsServerIP); + &a->Ipc->ClientIPAddress, &a->Ipc->SubnetMask, &a->Ipc->DefaultGateway, &a->Ipc->BroadcastAddress, + macstr, &a->CurrentDhcpOptionList.ServerAddress, &a->DnsServerIP); NnMainLoop(t, a); Debug("NnMainLoop End.\n"); @@ -3203,7 +3203,7 @@ void FreeNativeNat(NATIVE_NAT *t) ReleaseCancel(t->Cancel); // Release the NAT table - for (i = 0;i < LIST_NUM(t->NatTableForSend->AllList);i++) + for (i = 0; i < LIST_NUM(t->NatTableForSend->AllList); i++) { NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i); @@ -3254,7 +3254,7 @@ NAT_ENTRY *GetOldestNatEntryOfIp(VH *v, UINT ip, UINT protocol) return NULL; } - for (i = 0;i < LIST_NUM(v->NatTable);i++) + for (i = 0; i < LIST_NUM(v->NatTable); i++) { NAT_ENTRY *e = LIST_DATA(v->NatTable, i); @@ -3291,7 +3291,7 @@ UINT GetNumNatEntriesPerIp(VH *v, UINT ip, UINT protocol, bool tcp_syn_sent) return 0; } - for (i = 0;i < LIST_NUM(v->NatTable);i++) + for (i = 0; i < LIST_NUM(v->NatTable); i++) { NAT_ENTRY *e = LIST_DATA(v->NatTable, i); @@ -3425,7 +3425,7 @@ void NatThreadMain(VH *v) LIST_ELEMENT_DELETED: num = LIST_NUM(v->NatTable); - for (i = 0;i < num;i++) + for (i = 0; i < num; i++) { NAT_ENTRY *n = LIST_DATA(v->NatTable, i); @@ -3484,7 +3484,7 @@ LIST_ELEMENT_DELETED: NAT_ENTRY **nn = ToArray(v->NatTable); UINT i; - for (i = 0;i < num;i++) + for (i = 0; i < num; i++) { NAT_ENTRY *n = nn[i]; n->DisconnectNow = true; @@ -3695,7 +3695,7 @@ bool ArpaToIP(IP *ip, char *str) // Convert the token [0, 1, 2, 3] to IP UINT i; Zero(ip, sizeof(IP)); - for (i = 0;i < 4;i++) + for (i = 0; i < 4; i++) { ip->addr[i] = (UCHAR)ToInt(token->Token[3 - i]); } @@ -3815,7 +3815,7 @@ void NatIcmpThreadProc(THREAD *thread, void *param) // Send a query by using the ICMP API ret = IcmpApiEchoSend(&dest_ip, n->IcmpQueryBlock->Ttl, - icmp_payload, icmp_payload_size, NAT_ICMP_TIMEOUT_WITH_API); + icmp_payload, icmp_payload_size, NAT_ICMP_TIMEOUT_WITH_API); } } } @@ -4015,7 +4015,7 @@ bool NatTransactIcmp(VH *v, NAT_ENTRY *n) if (ret != NULL) { if ((ret->Ok && CmpIpAddr(&ret->IpAddress, &dest_ip) == 0) || - (ret->DataSize >= sizeof(IPV4_HEADER) && ((IPV4_HEADER *)ret->Data)->DstIP == n->DestIp)) + (ret->DataSize >= sizeof(IPV4_HEADER) && ((IPV4_HEADER *)ret->Data)->DstIP == n->DestIp)) { // Insert to the queue void *data = Malloc(recv_size); @@ -4203,7 +4203,7 @@ bool NatTransactUdp(VH *v, NAT_ENTRY *n) UINT send_size; bool is_nbtdgm = false; LIST *local_ip_list = NULL; - + if (dest_port == SPECIAL_UDP_PORT_NBTDGM) { // Determine whether NetBIOS Datagram packet @@ -4234,7 +4234,7 @@ bool NatTransactUdp(VH *v, NAT_ENTRY *n) // Transfer by rewriting it properly UINT i; - for (i = 0;i < LIST_NUM(local_ip_list);i++) + for (i = 0; i < LIST_NUM(local_ip_list); i++) { IP *my_ip = LIST_DATA(local_ip_list, i); @@ -4417,108 +4417,108 @@ bool NatTransactTcp(VH *v, NAT_ENTRY *n) break; case NAT_TCP_ESTABLISHED: // TCP connection established + { + UINT old_send_fifo_size = 0; + + // Transmit to the socket if there is data in the receive buffer + while (n->RecvFifo->size > 0) { - UINT old_send_fifo_size = 0; - - // Transmit to the socket if there is data in the receive buffer - while (n->RecvFifo->size > 0) + UINT sent_size = Send(n->Sock, ((UCHAR *)n->RecvFifo->p) + n->RecvFifo->pos, + n->RecvFifo->size, false); + if (sent_size == 0) { - UINT sent_size = Send(n->Sock, ((UCHAR *)n->RecvFifo->p) + n->RecvFifo->pos, - n->RecvFifo->size, false); - if (sent_size == 0) - { - // Communication has been disconnected - n->TcpFinished = true; - v->NatDoCancelFlag = true; - break; - } - else if (sent_size == SOCK_LATER) - { - // Blocking - break; - } - else - { - // Successful transmission - ReadFifo(n->RecvFifo, NULL, sent_size); - n->SendAckNext = true; - - if (false) - { - IP ip; - - n->test_TotalSent += sent_size; - - UINTToIP(&ip, n->DestIp); - Debug("TCP %u: %r:%u %u\n", n->Id, &ip, n->DestPort, (UINT)n->test_TotalSent); - } - } + // Communication has been disconnected + n->TcpFinished = true; + v->NatDoCancelFlag = true; + break; } - - old_send_fifo_size = FifoSize(n->SendFifo); - - // Write to the transmission buffer by obtaining data from the socket - while (true) + else if (sent_size == SOCK_LATER) { - void *buf = (void *)v->TmpBuf; - UINT want_to_recv_size = 0; - UINT recv_size; - // Calculate the size of wanting to receive - if (n->SendFifo->size < NAT_SEND_BUF_SIZE) - { - // Still can receive - want_to_recv_size = MIN(NAT_SEND_BUF_SIZE - n->SendFifo->size, NAT_TMPBUF_SIZE); - } - if (want_to_recv_size == 0) - { - SetNoNeedToRead(n->Sock); - break; - } - recv_size = Recv(n->Sock, buf, want_to_recv_size, false); - if (recv_size == 0) - { - // Communication has been disconnected - n->TcpFinished = true; - v->NatDoCancelFlag = true; - if (n->TcpDisconnected == false) - { - Disconnect(n->Sock); - n->TcpDisconnected = true; - } - break; - } - else if (recv_size == SOCK_LATER) - { - // Blocking - break; - } - else - { - // Successful reception - WriteFifo(n->SendFifo, buf, recv_size); - v->NatDoCancelFlag = true; - } + // Blocking + break; } - - if (old_send_fifo_size == 0 && FifoSize(n->SendFifo) != 0) + else { - // Reset the time data for timeout when the data is newly queued - // in the empty transmission buffer in the transmission process - n->TcpLastRecvAckTime = v->Now; - } + // Successful transmission + ReadFifo(n->RecvFifo, NULL, sent_size); + n->SendAckNext = true; - // Raise a transmission time-out if a certain period of time elapsed - // after receiving the last ACK, and the transmission buffer is not - // empty, and the reception window size of other party is not 0 - if ((n->TcpLastRecvAckTime + (UINT64)VIRTUAL_TCP_SEND_TIMEOUT) < v->Now) - { - if (FifoSize(n->SendFifo) != 0 && n->TcpSendWindowSize != 0) + if (false) { - timeouted = true; + IP ip; + + n->test_TotalSent += sent_size; + + UINTToIP(&ip, n->DestIp); + Debug("TCP %u: %r:%u %u\n", n->Id, &ip, n->DestPort, (UINT)n->test_TotalSent); } } } - break; + + old_send_fifo_size = FifoSize(n->SendFifo); + + // Write to the transmission buffer by obtaining data from the socket + while (true) + { + void *buf = (void *)v->TmpBuf; + UINT want_to_recv_size = 0; + UINT recv_size; + // Calculate the size of wanting to receive + if (n->SendFifo->size < NAT_SEND_BUF_SIZE) + { + // Still can receive + want_to_recv_size = MIN(NAT_SEND_BUF_SIZE - n->SendFifo->size, NAT_TMPBUF_SIZE); + } + if (want_to_recv_size == 0) + { + SetNoNeedToRead(n->Sock); + break; + } + recv_size = Recv(n->Sock, buf, want_to_recv_size, false); + if (recv_size == 0) + { + // Communication has been disconnected + n->TcpFinished = true; + v->NatDoCancelFlag = true; + if (n->TcpDisconnected == false) + { + Disconnect(n->Sock); + n->TcpDisconnected = true; + } + break; + } + else if (recv_size == SOCK_LATER) + { + // Blocking + break; + } + else + { + // Successful reception + WriteFifo(n->SendFifo, buf, recv_size); + v->NatDoCancelFlag = true; + } + } + + if (old_send_fifo_size == 0 && FifoSize(n->SendFifo) != 0) + { + // Reset the time data for timeout when the data is newly queued + // in the empty transmission buffer in the transmission process + n->TcpLastRecvAckTime = v->Now; + } + + // Raise a transmission time-out if a certain period of time elapsed + // after receiving the last ACK, and the transmission buffer is not + // empty, and the reception window size of other party is not 0 + if ((n->TcpLastRecvAckTime + (UINT64)VIRTUAL_TCP_SEND_TIMEOUT) < v->Now) + { + if (FifoSize(n->SendFifo) != 0 && n->TcpSendWindowSize != 0) + { + timeouted = true; + } + } + } + break; } @@ -4582,7 +4582,7 @@ void DeleteNatTcp(VH *v, NAT_ENTRY *n) if (n->TcpRecvList != NULL) { UINT i; - for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) + for (i = 0; i < LIST_NUM(n->TcpRecvList); i++) { IP_PART *p = LIST_DATA(n->TcpRecvList, i); Free(p); @@ -4627,7 +4627,7 @@ void SendBeacon(VH *v) UINT dest_ip; ARPV4_HEADER arp; static char beacon_str[] = - "SecureNAT Virtual TCP/IP Stack Beacon"; + "SecureNAT Virtual TCP/IP Stack Beacon"; // Validate arguments if (v == NULL) { @@ -4647,11 +4647,11 @@ void SendBeacon(VH *v) Copy(arp.SrcAddress, v->MacAddress, 6); arp.SrcIP = v->HostIP; arp.TargetAddress[0] = - arp.TargetAddress[1] = - arp.TargetAddress[2] = - arp.TargetAddress[3] = - arp.TargetAddress[4] = - arp.TargetAddress[5] = 0xff; + arp.TargetAddress[1] = + arp.TargetAddress[2] = + arp.TargetAddress[3] = + arp.TargetAddress[4] = + arp.TargetAddress[5] = 0xff; arp.TargetIP = dest_ip; // Transmission @@ -4750,10 +4750,10 @@ void PollingNatTcp(VH *v, NAT_ENTRY *n) n->LastSynAckSentTime = v->Now; // Send a SYN + ACK SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, - (UINT)(n->SendSeqInit + n->SendSeq), - (UINT)(n->RecvSeqInit + n->RecvSeq), - TCP_SYN | TCP_ACK, n->TcpRecvWindowSize, - v->TcpMss, NULL, 0); + (UINT)(n->SendSeqInit + n->SendSeq), + (UINT)(n->RecvSeqInit + n->RecvSeq), + TCP_SYN | TCP_ACK, n->TcpRecvWindowSize, + v->TcpMss, NULL, 0); n->SynAckSentCount++; } break; @@ -4763,10 +4763,10 @@ void PollingNatTcp(VH *v, NAT_ENTRY *n) if (n->TcpFinished == false || n->TcpForceReset) { SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, - (UINT)(n->SendSeq + n->SendSeqInit), - (UINT)(n->SendSeq + n->SendSeqInit), - TCP_RST, 0, - 0, NULL, 0); + (UINT)(n->SendSeq + n->SendSeqInit), + (UINT)(n->SendSeq + n->SendSeqInit), + TCP_RST, 0, + 0, NULL, 0); // Disconnect n->TcpStatus = NAT_TCP_WAIT_DISCONNECT; n->DisconnectNow = true; @@ -4777,10 +4777,10 @@ void PollingNatTcp(VH *v, NAT_ENTRY *n) if (n->FinSentTime == 0 || (n->FinSentTime > v->Now) || (n->FinSentTime + NAT_FIN_SEND_INTERVAL * (n->FinSentCount + 1)) < v->Now) { SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, - (UINT)(n->SendSeq + n->SendSeqInit), - (UINT)(n->RecvSeq + n->RecvSeqInit), - TCP_ACK | TCP_FIN, 0, - 0, NULL, 0); + (UINT)(n->SendSeq + n->SendSeqInit), + (UINT)(n->RecvSeq + n->RecvSeqInit), + TCP_ACK | TCP_FIN, 0, + 0, NULL, 0); n->FinSentTime = v->Now; n->FinSentSeq = (UINT)(n->SendSeq + n->SendSeqInit); n->FinSentCount++; @@ -4793,120 +4793,120 @@ void PollingNatTcp(VH *v, NAT_ENTRY *n) break; case NAT_TCP_ESTABLISHED: // Connection established + { + UINT send_data_size; + UINT current_pointer; + UINT notice_window_size_value = 0; + UINT buf_free_bytes = 0; + // Determine the value of the window size to be notified + if (FifoSize(n->RecvFifo) < NAT_RECV_BUF_SIZE) { - UINT send_data_size; - UINT current_pointer; - UINT notice_window_size_value = 0; - UINT buf_free_bytes = 0; - // Determine the value of the window size to be notified - if (FifoSize(n->RecvFifo) < NAT_RECV_BUF_SIZE) + buf_free_bytes = NAT_RECV_BUF_SIZE - FifoSize(n->RecvFifo); + } + notice_window_size_value = MIN(n->TcpRecvWindowSize, buf_free_bytes); + if (n->LastSentKeepAliveTime == 0 || + (n->LastSentKeepAliveTime + (UINT64)NAT_ACK_KEEPALIVE_SPAN) < v->Now || + (n->LastSentKeepAliveTime > v->Now)) + { + if (n->LastSentKeepAliveTime != 0) { - buf_free_bytes = NAT_RECV_BUF_SIZE - FifoSize(n->RecvFifo); + // Send an ACK packet for Keep-Alive + SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, + (UINT)(n->SendSeqInit + n->SendSeq), + (UINT)(n->RecvSeqInit + n->RecvSeq) - 1, + TCP_ACK, + notice_window_size_value, + 0, + NULL, + 0); } - notice_window_size_value = MIN(n->TcpRecvWindowSize, buf_free_bytes); - if (n->LastSentKeepAliveTime == 0 || - (n->LastSentKeepAliveTime + (UINT64)NAT_ACK_KEEPALIVE_SPAN) < v->Now || - (n->LastSentKeepAliveTime > v->Now)) + n->LastSentKeepAliveTime = v->Now; + } + if (n->TcpLastSentTime == 0 || + (n->TcpLastSentTime > v->Now) || + ((n->TcpLastSentTime + (UINT64)n->TcpSendTimeoutSpan) < v->Now) || + n->SendAckNext) + { + // If there is data to send, send the data + // Calculate the segment size to be transmitted + send_data_size = n->TcpSendWindowSize; + if (send_data_size > (n->TcpSendCWnd * n->TcpSendMaxSegmentSize)) { - if (n->LastSentKeepAliveTime != 0) + // Apply the cwnd value + send_data_size = n->TcpSendCWnd * n->TcpSendMaxSegmentSize; + } + if (send_data_size > n->SendFifo->size) + { + // Can not be sent over the data that is currently held + send_data_size = n->SendFifo->size; + } + if (send_data_size >= 1) + { + // Transmit the fragmented segments + current_pointer = 0; + while (send_data_size > 0) { - // Send an ACK packet for Keep-Alive + UINT send_segment_size = MIN(n->TcpSendMaxSegmentSize, send_data_size); + void *send_segment = (void *)(((UCHAR *)n->SendFifo->p) + n->SendFifo->pos + current_pointer); SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, - (UINT)(n->SendSeqInit + n->SendSeq), - (UINT)(n->RecvSeqInit + n->RecvSeq) - 1, - TCP_ACK, - notice_window_size_value, - 0, - NULL, - 0); + (UINT)(n->SendSeqInit + n->SendSeq + (UINT64)current_pointer), + (UINT)(n->RecvSeqInit + n->RecvSeq), + TCP_ACK | TCP_PSH, + notice_window_size_value, + 0, + send_segment, + send_segment_size); + current_pointer += send_segment_size; + send_data_size -= send_segment_size; + } + // Record the transmission time + n->TcpLastSentTime = v->Now; + // Record the stream size to be transmitted this time + n->SendMissionSize = current_pointer; + n->CurrentSendingMission = true; + // RTT measurement + if (n->CalcRTTStartTime == 0) + { + n->CalcRTTStartTime = v->Now; + n->CalcRTTStartValue = n->SendSeq + current_pointer - 1; + } + if (n->RetransmissionUsedFlag == false) + { + n->RetransmissionUsedFlag = true; + } + else + { + // Congestion is detected + if (n->TcpSendCWnd > 2) + { + n->TcpSendCWnd--; + } } - n->LastSentKeepAliveTime = v->Now; } - if (n->TcpLastSentTime == 0 || - (n->TcpLastSentTime > v->Now) || - ((n->TcpLastSentTime + (UINT64)n->TcpSendTimeoutSpan) < v->Now) || - n->SendAckNext) + else if (n->SendAckNext) { - // If there is data to send, send the data - // Calculate the segment size to be transmitted - send_data_size = n->TcpSendWindowSize; - if (send_data_size > (n->TcpSendCWnd * n->TcpSendMaxSegmentSize)) - { - // Apply the cwnd value - send_data_size = n->TcpSendCWnd * n->TcpSendMaxSegmentSize; - } - if (send_data_size > n->SendFifo->size) - { - // Can not be sent over the data that is currently held - send_data_size = n->SendFifo->size; - } - if (send_data_size >= 1) - { - // Transmit the fragmented segments - current_pointer = 0; - while (send_data_size > 0) - { - UINT send_segment_size = MIN(n->TcpSendMaxSegmentSize, send_data_size); - void *send_segment = (void *)(((UCHAR *)n->SendFifo->p) + n->SendFifo->pos + current_pointer); - SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, - (UINT)(n->SendSeqInit + n->SendSeq + (UINT64)current_pointer), - (UINT)(n->RecvSeqInit + n->RecvSeq), - TCP_ACK | TCP_PSH, - notice_window_size_value, - 0, - send_segment, - send_segment_size); - current_pointer += send_segment_size; - send_data_size -= send_segment_size; - } - // Record the transmission time - n->TcpLastSentTime = v->Now; - // Record the stream size to be transmitted this time - n->SendMissionSize = current_pointer; - n->CurrentSendingMission = true; - // RTT measurement - if (n->CalcRTTStartTime == 0) - { - n->CalcRTTStartTime = v->Now; - n->CalcRTTStartValue = n->SendSeq + current_pointer - 1; - } - if (n->RetransmissionUsedFlag == false) - { - n->RetransmissionUsedFlag = true; - } - else - { - // Congestion is detected - if (n->TcpSendCWnd > 2) - { - n->TcpSendCWnd--; - } - } - } - else if (n->SendAckNext) - { - // Send only an ACK - SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, - (UINT)(n->SendSeqInit + n->SendSeq), - (UINT)(n->RecvSeqInit + n->RecvSeq), - TCP_ACK, - notice_window_size_value, - 0, - NULL, - 0); - } - n->SendAckNext = false; + // Send only an ACK + SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, + (UINT)(n->SendSeqInit + n->SendSeq), + (UINT)(n->RecvSeqInit + n->RecvSeq), + TCP_ACK, + notice_window_size_value, + 0, + NULL, + 0); } - if (n->TcpFinished) + n->SendAckNext = false; + } + if (n->TcpFinished) + { + // Disconnect if all data transmission has completed + if (n->SendFifo->size == 0 && n->RecvFifo->size == 0) { - // Disconnect if all data transmission has completed - if (n->SendFifo->size == 0 && n->RecvFifo->size == 0) - { - n->TcpStatus = NAT_TCP_SEND_RESET; - } + n->TcpStatus = NAT_TCP_SEND_RESET; } } - break; + } + break; } } @@ -4935,7 +4935,7 @@ void TcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT de { // Disable User-mode NAT SendTcp(v, dest_ip, dest_port, src_ip, src_port, - 0, seq + 1, TCP_RST | TCP_ACK, 0, 0, NULL, 0); + 0, seq + 1, TCP_RST | TCP_ACK, 0, 0, NULL, 0); return; } @@ -4956,7 +4956,7 @@ void TcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT de { // Return the RST if it was not possible to create SendTcp(v, dest_ip, dest_port, src_ip, src_port, - 0, seq + 1, TCP_RST | TCP_ACK, 0, 0, NULL, 0); + 0, seq + 1, TCP_RST | TCP_ACK, 0, 0, NULL, 0); return; } @@ -4991,7 +4991,7 @@ void TcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT de { // Return a RST since a packet which is not registered in the NAT entry arrived SendTcp(v, dest_ip, dest_port, src_ip, src_port, - ack, ack, TCP_RST, 0, 0, NULL, 0); + ack, ack, TCP_RST, 0, 0, NULL, 0); return; } @@ -5016,7 +5016,7 @@ void TcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT de if ((tcp->Flag & TCP_ACK) && ((tcp->Flag & TCP_SYN) == false)) { if (seq == (UINT)(n->RecvSeqInit + n->RecvSeq) && - ack == (UINT)(n->SendSeqInit + n->SendSeq + 1)) + ack == (UINT)(n->SendSeqInit + n->SendSeq + 1)) { // Handshake complete since the ACK packet came back n->SendSeq++; // SYN packet consumes the seq by 1 @@ -5105,11 +5105,11 @@ TCP_RESET: // Smoothing n->CurrentRTT = - (UINT) - ( - ((UINT64)n->CurrentRTT * (UINT64)9 + - (UINT64)time_span * (UINT64)1) / (UINT64)10 - ); + (UINT) + ( + ((UINT64)n->CurrentRTT * (UINT64)9 + + (UINT64)time_span * (UINT64)1) / (UINT64)10 + ); n->TcpSendTimeoutSpan = n->CurrentRTT * 2; } } @@ -5167,18 +5167,18 @@ TCP_RESET: { UINT send_segment_size = MIN(n->TcpSendMaxSegmentSize, send_data_size); void *send_segment = (void *)(( - (UCHAR *)n->SendFifo->p) + n->SendFifo->pos + - current_pointer + send_offset); + (UCHAR *)n->SendFifo->p) + n->SendFifo->pos + + current_pointer + send_offset); SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort, - (UINT)(n->SendSeqInit + n->SendSeq + (UINT64)current_pointer - + (UINT)send_offset), - (UINT)(n->RecvSeqInit + n->RecvSeq), - TCP_ACK | TCP_PSH, - notice_window_size_value, - 0, - send_segment, - send_segment_size); + (UINT)(n->SendSeqInit + n->SendSeq + (UINT64)current_pointer + + (UINT)send_offset), + (UINT)(n->RecvSeqInit + n->RecvSeq), + TCP_ACK | TCP_PSH, + notice_window_size_value, + 0, + send_segment, + send_segment_size); current_pointer += send_segment_size; send_data_size -= send_segment_size; } @@ -5230,11 +5230,11 @@ TCP_RESET: WriteFifo(n->TcpRecvWindow, NULL, offset + size - FifoSize(n->TcpRecvWindow)); } Copy(((UCHAR *)n->TcpRecvWindow->p) + n->TcpRecvWindow->pos + - offset, data, size); + offset, data, size); me = ZeroMalloc(sizeof(IP_PART)); me->Offset = offset; me->Size = size; - for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) + for (i = 0; i < LIST_NUM(n->TcpRecvList); i++) { IP_PART *p = LIST_DATA(n->TcpRecvList, i); // If there are overlapped region, remove these @@ -5251,7 +5251,7 @@ TCP_RESET: me->Size = 0; } else if (me->Offset > p->Offset && me->Offset < (p->Offset + p->Size) && - (me->Offset + me->Size) > (p->Offset + p->Size)) + (me->Offset + me->Size) > (p->Offset + p->Size)) { // Partially overlapped p->Size -= p->Offset + p->Size - me->Offset; @@ -5273,7 +5273,7 @@ TCP_RESET: } KILL_NULL_FIRST: // Remove all blank items from reception list - for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) + for (i = 0; i < LIST_NUM(n->TcpRecvList); i++) { IP_PART *p = LIST_DATA(n->TcpRecvList, i); if (p->Size == 0) @@ -5285,7 +5285,7 @@ KILL_NULL_FIRST: } SCAN_FIRST: // Extract if there is something starting at offset 0 in the received list - for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) + for (i = 0; i < LIST_NUM(n->TcpRecvList); i++) { IP_PART *p = LIST_DATA(n->TcpRecvList, i); UINT sz; @@ -5301,7 +5301,7 @@ SCAN_FIRST: Free(p); ReadFifo(n->TcpRecvWindow, NULL, sz); // Slide all the items to the left - for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) + for (i = 0; i < LIST_NUM(n->TcpRecvList); i++) { p = LIST_DATA(n->TcpRecvList, i); p->Offset -= sz; @@ -5369,7 +5369,7 @@ void ParseTcpOption(TCP_OPTION *o, void *data, UINT size) return; } value_size -= 2; - + Copy(value, &buf[i], value_size); i += value_size; if (i > size) @@ -5427,7 +5427,7 @@ NAT_ENTRY *CreateNatTcp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT de } } - // If the connections other than SYN_SENT are too many, delete old ones + // If the connections other than SYN_SENT are too many, delete old ones if (o != NULL && o->SecureNAT_MaxTcpSessionsPerIp != 0) { if (GetNumNatEntriesPerIp(v, src_ip, NAT_TCP, false) >= o->SecureNAT_MaxTcpSessionsPerIp) @@ -5608,7 +5608,7 @@ void PollingNatIcmp(VH *v, NAT_ENTRY *n) icmp->Checksum = IpChecksum(icmp, icmp_size); SendIpEx(v, n->SrcIp, ipv4->SrcIP, ipv4->Protocol, ipv4_payload, ipv4_payload_size, - MAX(ipv4->TimeToLive - 1, 1)); + MAX(ipv4->TimeToLive - 1, 1)); } } } @@ -5654,7 +5654,7 @@ void PoolingNatUdp(VH *v, NAT_ENTRY *n) } SendUdp(v, n->SrcIp, n->SrcPort, src_ip, n->DestPort, - block->Buf, block->Size); + block->Buf, block->Size); FreeBlock(block); } @@ -5678,7 +5678,7 @@ void PoolingNat(VH *v) } // Process by scanning the all NAT entries - for (i = 0;i < LIST_NUM(v->NatTable);i++) + for (i = 0; i < LIST_NUM(v->NatTable); i++) { NAT_ENTRY *n = LIST_DATA(v->NatTable, i); @@ -6106,7 +6106,7 @@ void EncodeNetBiosName(UCHAR *dst, char *src) return; } - for (i = 0;i < 16;i++) + for (i = 0; i < 16; i++) { tmp[i] = ' '; } @@ -6124,7 +6124,7 @@ void EncodeNetBiosName(UCHAR *dst, char *src) tmp[15] = 0; - for (i = 0;i < 16;i++) + for (i = 0; i < 16; i++) { char c = tmp[i]; char *s = CharToNetBiosStr(c); @@ -6141,67 +6141,128 @@ char *CharToNetBiosStr(char c) switch (c) { - case '\0': return "AA"; - case 'A': return "EB"; - case 'B': return "EC"; - case 'C': return "ED"; - case 'D': return "EE"; - case 'E': return "EF"; - case 'F': return "EG"; - case 'G': return "EH"; - case 'H': return "EI"; - case 'I': return "EJ"; - case 'J': return "EK"; - case 'K': return "EL"; - case 'L': return "EM"; - case 'M': return "EN"; - case 'N': return "EO"; - case 'O': return "EP"; - case 'P': return "FA"; - case 'Q': return "FB"; - case 'R': return "FC"; - case 'S': return "FD"; - case 'T': return "FE"; - case 'U': return "FF"; - case 'V': return "FG"; - case 'W': return "FH"; - case 'X': return "FI"; - case 'Y': return "FJ"; - case 'Z': return "FK"; - case '0': return "DA"; - case '1': return "DB"; - case '2': return "DC"; - case '3': return "DD"; - case '4': return "DE"; - case '5': return "DF"; - case '6': return "DG"; - case '7': return "DH"; - case '8': return "DI"; - case '9': return "DJ"; - case ' ': return "CA"; - case '!': return "CB"; - case '\"': return "CC"; - case '#': return "CD"; - case '$': return "CE"; - case '%': return "CF"; - case '&': return "CG"; - case '\'': return "CH"; - case '(': return "CI"; - case ')': return "CJ"; - case '*': return "CK"; - case '+': return "CL"; - case ',': return "CM"; - case '-': return "CN"; - case '.': return "CO"; - case '=': return "DN"; - case ':': return "DK"; - case ';': return "DL"; - case '@': return "EA"; - case '^': return "FO"; - case '_': return "FP"; - case '{': return "HL"; - case '}': return "HN"; - case '~': return "HO"; + case '\0': + return "AA"; + case 'A': + return "EB"; + case 'B': + return "EC"; + case 'C': + return "ED"; + case 'D': + return "EE"; + case 'E': + return "EF"; + case 'F': + return "EG"; + case 'G': + return "EH"; + case 'H': + return "EI"; + case 'I': + return "EJ"; + case 'J': + return "EK"; + case 'K': + return "EL"; + case 'L': + return "EM"; + case 'M': + return "EN"; + case 'N': + return "EO"; + case 'O': + return "EP"; + case 'P': + return "FA"; + case 'Q': + return "FB"; + case 'R': + return "FC"; + case 'S': + return "FD"; + case 'T': + return "FE"; + case 'U': + return "FF"; + case 'V': + return "FG"; + case 'W': + return "FH"; + case 'X': + return "FI"; + case 'Y': + return "FJ"; + case 'Z': + return "FK"; + case '0': + return "DA"; + case '1': + return "DB"; + case '2': + return "DC"; + case '3': + return "DD"; + case '4': + return "DE"; + case '5': + return "DF"; + case '6': + return "DG"; + case '7': + return "DH"; + case '8': + return "DI"; + case '9': + return "DJ"; + case ' ': + return "CA"; + case '!': + return "CB"; + case '\"': + return "CC"; + case '#': + return "CD"; + case '$': + return "CE"; + case '%': + return "CF"; + case '&': + return "CG"; + case '\'': + return "CH"; + case '(': + return "CI"; + case ')': + return "CJ"; + case '*': + return "CK"; + case '+': + return "CL"; + case ',': + return "CM"; + case '-': + return "CN"; + case '.': + return "CO"; + case '=': + return "DN"; + case ':': + return "DK"; + case ';': + return "DL"; + case '@': + return "EA"; + case '^': + return "FO"; + case '_': + return "FP"; + case '{': + return "HL"; + case '}': + return "HN"; + case '~': + return "HO"; } return "CA"; @@ -6255,8 +6316,8 @@ bool ProcessNetBiosNameQueryPacketForMyself(VH *v, UINT src_ip, UINT src_port, U classid = Endian16(classid); if (((flags >> 11) & 0x0F) == 0 && - num_query == 1 && name_size == 0x20 && - zero1 == 0 && zero2 == 0 && zero3 == 0 && node_type == 0 && type == 0x0020 && classid == 0x0001) + num_query == 1 && name_size == 0x20 && + zero1 == 0 && zero2 == 0 && zero3 == 0 && node_type == 0 && type == 0x0020 && classid == 0x0001) { char my_pcname[MAX_SIZE]; @@ -6316,7 +6377,7 @@ bool ProcessNetBiosNameQueryPacketForMyself(VH *v, UINT src_ip, UINT src_port, U UINT i; // Return only private IP if there is a private IP - for (i = 0;i < LIST_NUM(ip_list);i++) + for (i = 0; i < LIST_NUM(ip_list); i++) { IP *ip = LIST_DATA(ip_list, i); @@ -6338,7 +6399,7 @@ bool ProcessNetBiosNameQueryPacketForMyself(VH *v, UINT src_ip, UINT src_port, U if (found == false) { // Return all IP if no private IP are found - for (i = 0;i < LIST_NUM(ip_list);i++) + for (i = 0; i < LIST_NUM(ip_list); i++) { IP *ip = LIST_DATA(ip_list, i); @@ -6524,7 +6585,7 @@ bool ParseDnsPacketEx(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest // Create a DNS entry nat = CreateNatDns(v, src_ip, src_port, dest_ip, dest_port, transaction_id, - false, hostname); + false, hostname); if (nat == false) { @@ -6741,7 +6802,7 @@ BUF *BuildDnsHostName(char *hostname) b = NewBuf(); // Add a host string - for (i = 0;i < token->NumTokens;i++) + for (i = 0; i < token->NumTokens; i++) { size = (UCHAR)StrLen(token->Token[i]); WriteBuf(b, &size, 1); @@ -6784,7 +6845,7 @@ void PollingNatDns(VH *v, NAT_ENTRY *n) // Create a NAT DNS entry NAT_ENTRY *CreateNatDns(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, - UINT transaction_id, bool dns_get_ip_from_host, char *dns_target_host_name) + UINT transaction_id, bool dns_get_ip_from_host, char *dns_target_host_name) { NAT_ENTRY *n; HUB_OPTION *o; @@ -7147,7 +7208,7 @@ void PollingIpCombine(VH *v) // Discard the old combining object o = NULL; - for (i = 0;i < LIST_NUM(v->IpCombine);i++) + for (i = 0; i < LIST_NUM(v->IpCombine); i++) { IP_COMBINE *c = LIST_DATA(v->IpCombine, i); @@ -7163,7 +7224,7 @@ void PollingIpCombine(VH *v) if (o != NULL) { - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { IP_COMBINE *c = LIST_DATA(o, i); @@ -7349,7 +7410,7 @@ void VirtualIcmpEchoRequestReceived(VH *v, UINT src_ip, UINT dst_ip, void *data, { // Process by the Native NAT NnIcmpEchoRecvForInternet(v, src_ip, dst_ip, data, size, ttl, icmp_data, icmp_size, - ip_header, ip_header_size, max_l3_size); + ip_header, ip_header_size, max_l3_size); return; } @@ -7363,7 +7424,7 @@ void VirtualIcmpEchoRequestReceived(VH *v, UINT src_ip, UINT dst_ip, void *data, { // Process in the Raw Socket VirtualIcmpEchoRequestReceivedRaw(v, src_ip, dst_ip, data, size, ttl, icmp_data, icmp_size, - ip_header, ip_header_size); + ip_header, ip_header_size); return; } @@ -7433,7 +7494,7 @@ void VirtualIcmpReceived(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size, { case ICMP_TYPE_ECHO_REQUEST: // ICMP Echo request VirtualIcmpEchoRequestReceived(v, src_ip, dst_ip, ((UCHAR *)data) + sizeof(ICMP_HEADER), msg_size, ttl, - icmp, size, ip_header, ip_header_size, max_l3_size); + icmp, size, ip_header, ip_header_size, max_l3_size); break; case ICMP_TYPE_ECHO_RESPONSE: // ICMP Echo response @@ -7534,7 +7595,7 @@ void CombineIp(VH *v, IP_COMBINE *c, UINT offset, void *data, UINT size, bool la // Check the overlap between the region which is represented by the offset and size of the // existing received list and the region which is represented by the offset and size - for (i = 0;i < LIST_NUM(c->IpParts);i++) + for (i = 0; i < LIST_NUM(c->IpParts); i++) { UINT moving_size; IP_PART *p = LIST_DATA(c->IpParts, i); @@ -7591,7 +7652,7 @@ void CombineIp(VH *v, IP_COMBINE *c, UINT offset, void *data, UINT size, bool la UINT total_size = 0; UINT i; - for (i = 0;i < LIST_NUM(c->IpParts);i++) + for (i = 0; i < LIST_NUM(c->IpParts); i++) { IP_PART *p = LIST_DATA(c->IpParts, i); @@ -7602,7 +7663,7 @@ void CombineIp(VH *v, IP_COMBINE *c, UINT offset, void *data, UINT size, bool la { // Received all of the IP packet IpReceived(v, c->SrcIP, c->DestIP, c->Protocol, c->Data, c->Size, c->MacBroadcast, c->Ttl, - c->HeadIpHeaderData, c->HeadIpHeaderDataSize, c->SrcIsLocalMacAddr, c->MaxL3Size); + c->HeadIpHeaderData, c->HeadIpHeaderDataSize, c->SrcIsLocalMacAddr, c->MaxL3Size); // Release the combining object FreeIpCombine(v, c); @@ -7628,7 +7689,7 @@ void FreeIpCombine(VH *v, IP_COMBINE *c) Free(c->Data); // Release the partial list - for (i = 0;i < LIST_NUM(c->IpParts);i++) + for (i = 0; i < LIST_NUM(c->IpParts); i++) { IP_PART *p = LIST_DATA(c->IpParts, i); @@ -7722,7 +7783,7 @@ void FreeIpCombineList(VH *v) return; } - for (i = 0;i < LIST_NUM(v->IpCombine);i++) + for (i = 0; i < LIST_NUM(v->IpCombine); i++) { IP_COMBINE *c = LIST_DATA(v->IpCombine, i); @@ -7845,7 +7906,7 @@ void VirtualIpReceived(VH *v, PKT *packet) // Because this packet has not been fragmented, it can be delivered to the upper layer immediately head_ip_header_data = (UCHAR *)packet->L3.IPv4Header; IpReceived(v, ip->SrcIP, ip->DstIP, ip->Protocol, data, size, packet->BroadcastPacket, ip->TimeToLive, - head_ip_header_data, head_ip_header_size, is_local_mac, ip_l3_size); + head_ip_header_data, head_ip_header_size, is_local_mac, ip_l3_size); } else { @@ -7870,8 +7931,8 @@ void VirtualIpReceived(VH *v, PKT *packet) { // Create a combining object because it is the first packet c = InsertIpCombine( - v, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol, packet->BroadcastPacket, - ip->TimeToLive, is_local_mac); + v, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol, packet->BroadcastPacket, + ip->TimeToLive, is_local_mac); if (c != NULL) { c->MaxL3Size = ip_l3_size; @@ -7894,7 +7955,7 @@ void SendWaitingIp(VH *v, UCHAR *mac, UINT dest_ip) } // Get a target list - for (i = 0;i < LIST_NUM(v->IpWaitTable);i++) + for (i = 0; i < LIST_NUM(v->IpWaitTable); i++) { IP_WAIT *w = LIST_DATA(v->IpWaitTable, i); @@ -7911,7 +7972,7 @@ void SendWaitingIp(VH *v, UCHAR *mac, UINT dest_ip) // Send the target packets at once if (o != NULL) { - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { IP_WAIT *w = LIST_DATA(o, i); @@ -7942,7 +8003,7 @@ void DeleteOldIpWaitTable(VH *v) } // Get the deleting list - for (i = 0;i < LIST_NUM(v->IpWaitTable);i++) + for (i = 0; i < LIST_NUM(v->IpWaitTable); i++) { IP_WAIT *w = LIST_DATA(v->IpWaitTable, i); @@ -7959,7 +8020,7 @@ void DeleteOldIpWaitTable(VH *v) // Delete all at once if (o != NULL) { - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { IP_WAIT *w = LIST_DATA(o, i); @@ -8023,7 +8084,7 @@ void FreeIpWaitTable(VH *v) return; } - for (i = 0;i < LIST_NUM(v->IpWaitTable);i++) + for (i = 0; i < LIST_NUM(v->IpWaitTable); i++) { IP_WAIT *w = LIST_DATA(v->IpWaitTable, i); @@ -8068,7 +8129,7 @@ void PollingArpWaitTable(VH *v) o = NULL; // Scan whole ARP waiting list - for (i = 0;i < LIST_NUM(v->ArpWaitTable);i++) + for (i = 0; i < LIST_NUM(v->ArpWaitTable); i++) { ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i); @@ -8099,7 +8160,7 @@ void PollingArpWaitTable(VH *v) // Remove if there is a ARP waiting record to be deleted if (o != NULL) { - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { ARP_WAIT *w = LIST_DATA(o, i); @@ -8210,7 +8271,7 @@ void FreeArpWaitTable(VH *v) return; } - for (i = 0;i < LIST_NUM(v->ArpWaitTable);i++) + for (i = 0; i < LIST_NUM(v->ArpWaitTable); i++) { ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i); @@ -8285,7 +8346,7 @@ void RefreshArpTable(VH *v) } o = NewListFast(NULL); - for (i = 0;i < LIST_NUM(v->ArpTable);i++) + for (i = 0; i < LIST_NUM(v->ArpTable); i++) { ARP_ENTRY *e = LIST_DATA(v->ArpTable, i); @@ -8298,7 +8359,7 @@ void RefreshArpTable(VH *v) } // Remove expired entries at once - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { ARP_ENTRY *e = LIST_DATA(o, i); @@ -8348,7 +8409,7 @@ void FreeArpTable(VH *v) } // Delete all entries - for (i = 0;i < LIST_NUM(v->ArpTable);i++) + for (i = 0; i < LIST_NUM(v->ArpTable); i++) { ARP_ENTRY *e = LIST_DATA(v->ArpTable, i); Free(e); @@ -8570,7 +8631,7 @@ void PollingBeacon(VH *v) } if (v->LastSendBeacon == 0 || - ((v->LastSendBeacon + BEACON_SEND_INTERVAL) <= Tick64())) + ((v->LastSendBeacon + BEACON_SEND_INTERVAL) <= Tick64())) { v->LastSendBeacon = Tick64(); @@ -8590,7 +8651,7 @@ void VirtualLayer2Send(VH *v, UCHAR *dest_mac, UCHAR *src_mac, USHORT protocol, return; } - // Create buffer + // Create buffer buf = Malloc(MAC_HEADER_SIZE + size); // MAC header @@ -8605,7 +8666,7 @@ void VirtualLayer2Send(VH *v, UCHAR *dest_mac, UCHAR *src_mac, USHORT protocol, // Size size += sizeof(MAC_HEADER); - // Generate the packet + // Generate the packet block = NewBlock(buf, size, 0); // Insert into the queue @@ -8665,7 +8726,7 @@ void SendIpEx(VH *v, UINT dest_ip, UINT src_ip, UCHAR protocol, void *data, UINT // Transmit the fragmented packet SendFragmentedIp(v, dest_ip, src_ip, id, - total_size, offset, protocol, buf + offset, size_of_this_packet, NULL, ttl); + total_size, offset, protocol, buf + offset, size_of_this_packet, NULL, ttl); if (last_packet) { break; @@ -8723,7 +8784,7 @@ void SendFragmentedIp(VH *v, UINT dest_ip, UINT src_ip, USHORT id, USHORT total_ if (dest_mac == NULL) { if (ip->DstIP == 0xffffffff || - (IsInNetwork(ip->DstIP, v->HostIP, v->HostMask) && (ip->DstIP & (~v->HostMask)) == (~v->HostMask))) + (IsInNetwork(ip->DstIP, v->HostIP, v->HostMask) && (ip->DstIP & (~v->HostMask)) == (~v->HostMask))) { // Broadcast address dest_mac = broadcast; @@ -9100,7 +9161,7 @@ void PollingDhcpServer(VH *v) if (v->LastDhcpPolling != 0) { if ((v->LastDhcpPolling + (UINT64)DHCP_POLLING_INTERVAL) > v->Now && - v->LastDhcpPolling < v->Now) + v->LastDhcpPolling < v->Now) { return; } @@ -9185,7 +9246,7 @@ UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip) { // Examine whether the specified IP address is within the range of assignment if (Endian32(v->DhcpIpStart) <= Endian32(request_ip) && - Endian32(request_ip) <= Endian32(v->DhcpIpEnd)) + Endian32(request_ip) <= Endian32(v->DhcpIpEnd)) { // Accept if within the range ret = request_ip; @@ -9196,7 +9257,7 @@ UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip) { // Examine whether the specified IP address is within the range of assignment if (Endian32(v->DhcpIpStart) <= Endian32(request_ip) && - Endian32(request_ip) <= Endian32(v->DhcpIpEnd)) + Endian32(request_ip) <= Endian32(v->DhcpIpEnd)) { // Accept if within the range ret = request_ip; @@ -9222,7 +9283,7 @@ UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip) { // Examine whether the found IP address is in the allocation region if (Endian32(v->DhcpIpStart) <= Endian32(d->IpAddress) && - Endian32(d->IpAddress) <= Endian32(v->DhcpIpEnd)) + Endian32(d->IpAddress) <= Endian32(v->DhcpIpEnd)) { // Use the IP address if it's found within the range ret = d->IpAddress; @@ -9262,7 +9323,7 @@ UINT GetFreeDhcpIpAddress(VH *v) ip_start = Endian32(v->DhcpIpStart); ip_end = Endian32(v->DhcpIpEnd); - for (i = ip_start; i <= ip_end;i++) + for (i = ip_start; i <= ip_end; i++) { UINT ip = Endian32(i); if (SearchDhcpLeaseByIp(v, ip) == NULL && SearchDhcpPendingLeaseByIp(v, ip) == NULL) @@ -9299,7 +9360,7 @@ UINT GetFreeDhcpIpAddressByRandom(VH *v, UCHAR *mac) num_retry = (ip_end - ip_start + 1) * 2; num_retry = MIN(num_retry, 65536 * 2); - for (i = 0;i < num_retry;i++) + for (i = 0; i < num_retry; i++) { UCHAR rand_seed[sizeof(UINT) + 6]; UCHAR hash[16]; @@ -9582,7 +9643,7 @@ void VirtualDhcpServer(VH *v, PKT *p) } // Transmission VirtualDhcpSend(v, tran_id, dest_ip, Endian16(p->L4.UDPHeader->SrcPort), - ip, dhcp->ClientMacAddress, b, dhcp->HardwareType, dhcp->HardwareAddressSize); + ip, dhcp->ClientMacAddress, b, dhcp->HardwareType, dhcp->HardwareAddressSize); // Release the memory FreeBuf(b); @@ -9617,7 +9678,7 @@ void VirtualDhcpServer(VH *v, PKT *p) } // Transmission VirtualDhcpSend(v, tran_id, dest_ip, Endian16(p->L4.UDPHeader->SrcPort), - ip, dhcp->ClientMacAddress, b, dhcp->HardwareType, dhcp->HardwareAddressSize); + ip, dhcp->ClientMacAddress, b, dhcp->HardwareType, dhcp->HardwareAddressSize); // Release the memory FreeBuf(b); @@ -9633,7 +9694,7 @@ void VirtualDhcpServer(VH *v, PKT *p) // Submit the DHCP response packet void VirtualDhcpSend(VH *v, UINT tran_id, UINT dest_ip, UINT dest_port, - UINT new_ip, UCHAR *client_mac, BUF *b, UINT hw_type, UINT hw_addr_size) + UINT new_ip, UCHAR *client_mac, BUF *b, UINT hw_type, UINT hw_addr_size) { UINT blank_size = 128 + 64; UINT dhcp_packet_size; @@ -9924,7 +9985,7 @@ void SetVirtualHostOption(VH *v, VH_OPTION *vo) LockVirtual(v); { // Set the MAC address - for (i = 0;i < 6;i++) + for (i = 0; i < 6; i++) { if (vo->MacAddress[i] != 0) { @@ -9974,8 +10035,8 @@ void SetVirtualHostOption(VH *v, VH_OPTION *vo) else { v->DhcpExpire = MAKESURE(DHCP_MIN_EXPIRE_TIMESPAN, - MIN(vo->DhcpExpireTimeSpan * 1000, 2000000000), - INFINITE); + MIN(vo->DhcpExpireTimeSpan * 1000, 2000000000), + INFINITE); } // Address range to be distributed @@ -10261,7 +10322,7 @@ void GenMacAddress(UCHAR *mac) PACKET_ADAPTER *VirtualGetPacketAdapter() { return NewPacketAdapter(VirtualPaInit, VirtualPaGetCancel, - VirtualPaGetNextPacket, VirtualPaPutPacket, VirtualPaFree); + VirtualPaGetNextPacket, VirtualPaPutPacket, VirtualPaFree); } diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index 75365d97..a80423d7 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -2398,6 +2398,7 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size) { UCHAR *buf; UINT i, icmp_type, buf_size, padding_size; + icmp_type = 0; // Validate arguments if (r == NULL || se == NULL || (data == NULL && data_size != 0)) {