1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Cedar Communication Module
3 
4 
5 // Virtual.c
6 // User-mode virtual host program
7 
8 #include "Virtual.h"
9 
10 #include "BridgeUnix.h"
11 #include "BridgeWin32.h"
12 #include "Connection.h"
13 #include "Hub.h"
14 #include "IPC.h"
15 #include "NativeStack.h"
16 #include "Server.h"
17 
18 #include "Mayaqua/DNS.h"
19 #include "Mayaqua/FileIO.h"
20 #include "Mayaqua/Memory.h"
21 #include "Mayaqua/Object.h"
22 #include "Mayaqua/Str.h"
23 #include "Mayaqua/Tick64.h"
24 
25 static UCHAR broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
26 static char v_vgs_hostname[256] = {0};
27 
28 static char secure_nat_target_hostname[MAX_SIZE] = {0};
29 
30 // Specify the destination host name to be used for connectivity testing in SecureNAT
NnSetSecureNatTargetHostname(char * name)31 void NnSetSecureNatTargetHostname(char *name)
32 {
33 	// Validate arguments
34 	if (name == NULL)
35 	{
36 		return;
37 	}
38 
39 	StrCpy(secure_nat_target_hostname, sizeof(secure_nat_target_hostname), name);
40 }
41 
42 // Delete the oldest NAT session if necessary
NnDeleteOldestNatSessionIfNecessary(NATIVE_NAT * t,UINT ip,UINT protocol)43 void NnDeleteOldestNatSessionIfNecessary(NATIVE_NAT *t, UINT ip, UINT protocol)
44 {
45 	UINT current_num;
46 	UINT max_sessions = 0;
47 	// Validate arguments
48 	if (t == NULL)
49 	{
50 		return;
51 	}
52 
53 	if (t->v->HubOption != NULL)
54 	{
55 		HUB_OPTION *o = t->v->HubOption;
56 
57 		switch (protocol)
58 		{
59 		case NAT_TCP:
60 			max_sessions = o->SecureNAT_MaxTcpSessionsPerIp;
61 			break;
62 
63 		case NAT_UDP:
64 			max_sessions = o->SecureNAT_MaxUdpSessionsPerIp;
65 			break;
66 
67 		case NAT_ICMP:
68 			max_sessions = o->SecureNAT_MaxIcmpSessionsPerIp;
69 			break;
70 		}
71 	}
72 
73 	if (max_sessions == 0)
74 	{
75 		return;
76 	}
77 
78 	current_num = NnGetNumNatEntriesPerIp(t, ip, protocol);
79 
80 	if (current_num >= max_sessions)
81 	{
82 		NnDeleteOldestNatSession(t, ip, protocol);
83 	}
84 }
85 
86 // Delete the oldest NAT session
NnDeleteOldestNatSession(NATIVE_NAT * t,UINT ip,UINT protocol)87 void NnDeleteOldestNatSession(NATIVE_NAT *t, UINT ip, UINT protocol)
88 {
89 	NATIVE_NAT_ENTRY *e;
90 	// Validate arguments
91 	if (t == NULL)
92 	{
93 		return;
94 	}
95 
96 	e = NnGetOldestNatEntryOfIp(t, ip, protocol);
97 
98 	if (e != NULL)
99 	{
100 		NnDeleteSession(t, e);
101 	}
102 }
103 
104 // Get the oldest NAT session
NnGetOldestNatEntryOfIp(NATIVE_NAT * t,UINT ip,UINT protocol)105 NATIVE_NAT_ENTRY *NnGetOldestNatEntryOfIp(NATIVE_NAT *t, UINT ip, UINT protocol)
106 {
107 	UINT i;
108 	NATIVE_NAT_ENTRY *oldest = NULL;
109 	UINT64 oldest_tick = 0xFFFFFFFFFFFFFFFFULL;
110 	// Validate arguments
111 	if (t == NULL)
112 	{
113 		return NULL;
114 	}
115 
116 	for (i = 0; i < LIST_NUM(t->NatTableForRecv->AllList); i++)
117 	{
118 		NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i);
119 
120 		if (e->SrcIp == ip)
121 		{
122 			if (e->Protocol == protocol)
123 			{
124 				if (e->LastCommTime <= oldest_tick)
125 				{
126 					oldest_tick = e->LastCommTime;
127 					oldest = e;
128 				}
129 			}
130 		}
131 	}
132 
133 	return oldest;
134 }
135 
136 // Get the number of NAT sessions per IP address
NnGetNumNatEntriesPerIp(NATIVE_NAT * t,UINT src_ip,UINT protocol)137 UINT NnGetNumNatEntriesPerIp(NATIVE_NAT *t, UINT src_ip, UINT protocol)
138 {
139 	UINT ret = 0;
140 	UINT i;
141 	// Validate arguments
142 	if (t == NULL)
143 	{
144 		return 0;
145 	}
146 
147 	for (i = 0; i < LIST_NUM(t->NatTableForRecv->AllList); i++)
148 	{
149 		NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i);
150 
151 		if (e->SrcIp == src_ip)
152 		{
153 			if (e->Protocol == protocol)
154 			{
155 				ret++;
156 			}
157 		}
158 	}
159 
160 	return ret;
161 }
162 
163 // Delete the old NAT sessions
NnDeleteOldSessions(NATIVE_NAT * t)164 void NnDeleteOldSessions(NATIVE_NAT *t)
165 {
166 	UINT i;
167 	LIST *o;
168 	UINT64 now;
169 	// Validate arguments
170 	if (t == NULL)
171 	{
172 		return;
173 	}
174 
175 	o = NULL;
176 	now = t->v->Now;
177 
178 	for (i = 0; i < LIST_NUM(t->NatTableForSend->AllList); i++)
179 	{
180 		NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i);
181 		UINT64 timeout;
182 
183 		if (e->Status == NAT_TCP_CONNECTED || e->Status == NAT_TCP_ESTABLISHED)
184 		{
185 			timeout = e->LastCommTime + (UINT64)(e->Protocol == NAT_TCP ? t->v->NatTcpTimeout : t->v->NatUdpTimeout);
186 		}
187 		else
188 		{
189 			timeout = e->LastCommTime + (UINT64)NN_TIMEOUT_FOR_UNESTBALISHED_TCP;
190 		}
191 
192 		if (timeout < now)
193 		{
194 			// Time-out occurs
195 			if (o == NULL)
196 			{
197 				o = NewListFast(NULL);
198 			}
199 
200 			Add(o, e);
201 		}
202 	}
203 
204 	if (o != NULL)
205 	{
206 		for (i = 0; i < LIST_NUM(o); i++)
207 		{
208 			NATIVE_NAT_ENTRY *e = LIST_DATA(o, i);
209 
210 			NnDeleteSession(t, e);
211 		}
212 
213 		ReleaseList(o);
214 	}
215 }
216 
217 // Delete the NAT entry
NnDeleteSession(NATIVE_NAT * t,NATIVE_NAT_ENTRY * e)218 void NnDeleteSession(NATIVE_NAT *t, NATIVE_NAT_ENTRY *e)
219 {
220 	// Validate arguments
221 	if (t == NULL || e == NULL)
222 	{
223 		return;
224 	}
225 
226 	switch (e->Protocol)
227 	{
228 	case NAT_TCP:
229 		// Send a RST to the client side
230 		SendTcp(t->v, e->DestIp, e->DestPort, e->SrcIp, e->SrcPort,
231 		        e->LastAck, e->LastSeq + (e->Status == NAT_TCP_CONNECTING ? 1 : 0), TCP_RST | TCP_ACK, 0, 0, NULL, 0);
232 
233 		NLog(t->v, "LH_NAT_TCP_DELETED", e->Id);
234 		break;
235 
236 	case NAT_UDP:
237 		NLog(t->v, "LH_NAT_UDP_DELETED", e->Id);
238 		break;
239 
240 	case NAT_ICMP:
241 		Debug("NAT ICMP %u Deleted.\n", e->Id);
242 		break;
243 	}
244 
245 	DeleteHash(t->NatTableForSend, e);
246 	DeleteHash(t->NatTableForRecv, e);
247 
248 	Free(e);
249 }
250 
251 // Poll the IP combining object
NnPollingIpCombine(NATIVE_NAT * t)252 void NnPollingIpCombine(NATIVE_NAT *t)
253 {
254 	LIST *o;
255 	UINT i;
256 	// Validate arguments
257 	if (t == NULL)
258 	{
259 		return;
260 	}
261 
262 	// Discard the old combining object
263 	o = NULL;
264 	for (i = 0; i < LIST_NUM(t->IpCombine); i++)
265 	{
266 		IP_COMBINE *c = LIST_DATA(t->IpCombine, i);
267 
268 		if (c->Expire < t->v->Now)
269 		{
270 			if (o == NULL)
271 			{
272 				o = NewListFast(NULL);
273 			}
274 			Add(o, c);
275 		}
276 	}
277 
278 	if (o != NULL)
279 	{
280 		for (i = 0; i < LIST_NUM(o); i++)
281 		{
282 			IP_COMBINE *c = LIST_DATA(o, i);
283 
284 			// Remove from the list
285 			Delete(t->IpCombine, c);
286 
287 			// Release the memory
288 			NnFreeIpCombine(t, c);
289 		}
290 		ReleaseList(o);
291 	}
292 }
293 
294 // Combine the IP packet received to the IP combining object
NnCombineIp(NATIVE_NAT * t,IP_COMBINE * c,UINT offset,void * data,UINT size,bool last_packet,UCHAR * head_ip_header_data,UINT head_ip_header_size)295 void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT size, bool last_packet, UCHAR *head_ip_header_data, UINT head_ip_header_size)
296 {
297 	UINT i;
298 	IP_PART *p;
299 	UINT need_size;
300 	UINT data_size_delta;
301 	// Validate arguments
302 	if (c == NULL || data == NULL)
303 	{
304 		return;
305 	}
306 
307 	// Check the size and offset
308 	if ((offset + size) > 65535)
309 	{
310 		// Do not process a packet larger than 64Kbytes
311 		return;
312 	}
313 
314 	if (last_packet == false && c->Size != 0)
315 	{
316 		if ((offset + size) > c->Size)
317 		{
318 			// Do not process a packet larger than the packet size
319 			return;
320 		}
321 	}
322 
323 	if (head_ip_header_data != NULL && head_ip_header_size >= sizeof(IPV4_HEADER))
324 	{
325 		if (c->HeadIpHeaderData == NULL)
326 		{
327 			c->HeadIpHeaderData = Clone(head_ip_header_data, head_ip_header_size);
328 			c->HeadIpHeaderDataSize = head_ip_header_size;
329 		}
330 	}
331 
332 	need_size = offset + size;
333 	data_size_delta = c->DataReserved;
334 	// Ensure sufficient if the buffer is insufficient
335 	while (c->DataReserved < need_size)
336 	{
337 		c->DataReserved = c->DataReserved * 4;
338 		c->Data = ReAlloc(c->Data, c->DataReserved);
339 	}
340 	data_size_delta = c->DataReserved - data_size_delta;
341 	t->CurrentIpQuota += data_size_delta;
342 
343 	// Overwrite the data into the buffer
344 	Copy(((UCHAR *)c->Data) + offset, data, size);
345 
346 	if (last_packet)
347 	{
348 		// If No More Fragment packet arrives, the size of this datagram is finalized
349 		c->Size = offset + size;
350 	}
351 
352 	// Check the overlap between the region which is represented by the offset and size of the
353 	// existing received list and the region which is represented by the offset and size
354 	for (i = 0; i < LIST_NUM(c->IpParts); i++)
355 	{
356 		UINT moving_size;
357 		IP_PART *p = LIST_DATA(c->IpParts, i);
358 
359 		// Check the overlapping between the existing area and head area
360 		if ((p->Offset <= offset) && ((p->Offset + p->Size) > offset))
361 		{
362 			// Compress behind the offset of this packet since a duplication is
363 			// found in the first part with the existing packet and this packet
364 
365 			if ((offset + size) <= (p->Offset + p->Size))
366 			{
367 				// This packet is buried in the existing packet
368 				size = 0;
369 			}
370 			else
371 			{
372 				// Retral region is not overlapped
373 				moving_size = p->Offset + p->Size - offset;
374 				offset += moving_size;
375 				size -= moving_size;
376 			}
377 		}
378 		if ((p->Offset < (offset + size)) && ((p->Offset + p->Size) >= (offset + size)))
379 		{
380 			// Compress the size of this packet forward because a duplication is
381 			// found between the posterior portion the existing packet and this packet
382 
383 			moving_size = p->Offset + p->Size - offset - size;
384 			size -= moving_size;
385 		}
386 
387 		if ((p->Offset >= offset) && ((p->Offset + p->Size) <= (offset + size)))
388 		{
389 			// This packet was overwritten to completely hunched over a existing packet
390 			p->Size = 0;
391 		}
392 	}
393 
394 	if (size != 0)
395 	{
396 		// Register this packet
397 		p = ZeroMalloc(sizeof(IP_PART));
398 
399 		p->Offset = offset;
400 		p->Size = size;
401 
402 		Add(c->IpParts, p);
403 	}
404 
405 	if (c->Size != 0)
406 	{
407 		// Get the total size of the data portion list already received
408 		UINT total_size = 0;
409 		UINT i;
410 
411 		for (i = 0; i < LIST_NUM(c->IpParts); i++)
412 		{
413 			IP_PART *p = LIST_DATA(c->IpParts, i);
414 
415 			total_size += p->Size;
416 		}
417 
418 		if (total_size == c->Size)
419 		{
420 			// Received whole of the IP packet
421 			//Debug("Combine: %u\n", total_size);
422 			NnIpReceived(t, c->SrcIP, c->DestIP, c->Protocol, c->Data, c->Size, c->Ttl,
423 			             c->HeadIpHeaderData, c->HeadIpHeaderDataSize, c->MaxL3Size);
424 
425 			// Release the combining object
426 			NnFreeIpCombine(t, c);
427 
428 			// Remove from the combining object list
429 			Delete(t->IpCombine, c);
430 		}
431 	}
432 }
433 
434 // Release the IP combining object
NnFreeIpCombine(NATIVE_NAT * t,IP_COMBINE * c)435 void NnFreeIpCombine(NATIVE_NAT *t, IP_COMBINE *c)
436 {
437 	UINT i;
438 	// Validate arguments
439 	if (c == NULL)
440 	{
441 		return;
442 	}
443 
444 	// Release the data
445 	t->CurrentIpQuota -= c->DataReserved;
446 	Free(c->Data);
447 
448 	// Release the partial list
449 	for (i = 0; i < LIST_NUM(c->IpParts); i++)
450 	{
451 		IP_PART *p = LIST_DATA(c->IpParts, i);
452 
453 		Free(p);
454 	}
455 
456 	Free(c->HeadIpHeaderData);
457 
458 	ReleaseList(c->IpParts);
459 	Free(c);
460 }
461 
462 // Search the IP combining list
NnSearchIpCombine(NATIVE_NAT * t,UINT src_ip,UINT dest_ip,USHORT id,UCHAR protocol)463 IP_COMBINE *NnSearchIpCombine(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol)
464 {
465 	IP_COMBINE *c, tt;
466 	// Validate arguments
467 	if (t == NULL)
468 	{
469 		return NULL;
470 	}
471 
472 	tt.DestIP = dest_ip;
473 	tt.SrcIP = src_ip;
474 	tt.Id = id;
475 	tt.Protocol = protocol;
476 
477 	c = Search(t->IpCombine, &tt);
478 
479 	return c;
480 }
481 
482 // Insert by creating a new object to the IP combining list
NnInsertIpCombine(NATIVE_NAT * t,UINT src_ip,UINT dest_ip,USHORT id,UCHAR protocol,bool mac_broadcast,UCHAR ttl,bool src_is_localmac)483 IP_COMBINE *NnInsertIpCombine(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol, bool mac_broadcast, UCHAR ttl, bool src_is_localmac)
484 {
485 	IP_COMBINE *c;
486 	// Validate arguments
487 	if (t == NULL)
488 	{
489 		return NULL;
490 	}
491 
492 	// Examine the quota
493 	if ((t->CurrentIpQuota + IP_COMBINE_INITIAL_BUF_SIZE) > IP_COMBINE_WAIT_QUEUE_SIZE_QUOTA)
494 	{
495 		// IP packet can not be stored any more
496 		return NULL;
497 	}
498 
499 	c = ZeroMalloc(sizeof(IP_COMBINE));
500 	c->SrcIsLocalMacAddr = src_is_localmac;
501 	c->DestIP = dest_ip;
502 	c->SrcIP = src_ip;
503 	c->Id = id;
504 	c->Expire = t->v->Now + (UINT64)IP_COMBINE_TIMEOUT;
505 	c->Size = 0;
506 	c->IpParts = NewList(NULL);
507 	c->Protocol = protocol;
508 	c->MacBroadcast = mac_broadcast;
509 	c->Ttl = ttl;
510 
511 	// Secure the memory
512 	c->DataReserved = IP_COMBINE_INITIAL_BUF_SIZE;
513 	c->Data = Malloc(c->DataReserved);
514 	t->CurrentIpQuota += c->DataReserved;
515 
516 	Insert(t->IpCombine, c);
517 
518 	return c;
519 }
520 
521 // Initialize the IP combining list
NnInitIpCombineList(NATIVE_NAT * t)522 void NnInitIpCombineList(NATIVE_NAT *t)
523 {
524 	// Validate arguments
525 	if (t == NULL)
526 	{
527 		return;
528 	}
529 
530 	t->IpCombine = NewList(CompareIpCombine);
531 }
532 
533 // Release the IP combining list
NnFreeIpCombineList(NATIVE_NAT * t)534 void NnFreeIpCombineList(NATIVE_NAT *t)
535 {
536 	UINT i;
537 	// Validate arguments
538 	if (t == NULL)
539 	{
540 		return;
541 	}
542 
543 	for (i = 0; i < LIST_NUM(t->IpCombine); i++)
544 	{
545 		IP_COMBINE *c = LIST_DATA(t->IpCombine, i);
546 
547 		NnFreeIpCombine(t, c);
548 	}
549 
550 	ReleaseList(t->IpCombine);
551 }
552 
553 // A TCP packet is received
NnTcpReceived(NATIVE_NAT * t,UINT src_ip,UINT dest_ip,void * data,UINT size,UCHAR ttl,UINT max_l3_size)554 void NnTcpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, UINT max_l3_size)
555 {
556 	TCP_HEADER *tcp;
557 	UCHAR *payload;
558 	UINT payload_size;
559 	UINT tcp_header_size;
560 	// Validate arguments
561 	if (t == NULL || data == NULL)
562 	{
563 		return;
564 	}
565 
566 	// TCP header
567 	if (size < sizeof(TCP_HEADER))
568 	{
569 		return;
570 	}
571 
572 	tcp = (TCP_HEADER *)data;
573 
574 	// Get the TCP header size
575 	tcp_header_size = TCP_GET_HEADER_SIZE(tcp) * 4;
576 	if (size < tcp_header_size || tcp_header_size < sizeof(TCP_HEADER))
577 	{
578 		return;
579 	}
580 
581 	// Payload
582 	payload = ((UCHAR *)data) + tcp_header_size;
583 	payload_size = size - tcp_header_size;
584 
585 	// Search the port from the NAT table
586 	if (true)
587 	{
588 		NATIVE_NAT_ENTRY tt;
589 		NATIVE_NAT_ENTRY *e;
590 
591 		NnSetNat(&tt, NAT_TCP, 0, 0, src_ip, Endian16(tcp->SrcPort), dest_ip, Endian16(tcp->DstPort));
592 
593 		e = SearchHash(t->NatTableForRecv, &tt);
594 
595 		if (e != NULL)
596 		{
597 			// Last communication time
598 			e->LastCommTime = t->v->Now;
599 			e->TotalRecv += (UINT64)size;
600 
601 			// Rewrite the TCP header
602 			tcp->Checksum = 0;
603 			tcp->DstPort = Endian16(e->SrcPort);
604 
605 			if (tcp->Flag & TCP_FIN || tcp->Flag & TCP_RST)
606 			{
607 				// Disconnect
608 				e->Status = NAT_TCP_WAIT_DISCONNECT;
609 			}
610 
611 			if (tcp->Flag & TCP_SYN && tcp->Flag & TCP_ACK)
612 			{
613 				// Connection complete
614 				if (e->Status != NAT_TCP_WAIT_DISCONNECT)
615 				{
616 					e->Status = NAT_TCP_ESTABLISHED;
617 				}
618 			}
619 
620 			e->LastSeq = Endian32(tcp->AckNumber);
621 			e->LastAck = Endian32(tcp->SeqNumber);
622 
623 			// Checksum recalculation
624 			tcp->Checksum = CalcChecksumForIPv4(src_ip, e->SrcIp, IP_PROTO_TCP, tcp, size, 0);
625 
626 			// IP transmission
627 			SendIp(t->v, e->SrcIp, src_ip, IP_PROTO_TCP, tcp, size);
628 		}
629 	}
630 }
631 
632 // An ICMP packet has been received
NnIcmpReceived(NATIVE_NAT * t,UINT src_ip,UINT dest_ip,void * data,UINT size,UCHAR ttl,UINT max_l3_size)633 void NnIcmpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, UINT max_l3_size)
634 {
635 	ICMP_HEADER *icmp;
636 	// Validate arguments
637 	if (t == NULL || data == NULL)
638 	{
639 		return;
640 	}
641 	if (ttl == 0)
642 	{
643 		ttl = 1;
644 	}
645 
646 	// ICMP header
647 	if (size < sizeof(ICMP_HEADER))
648 	{
649 		return;
650 	}
651 
652 	icmp = (ICMP_HEADER *)data;
653 
654 	if (icmp->Type == ICMP_TYPE_ECHO_RESPONSE)
655 	{
656 		UCHAR *payload;
657 		UINT payload_size;
658 		ICMP_ECHO *echo;
659 		NATIVE_NAT_ENTRY tt, *e;
660 
661 		// Echo Response
662 		echo = (ICMP_ECHO *)(((UCHAR *)data) + sizeof(ICMP_HEADER));
663 
664 		if (size < (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
665 		{
666 			return;
667 		}
668 
669 		payload = ((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
670 		payload_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
671 
672 		// Search the NAT
673 		NnSetNat(&tt, NAT_ICMP, 0, 0, 0, 0, dest_ip, Endian16(echo->Identifier));
674 
675 		e = SearchHash(t->NatTableForRecv, &tt);
676 
677 		if (e != NULL)
678 		{
679 			// Rewrite the header
680 			icmp->Checksum = 0;
681 			echo->Identifier = Endian16(e->SrcPort);
682 			icmp->Checksum = IpChecksum(icmp, size);
683 
684 			e->LastCommTime = t->v->Now;
685 			e->TotalRecv += (UINT64)size;
686 
687 			// Transmission
688 			SendIpEx(t->v, e->SrcIp, src_ip, IP_PROTO_ICMPV4, icmp, size, MAX(ttl - 1, 1));
689 		}
690 	}
691 	else if (icmp->Type == ICMP_TYPE_ECHO_REQUEST)
692 	{
693 		UCHAR *payload;
694 		UINT payload_size;
695 		ICMP_ECHO *echo;
696 
697 		// Echo Response
698 		echo = (ICMP_ECHO *)(((UCHAR *)data) + sizeof(ICMP_HEADER));
699 
700 		if (size < (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
701 		{
702 			return;
703 		}
704 
705 		payload = ((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
706 		payload_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
707 
708 		if (dest_ip == t->PublicIP)
709 		{
710 			// Respond as soon as the Echo Request is received at the public side interface
711 			ICMP_HEADER *ret_icmp;
712 			ICMP_ECHO *ret_echo;
713 			UINT ret_size = sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + payload_size;
714 
715 			ret_icmp = ZeroMalloc(ret_size);
716 			ret_echo = (ICMP_ECHO *)(((UCHAR *)ret_icmp) + sizeof(ICMP_HEADER));
717 
718 			ret_icmp->Type = ICMP_TYPE_ECHO_RESPONSE;
719 			ret_icmp->Code = icmp->Code;
720 
721 			ret_echo->Identifier = echo->Identifier;
722 			ret_echo->SeqNo = echo->SeqNo;
723 
724 			Copy((UCHAR *)ret_icmp + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO),
725 			     payload, payload_size);
726 
727 			ret_icmp->Checksum = IpChecksum(ret_icmp, ret_size);
728 
729 			NnIpSendForInternet(t, IP_PROTO_ICMPV4, 0, dest_ip, src_ip, ret_icmp, ret_size, max_l3_size);
730 
731 			Free(ret_icmp);
732 		}
733 	}
734 	else
735 	{
736 		if (icmp->Type == ICMP_TYPE_DESTINATION_UNREACHABLE || icmp->Type == ICMP_TYPE_TIME_EXCEEDED)
737 		{
738 			// Rewrite the Src IP of the IPv4 header of the ICMP response packet
739 			if (size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + sizeof(IPV4_HEADER)))
740 			{
741 				IPV4_HEADER *orig_ipv4 = (IPV4_HEADER *)(((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
742 				UINT orig_ipv4_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
743 
744 				UINT orig_ipv4_header_size = GetIpHeaderSize((UCHAR *)orig_ipv4, orig_ipv4_size);
745 
746 				if (orig_ipv4_header_size >= sizeof(IPV4_HEADER) && orig_ipv4_size >= orig_ipv4_header_size)
747 				{
748 					if (orig_ipv4->Protocol == IP_PROTO_ICMPV4)
749 					{
750 						// Search the inner ICMP header
751 						UINT inner_icmp_size = orig_ipv4_size - orig_ipv4_header_size;
752 
753 						if (inner_icmp_size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
754 						{
755 							ICMP_HEADER *inner_icmp = (ICMP_HEADER *)(((UCHAR *)data) +
756 							                          sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + orig_ipv4_header_size);
757 
758 							if (inner_icmp->Type == ICMP_TYPE_ECHO_REQUEST)
759 							{
760 								ICMP_ECHO *inner_echo = (ICMP_ECHO *)(((UCHAR *)inner_icmp) + sizeof(ICMP_HEADER));
761 								NATIVE_NAT_ENTRY tt, *e;
762 
763 								// Search for the existing NAT table entry
764 								NnSetNat(&tt, NAT_ICMP, 0, 0, 0, 0, orig_ipv4->SrcIP, Endian16(inner_echo->Identifier));
765 
766 								e = SearchHash(t->NatTableForRecv, &tt);
767 
768 								if (e != NULL)
769 								{
770 									e->LastCommTime = t->v->Now;
771 
772 									// Rewrite the inner IP packet and the ICMP header according to the NAT table
773 									inner_echo->Identifier = Endian16(e->SrcPort);
774 									inner_icmp->Checksum = 0;
775 
776 									orig_ipv4->SrcIP = e->SrcIp;
777 
778 									orig_ipv4->Checksum = 0;
779 									orig_ipv4->Checksum = IpChecksum(orig_ipv4, orig_ipv4_header_size);
780 
781 									// Rewrite the outer ICMP header
782 									if (true)
783 									{
784 										UCHAR *payload;
785 										UINT payload_size;
786 										ICMP_ECHO *echo;
787 
788 										// Echo Response
789 										echo = (ICMP_ECHO *)(((UCHAR *)data) + sizeof(ICMP_HEADER));
790 
791 										if (size < (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
792 										{
793 											return;
794 										}
795 
796 										payload = ((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
797 										payload_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
798 
799 										// Rewrite the header
800 										icmp->Checksum = 0;
801 										echo->Identifier = Endian16(e->SrcPort);
802 										icmp->Checksum = IpChecksum(icmp, size);
803 
804 										// Transmission
805 										SendIpEx(t->v, e->SrcIp, src_ip, IP_PROTO_ICMPV4, icmp, size, MAX(ttl - 1, 1));
806 									}
807 								}
808 							}
809 						}
810 					}
811 				}
812 			}
813 		}
814 	}
815 }
816 
817 // An UDP packet has been received
NnUdpReceived(NATIVE_NAT * t,UINT src_ip,UINT dest_ip,void * data,UINT size,UCHAR ttl,UINT max_l3_size)818 void NnUdpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, UINT max_l3_size)
819 {
820 	UDP_HEADER *udp;
821 	UCHAR *payload;
822 	UINT payload_size;
823 	// Validate arguments
824 	if (t == NULL || data == NULL)
825 	{
826 		return;
827 	}
828 
829 	// UDP header
830 	if (size <= sizeof(UDP_HEADER))
831 	{
832 		return;
833 	}
834 
835 	udp = (UDP_HEADER *)data;
836 
837 	// Payload
838 	payload = ((UCHAR *)data) + sizeof(UDP_HEADER);
839 	payload_size = size - sizeof(UDP_HEADER);
840 
841 	// Inspect the payload size
842 	if (payload_size < (Endian16(udp->PacketLength) - sizeof(UDP_HEADER)))
843 	{
844 		return;
845 	}
846 
847 	// Truncate the payload
848 	payload_size = Endian16(udp->PacketLength) - sizeof(UDP_HEADER);
849 
850 	// Search the port number from the NAT table
851 	if (true)
852 	{
853 		NATIVE_NAT_ENTRY tt;
854 		NATIVE_NAT_ENTRY *e;
855 
856 		NnSetNat(&tt, NAT_UDP, 0, 0, 0, 0, dest_ip, Endian16(udp->DstPort));
857 
858 		e = SearchHash(t->NatTableForRecv, &tt);
859 
860 		if (e != NULL)
861 		{
862 			// Last communication time
863 			e->LastCommTime = t->v->Now;
864 			e->TotalRecv += (UINT64)payload_size;
865 
866 			// Deliver to the client by rewriting the port number
867 			SendUdp(t->v, e->SrcIp, e->SrcPort, src_ip, Endian16(udp->SrcPort),
868 			        payload, payload_size);
869 		}
870 	}
871 }
872 
873 // A combined IP packet is received
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)874 void NnIpReceived(NATIVE_NAT *t, UINT src_ip, UINT dest_ip, UINT protocol, void *data, UINT size,
875                   UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size)
876 {
877 	// Validate arguments
878 	if (t == NULL || data == NULL)
879 	{
880 		return;
881 	}
882 
883 	if (dest_ip != t->PublicIP)
884 	{
885 		// Destination IP is not a unicast
886 		return;
887 	}
888 
889 	switch (protocol)
890 	{
891 	case IP_PROTO_UDP:
892 		// UDP
893 		NnUdpReceived(t, src_ip, dest_ip, data, size, ttl, max_l3_size);
894 		break;
895 
896 	case IP_PROTO_TCP:
897 		// TCP
898 		NnTcpReceived(t, src_ip, dest_ip, data, size, ttl, max_l3_size);
899 		break;
900 
901 	case IP_PROTO_ICMPV4:
902 		// ICMP
903 		NnIcmpReceived(t, src_ip, dest_ip, data, size, ttl, max_l3_size);
904 		break;
905 	}
906 }
907 
908 // Received an IP packet
NnFragmentedIpReceived(NATIVE_NAT * t,PKT * packet)909 void NnFragmentedIpReceived(NATIVE_NAT *t, PKT *packet)
910 {
911 	IPV4_HEADER *ip;
912 	void *data;
913 	UINT data_size_recved;
914 	UINT size;
915 	UINT ipv4_header_size;
916 	bool last_packet = false;
917 	UINT l3_size = 0;
918 	UCHAR *head_ip_header_data = NULL;
919 	UINT head_ip_header_size = 0;
920 	// Validate arguments
921 	if (t == NULL || packet == NULL)
922 	{
923 		return;
924 	}
925 
926 	ip = packet->L3.IPv4Header;
927 
928 	// Get the size of the IPv4 header
929 	ipv4_header_size = IPV4_GET_HEADER_LEN(packet->L3.IPv4Header) * 4;
930 	head_ip_header_size = ipv4_header_size;
931 
932 	// Get the pointer to the data
933 	data = ((UCHAR *)packet->L3.PointerL3) + ipv4_header_size;
934 
935 	// Get the data size
936 	size = l3_size = Endian16(ip->TotalLength);
937 	if (size <= ipv4_header_size)
938 	{
939 		// There is no data
940 		return;
941 	}
942 	size -= ipv4_header_size;
943 
944 	// Get the size of data actually received
945 	data_size_recved = packet->PacketSize - (ipv4_header_size + MAC_HEADER_SIZE);
946 	if (data_size_recved < size)
947 	{
948 		// Data insufficient (It may be missing on the way)
949 		return;
950 	}
951 
952 	if (IPV4_GET_OFFSET(ip) == 0 && (IPV4_GET_FLAGS(ip) & 0x01) == 0)
953 	{
954 		// Because this packet has not been fragmented, it can be passed to the upper layer immediately
955 		head_ip_header_data = (UCHAR *)packet->L3.IPv4Header;
956 		NnIpReceived(t, ip->SrcIP, ip->DstIP, ip->Protocol, data, size, ip->TimeToLive,
957 		             head_ip_header_data, head_ip_header_size, l3_size);
958 	}
959 	else
960 	{
961 		// This packet is necessary to combine because it is fragmented
962 		UINT offset = IPV4_GET_OFFSET(ip) * 8;
963 		IP_COMBINE *c = NnSearchIpCombine(t, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol);
964 
965 		if (offset == 0)
966 		{
967 			head_ip_header_data = (UCHAR *)packet->L3.IPv4Header;
968 		}
969 
970 		last_packet = ((IPV4_GET_FLAGS(ip) & 0x01) == 0 ? true : false);
971 
972 		if (c != NULL)
973 		{
974 			// It is the second or subsequent packet
975 			c->MaxL3Size = MAX(c->MaxL3Size, l3_size);
976 			NnCombineIp(t, c, offset, data, size, last_packet, head_ip_header_data, head_ip_header_size);
977 		}
978 		else
979 		{
980 			// Create a combining object because it is the first packet
981 			c = NnInsertIpCombine(
982 			        t, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol, packet->BroadcastPacket,
983 			        ip->TimeToLive, false);
984 			if (c != NULL)
985 			{
986 				c->MaxL3Size = MAX(c->MaxL3Size, l3_size);
987 				NnCombineIp(t, c, offset, data, size, last_packet, head_ip_header_data, head_ip_header_size);
988 			}
989 		}
990 	}
991 }
992 
993 // Layer 2 packet processing
NnLayer2(NATIVE_NAT * t,PKT * packet)994 void NnLayer2(NATIVE_NAT *t, PKT *packet)
995 {
996 	// Validate arguments
997 	if (t == NULL || packet == NULL)
998 	{
999 		return;
1000 	}
1001 
1002 	if (packet->TypeL3 == L3_IPV4)
1003 	{
1004 		// IPv4
1005 		NnFragmentedIpReceived(t, packet);
1006 	}
1007 }
1008 
1009 // Extract the received packets of native NAT, and deliver it to the VPN client
NnPoll(NATIVE_NAT * t)1010 void NnPoll(NATIVE_NAT *t)
1011 {
1012 	// Validate arguments
1013 	if (t == NULL)
1014 	{
1015 		return;
1016 	}
1017 
1018 	LockQueue(t->RecvQueue);
1019 	{
1020 		while (true)
1021 		{
1022 			PKT *pkt = GetNext(t->RecvQueue);
1023 
1024 			if (pkt == NULL)
1025 			{
1026 				break;
1027 			}
1028 
1029 			NnLayer2(t, pkt);
1030 
1031 			FreePacketWithData(pkt);
1032 		}
1033 	}
1034 	UnlockQueue(t->RecvQueue);
1035 
1036 	if (t->SendStateChanged)
1037 	{
1038 		TUBE *halt_tube = NULL;
1039 
1040 		Lock(t->Lock);
1041 		{
1042 			if (t->HaltTube != NULL)
1043 			{
1044 				halt_tube = t->HaltTube;
1045 
1046 				AddRef(halt_tube->Ref);
1047 			}
1048 		}
1049 		Unlock(t->Lock);
1050 
1051 		if (halt_tube != NULL)
1052 		{
1053 			TubeFlushEx(halt_tube, true);
1054 
1055 			t->SendStateChanged = false;
1056 
1057 			ReleaseTube(halt_tube);
1058 		}
1059 	}
1060 
1061 	NnPollingIpCombine(t);
1062 
1063 	NnDeleteOldSessions(t);
1064 }
1065 
1066 // Send a fragmented IP packet to the Internet
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)1067 void NnIpSendFragmentedForInternet(NATIVE_NAT *t, UCHAR ip_protocol, UINT src_ip, UINT dest_ip, USHORT id, USHORT total_size,
1068                                    USHORT offset, void *data, UINT size, UCHAR ttl)
1069 {
1070 	UCHAR *buf;
1071 	IPV4_HEADER *ip;
1072 	BLOCK *b;
1073 	// Validate arguments
1074 	if (t == NULL || data == NULL)
1075 	{
1076 		return;
1077 	}
1078 
1079 	// Memory allocation
1080 	buf = Malloc(size + IP_HEADER_SIZE);
1081 	ip = (IPV4_HEADER *)&buf[0];
1082 
1083 	// IP header construction
1084 	ip->VersionAndHeaderLength = 0;
1085 	IPV4_SET_VERSION(ip, 4);
1086 	IPV4_SET_HEADER_LEN(ip, (IP_HEADER_SIZE / 4));
1087 	ip->TypeOfService = DEFAULT_IP_TOS;
1088 	ip->TotalLength = Endian16((USHORT)(size + IP_HEADER_SIZE));
1089 	ip->Identification = Endian16(id);
1090 	ip->FlagsAndFragmentOffset[0] = ip->FlagsAndFragmentOffset[1] = 0;
1091 	IPV4_SET_OFFSET(ip, (offset / 8));
1092 	if ((offset + size) >= total_size)
1093 	{
1094 		IPV4_SET_FLAGS(ip, 0x00);
1095 	}
1096 	else
1097 	{
1098 		IPV4_SET_FLAGS(ip, 0x01);
1099 	}
1100 	ip->TimeToLive = (ttl == 0 ? DEFAULT_IP_TTL : ttl);
1101 	ip->Protocol = ip_protocol;
1102 	ip->Checksum = 0;
1103 	ip->SrcIP = src_ip;
1104 	ip->DstIP = dest_ip;
1105 
1106 	// Checksum calculation
1107 	ip->Checksum = IpChecksum(ip, IP_HEADER_SIZE);
1108 
1109 	// Data copy
1110 	Copy(buf + IP_HEADER_SIZE, data, size);
1111 
1112 	// Transmission
1113 	b = NewBlock(buf, size + IP_HEADER_SIZE, 0);
1114 
1115 	LockQueue(t->SendQueue);
1116 	{
1117 		if (t->SendQueue->num_item <= NN_MAX_QUEUE_LENGTH)
1118 		{
1119 			InsertQueue(t->SendQueue, b);
1120 
1121 			t->SendStateChanged = true;
1122 		}
1123 		else
1124 		{
1125 			FreeBlock(b);
1126 		}
1127 	}
1128 	UnlockQueue(t->SendQueue);
1129 }
1130 
1131 // Send an IP packet to the Internet
NnIpSendForInternet(NATIVE_NAT * t,UCHAR ip_protocol,UCHAR ttl,UINT src_ip,UINT dest_ip,void * data,UINT size,UINT max_l3_size)1132 void NnIpSendForInternet(NATIVE_NAT *t, UCHAR ip_protocol, UCHAR ttl, UINT src_ip, UINT dest_ip, void *data, UINT size, UINT max_l3_size)
1133 {
1134 	UINT mss = 0;
1135 	UCHAR *buf;
1136 	USHORT offset;
1137 	USHORT id;
1138 	USHORT total_size;
1139 	UINT size_of_this_packet;
1140 	// Validate arguments
1141 	if (t == NULL || data == NULL)
1142 	{
1143 		return;
1144 	}
1145 
1146 	// Maximum segment size
1147 	if (max_l3_size > IP_HEADER_SIZE)
1148 	{
1149 		mss = max_l3_size - IP_HEADER_SIZE;
1150 	}
1151 
1152 	if (mss == 0)
1153 	{
1154 		mss = t->v->IpMss;
1155 	}
1156 
1157 	mss = MAX(mss, 1000);
1158 
1159 	// Buffer
1160 	buf = (UCHAR *)data;
1161 
1162 	// ID
1163 	id = (t->NextId++);
1164 
1165 	// Total size
1166 	total_size = (USHORT)size;
1167 
1168 	// Start to fragment
1169 	offset = 0;
1170 
1171 	while (true)
1172 	{
1173 		bool last_packet = false;
1174 		// Get the size of this packet
1175 		size_of_this_packet = MIN((USHORT)mss, (total_size - offset));
1176 		if ((offset + (USHORT)size_of_this_packet) == total_size)
1177 		{
1178 			last_packet = true;
1179 		}
1180 
1181 		// Transmit the fragmented packet
1182 		NnIpSendFragmentedForInternet(t, ip_protocol, src_ip, dest_ip, id, total_size, offset,
1183 		                              buf + offset, size_of_this_packet, ttl);
1184 		if (last_packet)
1185 		{
1186 			break;
1187 		}
1188 
1189 		offset += (USHORT)size_of_this_packet;
1190 	}
1191 }
1192 
1193 // Communication of ICMP towards the Internet
NnIcmpEchoRecvForInternet(VH * v,UINT src_ip,UINT dest_ip,void * data,UINT size,UCHAR ttl,void * icmp_data,UINT icmp_size,UCHAR * ip_header,UINT ip_header_size,UINT max_l3_size)1194 void NnIcmpEchoRecvForInternet(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size)
1195 {
1196 	NATIVE_NAT_ENTRY tt;
1197 	NATIVE_NAT_ENTRY *e;
1198 	NATIVE_NAT *t;
1199 	USHORT src_port;
1200 	ICMP_HEADER *old_icmp_header;
1201 	ICMP_ECHO *old_icmp_echo;
1202 	ICMP_HEADER *icmp;
1203 	ICMP_ECHO *echo;
1204 	UCHAR *payload_data;
1205 	UINT payload_size;
1206 	// Validate arguments
1207 	if (NnIsActive(v) == false || icmp_data == NULL)
1208 	{
1209 		return;
1210 	}
1211 
1212 	t = v->NativeNat;
1213 
1214 	old_icmp_header = (ICMP_HEADER *)icmp_data;
1215 	old_icmp_echo = (ICMP_ECHO *)(((UCHAR *)icmp_data) + sizeof(ICMP_HEADER));
1216 
1217 	if (size < (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
1218 	{
1219 		return;
1220 	}
1221 
1222 	payload_data = ((UCHAR *)icmp_data) + (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
1223 	payload_size = icmp_size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
1224 
1225 	if (dest_ip == v->HostIP)
1226 	{
1227 		// Respond because it is addressed to me
1228 		VirtualIcmpEchoSendResponse(v, dest_ip, src_ip, Endian16(old_icmp_echo->Identifier),
1229 		                            Endian16(old_icmp_echo->SeqNo), payload_data, payload_size);
1230 
1231 		return;
1232 	}
1233 
1234 	if (ttl <= 1)
1235 	{
1236 		// Reply the Time Exceeded immediately for the packet whose TTL is 1
1237 		UINT reply_size = sizeof(ICMP_HEADER) + 4 + ip_header_size + 8;
1238 		UCHAR *reply_data = ZeroMalloc(reply_size);
1239 		ICMP_HEADER *icmp = (ICMP_HEADER *)reply_data;
1240 		icmp->Type = ICMP_TYPE_TIME_EXCEEDED;
1241 		icmp->Code = ICMP_CODE_TTL_EXCEEDED_IN_TRANSIT;
1242 		Copy(reply_data + sizeof(ICMP_HEADER) + 4, ip_header, ip_header_size);
1243 		Copy(reply_data + sizeof(ICMP_HEADER) + 4 + ip_header_size, icmp_data, MIN(icmp_size, 8));
1244 
1245 		icmp->Checksum = IpChecksum(icmp, reply_size);
1246 
1247 		SendIp(v, src_ip, v->HostIP, IP_PROTO_ICMPV4, reply_data, reply_size);
1248 
1249 		Free(reply_data);
1250 
1251 		return;
1252 	}
1253 
1254 	src_port = Endian16(old_icmp_echo->Identifier);
1255 
1256 	// Search whether there is an existing session
1257 	NnSetNat(&tt, NAT_ICMP, src_ip, src_port, 0, 0, 0, 0);
1258 
1259 	e = SearchHash(t->NatTableForSend, &tt);
1260 
1261 	if (e == NULL)
1262 	{
1263 		// Create a new session because there is no existing one
1264 		UINT public_port;
1265 
1266 		if (CanCreateNewNatEntry(v) == false)
1267 		{
1268 			// Can not make any more
1269 			return;
1270 		}
1271 
1272 		NnDeleteOldestNatSessionIfNecessary(t, src_ip, NAT_ICMP);
1273 
1274 		// Get a free port
1275 		public_port = NnMapNewPublicPort(t, NAT_ICMP, 0, 0, t->PublicIP);
1276 		if (public_port == 0)
1277 		{
1278 			// There are no free ports
1279 			return;
1280 		}
1281 
1282 		e = ZeroMalloc(sizeof(NATIVE_NAT_ENTRY));
1283 
1284 		e->Status = NAT_TCP_ESTABLISHED;
1285 
1286 		e->HashCodeForSend = INFINITE;
1287 		e->HashCodeForRecv = INFINITE;
1288 		e->Id = Inc(v->Counter);
1289 		e->Protocol = NAT_ICMP;
1290 		e->SrcIp = src_ip;
1291 		e->SrcPort = src_port;
1292 		e->DestIp = 0;
1293 		e->DestPort = 0;
1294 		e->PublicIp = t->PublicIP;
1295 		e->PublicPort = public_port;
1296 
1297 		e->CreatedTime = v->Now;
1298 		e->LastCommTime = v->Now;
1299 
1300 		// Add to the list
1301 		AddHash(t->NatTableForSend, e);
1302 		AddHash(t->NatTableForRecv, e);
1303 
1304 		// Log
1305 		if (true)
1306 		{
1307 			IP ip1, ip2;
1308 			char s1[MAX_SIZE], s2[MAX_SIZE];
1309 			UINTToIP(&ip1, src_ip);
1310 			UINTToIP(&ip2, dest_ip);
1311 			IPToStr(s1, 0, &ip1);
1312 			IPToStr(s2, 0, &ip2);
1313 
1314 			Debug("ICMP Session %u:  %s:0x%x -> %s:0x%x\n", e->Id, s1, src_port, s2, public_port);
1315 		}
1316 	}
1317 
1318 	// Rebuild the ICMP header
1319 	icmp = ZeroMalloc(sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + payload_size);
1320 	icmp->Code = old_icmp_header->Code;
1321 	icmp->Type = old_icmp_header->Type;
1322 	icmp->Checksum = 0;
1323 
1324 	echo = (ICMP_ECHO *)(((UCHAR *)icmp) + sizeof(ICMP_HEADER));
1325 	echo->SeqNo = old_icmp_echo->SeqNo;
1326 	echo->Identifier = Endian16(e->PublicPort);
1327 
1328 	Copy(((UCHAR *)icmp) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO), payload_data, payload_size);
1329 
1330 	icmp->Checksum = IpChecksum(icmp, sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + payload_size);
1331 
1332 	e->TotalSent += (UINT64)payload_size;
1333 	e->LastCommTime = v->Now;
1334 
1335 	// Send to the Internet
1336 	NnIpSendForInternet(t, IP_PROTO_ICMPV4, ttl - 1, e->PublicIp, dest_ip, icmp, sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + payload_size, max_l3_size);
1337 
1338 	Free(icmp);
1339 }
1340 
1341 // Communication of UDP towards the Internet
NnUdpRecvForInternet(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size,UINT max_l3_size)1342 void NnUdpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, UINT max_l3_size)
1343 {
1344 	NATIVE_NAT_ENTRY tt;
1345 	NATIVE_NAT_ENTRY *e;
1346 	NATIVE_NAT *t;
1347 	UDP_HEADER *udp;
1348 	// Validate arguments
1349 	if (NnIsActive(v) == false || data == NULL)
1350 	{
1351 		return;
1352 	}
1353 
1354 	t = v->NativeNat;
1355 
1356 	// Search whether there is an existing session
1357 	NnSetNat(&tt, NAT_UDP, src_ip, src_port, 0, 0, 0, 0);
1358 
1359 	e = SearchHash(t->NatTableForSend, &tt);
1360 
1361 	if (e == NULL)
1362 	{
1363 		// Create a new session because there is no existing one
1364 		UINT public_port;
1365 
1366 		if (CanCreateNewNatEntry(v) == false)
1367 		{
1368 			// Can not make any more
1369 			return;
1370 		}
1371 
1372 		NnDeleteOldestNatSessionIfNecessary(t, src_ip, NAT_UDP);
1373 
1374 		// Get a free port
1375 		public_port = NnMapNewPublicPort(t, NAT_UDP, 0, 0, t->PublicIP);
1376 		if (public_port == 0)
1377 		{
1378 			// There are no free ports
1379 			return;
1380 		}
1381 
1382 		e = ZeroMalloc(sizeof(NATIVE_NAT_ENTRY));
1383 
1384 		e->Status = NAT_TCP_ESTABLISHED;
1385 
1386 		e->HashCodeForSend = INFINITE;
1387 		e->HashCodeForRecv = INFINITE;
1388 		e->Id = Inc(v->Counter);
1389 		e->Protocol = NAT_UDP;
1390 		e->SrcIp = src_ip;
1391 		e->SrcPort = src_port;
1392 		e->DestIp = 0;
1393 		e->DestPort = 0;
1394 		e->PublicIp = t->PublicIP;
1395 		e->PublicPort = public_port;
1396 
1397 		e->CreatedTime = v->Now;
1398 		e->LastCommTime = v->Now;
1399 
1400 		// Add to the list
1401 		AddHash(t->NatTableForSend, e);
1402 		AddHash(t->NatTableForRecv, e);
1403 
1404 		// Log
1405 		if (true)
1406 		{
1407 			IP ip1, ip2;
1408 			char s1[MAX_SIZE], s2[MAX_SIZE];
1409 			UINTToIP(&ip1, src_ip);
1410 			UINTToIP(&ip2, dest_ip);
1411 			IPToStr(s1, 0, &ip1);
1412 			IPToStr(s2, 0, &ip2);
1413 
1414 			NLog(v, "LH_NAT_UDP_CREATED", e->Id, s1, src_port, s2, dest_port);
1415 		}
1416 	}
1417 
1418 	// Rebuild the UDP header
1419 	udp = ZeroMalloc(sizeof(UDP_HEADER) + size);
1420 
1421 	udp->SrcPort = Endian16(e->PublicPort);
1422 	udp->DstPort = Endian16(dest_port);
1423 	udp->PacketLength = Endian16((USHORT)sizeof(UDP_HEADER) + size);
1424 
1425 	Copy(((UCHAR *)udp) + sizeof(UDP_HEADER), data, size);
1426 
1427 	udp->Checksum = CalcChecksumForIPv4(e->PublicIp, dest_ip, IP_PROTO_UDP, udp, sizeof(UDP_HEADER) + size, 0);
1428 
1429 	e->TotalSent += (UINT64)size;
1430 	e->LastCommTime = v->Now;
1431 
1432 	// Send to the Internet
1433 	NnIpSendForInternet(t, IP_PROTO_UDP, 127, e->PublicIp, dest_ip, udp, sizeof(UDP_HEADER) + size, max_l3_size);
1434 
1435 	Free(udp);
1436 }
1437 
1438 // Communication of TCP towards the Internet
NnTcpRecvForInternet(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,TCP_HEADER * old_tcp,void * data,UINT size,UINT max_l3_size)1439 void NnTcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, TCP_HEADER *old_tcp, void *data, UINT size, UINT max_l3_size)
1440 {
1441 	NATIVE_NAT_ENTRY tt;
1442 	NATIVE_NAT_ENTRY *e;
1443 	NATIVE_NAT *t;
1444 	UINT tcp_header_size;
1445 	TCP_HEADER *tcp;
1446 	// Validate arguments
1447 	if (NnIsActive(v) == false || old_tcp == NULL || data == NULL)
1448 	{
1449 		return;
1450 	}
1451 
1452 	t = v->NativeNat;
1453 
1454 	// Search whether there is an existing session
1455 	NnSetNat(&tt, NAT_TCP, src_ip, src_port, dest_ip, dest_port, 0, 0);
1456 
1457 	e = SearchHash(t->NatTableForSend, &tt);
1458 
1459 	if (e == NULL)
1460 	{
1461 		// Create a new session because there is no existing one
1462 		UINT public_port;
1463 
1464 		if (((old_tcp->Flag & TCP_SYN) && ((old_tcp->Flag & TCP_ACK) == 0)) == false)
1465 		{
1466 			// If there is no existing session, pass through only for SYN packet
1467 			return;
1468 		}
1469 
1470 		if (CanCreateNewNatEntry(v) == false)
1471 		{
1472 			// Can not make any more
1473 			return;
1474 		}
1475 
1476 		NnDeleteOldestNatSessionIfNecessary(t, src_ip, NAT_TCP);
1477 
1478 		// Get a free port
1479 		public_port = NnMapNewPublicPort(t, NAT_TCP, dest_ip, dest_port, t->PublicIP);
1480 		if (public_port == 0)
1481 		{
1482 			// There are no free ports
1483 			return;
1484 		}
1485 
1486 		e = ZeroMalloc(sizeof(NATIVE_NAT_ENTRY));
1487 
1488 		e->HashCodeForSend = INFINITE;
1489 		e->HashCodeForRecv = INFINITE;
1490 		e->Id = Inc(v->Counter);
1491 		e->Status = NAT_TCP_CONNECTING;
1492 		e->Protocol = NAT_TCP;
1493 		e->SrcIp = src_ip;
1494 		e->SrcPort = src_port;
1495 		e->DestIp = dest_ip;
1496 		e->DestPort = dest_port;
1497 		e->PublicIp = t->PublicIP;
1498 		e->PublicPort = public_port;
1499 
1500 		e->CreatedTime = v->Now;
1501 		e->LastCommTime = v->Now;
1502 
1503 		// Add to the list
1504 		AddHash(t->NatTableForSend, e);
1505 		AddHash(t->NatTableForRecv, e);
1506 
1507 		// Log
1508 		if (true)
1509 		{
1510 			IP ip1, ip2;
1511 			char s1[MAX_SIZE], s2[MAX_SIZE];
1512 			UINTToIP(&ip1, src_ip);
1513 			UINTToIP(&ip2, dest_ip);
1514 			IPToStr(s1, 0, &ip1);
1515 			IPToStr(s2, 0, &ip2);
1516 
1517 			NLog(v, "LH_NAT_TCP_CREATED", e->Id, s1, src_port, s2, dest_port);
1518 		}
1519 	}
1520 
1521 	// Update the last communication time
1522 	e->LastCommTime = v->Now;
1523 
1524 	e->TotalSent += (UINT64)size;
1525 
1526 	tcp_header_size = TCP_GET_HEADER_SIZE(old_tcp) * 4;
1527 
1528 	// Create a new TCP packet
1529 	tcp = ZeroMalloc(tcp_header_size + size);
1530 
1531 	// Copy the old TCP header
1532 	Copy(tcp, old_tcp, tcp_header_size);
1533 
1534 	if (tcp->Flag & TCP_RST || tcp->Flag & TCP_FIN)
1535 	{
1536 		// Disconnect
1537 		e->Status = NAT_TCP_WAIT_DISCONNECT;
1538 	}
1539 
1540 	// Rewrite the TCP header
1541 	tcp->Checksum = 0;
1542 	tcp->SrcPort = Endian16(e->PublicPort);
1543 
1544 	e->LastSeq = Endian32(tcp->SeqNumber);
1545 	e->LastAck = Endian32(tcp->AckNumber);
1546 
1547 	// Payload
1548 	Copy(((UCHAR *)tcp) + tcp_header_size, data, size);
1549 
1550 	// Checksum calculation
1551 	tcp->Checksum = CalcChecksumForIPv4(e->PublicIp, dest_ip, IP_PROTO_TCP, tcp, tcp_header_size + size, 0);
1552 
1553 	// Send to the Internet
1554 	NnIpSendForInternet(t, IP_PROTO_TCP, 127, e->PublicIp, dest_ip, tcp, tcp_header_size + size, max_l3_size);
1555 
1556 	Free(tcp);
1557 }
1558 
1559 // Assign a new public-side port
NnMapNewPublicPort(NATIVE_NAT * t,UINT protocol,UINT dest_ip,UINT dest_port,UINT public_ip)1560 UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_port, UINT public_ip)
1561 {
1562 	UINT i;
1563 	UINT base_port;
1564 	UINT port_start = 1025;
1565 	UINT port_end = 65500;
1566 	// Validate arguments
1567 	if (t == NULL)
1568 	{
1569 		return 0;
1570 	}
1571 
1572 	if (t->IsRawIpMode)
1573 	{
1574 		port_start = NN_RAW_IP_PORT_START;
1575 		port_end = NN_RAW_IP_PORT_END;
1576 	}
1577 
1578 	base_port = Rand32() % (port_end - port_start) + port_start;
1579 
1580 	for (i = 0; i < (port_end - port_start); i++)
1581 	{
1582 		UINT port;
1583 		NATIVE_NAT_ENTRY tt;
1584 		NATIVE_NAT *e;
1585 
1586 		port = base_port + i;
1587 		if (port > port_end)
1588 		{
1589 			port = port - port_end + port_start;
1590 		}
1591 
1592 		// Is this port vacant?
1593 		NnSetNat(&tt, protocol, 0, 0, dest_ip, dest_port, public_ip, port);
1594 
1595 		e = SearchHash(t->NatTableForRecv, &tt);
1596 
1597 		if (e == NULL)
1598 		{
1599 			// Free port is found
1600 			return port;
1601 		}
1602 	}
1603 
1604 	return 0;
1605 }
1606 
1607 // Examine whether the native NAT is available
NnIsActive(VH * v)1608 bool NnIsActive(VH *v)
1609 {
1610 	return NnIsActiveEx(v, NULL);
1611 }
NnIsActiveEx(VH * v,bool * is_ipraw_mode)1612 bool NnIsActiveEx(VH *v, bool *is_ipraw_mode)
1613 {
1614 	// Validate arguments
1615 	if (v == NULL)
1616 	{
1617 		return false;
1618 	}
1619 
1620 	if (v->NativeNat == NULL)
1621 	{
1622 		return false;
1623 	}
1624 
1625 	if (v->NativeNat->PublicIP == 0)
1626 	{
1627 		return false;
1628 	}
1629 
1630 	if (v->NativeNat->Active)
1631 	{
1632 		if (is_ipraw_mode != NULL)
1633 		{
1634 			*is_ipraw_mode = v->NativeNat->IsRawIpMode;
1635 		}
1636 	}
1637 
1638 	return v->NativeNat->Active;
1639 }
1640 
1641 // Native NAT main loop
NnMainLoop(NATIVE_NAT * t,NATIVE_STACK * a)1642 void NnMainLoop(NATIVE_NAT *t, NATIVE_STACK *a)
1643 {
1644 	IPC *ipc;
1645 	TUBE *tubes[3];
1646 	UINT num_tubes = 0;
1647 	UINT64 next_poll_tick = 0;
1648 	INTERRUPT_MANAGER *interrupt;
1649 	USHORT dns_src_port = 0;
1650 	USHORT dns_tran_id = 0;
1651 	USHORT tcp_src_port = 0;
1652 	UINT tcp_seq = 0;
1653 	IP yahoo_ip;
1654 	bool wait_for_dns = false;
1655 	UINT64 tcp_last_recv_tick = 0;
1656 	UINT dhcp_renew_interval;
1657 	UINT64 next_dhcp_renew_tick = 0;
1658 	// Validate arguments
1659 	if (t == NULL || a == NULL)
1660 	{
1661 		return;
1662 	}
1663 
1664 	dhcp_renew_interval = a->CurrentDhcpOptionList.LeaseTime;
1665 
1666 	if (dhcp_renew_interval == 0)
1667 	{
1668 		dhcp_renew_interval = IPC_DHCP_DEFAULT_LEASE;
1669 	}
1670 
1671 	dhcp_renew_interval = MAX(dhcp_renew_interval, IPC_DHCP_MIN_LEASE) / 2;
1672 
1673 	interrupt = NewInterruptManager();
1674 
1675 	ipc = a->Ipc;
1676 
1677 	tubes[num_tubes++] = ipc->Sock->RecvTube;
1678 	//tubes[num_tubes++] = ipc->Sock->SendTube;	// bug 2015.10.01 remove
1679 	tubes[num_tubes++] = t->HaltTube;
1680 
1681 	Zero(&yahoo_ip, sizeof(yahoo_ip));
1682 
1683 	next_poll_tick = Tick64() + (UINT64)NN_POLL_CONNECTIVITY_INTERVAL;
1684 	AddInterrupt(interrupt, next_poll_tick);
1685 
1686 	tcp_last_recv_tick = Tick64();
1687 	next_dhcp_renew_tick = Tick64() + (UINT64)dhcp_renew_interval * 1000;
1688 	AddInterrupt(interrupt, next_dhcp_renew_tick);
1689 
1690 	while (t->Halt == false && t->v->UseNat)
1691 	{
1692 		UINT64 now = Tick64();
1693 		bool call_cancel = false;
1694 		bool state_changed = false;
1695 		UINT wait_interval;
1696 
1697 		if (t->v->HubOption != NULL)
1698 		{
1699 			if (t->IsRawIpMode == false && t->v->HubOption->DisableKernelModeSecureNAT)
1700 			{
1701 				break;
1702 			}
1703 			if (t->IsRawIpMode && t->v->HubOption->DisableIpRawModeSecureNAT)
1704 			{
1705 				break;
1706 			}
1707 		}
1708 
1709 		IPCFlushArpTable(ipc);
1710 		call_cancel = false;
1711 
1712 LABEL_RESTART:
1713 		state_changed = false;
1714 
1715 		if (next_poll_tick == 0 || next_poll_tick <= now)
1716 		{
1717 			BUF *dns_query;
1718 
1719 			dns_src_port = NnGenSrcPort(a->IsIpRawMode);
1720 			dns_tran_id = Rand16();
1721 
1722 			// Start a connectivity check periodically
1723 			dns_query = NnBuildIpPacket(NnBuildUdpPacket(NnBuildDnsQueryPacket(NN_CHECK_HOSTNAME, dns_tran_id),
1724 			                            IPToUINT(&ipc->ClientIPAddress), dns_src_port, IPToUINT(&a->DnsServerIP), 53),
1725 			                            IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP), IP_PROTO_UDP, 0);
1726 
1727 			IPCSendIPv4(ipc, dns_query->Buf, dns_query->Size);
1728 
1729 			wait_for_dns = true;
1730 
1731 			FreeBuf(dns_query);
1732 
1733 			next_poll_tick = now + (UINT64)NN_POLL_CONNECTIVITY_INTERVAL;
1734 			AddInterrupt(interrupt, next_poll_tick);
1735 		}
1736 
1737 		if (next_dhcp_renew_tick == 0 || next_dhcp_renew_tick <= now)
1738 		{
1739 			IP ip;
1740 
1741 			UINTToIP(&ip, a->CurrentDhcpOptionList.ServerAddress);
1742 
1743 			IPCDhcpRenewIP(ipc, &ip);
1744 
1745 			next_dhcp_renew_tick = now + (UINT64)dhcp_renew_interval * 1000;
1746 			AddInterrupt(interrupt, next_dhcp_renew_tick);
1747 		}
1748 
1749 		// Send an IP packet to IPC
1750 		LockQueue(t->SendQueue);
1751 		{
1752 			while (true)
1753 			{
1754 				BLOCK *b = GetNext(t->SendQueue);
1755 
1756 				if (b == NULL)
1757 				{
1758 					break;
1759 				}
1760 
1761 				IPCSendIPv4(ipc, b->Buf, b->Size);
1762 
1763 				state_changed = true;
1764 
1765 				FreeBlock(b);
1766 			}
1767 		}
1768 		UnlockQueue(t->SendQueue);
1769 
1770 		// Happy processing
1771 		IPCProcessL3EventsIPv4Only(ipc);
1772 
1773 		LockQueue(t->RecvQueue);
1774 		{
1775 			while (true)
1776 			{
1777 				// Receive an IP packet from IPC
1778 				BLOCK *b = IPCRecvIPv4(ipc);
1779 				PKT *pkt;
1780 
1781 				if (b == NULL)
1782 				{
1783 					// Can not receive any more
1784 					break;
1785 				}
1786 
1787 				// Parse the packet
1788 				pkt = ParsePacketIPv4WithDummyMacHeader(b->Buf, b->Size);
1789 
1790 				FreeBlock(b);
1791 
1792 				if (pkt != NULL)
1793 				{
1794 					bool no_store = false;
1795 
1796 					// Read the contents of the packet first, to determine whether it is a response for the connectivity test packet
1797 					if (wait_for_dns)
1798 					{
1799 						if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_UDP &&
1800 						        pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) &&
1801 						        pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) &&
1802 						        pkt->L4.UDPHeader->SrcPort == Endian16(53) && pkt->L4.UDPHeader->DstPort == Endian16(dns_src_port))
1803 						{
1804 							DNSV4_HEADER *dns_header = (DNSV4_HEADER *)pkt->Payload;
1805 							if (pkt->PayloadSize >= sizeof(DNSV4_HEADER))
1806 							{
1807 								if (dns_header->TransactionId == Endian16(dns_tran_id))
1808 								{
1809 									IP ret_ip;
1810 
1811 									if (NnParseDnsResponsePacket(pkt->Payload, pkt->PayloadSize, &ret_ip))
1812 									{
1813 										BUF *tcp_query;
1814 
1815 										Copy(&yahoo_ip, &ret_ip, sizeof(IP));
1816 
1817 										//SetIP(&yahoo_ip, 192, 168, 2, 32);
1818 
1819 										// DNS response has been received
1820 										no_store = true;
1821 
1822 										tcp_src_port = NnGenSrcPort(a->IsIpRawMode);
1823 
1824 										// Generate a TCP connection attempt packet
1825 										tcp_seq = Rand32();
1826 										tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), tcp_src_port,
1827 										                            IPToUINT(&yahoo_ip), 80, tcp_seq, 0, TCP_SYN, 8192, 1414),
1828 										                            IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0);
1829 
1830 										IPCSendIPv4(ipc, tcp_query->Buf, tcp_query->Size);
1831 
1832 										FreeBuf(tcp_query);
1833 
1834 										wait_for_dns = false;
1835 									}
1836 								}
1837 							}
1838 						}
1839 					}
1840 
1841 					if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_TCP &&
1842 					        pkt->L3.IPv4Header->SrcIP == IPToUINT(&yahoo_ip) &&
1843 					        pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) &&
1844 					        pkt->L4.TCPHeader->SrcPort == Endian16(80) && pkt->L4.TCPHeader->DstPort == Endian16(tcp_src_port))
1845 					{
1846 						TCP_HEADER *tcp_header = (TCP_HEADER *)pkt->L4.TCPHeader;
1847 						if ((tcp_header->Flag & TCP_SYN) && (tcp_header->Flag & TCP_ACK))
1848 						{
1849 							// There was a TCP response
1850 							BUF *tcp_query;
1851 							UINT recv_seq = Endian32(tcp_header->SeqNumber) + 1;
1852 
1853 							no_store = true;
1854 
1855 							// Send a RST
1856 							tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), tcp_src_port,
1857 							                            IPToUINT(&yahoo_ip), 80, tcp_seq + 1, recv_seq, TCP_RST | TCP_ACK, 8192, 0),
1858 							                            IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0);
1859 
1860 							IPCSendIPv4(ipc, tcp_query->Buf, tcp_query->Size);
1861 
1862 							FreeBuf(tcp_query);
1863 
1864 							tcp_last_recv_tick = now;
1865 						}
1866 					}
1867 
1868 					if (t->RecvQueue->num_item > NN_MAX_QUEUE_LENGTH)
1869 					{
1870 						no_store = true;
1871 					}
1872 
1873 					if (no_store == false)
1874 					{
1875 						// Put in the queue
1876 						InsertQueue(t->RecvQueue, pkt);
1877 						call_cancel = true;
1878 						state_changed = true;
1879 					}
1880 					else
1881 					{
1882 						// Release the packet
1883 						FreePacketWithData(pkt);
1884 					}
1885 				}
1886 			}
1887 		}
1888 		UnlockQueue(t->RecvQueue);
1889 
1890 		if (state_changed)
1891 		{
1892 			goto LABEL_RESTART;
1893 		}
1894 
1895 		if (call_cancel)
1896 		{
1897 			CANCEL *c = NULL;
1898 
1899 			Lock(t->CancelLock);
1900 			{
1901 				c = t->Cancel;
1902 
1903 				AddRef(c->ref);
1904 			}
1905 			Unlock(t->CancelLock);
1906 
1907 			Cancel(c);
1908 
1909 			ReleaseCancel(c);
1910 		}
1911 
1912 		if (IsTubeConnected(ipc->Sock->RecvTube) == false || IsTubeConnected(ipc->Sock->SendTube) == false)
1913 		{
1914 			// Disconnected
1915 			break;
1916 		}
1917 
1918 		if ((tcp_last_recv_tick + (UINT64)NN_POLL_CONNECTIVITY_TIMEOUT) < now)
1919 		{
1920 			// Connectivity test has timed out because a certain period of time has elapsed
1921 			Debug("NN_POLL_CONNECTIVITY_TIMEOUT\n");
1922 			break;
1923 		}
1924 
1925 		wait_interval = GetNextIntervalForInterrupt(interrupt);
1926 		wait_interval = MIN(wait_interval, 1234);
1927 
1928 		if (wait_interval != 0)
1929 		{
1930 			WaitForTubes(tubes, num_tubes, wait_interval);
1931 		}
1932 	}
1933 
1934 	FreeInterruptManager(interrupt);
1935 }
1936 
1937 // Build an IP packet
NnBuildIpPacket(BUF * payload,UINT src_ip,UINT dst_ip,UCHAR protocol,UCHAR ttl)1938 BUF *NnBuildIpPacket(BUF *payload, UINT src_ip, UINT dst_ip, UCHAR protocol, UCHAR ttl)
1939 {
1940 	BUF *ret = NewBuf();
1941 	IPV4_HEADER h;
1942 
1943 	if (ttl == 0)
1944 	{
1945 		ttl = 127;
1946 	}
1947 
1948 	// IP header
1949 	Zero(&h, sizeof(h));
1950 	IPV4_SET_VERSION(&h, 4);
1951 	IPV4_SET_HEADER_LEN(&h, sizeof(IPV4_HEADER) / 4);
1952 	h.TotalLength = Endian16((USHORT)sizeof(IPV4_HEADER) + payload->Size);
1953 	h.Identification = Rand16();
1954 	h.TimeToLive = ttl;
1955 	h.Protocol = protocol;
1956 	h.SrcIP = src_ip;
1957 	h.DstIP = dst_ip;
1958 
1959 	h.Checksum = IpChecksum(&h, sizeof(h));
1960 
1961 	WriteBuf(ret, &h, sizeof(h));
1962 	WriteBufBuf(ret, payload);
1963 
1964 	SeekBufToBegin(ret);
1965 
1966 	FreeBuf(payload);
1967 
1968 	return ret;
1969 }
1970 
1971 // Build an UDP packet
NnBuildUdpPacket(BUF * payload,UINT src_ip,USHORT src_port,UINT dst_ip,USHORT dst_port)1972 BUF *NnBuildUdpPacket(BUF *payload, UINT src_ip, USHORT src_port, UINT dst_ip, USHORT dst_port)
1973 {
1974 	BUF *ret = NewBuf();
1975 	BUF *phbuf = NewBuf();
1976 	UDPV4_PSEUDO_HEADER ph;
1977 	UDP_HEADER h;
1978 
1979 	// UDP pseudo header
1980 	Zero(&ph, sizeof(ph));
1981 
1982 	ph.SrcIP = src_ip;
1983 	ph.DstIP = dst_ip;
1984 	ph.SrcPort = Endian16(src_port);
1985 	ph.DstPort = Endian16(dst_port);
1986 	ph.Protocol = IP_PROTO_UDP;
1987 	ph.PacketLength1 = ph.PacketLength2 = Endian16(payload->Size + (USHORT)sizeof(UDP_HEADER));
1988 
1989 	WriteBuf(phbuf, &ph, sizeof(ph));
1990 	WriteBufBuf(phbuf, payload);
1991 
1992 	// UDP header
1993 	Zero(&h, sizeof(h));
1994 	h.SrcPort = Endian16(src_port);
1995 	h.DstPort = Endian16(dst_port);
1996 	h.PacketLength = Endian16(payload->Size + (USHORT)sizeof(UDP_HEADER));
1997 	h.Checksum = IpChecksum(phbuf->Buf, phbuf->Size);
1998 
1999 	WriteBuf(ret, &h, sizeof(h));
2000 	WriteBuf(ret, payload->Buf, payload->Size);
2001 
2002 	SeekBufToBegin(ret);
2003 
2004 	FreeBuf(payload);
2005 	FreeBuf(phbuf);
2006 
2007 	return ret;
2008 }
2009 
2010 // Build a TCP packet
NnBuildTcpPacket(BUF * payload,UINT src_ip,USHORT src_port,UINT dst_ip,USHORT dst_port,UINT seq,UINT ack,UINT flag,UINT window_size,UINT mss)2011 BUF *NnBuildTcpPacket(BUF *payload, UINT src_ip, USHORT src_port, UINT dst_ip, USHORT dst_port, UINT seq, UINT ack, UINT flag, UINT window_size, UINT mss)
2012 {
2013 	BUF *ret;
2014 	IPV4_PSEUDO_HEADER *vh;
2015 	TCP_HEADER *tcp;
2016 	static UCHAR tcp_mss_option[] = {0x02, 0x04, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00};
2017 	UINT header_size = TCP_HEADER_SIZE;
2018 	UINT total_size;
2019 
2020 	// Memory allocation
2021 	vh = Malloc(sizeof(IPV4_PSEUDO_HEADER) + TCP_HEADER_SIZE + payload->Size + 32);
2022 	tcp = (TCP_HEADER *)(((UCHAR *)vh) + sizeof(IPV4_PSEUDO_HEADER));
2023 
2024 	if (mss != 0)
2025 	{
2026 		USHORT *mss_size;
2027 		mss_size = (USHORT *)(&tcp_mss_option[2]);
2028 		*mss_size = Endian16((USHORT)mss);
2029 		header_size += sizeof(tcp_mss_option);
2030 	}
2031 
2032 	total_size = header_size + payload->Size;
2033 
2034 	// Pseudo header generation
2035 	vh->SrcIP = src_ip;
2036 	vh->DstIP = dst_ip;
2037 	vh->Reserved = 0;
2038 	vh->Protocol = IP_PROTO_TCP;
2039 	vh->PacketLength = Endian16((USHORT)total_size);
2040 
2041 	// TCP header generation
2042 	tcp->SrcPort = Endian16((USHORT)src_port);
2043 	tcp->DstPort = Endian16((USHORT)dst_port);
2044 	tcp->SeqNumber = Endian32(seq);
2045 	tcp->AckNumber = Endian32(ack);
2046 	tcp->HeaderSizeAndReserved = 0;
2047 	TCP_SET_HEADER_SIZE(tcp, (UCHAR)(header_size / 4));
2048 	tcp->Flag = (UCHAR)flag;
2049 	tcp->WindowSize = Endian16((USHORT)window_size);
2050 	tcp->Checksum = 0;
2051 	tcp->UrgentPointer = 0;
2052 
2053 	// Copy the option values
2054 	if (mss != 0)
2055 	{
2056 		Copy(((UCHAR *)tcp) + TCP_HEADER_SIZE, tcp_mss_option, sizeof(tcp_mss_option));
2057 	}
2058 
2059 	// Data copy
2060 	Copy(((UCHAR *)tcp) + header_size, payload->Buf, payload->Size);
2061 
2062 	// Checksum calculation
2063 	tcp->Checksum = IpChecksum(vh, total_size + 12);
2064 
2065 	ret = NewBufFromMemory(tcp, total_size);
2066 
2067 	Free(vh);
2068 
2069 	FreeBuf(payload);
2070 
2071 	return ret;
2072 }
2073 
2074 // Build a DNS query packet
NnBuildDnsQueryPacket(char * hostname,USHORT tran_id)2075 BUF *NnBuildDnsQueryPacket(char *hostname, USHORT tran_id)
2076 {
2077 	BUF *buf = NewBuf();
2078 	DNSV4_HEADER header;
2079 
2080 	Zero(&header, sizeof(header));
2081 
2082 	header.TransactionId = Endian16(tran_id);
2083 	header.Flag1 = 0x01;
2084 	header.Flag2 = 0x00;
2085 	header.NumQuery = Endian16(1);
2086 
2087 	WriteBuf(buf, &header, sizeof(header));
2088 
2089 	BuildDnsQueryPacket(buf, hostname, false);
2090 
2091 	SeekBufToBegin(buf);
2092 
2093 	return buf;
2094 }
2095 
2096 // Read a DNS record
NnReadDnsRecord(BUF * buf,bool answer,USHORT * ret_type,USHORT * ret_class)2097 BUF *NnReadDnsRecord(BUF *buf, bool answer, USHORT *ret_type, USHORT *ret_class)
2098 {
2099 	USHORT type;
2100 	USHORT clas;
2101 	UINT ttl;
2102 	BUF *ret = NULL;
2103 	// Validate arguments
2104 	if (buf == NULL)
2105 	{
2106 		return NULL;
2107 	}
2108 
2109 	// Read the DNS label
2110 	if (NnReadDnsLabel(buf) == false)
2111 	{
2112 		return false;
2113 	}
2114 
2115 	// Type and Class
2116 	if (ReadBuf(buf, &type, sizeof(USHORT)) != sizeof(USHORT))
2117 	{
2118 		return false;
2119 	}
2120 
2121 	if (ret_type != NULL)
2122 	{
2123 		*ret_type = Endian16(type);
2124 	}
2125 
2126 	if (ReadBuf(buf, &clas, sizeof(USHORT)) != sizeof(USHORT))
2127 	{
2128 		return false;
2129 	}
2130 
2131 	if (ret_class != NULL)
2132 	{
2133 		*ret_class = Endian16(clas);
2134 	}
2135 
2136 	if (answer)
2137 	{
2138 		USHORT data_len;
2139 		UCHAR *data;
2140 
2141 		// TTL
2142 		if (ReadBuf(buf, &ttl, sizeof(UINT)) != sizeof(UINT))
2143 		{
2144 			return false;
2145 		}
2146 
2147 		// data_len
2148 		if (ReadBuf(buf, &data_len, sizeof(USHORT)) != sizeof(USHORT))
2149 		{
2150 			return false;
2151 		}
2152 
2153 		data_len = Endian16(data_len);
2154 
2155 		// data
2156 		data = Malloc(data_len);
2157 		if (ReadBuf(buf, data, data_len) != data_len)
2158 		{
2159 			Free(data);
2160 			return false;
2161 		}
2162 
2163 		ret = NewBufFromMemory(data, data_len);
2164 
2165 		Free(data);
2166 	}
2167 	else
2168 	{
2169 		ret = NewBuf();
2170 	}
2171 
2172 	return ret;
2173 }
2174 
2175 // Read the DNS label
NnReadDnsLabel(BUF * buf)2176 bool NnReadDnsLabel(BUF *buf)
2177 {
2178 	UCHAR c;
2179 	UCHAR tmp[256];
2180 	// Validate arguments
2181 	if (buf == NULL)
2182 	{
2183 		return false;
2184 	}
2185 
2186 LABEL_START:
2187 
2188 	if (ReadBuf(buf, &c, 1) != 1)
2189 	{
2190 		return false;
2191 	}
2192 
2193 	if (c == 0)
2194 	{
2195 		return true;
2196 	}
2197 
2198 	if (c & 0xC0)
2199 	{
2200 		// Compression label
2201 		if (ReadBuf(buf, &c, 1) != 1)
2202 		{
2203 			return false;
2204 		}
2205 		else
2206 		{
2207 			return true;
2208 		}
2209 	}
2210 	else
2211 	{
2212 		// Usual label
2213 		if (ReadBuf(buf, tmp, c) != c)
2214 		{
2215 			return false;
2216 		}
2217 		else
2218 		{
2219 			goto LABEL_START;
2220 		}
2221 	}
2222 
2223 }
2224 
2225 // Parse the DNS response packet
NnParseDnsResponsePacket(UCHAR * data,UINT size,IP * ret_ip)2226 bool NnParseDnsResponsePacket(UCHAR *data, UINT size, IP *ret_ip)
2227 {
2228 	BUF *buf = NewBufFromMemory(data, size);
2229 	bool ret = false;
2230 	DNSV4_HEADER h;
2231 
2232 	if (ReadBuf(buf, &h, sizeof(h)) == sizeof(h))
2233 	{
2234 		UINT num_questions = Endian16(h.NumQuery);
2235 		UINT num_answers = Endian16(h.AnswerRRs);
2236 		UINT i;
2237 
2238 		for (i = 0; i < num_questions; i++)
2239 		{
2240 			BUF *r = NnReadDnsRecord(buf, false, NULL, NULL);
2241 
2242 			if (r != NULL)
2243 			{
2244 				FreeBuf(r);
2245 			}
2246 			else
2247 			{
2248 				goto LABEL_CLEANUP;
2249 			}
2250 		}
2251 
2252 		for (i = 0; i < num_answers; i++)
2253 		{
2254 			USHORT tp, cl;
2255 			BUF *r = NnReadDnsRecord(buf, true, &tp, &cl);
2256 
2257 			if (r != NULL)
2258 			{
2259 				if (tp == 0x0001 && cl == 0x0001 && r->Size == IPV4_SIZE)
2260 				{
2261 					ret = true;
2262 
2263 					if (ret_ip != NULL)
2264 					{
2265 						ZeroIP4(ret_ip);
2266 						Copy(IPV4(ret_ip->address), r->Buf, IPV4_SIZE);
2267 					}
2268 				}
2269 
2270 				FreeBuf(r);
2271 			}
2272 			else
2273 			{
2274 				goto LABEL_CLEANUP;
2275 			}
2276 		}
2277 	}
2278 
2279 LABEL_CLEANUP:
2280 	FreeBuf(buf);
2281 
2282 	return ret;
2283 }
2284 
2285 // Test the connectivity of the stack to the Internet
NnTestConnectivity(NATIVE_STACK * a,TUBE * halt_tube)2286 bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
2287 {
2288 	BUF *dns_query;
2289 	BUF *dns_query2;
2290 	bool ok = false;
2291 	USHORT dns_tran_id = Rand16();
2292 	UINT64 next_send_tick = 0;
2293 	UINT64 giveup_time;
2294 	IPC *ipc;
2295 	INTERRUPT_MANAGER *interrupt;
2296 	TUBE *tubes[3];
2297 	UINT num_tubes = 0;
2298 	IP yahoo_ip;
2299 	IP my_priv_ip;
2300 	UINT num_send_dns = 0;
2301 	IP using_dns;
2302 	UINT src_port = 0;
2303 	// Validate arguments
2304 	if (a == NULL)
2305 	{
2306 		return false;
2307 	}
2308 
2309 	src_port = NnGenSrcPort(a->IsIpRawMode);
2310 
2311 	Copy(&using_dns, &a->DnsServerIP, sizeof(IP));
2312 
2313 	// Get my physical IP
2314 	if (a->IsIpRawMode)
2315 	{
2316 		if (GetMyPrivateIP(&my_priv_ip, false) == false)
2317 		{
2318 			Debug("NnTestConnectivity: GetMyPrivateIP failed.\n");
2319 			return false;
2320 		}
2321 		else
2322 		{
2323 			Debug("NnTestConnectivity: GetMyPrivateIP ok: %r\n", &my_priv_ip);
2324 
2325 			if (a->Eth != NULL)
2326 			{
2327 				Copy(&a->Eth->MyPhysicalIPForce, &my_priv_ip, sizeof(IP));
2328 			}
2329 		}
2330 	}
2331 
2332 	ipc = a->Ipc;
2333 	interrupt = NewInterruptManager();
2334 
2335 	tubes[num_tubes++] = ipc->Sock->RecvTube;
2336 	tubes[num_tubes++] = ipc->Sock->SendTube;
2337 
2338 	if (halt_tube != NULL)
2339 	{
2340 		tubes[num_tubes++] = halt_tube;
2341 	}
2342 
2343 	Zero(&yahoo_ip, sizeof(yahoo_ip));
2344 
2345 	// Try to get an IP address of www.yahoo.com
2346 	dns_query = NnBuildIpPacket(NnBuildUdpPacket(NnBuildDnsQueryPacket(NN_CHECK_HOSTNAME, dns_tran_id),
2347 	                            IPToUINT(&ipc->ClientIPAddress), src_port, IPToUINT(&a->DnsServerIP), 53),
2348 	                            IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP), IP_PROTO_UDP, 0);
2349 
2350 	dns_query2 = NnBuildIpPacket(NnBuildUdpPacket(NnBuildDnsQueryPacket(NN_CHECK_HOSTNAME, dns_tran_id),
2351 	                             IPToUINT(&ipc->ClientIPAddress), src_port, IPToUINT(&a->DnsServerIP), 53),
2352 	                             IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP2), IP_PROTO_UDP, 0);
2353 
2354 	giveup_time = Tick64() + NN_CHECK_CONNECTIVITY_TIMEOUT;
2355 	AddInterrupt(interrupt, giveup_time);
2356 	while (true)
2357 	{
2358 		UINT64 now = Tick64();
2359 
2360 		IPCFlushArpTable(a->Ipc);
2361 
2362 		if (now >= giveup_time)
2363 		{
2364 			break;
2365 		}
2366 
2367 		// Send a packet periodically
2368 		if (next_send_tick == 0 || next_send_tick <= now)
2369 		{
2370 			next_send_tick = now + (UINT64)NN_CHECK_CONNECTIVITY_INTERVAL;
2371 
2372 			AddInterrupt(interrupt, next_send_tick);
2373 
2374 			if ((num_send_dns % 2) == 0)
2375 			{
2376 				IPCSendIPv4(ipc, dns_query->Buf, dns_query->Size);
2377 			}
2378 			else
2379 			{
2380 				IPCSendIPv4(ipc, dns_query2->Buf, dns_query2->Size);
2381 			}
2382 
2383 			num_send_dns++;
2384 		}
2385 
2386 		// Happy processing
2387 		IPCProcessL3EventsIPv4Only(ipc);
2388 
2389 		while (true)
2390 		{
2391 			// Receive a packet
2392 			BLOCK *b = IPCRecvIPv4(ipc);
2393 			PKT *pkt;
2394 
2395 			if (b == NULL)
2396 			{
2397 				break;
2398 			}
2399 
2400 			// Parse the packet
2401 			pkt = ParsePacketIPv4WithDummyMacHeader(b->Buf, b->Size);
2402 
2403 			if (pkt != NULL)
2404 			{
2405 				if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_UDP &&
2406 				        (pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) ||
2407 				         pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP2)) &&
2408 				        pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) &&
2409 				        pkt->L4.UDPHeader->SrcPort == Endian16(53) && pkt->L4.UDPHeader->DstPort == Endian16(src_port))
2410 				{
2411 					DNSV4_HEADER *dns_header = (DNSV4_HEADER *)pkt->Payload;
2412 					if (pkt->PayloadSize >= sizeof(DNSV4_HEADER))
2413 					{
2414 						if (dns_header->TransactionId == Endian16(dns_tran_id))
2415 						{
2416 							IP ret_ip;
2417 
2418 							if (NnParseDnsResponsePacket(pkt->Payload, pkt->PayloadSize, &ret_ip))
2419 							{
2420 								UINTToIP(&using_dns, pkt->L3.IPv4Header->SrcIP);
2421 								Debug("NativeStack: Using DNS: %r\n", &using_dns);
2422 
2423 								Copy(&yahoo_ip, &ret_ip, sizeof(IP));
2424 							}
2425 						}
2426 					}
2427 				}
2428 			}
2429 
2430 			FreePacketWithData(pkt);
2431 			FreeBlock(b);
2432 		}
2433 
2434 		if ((halt_tube != NULL && IsTubeConnected(halt_tube) == false) ||
2435 		        IsTubeConnected(ipc->Sock->SendTube) == false || IsTubeConnected(ipc->Sock->RecvTube) == false)
2436 		{
2437 			// Disconnected
2438 			break;
2439 		}
2440 
2441 		if (IsZeroIP(&yahoo_ip) == false)
2442 		{
2443 			// There is a response
2444 			break;
2445 		}
2446 
2447 		// Keep the CPU waiting
2448 		WaitForTubes(tubes, num_tubes, GetNextIntervalForInterrupt(interrupt));
2449 	}
2450 
2451 	FreeBuf(dns_query);
2452 	FreeBuf(dns_query2);
2453 
2454 	if (IsZeroIP(&yahoo_ip) == false)
2455 	{
2456 		BUF *tcp_query;
2457 		UINT seq = Rand32();
2458 		bool tcp_get_response = false;
2459 		UINT recv_seq = 0;
2460 
2461 		// Since the IP address of www.yahoo.com has gotten, try to connect by TCP
2462 		giveup_time = Tick64() + NN_CHECK_CONNECTIVITY_TIMEOUT;
2463 		AddInterrupt(interrupt, giveup_time);
2464 
2465 		// Generate a TCP packet
2466 		tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), src_port,
2467 		                            IPToUINT(&yahoo_ip), 80, seq, 0, TCP_SYN, 8192, 1414),
2468 		                            IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0);
2469 
2470 		Debug("Test TCP to %r\n", &yahoo_ip);
2471 
2472 		next_send_tick = 0;
2473 
2474 		while (true)
2475 		{
2476 			UINT64 now = Tick64();
2477 
2478 			IPCFlushArpTable(a->Ipc);
2479 
2480 			if (now >= giveup_time)
2481 			{
2482 				break;
2483 			}
2484 
2485 			// Send the packet periodically
2486 			if (next_send_tick == 0 || next_send_tick <= now)
2487 			{
2488 				next_send_tick = now + (UINT64)NN_CHECK_CONNECTIVITY_INTERVAL;
2489 
2490 				AddInterrupt(interrupt, next_send_tick);
2491 
2492 				IPCSendIPv4(ipc, tcp_query->Buf, tcp_query->Size);
2493 			}
2494 
2495 			// Happy procedure
2496 			IPCProcessL3EventsIPv4Only(ipc);
2497 
2498 			while (true)
2499 			{
2500 				// Receive a packet
2501 				BLOCK *b = IPCRecvIPv4(ipc);
2502 				PKT *pkt;
2503 
2504 				if (b == NULL)
2505 				{
2506 					break;
2507 				}
2508 
2509 				// Parse the packet
2510 				pkt = ParsePacketIPv4WithDummyMacHeader(b->Buf, b->Size);
2511 
2512 				if (pkt != NULL)
2513 				{
2514 					if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_TCP &&
2515 					        pkt->L3.IPv4Header->SrcIP == IPToUINT(&yahoo_ip) &&
2516 					        pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) &&
2517 					        pkt->L4.TCPHeader->SrcPort == Endian16(80) && pkt->L4.TCPHeader->DstPort == Endian16(src_port))
2518 					{
2519 						TCP_HEADER *tcp_header = (TCP_HEADER *)pkt->L4.TCPHeader;
2520 						if ((tcp_header->Flag & TCP_SYN) && (tcp_header->Flag & TCP_ACK))
2521 						{
2522 							// There was a TCP response
2523 							tcp_get_response = true;
2524 							recv_seq = Endian32(tcp_header->SeqNumber);
2525 						}
2526 					}
2527 				}
2528 
2529 				FreePacketWithData(pkt);
2530 				FreeBlock(b);
2531 			}
2532 
2533 			if ((halt_tube != NULL && IsTubeConnected(halt_tube) == false) ||
2534 			        IsTubeConnected(ipc->Sock->SendTube) == false || IsTubeConnected(ipc->Sock->RecvTube) == false)
2535 			{
2536 				// Disconnected
2537 				break;
2538 			}
2539 
2540 			if (tcp_get_response)
2541 			{
2542 				WHERE;
2543 				break;
2544 			}
2545 
2546 			// Keep the CPU waiting
2547 			WaitForTubes(tubes, num_tubes, GetNextIntervalForInterrupt(interrupt));
2548 		}
2549 
2550 		FreeBuf(tcp_query);
2551 
2552 		// Send a RST
2553 		if (recv_seq != 0)
2554 		{
2555 			recv_seq++;
2556 		}
2557 
2558 		tcp_query = NnBuildIpPacket(NnBuildTcpPacket(NewBuf(), IPToUINT(&ipc->ClientIPAddress), src_port,
2559 		                            IPToUINT(&yahoo_ip), 80, seq + 1, recv_seq, TCP_RST | TCP_ACK, 8192, 0),
2560 		                            IPToUINT(&ipc->ClientIPAddress), IPToUINT(&yahoo_ip), IP_PROTO_TCP, 0);
2561 
2562 		IPCSendIPv4(ipc, tcp_query->Buf, tcp_query->Size);
2563 
2564 		FreeBuf(tcp_query);
2565 
2566 		SleepThread(100);
2567 
2568 		if (tcp_get_response)
2569 		{
2570 			ok = true;
2571 		}
2572 	}
2573 
2574 	FreeInterruptManager(interrupt);
2575 
2576 	if (ok)
2577 	{
2578 		if (IsZeroIP(&using_dns) == false)
2579 		{
2580 			Copy(&a->DnsServerIP, &using_dns, sizeof(IP));
2581 		}
2582 
2583 		if (a->IsIpRawMode)
2584 		{
2585 			if (NsStartIpTablesTracking(a) == false)
2586 			{
2587 				Debug("NsStartIpTablesTracking failed.\n");
2588 				ok = false;
2589 			}
2590 		}
2591 	}
2592 
2593 	return ok;
2594 }
2595 
2596 // Generate source port number by a random number
NnGenSrcPort(bool raw_ip_mode)2597 UINT NnGenSrcPort(bool raw_ip_mode)
2598 {
2599 	if (raw_ip_mode == false)
2600 	{
2601 		return 1025 + Rand32() % (65500 - 1025);
2602 	}
2603 	else
2604 	{
2605 		return NN_RAW_IP_PORT_START + Rand32() % (NN_RAW_IP_PORT_END - NN_RAW_IP_PORT_START);
2606 	}
2607 }
2608 
2609 // Get a next good interface for the native NAT
NnGetNextInterface(NATIVE_NAT * t)2610 NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t)
2611 {
2612 	NATIVE_STACK *ret = NULL;
2613 	UINT current_hash;
2614 	TOKEN_LIST *device_list;
2615 	UINT i;
2616 	char tmp[MAX_SIZE];
2617 	char *dev_name;
2618 	UINT current_ip_hash;
2619 	// Validate arguments
2620 	if (t == NULL)
2621 	{
2622 		return NULL;
2623 	}
2624 
2625 	t->NextWaitTimeForRetry = NN_NEXT_WAIT_TIME_FOR_DEVICE_ENUM * MIN((t->FailedCount + 1), NN_NEXT_WAIT_TIME_MAX_FAIL_COUNT);
2626 
2627 	// Get the device list
2628 	device_list = GetEthListEx(NULL,
2629 	                           !(t->v->HubOption != NULL && t->v->HubOption->DisableKernelModeSecureNAT),
2630 	                           !(t->v->HubOption != NULL && t->v->HubOption->DisableIpRawModeSecureNAT));
2631 
2632 	if (device_list == NULL || device_list->NumTokens == 0)
2633 	{
2634 		// Device list acquisition failure (Or no device acquired as a result)
2635 		FreeToken(device_list);
2636 		t->FailedCount++;
2637 		return NULL;
2638 	}
2639 
2640 	current_hash = GetEthDeviceHash();
2641 	current_ip_hash = GetHostIPAddressHash32();
2642 
2643 	if (t->LastInterfaceDeviceHash != current_hash || t->LastHostAddressHash != current_ip_hash)
2644 	{
2645 		// Device list is altered from the previous search
2646 		t->LastInterfaceIndex = INFINITE;
2647 		t->FailedCount = 0;
2648 	}
2649 
2650 	t->LastInterfaceDeviceHash = current_hash;
2651 	t->LastHostAddressHash = current_ip_hash;
2652 
2653 	if (t->LastInterfaceIndex == INFINITE)
2654 	{
2655 		i = 0;
2656 	}
2657 	else
2658 	{
2659 		i = t->LastInterfaceIndex + 1;
2660 		if (i >= device_list->NumTokens)
2661 		{
2662 			i = 0;
2663 		}
2664 	}
2665 
2666 	if ((i + 1) == device_list->NumTokens)
2667 	{
2668 		// Searched to the end
2669 		t->LastInterfaceIndex = INFINITE;
2670 
2671 		// Increase the number of search failures by one
2672 		t->FailedCount++;
2673 	}
2674 	else
2675 	{
2676 		// It is not the end yet
2677 		t->LastInterfaceIndex = i;
2678 		t->NextWaitTimeForRetry = 0;
2679 	}
2680 
2681 	dev_name = device_list->Token[i];
2682 
2683 	if (IsInLinesFile(NN_NO_NATIVE_NAT_FILENAME, dev_name, true) == false)
2684 	{
2685 		// Try to open the device
2686 		BinToStr(tmp, sizeof(tmp), t->v->MacAddress, 6);
2687 		ret = NewNativeStack(NULL, dev_name, tmp);
2688 
2689 		if (ret != NULL)
2690 		{
2691 			// Test whether an IP address can be obtained from a DHCP server
2692 			DHCP_OPTION_LIST opt;
2693 
2694 			Copy(t->CurrentMacAddress, ret->Ipc->MacAddress, 6);
2695 
2696 			Zero(&opt, sizeof(opt));
2697 
2698 			BinToStr(tmp, sizeof(tmp), ret->MacAddress, 6);
2699 			Format(ret->Ipc->ClientHostname, sizeof(ret->Ipc->ClientHostname), NN_HOSTNAME_FORMAT, tmp);
2700 			StrLower(ret->Ipc->ClientHostname);
2701 
2702 			Debug("IPCDhcpAllocateIP for %s\n", ret->DeviceName);
2703 			if (IPCDhcpAllocateIP(ret->Ipc, &opt, t->HaltTube2))
2704 			{
2705 				char client_ip[64];
2706 				char dhcp_ip[64];
2707 				char client_mask[64];
2708 				char gateway_ip[64];
2709 
2710 				IP ip;
2711 				IP subnet;
2712 				IP gw;
2713 
2714 				IPToStr32(client_ip, sizeof(client_ip), opt.ClientAddress);
2715 				IPToStr32(client_mask, sizeof(client_mask), opt.SubnetMask);
2716 				IPToStr32(dhcp_ip, sizeof(dhcp_ip), opt.ServerAddress);
2717 				IPToStr32(gateway_ip, sizeof(gateway_ip), opt.Gateway);
2718 
2719 				Debug("DHCP: client_ip=%s, client_mask=%s, dhcp_ip=%s, gateway_ip=%s\n",
2720 				      client_ip, client_mask, dhcp_ip, gateway_ip);
2721 
2722 				Copy(&ret->CurrentDhcpOptionList, &opt, sizeof(DHCP_OPTION_LIST));
2723 
2724 				// IP parameter settings
2725 				UINTToIP(&ip, opt.ClientAddress);
2726 				UINTToIP(&subnet, opt.SubnetMask);
2727 				UINTToIP(&gw, opt.Gateway);
2728 
2729 				IPCSetIPv4Parameters(ret->Ipc, &ip, &subnet, &gw, &opt.ClasslessRoute);
2730 
2731 				// Determine the DNS server to use
2732 				UINTToIP(&ret->DnsServerIP, opt.DnsServer);
2733 				UINTToIP(&ret->DnsServerIP2, opt.DnsServer2);
2734 				if (IsZeroIP(&ret->DnsServerIP))
2735 				{
2736 					// Use 8.8.8.8 instead If the DNS is not assigned from the DHCP server
2737 					SetIP(&ret->DnsServerIP, 8, 8, 8, 8);
2738 				}
2739 				if (IsZeroIP(&ret->DnsServerIP2))
2740 				{
2741 					// Use 8.8.4.4 instead If the DNS is not assigned from the DHCP server
2742 					SetIP(&ret->DnsServerIP2, 8, 8, 4, 4);
2743 				}
2744 
2745 				// Connectivity test
2746 				// (always fail if the default gateway is not set)
2747 				if (opt.Gateway != 0 &&
2748 				        NnTestConnectivity(ret, t->HaltTube2))
2749 				{
2750 					// Reset the number of search failures
2751 					t->FailedCount = 0;
2752 					Debug("Connectivity OK.\n");
2753 				}
2754 				else
2755 				{
2756 					Debug("Connectivity Failed.\n");
2757 					FreeNativeStack(ret);
2758 					ret = NULL;
2759 				}
2760 			}
2761 			else
2762 			{
2763 				Debug("DHCP Failed.\n");
2764 				FreeNativeStack(ret);
2765 				ret = NULL;
2766 
2767 				Zero(t->CurrentMacAddress, sizeof(t->CurrentMacAddress));
2768 			}
2769 		}
2770 	}
2771 
2772 	FreeToken(device_list);
2773 
2774 	return ret;
2775 }
2776 
2777 // Native NAT thread
NativeNatThread(THREAD * thread,void * param)2778 void NativeNatThread(THREAD *thread, void *param)
2779 {
2780 	NATIVE_NAT *t = (NATIVE_NAT *)param;
2781 	void *wait_handle = InitWaitUntilHostIPAddressChanged();
2782 	// Validate arguments
2783 	if (thread == NULL || param == NULL)
2784 	{
2785 		return;
2786 	}
2787 
2788 	while (t->Halt == false)
2789 	{
2790 		NATIVE_STACK *a;
2791 
2792 		while (t->v->UseNat == false || t->v->HubOption == NULL || (t->v->HubOption->DisableKernelModeSecureNAT && t->v->HubOption->DisableIpRawModeSecureNAT))
2793 		{
2794 			if (t->Halt)
2795 			{
2796 				break;
2797 			}
2798 
2799 			// If the NAT is disabled, wait until it becomes enabled
2800 			Wait(t->HaltEvent, 1234);
2801 		}
2802 
2803 		if (t->Halt)
2804 		{
2805 			break;
2806 		}
2807 
2808 		// Get a next good native NAT stack
2809 		Debug("NnGetNextInterface Start.\n");
2810 
2811 		NnClearQueue(t);
2812 
2813 		a = NnGetNextInterface(t);
2814 
2815 		if (a != NULL)
2816 		{
2817 			char macstr[64];
2818 			// Acquisition success
2819 			Debug("NnGetNextInterface Ok: %s\n", a->DeviceName);
2820 
2821 			t->IsRawIpMode = a->IsIpRawMode;
2822 
2823 			Lock(t->Lock);
2824 			{
2825 				if (a->Sock1 != NULL)
2826 				{
2827 					t->HaltTube = a->Sock2->RecvTube;
2828 
2829 					if (t->HaltTube != NULL)
2830 					{
2831 						AddRef(t->HaltTube->Ref);
2832 					}
2833 				}
2834 			}
2835 			Unlock(t->Lock);
2836 
2837 			NnClearQueue(t);
2838 
2839 			t->PublicIP = IPToUINT(&a->Ipc->ClientIPAddress);
2840 			t->Active = true;
2841 
2842 
2843 			Debug("NnMainLoop Start.\n");
2844 			MacToStr(macstr, sizeof(macstr), a->Ipc->MacAddress);
2845 			NLog(t->v, "LH_KERNEL_MODE_START", a->DeviceName,
2846 			     &a->Ipc->ClientIPAddress, &a->Ipc->SubnetMask, &a->Ipc->DefaultGateway, &a->Ipc->BroadcastAddress,
2847 			     macstr, &a->CurrentDhcpOptionList.ServerAddress, &a->DnsServerIP);
2848 			NnMainLoop(t, a);
2849 			Debug("NnMainLoop End.\n");
2850 
2851 			t->IsRawIpMode = false;
2852 
2853 			t->Active = false;
2854 			t->PublicIP = 0;
2855 
2856 
2857 			NnClearQueue(t);
2858 
2859 			// Close the stack
2860 			Lock(t->Lock);
2861 			{
2862 				if (t->HaltTube != NULL)
2863 				{
2864 					ReleaseTube(t->HaltTube);
2865 					t->HaltTube = NULL;
2866 				}
2867 			}
2868 			Unlock(t->Lock);
2869 			FreeNativeStack(a);
2870 
2871 			Zero(t->CurrentMacAddress, 6);
2872 		}
2873 		else
2874 		{
2875 			Debug("NnGetNextInterface Failed.\n");
2876 		}
2877 
2878 		// Wait for a certain period of time
2879 		if (t->NextWaitTimeForRetry != 0)
2880 		{
2881 			WaitUntilHostIPAddressChanged(wait_handle, t->HaltEvent, t->NextWaitTimeForRetry, 1000);
2882 		}
2883 	}
2884 
2885 	FreeWaitUntilHostIPAddressChanged(wait_handle);
2886 }
2887 
2888 // Erase the contents of the queue for transmission and reception
NnClearQueue(NATIVE_NAT * t)2889 void NnClearQueue(NATIVE_NAT *t)
2890 {
2891 	// Validate arguments
2892 	if (t == NULL)
2893 	{
2894 		return;
2895 	}
2896 
2897 	LockQueue(t->SendQueue);
2898 	{
2899 		while (true)
2900 		{
2901 			BLOCK *b = GetNext(t->SendQueue);
2902 
2903 			if (b == NULL)
2904 			{
2905 				break;
2906 			}
2907 
2908 			FreeBlock(b);
2909 		}
2910 	}
2911 	UnlockQueue(t->SendQueue);
2912 
2913 	LockQueue(t->RecvQueue);
2914 	{
2915 		while (true)
2916 		{
2917 			PKT *p = GetNext(t->RecvQueue);
2918 
2919 			if (p == NULL)
2920 			{
2921 				break;
2922 			}
2923 
2924 			FreePacketWithData(p);
2925 		}
2926 	}
2927 	UnlockQueue(t->RecvQueue);
2928 }
2929 
2930 // Structure setting function to search for native NAT
NnSetNat(NATIVE_NAT_ENTRY * e,UINT protocol,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,UINT pub_ip,UINT pub_port)2931 void NnSetNat(NATIVE_NAT_ENTRY *e, UINT protocol, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT pub_ip, UINT pub_port)
2932 {
2933 	// Validate arguments
2934 	if (e == NULL)
2935 	{
2936 		return;
2937 	}
2938 
2939 	Zero(e, sizeof(NATIVE_NAT_ENTRY));
2940 
2941 	e->Protocol = protocol;
2942 	e->SrcIp = src_ip;
2943 	e->SrcPort = src_port;
2944 	e->DestIp = dest_ip;
2945 	e->DestPort = dest_port;
2946 	e->PublicIp = pub_ip;
2947 	e->PublicPort = pub_port;
2948 	e->HashCodeForSend = e->HashCodeForRecv = INFINITE;
2949 }
2950 
2951 // Get the hash code of the native NAT table (receiving direction)
GetHashNativeNatTableForRecv(void * p)2952 UINT GetHashNativeNatTableForRecv(void *p)
2953 {
2954 	UINT r;
2955 	NATIVE_NAT_ENTRY *e = (NATIVE_NAT_ENTRY *)p;
2956 	if (e == NULL)
2957 	{
2958 		return 0;
2959 	}
2960 
2961 	if (e->HashCodeForRecv != INFINITE)
2962 	{
2963 		return e->HashCodeForRecv;
2964 	}
2965 
2966 	r = 0;
2967 
2968 	r += e->Protocol;
2969 	r += e->PublicIp;
2970 	r += e->PublicPort;
2971 
2972 	if (e->Protocol == NAT_TCP)
2973 	{
2974 		r += e->DestIp;
2975 		r += e->DestPort;
2976 	}
2977 
2978 	e->HashCodeForRecv = r;
2979 
2980 	return r;
2981 }
2982 
2983 // Comparison function of native NAT table (receiving direction)
CmpNativeNatTableForRecv(void * p1,void * p2)2984 int CmpNativeNatTableForRecv(void *p1, void *p2)
2985 {
2986 	int r;
2987 	NATIVE_NAT_ENTRY *e1, *e2;
2988 	if (p1 == NULL || p2 == NULL)
2989 	{
2990 		return 0;
2991 	}
2992 	e1 = *(NATIVE_NAT_ENTRY **)p1;
2993 	e2 = *(NATIVE_NAT_ENTRY **)p2;
2994 	if (e1 == NULL || e2 == NULL)
2995 	{
2996 		return 0;
2997 	}
2998 
2999 	r = COMPARE_RET(e1->Protocol, e2->Protocol);
3000 	if (r != 0)
3001 	{
3002 		return r;
3003 	}
3004 
3005 	r = COMPARE_RET(e1->PublicIp, e2->PublicIp);
3006 	if (r != 0)
3007 	{
3008 		return r;
3009 	}
3010 
3011 	r = COMPARE_RET(e1->PublicPort, e2->PublicPort);
3012 	if (r != 0)
3013 	{
3014 		return r;
3015 	}
3016 
3017 	if (e1->Protocol == NAT_TCP)
3018 	{
3019 		r = COMPARE_RET(e1->DestIp, e2->DestIp);
3020 		if (r != 0)
3021 		{
3022 			return r;
3023 		}
3024 
3025 		r = COMPARE_RET(e1->DestPort, e2->DestPort);
3026 		if (r != 0)
3027 		{
3028 			return r;
3029 		}
3030 	}
3031 
3032 	return 0;
3033 }
3034 
3035 // Get the hash code of the native NAT table (transmit direction)
GetHashNativeNatTableForSend(void * p)3036 UINT GetHashNativeNatTableForSend(void *p)
3037 {
3038 	UINT r;
3039 	NATIVE_NAT_ENTRY *e = (NATIVE_NAT_ENTRY *)p;
3040 	if (e == NULL)
3041 	{
3042 		return 0;
3043 	}
3044 
3045 	if (e->HashCodeForSend != INFINITE)
3046 	{
3047 		return e->HashCodeForSend;
3048 	}
3049 
3050 	r = 0;
3051 
3052 	r += e->Protocol;
3053 	r += e->SrcIp;
3054 	r += e->SrcPort;
3055 
3056 	if (e->Protocol == NAT_TCP)
3057 	{
3058 		r += e->DestIp;
3059 		r += e->DestPort;
3060 	}
3061 
3062 	e->HashCodeForSend = r;
3063 
3064 	return r;
3065 }
3066 
3067 // Comparison function of native NAT table (transmit direction)
CmpNativeNatTableForSend(void * p1,void * p2)3068 int CmpNativeNatTableForSend(void *p1, void *p2)
3069 {
3070 	int r;
3071 	NATIVE_NAT_ENTRY *e1, *e2;
3072 	if (p1 == NULL || p2 == NULL)
3073 	{
3074 		return 0;
3075 	}
3076 	e1 = *(NATIVE_NAT_ENTRY **)p1;
3077 	e2 = *(NATIVE_NAT_ENTRY **)p2;
3078 	if (e1 == NULL || e2 == NULL)
3079 	{
3080 		return 0;
3081 	}
3082 
3083 	r = COMPARE_RET(e1->Protocol, e2->Protocol);
3084 	if (r != 0)
3085 	{
3086 		return r;
3087 	}
3088 
3089 	r = COMPARE_RET(e1->SrcIp, e2->SrcIp);
3090 	if (r != 0)
3091 	{
3092 		return r;
3093 	}
3094 
3095 	r = COMPARE_RET(e1->SrcPort, e2->SrcPort);
3096 	if (r != 0)
3097 	{
3098 		return r;
3099 	}
3100 
3101 	if (e1->Protocol == NAT_TCP)
3102 	{
3103 		r = COMPARE_RET(e1->DestIp, e2->DestIp);
3104 		if (r != 0)
3105 		{
3106 			return r;
3107 		}
3108 
3109 		r = COMPARE_RET(e1->DestPort, e2->DestPort);
3110 		if (r != 0)
3111 		{
3112 			return r;
3113 		}
3114 	}
3115 
3116 	return 0;
3117 }
3118 
3119 // Start the native NAT
NewNativeNat(VH * v)3120 NATIVE_NAT *NewNativeNat(VH *v)
3121 {
3122 	NATIVE_NAT *t;
3123 	// Validate arguments
3124 	if (v == NULL)
3125 	{
3126 		return NULL;
3127 	}
3128 
3129 	t = ZeroMalloc(sizeof(NATIVE_NAT));
3130 
3131 	t->v = v;
3132 
3133 	t->Cancel = v->Cancel;
3134 	AddRef(t->Cancel->ref);
3135 
3136 	// Data structure initialization
3137 	t->LastInterfaceIndex = INFINITE;
3138 	t->SendQueue = NewQueue();
3139 	t->RecvQueue = NewQueue();
3140 	NnInitIpCombineList(t);
3141 
3142 	t->Lock = NewLock();
3143 
3144 	t->CancelLock = NewLock();
3145 
3146 	t->HaltEvent = NewEvent();
3147 
3148 	NewTubePair(&t->HaltTube2, &t->HaltTube3, 0);
3149 
3150 	// Create a NAT table
3151 	t->NatTableForSend = NewHashList(GetHashNativeNatTableForSend, CmpNativeNatTableForSend, 11, true);
3152 	t->NatTableForRecv = NewHashList(GetHashNativeNatTableForRecv, CmpNativeNatTableForRecv, 11, true);
3153 
3154 	t->Thread = NewThread(NativeNatThread, t);
3155 
3156 	return t;
3157 }
3158 
3159 // Stop the native NAT
FreeNativeNat(NATIVE_NAT * t)3160 void FreeNativeNat(NATIVE_NAT *t)
3161 {
3162 	TUBE *tube;
3163 	UINT i;
3164 	// Validate arguments
3165 	if (t == NULL)
3166 	{
3167 		return;
3168 	}
3169 
3170 	t->Halt = true;
3171 
3172 	Lock(t->Lock);
3173 	{
3174 		tube = t->HaltTube;
3175 
3176 		if (tube != NULL)
3177 		{
3178 			AddRef(tube->Ref);
3179 		}
3180 	}
3181 	Unlock(t->Lock);
3182 
3183 	if (tube != NULL)
3184 	{
3185 		TubeFlushEx(tube, true);
3186 
3187 		SleepThread(100);
3188 
3189 		TubeDisconnect(tube);
3190 
3191 		ReleaseTube(tube);
3192 	}
3193 
3194 	TubeDisconnect(t->HaltTube2);
3195 	TubeDisconnect(t->HaltTube3);
3196 
3197 	Set(t->HaltEvent);
3198 
3199 	WaitThread(t->Thread, INFINITE);
3200 
3201 	ReleaseThread(t->Thread);
3202 
3203 	DeleteLock(t->Lock);
3204 
3205 	DeleteLock(t->CancelLock);
3206 
3207 	ReleaseEvent(t->HaltEvent);
3208 
3209 	ReleaseTube(t->HaltTube2);
3210 	ReleaseTube(t->HaltTube3);
3211 
3212 	NnClearQueue(t);
3213 
3214 	ReleaseQueue(t->RecvQueue);
3215 	ReleaseQueue(t->SendQueue);
3216 
3217 	ReleaseCancel(t->Cancel);
3218 
3219 	// Release the NAT table
3220 	for (i = 0; i < LIST_NUM(t->NatTableForSend->AllList); i++)
3221 	{
3222 		NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i);
3223 
3224 		Free(e);
3225 	}
3226 
3227 	ReleaseHashList(t->NatTableForSend);
3228 	ReleaseHashList(t->NatTableForRecv);
3229 
3230 	NnFreeIpCombineList(t);
3231 
3232 	Free(t);
3233 }
3234 
3235 // Take the log of Virtual Host
VLog(VH * v,char * str)3236 void VLog(VH *v, char *str)
3237 {
3238 	// Not take!!
3239 	return;
3240 }
3241 
3242 // Disconnect the NAT entry immediately
DisconnectNatEntryNow(VH * v,NAT_ENTRY * e)3243 void DisconnectNatEntryNow(VH *v, NAT_ENTRY *e)
3244 {
3245 	// Validate arguments
3246 	if (v == NULL || e == NULL)
3247 	{
3248 		return;
3249 	}
3250 
3251 	if (e->DisconnectNow == false)
3252 	{
3253 		e->DisconnectNow = true;
3254 
3255 		SetSockEvent(v->SockEvent);
3256 	}
3257 }
3258 
3259 // Get the NAT entry with specified source IP address and the oldest last communication time
GetOldestNatEntryOfIp(VH * v,UINT ip,UINT protocol)3260 NAT_ENTRY *GetOldestNatEntryOfIp(VH *v, UINT ip, UINT protocol)
3261 {
3262 	UINT i;
3263 	NAT_ENTRY *oldest = NULL;
3264 	UINT64 oldest_tick = 0xFFFFFFFFFFFFFFFFULL;
3265 	// Validate arguments
3266 	if (v == NULL)
3267 	{
3268 		return NULL;
3269 	}
3270 
3271 	for (i = 0; i < LIST_NUM(v->NatTable); i++)
3272 	{
3273 		NAT_ENTRY *e = LIST_DATA(v->NatTable, i);
3274 
3275 		if (e->DisconnectNow == false)
3276 		{
3277 			if (e->SrcIp == ip)
3278 			{
3279 				if (e->Protocol == protocol)
3280 				{
3281 					if (protocol != NAT_TCP || e->TcpStatus != NAT_TCP_CONNECTING)
3282 					{
3283 						if (e->LastCommTime <= oldest_tick)
3284 						{
3285 							oldest_tick = e->LastCommTime;
3286 							oldest = e;
3287 						}
3288 					}
3289 				}
3290 			}
3291 		}
3292 	}
3293 
3294 	return oldest;
3295 }
3296 
3297 // Get the number of current NAT entries per IP address
GetNumNatEntriesPerIp(VH * v,UINT ip,UINT protocol,bool tcp_syn_sent)3298 UINT GetNumNatEntriesPerIp(VH *v, UINT ip, UINT protocol, bool tcp_syn_sent)
3299 {
3300 	UINT ret = 0;
3301 	UINT i;
3302 	// Validate arguments
3303 	if (v == NULL)
3304 	{
3305 		return 0;
3306 	}
3307 
3308 	for (i = 0; i < LIST_NUM(v->NatTable); i++)
3309 	{
3310 		NAT_ENTRY *e = LIST_DATA(v->NatTable, i);
3311 
3312 		if (e->DisconnectNow == false)
3313 		{
3314 			if (e->SrcIp == ip)
3315 			{
3316 				if (e->Protocol == protocol)
3317 				{
3318 					bool ok = false;
3319 
3320 					if (protocol == NAT_TCP)
3321 					{
3322 						if (tcp_syn_sent)
3323 						{
3324 							if (e->TcpStatus == NAT_TCP_CONNECTING)
3325 							{
3326 								ok = true;
3327 							}
3328 						}
3329 						else
3330 						{
3331 							if (e->TcpStatus != NAT_TCP_CONNECTING)
3332 							{
3333 								ok = true;
3334 							}
3335 						}
3336 					}
3337 					else
3338 					{
3339 						ok = true;
3340 					}
3341 
3342 					if (ok)
3343 					{
3344 						ret++;
3345 					}
3346 				}
3347 			}
3348 		}
3349 	}
3350 
3351 	return ret;
3352 }
3353 
3354 // Check whether the NAT is available
CanCreateNewNatEntry(VH * v)3355 bool CanCreateNewNatEntry(VH *v)
3356 {
3357 	// Validate arguments
3358 	if (v == NULL)
3359 	{
3360 		return false;
3361 	}
3362 
3363 	if (v->UseNat == false)
3364 	{
3365 		// NAT stopped
3366 		return false;
3367 	}
3368 
3369 	if (NnIsActive(v) && v->NativeNat != NULL && v->NativeNat->NatTableForRecv != NULL)
3370 	{
3371 		if (v->NativeNat->NatTableForRecv->AllList->num_item > NAT_MAX_SESSIONS_KERNEL)
3372 		{
3373 			// Number of sessions exceeded (kernel mode)
3374 			return false;
3375 		}
3376 	}
3377 	else
3378 	{
3379 		if (v->NatTable->num_item > NAT_MAX_SESSIONS)
3380 		{
3381 			// Number of sessions exceeded (user mode)
3382 			return false;
3383 		}
3384 	}
3385 
3386 	return true;
3387 }
3388 
3389 // Set a pointer to the Virtual HUB options
NatSetHubOption(VH * v,HUB_OPTION * o)3390 void NatSetHubOption(VH *v, HUB_OPTION *o)
3391 {
3392 	// Validate arguments
3393 	if (v == NULL)
3394 	{
3395 		return;
3396 	}
3397 
3398 	v->HubOption = o;
3399 }
3400 
3401 // Get a pointer to the Virtual HUB options
NatGetHubOption(VH * v)3402 HUB_OPTION *NatGetHubOption(VH *v)
3403 {
3404 	// Validate arguments
3405 	if (v == NULL)
3406 	{
3407 		return NULL;
3408 	}
3409 
3410 	return v->HubOption;
3411 }
3412 
3413 // The main function of NAT processing thread
NatThreadMain(VH * v)3414 void NatThreadMain(VH *v)
3415 {
3416 	bool halt_flag;
3417 	// Validate arguments
3418 	if (v == NULL)
3419 	{
3420 		return;
3421 	}
3422 
3423 	v->TmpBuf = Malloc(NAT_TMPBUF_SIZE);
3424 
3425 	while (true)
3426 	{
3427 		// Wait until the next event is set
3428 		WaitSockEvent(v->SockEvent, SELECT_TIME);
3429 
3430 		halt_flag = false;
3431 
3432 		LockVirtual(v);
3433 		{
3434 			// Process on all NAT sessions
3435 			UINT i, num;
3436 
3437 			v->Now = Tick64();
3438 			v->NatDoCancelFlag = false;
3439 
3440 LIST_ELEMENT_DELETED:
3441 			num = LIST_NUM(v->NatTable);
3442 			for (i = 0; i < num; i++)
3443 			{
3444 				NAT_ENTRY *n = LIST_DATA(v->NatTable, i);
3445 
3446 				switch (n->Protocol)
3447 				{
3448 				case NAT_TCP:		// TCP
3449 					if (NatTransactTcp(v, n) == false)
3450 					{
3451 						goto LIST_ELEMENT_DELETED;
3452 					}
3453 					break;
3454 
3455 				case NAT_UDP:		// UDP
3456 					if (NatTransactUdp(v, n) == false)
3457 					{
3458 						goto LIST_ELEMENT_DELETED;
3459 					}
3460 					break;
3461 
3462 				case NAT_ICMP:		// ICMP
3463 					if (NatTransactIcmp(v, n) == false)
3464 					{
3465 						goto LIST_ELEMENT_DELETED;
3466 					}
3467 					break;
3468 
3469 				case NAT_DNS:		// DNS
3470 					if (NatTransactDns(v, n) == false)
3471 					{
3472 						goto LIST_ELEMENT_DELETED;
3473 					}
3474 					break;
3475 				}
3476 			}
3477 
3478 			if (v->NatDoCancelFlag)
3479 			{
3480 				// Hit the cancel of the parent thread
3481 				Cancel(v->Cancel);
3482 			}
3483 
3484 			// Halting flag check
3485 			if (v->HaltNat)
3486 			{
3487 				halt_flag = true;
3488 			}
3489 		}
3490 		UnlockVirtual(v);
3491 
3492 		if (halt_flag)
3493 		{
3494 			// Terminate the thread by disconnecting all entries forcibly
3495 			LockVirtual(v);
3496 			{
3497 				UINT num = LIST_NUM(v->NatTable);
3498 				NAT_ENTRY **nn = ToArray(v->NatTable);
3499 				UINT i;
3500 
3501 				for (i = 0; i < num; i++)
3502 				{
3503 					NAT_ENTRY *n = nn[i];
3504 					n->DisconnectNow = true;
3505 
3506 					switch (n->Protocol)
3507 					{
3508 					case NAT_TCP:		// TCP
3509 						NatTransactTcp(v, n);
3510 						break;
3511 
3512 					case NAT_UDP:		// UDP
3513 						NatTransactUdp(v, n);
3514 						break;
3515 
3516 					case NAT_ICMP:		// ICMP
3517 						NatTransactIcmp(v, n);
3518 						break;
3519 
3520 					case NAT_DNS:		// DNS
3521 						NatTransactDns(v, n);
3522 						break;
3523 					}
3524 				}
3525 
3526 				Free(nn);
3527 			}
3528 			UnlockVirtual(v);
3529 			break;
3530 		}
3531 	}
3532 
3533 	Free(v->TmpBuf);
3534 }
3535 
3536 // DNS: Thread to get the IP address
NatGetIPThread(THREAD * t,void * param)3537 void NatGetIPThread(THREAD *t, void *param)
3538 {
3539 	NAT_DNS_QUERY *q;
3540 	// Validate arguments
3541 	if (t == NULL || param == NULL)
3542 	{
3543 		return;
3544 	}
3545 
3546 	q = (NAT_DNS_QUERY *)param;
3547 	AddWaitThread(t);
3548 
3549 	q->Ok = GetIP(&q->Ip, q->Hostname);
3550 
3551 	DelWaitThread(t);
3552 
3553 	if (Release(q->ref) == 0)
3554 	{
3555 		Free(q);
3556 	}
3557 }
3558 
3559 // DNS: Get an IP address from host name
NatGetIP(IP * ip,char * hostname)3560 bool NatGetIP(IP *ip, char *hostname)
3561 {
3562 	TOKEN_LIST *t;
3563 	bool ret = false;
3564 	// Validate arguments
3565 	if (ip == NULL || hostname == NULL)
3566 	{
3567 		return false;
3568 	}
3569 
3570 	t = ParseToken(hostname, ".");
3571 	if (t == NULL)
3572 	{
3573 		return false;
3574 	}
3575 	if (t->NumTokens == 0)
3576 	{
3577 		FreeToken(t);
3578 		return false;
3579 	}
3580 
3581 	if (t->NumTokens == 1)
3582 	{
3583 		ret = GetIP(ip, hostname);
3584 	}
3585 	else
3586 	{
3587 		char *hostname2 = t->Token[0];
3588 		NAT_DNS_QUERY *q1, *q2;
3589 		THREAD *t1, *t2;
3590 
3591 		q1 = ZeroMalloc(sizeof(NAT_DNS_QUERY));
3592 		q2 = ZeroMalloc(sizeof(NAT_DNS_QUERY));
3593 		q1->ref = NewRef();
3594 		q2->ref = NewRef();
3595 		AddRef(q1->ref);
3596 		AddRef(q2->ref);
3597 		StrCpy(q1->Hostname, sizeof(q1->Hostname), hostname);
3598 		StrCpy(q2->Hostname, sizeof(q2->Hostname), hostname2);
3599 
3600 		t1 = NewThread(NatGetIPThread, q1);
3601 		t2 = NewThread(NatGetIPThread, q2);
3602 
3603 		WaitThread(t1, NAT_DNS_QUERY_TIMEOUT);
3604 
3605 		if (q1->Ok)
3606 		{
3607 			ret = true;
3608 			Copy(ip, &q1->Ip, sizeof(IP));
3609 		}
3610 		else
3611 		{
3612 			WaitThread(t2, NAT_DNS_QUERY_TIMEOUT);
3613 			if (q1->Ok)
3614 			{
3615 				ret = true;
3616 				Copy(ip, &q1->Ip, sizeof(IP));
3617 			}
3618 			else if (q2->Ok)
3619 			{
3620 				ret = true;
3621 				Copy(ip, &q2->Ip, sizeof(IP));
3622 			}
3623 		}
3624 
3625 		ReleaseThread(t1);
3626 		ReleaseThread(t2);
3627 
3628 		if (Release(q1->ref) == 0)
3629 		{
3630 			Free(q1);
3631 		}
3632 		if (Release(q2->ref) == 0)
3633 		{
3634 			Free(q2);
3635 		}
3636 	}
3637 
3638 	FreeToken(t);
3639 
3640 	return ret;
3641 }
3642 
3643 // DNS query function
NatDnsThread(THREAD * t,void * param)3644 void NatDnsThread(THREAD *t, void *param)
3645 {
3646 	NAT_ENTRY *n;
3647 	IP ip;
3648 	// Validate arguments
3649 	if (t == NULL || param == NULL)
3650 	{
3651 		return;
3652 	}
3653 	n = (NAT_ENTRY *)param;
3654 
3655 	// Notify the initialization completion
3656 	NoticeThreadInit(t);
3657 
3658 	// Run processing
3659 	if (EndWith(n->DnsTargetHostName, ".in-addr.arpa") == false)
3660 	{
3661 		// Forward resolution
3662 		if (NatGetIP(&ip, n->DnsTargetHostName))
3663 		{
3664 			// Forward resolution success
3665 			Copy(&n->DnsResponseIp, &ip, sizeof(IP));
3666 			n->DnsOk = true;
3667 		}
3668 	}
3669 	else
3670 	{
3671 		// Reverse resolution
3672 		IP ip;
3673 		n->DnsGetIpFromHost = true;		// Set the reverse resolution flag
3674 		// Convert a *.in-addr.arpa string to an IP address
3675 		if (ArpaToIP(&ip, n->DnsTargetHostName))
3676 		{
3677 			// Reverse resolution process
3678 			char tmp[256];
3679 			if (GetHostName(tmp, sizeof(tmp), &ip))
3680 			{
3681 				// Reverse resolution success
3682 				n->DnsResponseHostName = CopyStr(tmp);
3683 				n->DnsOk = true;
3684 			}
3685 		}
3686 	}
3687 
3688 	// Notify the results
3689 	n->DnsFinished = true;
3690 
3691 	SetSockEvent(n->v->SockEvent);
3692 }
3693 
3694 // Convert a reverse resolution address to an IP address
ArpaToIP(IP * ip,char * str)3695 bool ArpaToIP(IP *ip, char *str)
3696 {
3697 	TOKEN_LIST *token;
3698 	bool ret = false;
3699 	// Validate arguments
3700 	if (ip == NULL || str == NULL)
3701 	{
3702 		return false;
3703 	}
3704 
3705 	// Token conversion
3706 	token = ParseToken(str, ".");
3707 	if (token->NumTokens == 6)
3708 	{
3709 		// Convert the token [0, 1, 2, 3] to IP
3710 		UINT i;
3711 		ZeroIP4(ip);
3712 		for (i = 0; i < IPV4_SIZE; ++i)
3713 		{
3714 			IPV4(ip->address)[i] = (UCHAR)ToInt(token->Token[3 - i]);
3715 		}
3716 		ret = true;
3717 	}
3718 
3719 	FreeToken(token);
3720 
3721 	if (IPToUINT(ip) == 0)
3722 	{
3723 		ret = false;
3724 	}
3725 
3726 	return ret;
3727 }
3728 
3729 // Handle a DNS entry
NatTransactDns(VH * v,NAT_ENTRY * n)3730 bool NatTransactDns(VH *v, NAT_ENTRY *n)
3731 {
3732 	// Validate arguments
3733 	if (v == NULL || n == NULL)
3734 	{
3735 		return true;
3736 	}
3737 
3738 	if (n->DisconnectNow)
3739 	{
3740 		goto DISCONNECT;
3741 	}
3742 
3743 	if (n->DnsThread == NULL && n->DnsFinished == false)
3744 	{
3745 		// Create a thread
3746 		THREAD *t = NewThread(NatDnsThread, (void *)n);
3747 		WaitThreadInit(t);
3748 		n->DnsThread = t;
3749 	}
3750 	else
3751 	{
3752 		// Wait for the result
3753 		if (n->DnsFinished)
3754 		{
3755 			// Results have been received
3756 			WaitThread(n->DnsThread, INFINITE);
3757 			ReleaseThread(n->DnsThread);
3758 			n->DnsThread = NULL;
3759 			// Notify to the main thread
3760 			v->NatDoCancelFlag = true;
3761 		}
3762 	}
3763 
3764 	return true;
3765 
3766 DISCONNECT:
3767 
3768 	// Releasing process
3769 	if (n->DnsThread != NULL)
3770 	{
3771 		WaitThread(n->DnsThread, INFINITE);
3772 		ReleaseThread(n->DnsThread);
3773 		n->DnsThread = NULL;
3774 	}
3775 
3776 	if (n->DnsTargetHostName != NULL)
3777 	{
3778 		Free(n->DnsTargetHostName);
3779 		n->DnsTargetHostName = NULL;
3780 	}
3781 
3782 	if (n->DnsResponseHostName != NULL)
3783 	{
3784 		Free(n->DnsResponseHostName);
3785 		n->DnsResponseHostName = NULL;
3786 	}
3787 
3788 	DeleteLock(n->lock);
3789 	Delete(v->NatTable, n);
3790 	Free(n);
3791 
3792 	return false;
3793 }
3794 
3795 // ICMP thread procedure
NatIcmpThreadProc(THREAD * thread,void * param)3796 void NatIcmpThreadProc(THREAD *thread, void *param)
3797 {
3798 	NAT_ENTRY *n;
3799 	ICMP_RESULT *ret = NULL;
3800 	USHORT src_id = 0, src_seqno = 0;
3801 	// Validate arguments
3802 	if (thread == NULL || param == NULL)
3803 	{
3804 		return;
3805 	}
3806 
3807 	n = (NAT_ENTRY *)param;
3808 
3809 	if (n->IcmpQueryBlock)
3810 	{
3811 		UCHAR *data = n->IcmpQueryBlock->Buf;
3812 		UINT size = n->IcmpQueryBlock->Size;
3813 
3814 		if (size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
3815 		{
3816 			ICMP_HEADER *icmp = (ICMP_HEADER *)data;
3817 			ICMP_ECHO *echo = (ICMP_ECHO *)(data + sizeof(ICMP_HEADER));
3818 
3819 			if (icmp->Type == ICMP_TYPE_ECHO_REQUEST && icmp->Code == 0)
3820 			{
3821 				UCHAR *icmp_payload = data + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
3822 				UINT icmp_payload_size = size - sizeof(ICMP_HEADER) - sizeof(ICMP_ECHO);
3823 				IP dest_ip;
3824 
3825 				src_id = Endian16(echo->Identifier);
3826 				src_seqno = Endian16(echo->SeqNo);
3827 
3828 				UINTToIP(&dest_ip, n->DestIp);
3829 
3830 				// Send a query by using the ICMP API
3831 				ret = IcmpApiEchoSend(&dest_ip, n->IcmpQueryBlock->Ttl,
3832 				                      icmp_payload, icmp_payload_size, NAT_ICMP_TIMEOUT_WITH_API);
3833 			}
3834 		}
3835 	}
3836 
3837 	if (ret != NULL && ret->Timeout == false)
3838 	{
3839 		// Convert to an IPv4 + ICMP packet since the result of ICMP API was obtained
3840 		IPV4_HEADER ipv4;
3841 		ICMP_HEADER icmp;
3842 		ICMP_ECHO echo;
3843 		BUF *buf = NewBuf();
3844 
3845 		// IPv4 header
3846 		Zero(&ipv4, sizeof(ipv4));
3847 		IPV4_SET_VERSION(&ipv4, 4);
3848 		IPV4_SET_HEADER_LEN(&ipv4, sizeof(IPV4_HEADER) / 4);
3849 		ipv4.TimeToLive = ret->Ttl;
3850 		ipv4.Protocol = IP_PROTO_ICMPV4;
3851 		ipv4.SrcIP = IPToUINT(&ret->IpAddress);
3852 		ipv4.DstIP = 0x01010101;
3853 
3854 
3855 		// ICMP header
3856 		Zero(&icmp, sizeof(icmp));
3857 		Zero(&echo, sizeof(echo));
3858 
3859 		if (ret->Ok)
3860 		{
3861 			// Normal response
3862 			echo.Identifier = Endian16(src_id);
3863 			echo.SeqNo = Endian16(src_seqno);
3864 
3865 			ipv4.TotalLength = Endian16((USHORT)(sizeof(ipv4) + sizeof(icmp) + sizeof(echo) + ret->DataSize));
3866 
3867 			WriteBuf(buf, &ipv4, sizeof(ipv4));
3868 			WriteBuf(buf, &icmp, sizeof(icmp));
3869 			WriteBuf(buf, &echo, sizeof(echo));
3870 			WriteBuf(buf, ret->Data, ret->DataSize);
3871 		}
3872 		else
3873 		{
3874 			// Error reply
3875 			icmp.Type = ret->Type;
3876 			icmp.Code = ret->Code;
3877 			echo.Identifier = Endian16(src_id);
3878 			echo.SeqNo = Endian16(src_seqno);
3879 
3880 			ipv4.TotalLength = Endian16((USHORT)(sizeof(ipv4) + sizeof(icmp) + sizeof(echo) + n->IcmpOriginalCopySize));
3881 
3882 			WriteBuf(buf, &ipv4, sizeof(ipv4));
3883 			WriteBuf(buf, &icmp, sizeof(icmp));
3884 			WriteBuf(buf, &echo, sizeof(echo));
3885 
3886 			// Copy of the original packet to be included in the response packet
3887 			WriteBuf(buf, n->IcmpOriginalCopy, n->IcmpOriginalCopySize);
3888 		}
3889 
3890 		n->IcmpResponseBlock = NewBlock(Clone(buf->Buf, buf->Size), buf->Size, 0);
3891 		n->IcmpResponseBlock->Ttl = ret->Ttl;
3892 
3893 		FreeBuf(buf);
3894 	}
3895 	IcmpApiFreeResult(ret);
3896 
3897 	// Inform the completion of the processing
3898 	n->IcmpTaskFinished = true;
3899 	SetSockEvent(n->v->SockEvent);
3900 }
3901 
3902 // Process ICMP entry
NatTransactIcmp(VH * v,NAT_ENTRY * n)3903 bool NatTransactIcmp(VH *v, NAT_ENTRY *n)
3904 {
3905 	void *buf;
3906 	UINT recv_size;
3907 	BLOCK *block;
3908 	IP dest_ip;
3909 	UINT num_ignore_errors = 0;
3910 	UINT dest_port = 0;
3911 	// Validate arguments
3912 	if (v == NULL || n == NULL)
3913 	{
3914 		return true;
3915 	}
3916 
3917 	dest_port = n->DestPort;
3918 
3919 	if (n->DisconnectNow)
3920 	{
3921 		goto DISCONNECT;
3922 	}
3923 
3924 	if (v->IcmpRawSocketOk)
3925 	{
3926 		// Environment that the Raw sockets are available
3927 		if (n->UdpSocketCreated == false)
3928 		{
3929 			// Create a UDP socket
3930 			n->Sock = NewUDP(MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4));
3931 			if (n->Sock == NULL)
3932 			{
3933 				// Socket creation failure
3934 				goto DISCONNECT;
3935 			}
3936 			else
3937 			{
3938 				n->PublicIp = IPToUINT(&n->Sock->LocalIP);
3939 				n->PublicPort = n->Sock->LocalPort;
3940 
3941 				JoinSockToSockEvent(n->Sock, v->SockEvent);
3942 				n->UdpSocketCreated = true;
3943 			}
3944 		}
3945 	}
3946 	else
3947 	{
3948 		// Create a thread for using ICMP API if Raw sockets are not available
3949 		if (n->IcmpThread == NULL)
3950 		{
3951 			if (n->UdpSendQueue->num_item >= 1)
3952 			{
3953 				// Since UdpSendQueue contains only 1 query, get a first query
3954 				// and create a thread and pass the query to the thread
3955 				BLOCK *block = GetNext(n->UdpSendQueue);
3956 
3957 				n->IcmpQueryBlock = block;
3958 
3959 				n->IcmpThread = NewThread(NatIcmpThreadProc, n);
3960 			}
3961 		}
3962 
3963 		if (n->IcmpTaskFinished)
3964 		{
3965 			if (n->IcmpResponseBlock != NULL)
3966 			{
3967 				// Because there was a response from the thread that calls ICMP API, pass this result to the stack
3968 				block = n->IcmpResponseBlock;
3969 				n->IcmpResponseBlock = NULL;
3970 				InsertQueue(n->UdpRecvQueue, block);
3971 				v->NatDoCancelFlag = true;
3972 				n->LastCommTime = v->Now;
3973 			}
3974 			else
3975 			{
3976 				// Disconnect immediately when it fails
3977 				goto DISCONNECT;
3978 			}
3979 		}
3980 
3981 		// Examine whether this session timed-out
3982 		if ((n->LastCommTime + (UINT64)NAT_ICMP_TIMEOUT_WITH_API) < v->Now || n->LastCommTime > v->Now)
3983 		{
3984 			// Time-out
3985 			goto DISCONNECT;
3986 		}
3987 
3988 		return true;
3989 	}
3990 
3991 	// Following are processed only for if the raw sockets are available
3992 	buf = v->TmpBuf;
3993 	UINTToIP(&dest_ip, n->DestIp);
3994 
3995 	// Try to receive data from the UDP socket
3996 	while (true)
3997 	{
3998 		IP src_ip;
3999 		UINT src_port;
4000 		recv_size = RecvFrom(n->Sock, &src_ip, &src_port, buf, 65536);
4001 
4002 		if (recv_size == SOCK_LATER)
4003 		{
4004 			// Packet has not arrived
4005 			break;
4006 		}
4007 		else if (recv_size == 0)
4008 		{
4009 			Debug("ICMP ERROR\n");
4010 			// Error?
4011 			if (n->Sock->IgnoreRecvErr == false)
4012 			{
4013 				// A fatal error occurred
4014 				goto DISCONNECT;
4015 			}
4016 			else
4017 			{
4018 				if ((num_ignore_errors++) >= MAX_NUM_IGNORE_ERRORS)
4019 				{
4020 					goto DISCONNECT;
4021 				}
4022 			}
4023 		}
4024 		else
4025 		{
4026 			// Analyze the arriving packet
4027 			ICMP_RESULT *ret = IcmpParseResult(&dest_ip, n->SrcPort, 0, buf, recv_size);
4028 
4029 			if (ret != NULL)
4030 			{
4031 				if ((ret->Ok && CmpIpAddr(&ret->IpAddress, &dest_ip) == 0) ||
4032 				        (ret->DataSize >= sizeof(IPV4_HEADER) && ((IPV4_HEADER *)ret->Data)->DstIP == n->DestIp))
4033 				{
4034 					// Insert to the queue
4035 					void *data = Malloc(recv_size);
4036 					Copy(data, buf, recv_size);
4037 					block = NewBlock(data, recv_size, 0);
4038 					InsertQueue(n->UdpRecvQueue, block);
4039 					v->NatDoCancelFlag = true;
4040 					n->LastCommTime = v->Now;
4041 				}
4042 
4043 				IcmpFreeResult(ret);
4044 			}
4045 		}
4046 	}
4047 
4048 	// Try to send data to the UDP socket
4049 	while (block = GetNext(n->UdpSendQueue))
4050 	{
4051 		// Assemble the Echo header and ICMP header
4052 		UINT send_size;
4053 
4054 		SetTtl(n->Sock, block->Ttl);
4055 		send_size = SendTo(n->Sock, &dest_ip, dest_port, block->Buf, block->Size);
4056 
4057 		FreeBlock(block);
4058 		if (send_size == 0)
4059 		{
4060 			Debug("ICMP ERROR\n");
4061 			// Determine whether a fatal error
4062 			if (n->Sock->IgnoreSendErr == false)
4063 			{
4064 				// A fatal error occurred
4065 				goto DISCONNECT;
4066 			}
4067 		}
4068 		else
4069 		{
4070 			n->LastCommTime = v->Now;
4071 		}
4072 	}
4073 
4074 	// Examine whether this session timed-out
4075 	if ((n->LastCommTime + (UINT64)NAT_ICMP_TIMEOUT) < v->Now || n->LastCommTime > v->Now)
4076 	{
4077 		// Time-out
4078 		goto DISCONNECT;
4079 	}
4080 
4081 	return true;
4082 
4083 DISCONNECT:
4084 	// Disconnect this session
4085 	if (n->UdpSocketCreated)
4086 	{
4087 		// Close the socket
4088 		Disconnect(n->Sock);
4089 		ReleaseSock(n->Sock);
4090 		n->Sock = NULL;
4091 	}
4092 
4093 	// Terminate if the thread has been created
4094 	if (n->IcmpThread != NULL)
4095 	{
4096 		WaitThread(n->IcmpThread, INFINITE);
4097 		ReleaseThread(n->IcmpThread);
4098 		n->IcmpThread = NULL;
4099 	}
4100 
4101 	// Delete the entry
4102 	DeleteNatIcmp(v, n);
4103 
4104 	return false;
4105 }
4106 
4107 // Process the UDP entry
NatTransactUdp(VH * v,NAT_ENTRY * n)4108 bool NatTransactUdp(VH *v, NAT_ENTRY *n)
4109 {
4110 	void *buf;
4111 	UINT recv_size;
4112 	BLOCK *block;
4113 	IP dest_ip;
4114 	UINT num_ignore_errors;
4115 	UINT dest_port = 0;
4116 	// Validate arguments
4117 	if (v == NULL || n == NULL)
4118 	{
4119 		return true;
4120 	}
4121 
4122 	dest_port = n->DestPort;
4123 
4124 	if (n->DisconnectNow)
4125 	{
4126 		goto DISCONNECT;
4127 	}
4128 
4129 	if (n->UdpSocketCreated == false)
4130 	{
4131 		// Create a UDP socket
4132 		n->Sock = NewUDP(0);
4133 		if (n->Sock == NULL)
4134 		{
4135 			// Socket creation failure
4136 			goto DISCONNECT;
4137 		}
4138 		else
4139 		{
4140 			n->PublicIp = IPToUINT(&n->Sock->LocalIP);
4141 			n->PublicPort = n->Sock->LocalPort;
4142 
4143 			JoinSockToSockEvent(n->Sock, v->SockEvent);
4144 			n->UdpSocketCreated = true;
4145 		}
4146 	}
4147 
4148 	buf = v->TmpBuf;
4149 	if (n->ProxyDns == false)
4150 	{
4151 		UINTToIP(&dest_ip, n->DestIp);
4152 	}
4153 	else
4154 	{
4155 		UINTToIP(&dest_ip, n->DestIpProxy);
4156 	}
4157 
4158 	num_ignore_errors = 0;
4159 
4160 	// Try to receive data from the UDP socket
4161 	while (true)
4162 	{
4163 		IP src_ip;
4164 		UINT src_port;
4165 		recv_size = RecvFrom(n->Sock, &src_ip, &src_port, buf, 65536);
4166 
4167 		if (recv_size == SOCK_LATER)
4168 		{
4169 			// Packet has not arrived
4170 			break;
4171 		}
4172 		else if (recv_size == 0)
4173 		{
4174 			// Error?
4175 			if (n->Sock->IgnoreRecvErr == false)
4176 			{
4177 				// A fatal error occurred
4178 				goto DISCONNECT;
4179 			}
4180 			else
4181 			{
4182 				if ((num_ignore_errors++) > MAX_NUM_IGNORE_ERRORS)
4183 				{
4184 					goto DISCONNECT;
4185 				}
4186 			}
4187 		}
4188 		else
4189 		{
4190 			// Packet arrives. Check the source IP
4191 			if (IPToUINT(&src_ip) == n->DestIp || n->DestIp == 0xFFFFFFFF || (IPToUINT(&src_ip) == n->DestIpProxy && n->ProxyDns) && src_port == n->DestPort)
4192 			{
4193 				// Insert to the queue
4194 				void *data = Malloc(recv_size);
4195 				Copy(data, buf, recv_size);
4196 				block = NewBlock(data, recv_size, 0);
4197 
4198 				if (block != NULL)
4199 				{
4200 					if (src_port == SPECIAL_UDP_PORT_WSD || src_port == SPECIAL_UDP_PORT_SSDP)
4201 					{
4202 						// Make believe there is a response from the host really in the case of WSD packet
4203 						block->Param1 = IPToUINT(&src_ip);
4204 					}
4205 				}
4206 
4207 				InsertQueue(n->UdpRecvQueue, block);
4208 				v->NatDoCancelFlag = true;
4209 				n->LastCommTime = v->Now;
4210 			}
4211 		}
4212 	}
4213 
4214 	// Try to send data to the UDP socket
4215 	while (block = GetNext(n->UdpSendQueue))
4216 	{
4217 		UINT send_size;
4218 		bool is_nbtdgm = false;
4219 		LIST *local_ip_list = NULL;
4220 
4221 		if (dest_port == SPECIAL_UDP_PORT_NBTDGM)
4222 		{
4223 			// Determine whether NetBIOS Datagram packet
4224 			NBTDG_HEADER *nh = (NBTDG_HEADER *)block->Buf;
4225 
4226 			if (nh != NULL && block->Size >= sizeof(NBTDG_HEADER))
4227 			{
4228 				if (nh->SrcIP == n->SrcIp && Endian16(nh->SrcPort) == n->SrcPort)
4229 				{
4230 					local_ip_list = GetHostIPAddressList();
4231 
4232 					if (local_ip_list != NULL)
4233 					{
4234 						is_nbtdgm = true;
4235 					}
4236 				}
4237 			}
4238 		}
4239 
4240 		if (is_nbtdgm == false)
4241 		{
4242 			// Normal UDP packet
4243 			send_size = SendTo(n->Sock, &dest_ip, dest_port, block->Buf, block->Size);
4244 		}
4245 		else
4246 		{
4247 			// IP address and port number is embedded in the NetBIOS Datagram Packet.
4248 			// Transfer by rewriting it properly
4249 			UINT i;
4250 
4251 			for (i = 0; i < LIST_NUM(local_ip_list); i++)
4252 			{
4253 				IP *my_ip = LIST_DATA(local_ip_list, i);
4254 
4255 				if (IsIP4(my_ip) && IsZeroIp(my_ip) == false && IsLocalHostIP(my_ip) == false)
4256 				{
4257 					NBTDG_HEADER *nh = (NBTDG_HEADER *)block->Buf;
4258 
4259 					nh->SrcIP = IPToUINT(my_ip);
4260 					nh->SrcPort = Endian16(n->PublicPort);
4261 
4262 					send_size = SendTo(n->Sock, &dest_ip, dest_port, block->Buf, block->Size);
4263 				}
4264 			}
4265 		}
4266 
4267 		if (local_ip_list != NULL)
4268 		{
4269 			FreeHostIPAddressList(local_ip_list);
4270 		}
4271 
4272 		FreeBlock(block);
4273 		if (send_size == 0)
4274 		{
4275 			// Determining whether a fatal error
4276 			if (n->Sock->IgnoreSendErr == false)
4277 			{
4278 				// A fatal error occurred
4279 				goto DISCONNECT;
4280 			}
4281 		}
4282 		else
4283 		{
4284 			n->LastCommTime = v->Now;
4285 		}
4286 	}
4287 
4288 	// Examine whether this session timed-out
4289 	if ((n->LastCommTime + (UINT64)v->NatUdpTimeout) < v->Now || n->LastCommTime > v->Now)
4290 	{
4291 		// Time-out
4292 		goto DISCONNECT;
4293 	}
4294 
4295 	return true;
4296 
4297 DISCONNECT:
4298 	// Disconnect this session
4299 	if (n->UdpSocketCreated)
4300 	{
4301 		// Close the socket
4302 		Disconnect(n->Sock);
4303 		ReleaseSock(n->Sock);
4304 		n->Sock = NULL;
4305 	}
4306 
4307 	// Delete the entry
4308 	DeleteNatUdp(v, n);
4309 
4310 	return false;
4311 }
4312 
4313 // Thread to make a connection to the TCP host
NatTcpConnectThread(THREAD * t,void * p)4314 void NatTcpConnectThread(THREAD *t, void *p)
4315 {
4316 	NAT_ENTRY *n = (NAT_ENTRY *)p;
4317 	IP ip;
4318 	char hostname[MAX_SIZE];
4319 	UINT port_number;
4320 	SOCK *sock;
4321 	SOCK_EVENT *e;
4322 	// Validate arguments
4323 	if (n == NULL || t == NULL)
4324 	{
4325 		return;
4326 	}
4327 
4328 	UINTToIP(&ip, n->DestIp);
4329 	IPToStr(hostname, sizeof(hostname), &ip);
4330 	port_number = n->DestPort;
4331 	e = n->v->SockEvent;
4332 	AddRef(e->ref);
4333 
4334 	// Notify the initialization completion
4335 	NoticeThreadInit(t);
4336 
4337 	// Attempt to connect to the TCP host
4338 	Debug("NatTcpConnect Connecting to %s:%u\n", hostname, port_number);
4339 	sock = ConnectEx3(hostname, port_number, 0, &n->NatTcpCancelFlag, NULL, NULL, false, true);
4340 	if (sock == NULL)
4341 	{
4342 		// Connection failure
4343 		n->TcpMakeConnectionFailed = true;
4344 	}
4345 	else
4346 	{
4347 		// Successful connection
4348 		n->TcpMakeConnectionSucceed = true;
4349 	}
4350 	n->Sock = sock;
4351 	JoinSockToSockEvent(sock, e);
4352 	SetSockEvent(e);
4353 
4354 	ReleaseSockEvent(e);
4355 }
4356 
4357 // Create a thread for trying to connect to the TCP host
CreateNatTcpConnectThread(VH * v,NAT_ENTRY * n)4358 void CreateNatTcpConnectThread(VH *v, NAT_ENTRY *n)
4359 {
4360 	// Validate arguments
4361 	if (v == NULL || n == NULL)
4362 	{
4363 		return;
4364 	}
4365 
4366 	// Create a thread
4367 	n->NatTcpConnectThread = NewThread(NatTcpConnectThread, (void *)n);
4368 
4369 	// Wait for a thread initialization completion
4370 	WaitThreadInit(n->NatTcpConnectThread);
4371 }
4372 
4373 // Handle the TCP entry
NatTransactTcp(VH * v,NAT_ENTRY * n)4374 bool NatTransactTcp(VH *v, NAT_ENTRY *n)
4375 {
4376 	char str[MAX_SIZE];
4377 	bool timeouted = false;
4378 	// Validate arguments
4379 	if (v == NULL || n == NULL)
4380 	{
4381 		return false;
4382 	}
4383 
4384 	if (n->DisconnectNow)
4385 	{
4386 		goto DISCONNECT;
4387 	}
4388 
4389 	// Process by state of the TCP
4390 	switch (n->TcpStatus)
4391 	{
4392 	case NAT_TCP_CONNECTING:		// Waiting for connection
4393 		if (n->NatTcpConnectThread == NULL)
4394 		{
4395 			// Start a connection by creating a connection thread
4396 			CreateNatTcpConnectThread(v, n);
4397 		}
4398 		else
4399 		{
4400 			// Wait for the result of the connection thread that has already started
4401 			if (n->TcpMakeConnectionFailed || n->TcpMakeConnectionSucceed)
4402 			{
4403 				// Use the results because operation thread has already finished
4404 				WaitThread(n->NatTcpConnectThread, INFINITE);
4405 				ReleaseThread(n->NatTcpConnectThread);
4406 				n->NatTcpConnectThread = NULL;
4407 
4408 				if (n->TcpMakeConnectionSucceed)
4409 				{
4410 					// Connection is successful, and a Sock was created
4411 					n->TcpStatus = NAT_TCP_CONNECTED;
4412 					IPToStr32(str, sizeof(str), n->DestIp);
4413 					NLog(v, "LH_NAT_TCP_SUCCEED", n->Id, n->Sock->RemoteHostname, str, n->DestPort);
4414 				}
4415 				else
4416 				{
4417 					// Failed to connect
4418 					n->TcpStatus = NAT_TCP_SEND_RESET;
4419 					IPToStr32(str, sizeof(str), n->DestIp);
4420 					NLog(v, "LH_NAT_TCP_FAILED", n->Id, str, n->DestPort);
4421 				}
4422 				v->NatDoCancelFlag = true;
4423 			}
4424 		}
4425 		break;
4426 
4427 	case NAT_TCP_CONNECTED:			// TCP socket connection completed. Negotiating with the client host
4428 		break;
4429 
4430 	case NAT_TCP_SEND_RESET:		// TCP communication disconnection: Send a RST to the client host
4431 		break;
4432 
4433 	case NAT_TCP_ESTABLISHED:		// TCP connection established
4434 	{
4435 		UINT old_send_fifo_size = 0;
4436 
4437 		// Transmit to the socket if there is data in the receive buffer
4438 		while (n->RecvFifo->size > 0)
4439 		{
4440 			UINT sent_size = Send(n->Sock, ((UCHAR *)n->RecvFifo->p) + n->RecvFifo->pos,
4441 			                      n->RecvFifo->size, false);
4442 			if (sent_size == 0)
4443 			{
4444 				// Communication has been disconnected
4445 				n->TcpFinished = true;
4446 				v->NatDoCancelFlag = true;
4447 				break;
4448 			}
4449 			else if (sent_size == SOCK_LATER)
4450 			{
4451 				// Blocking
4452 				break;
4453 			}
4454 			else
4455 			{
4456 				// Successful transmission
4457 				ReadFifo(n->RecvFifo, NULL, sent_size);
4458 				n->SendAckNext = true;
4459 
4460 				if (false)
4461 				{
4462 					IP ip;
4463 
4464 					n->test_TotalSent += sent_size;
4465 
4466 					UINTToIP(&ip, n->DestIp);
4467 					Debug("TCP %u: %r:%u %u\n", n->Id, &ip, n->DestPort, (UINT)n->test_TotalSent);
4468 				}
4469 			}
4470 		}
4471 
4472 		old_send_fifo_size = FifoSize(n->SendFifo);
4473 
4474 		// Write to the transmission buffer by obtaining data from the socket
4475 		while (true)
4476 		{
4477 			void *buf = (void *)v->TmpBuf;
4478 			UINT want_to_recv_size = 0;
4479 			UINT recv_size;
4480 			// Calculate the size of wanting to receive
4481 			if (n->SendFifo->size < NAT_SEND_BUF_SIZE)
4482 			{
4483 				// Still can receive
4484 				want_to_recv_size = MIN(NAT_SEND_BUF_SIZE - n->SendFifo->size, NAT_TMPBUF_SIZE);
4485 			}
4486 			if (want_to_recv_size == 0)
4487 			{
4488 				SetNoNeedToRead(n->Sock);
4489 				break;
4490 			}
4491 			recv_size = Recv(n->Sock, buf, want_to_recv_size, false);
4492 			if (recv_size == 0)
4493 			{
4494 				// Communication has been disconnected
4495 				n->TcpFinished = true;
4496 				v->NatDoCancelFlag = true;
4497 				if (n->TcpDisconnected == false)
4498 				{
4499 					Disconnect(n->Sock);
4500 					n->TcpDisconnected = true;
4501 				}
4502 				break;
4503 			}
4504 			else if (recv_size == SOCK_LATER)
4505 			{
4506 				// Blocking
4507 				break;
4508 			}
4509 			else
4510 			{
4511 				// Successful reception
4512 				WriteFifo(n->SendFifo, buf, recv_size);
4513 				v->NatDoCancelFlag = true;
4514 			}
4515 		}
4516 
4517 		if (old_send_fifo_size == 0 && FifoSize(n->SendFifo) != 0)
4518 		{
4519 			// Reset the time data for timeout when the data is newly queued
4520 			// in the empty transmission buffer in the transmission process
4521 			n->TcpLastRecvAckTime = v->Now;
4522 		}
4523 
4524 		// Raise a transmission time-out if a certain period of time elapsed
4525 		// after receiving the last ACK, and the transmission buffer is not
4526 		// empty, and the reception window size of other party is not 0
4527 		if ((n->TcpLastRecvAckTime + (UINT64)VIRTUAL_TCP_SEND_TIMEOUT) < v->Now)
4528 		{
4529 			if (FifoSize(n->SendFifo) != 0 && n->TcpSendWindowSize != 0)
4530 			{
4531 				timeouted = true;
4532 			}
4533 		}
4534 	}
4535 	break;
4536 
4537 	}
4538 
4539 	// Timeout Detection
4540 	if ((n->LastCommTime + (UINT64)v->NatTcpTimeout) < v->Now || n->LastCommTime > v->Now)
4541 	{
4542 		timeouted = true;
4543 	}
4544 
4545 	if (timeouted)
4546 	{
4547 		// Time-out occurs, the session close
4548 		n->TcpStatus = NAT_TCP_SEND_RESET;
4549 		v->NatDoCancelFlag = true;
4550 	}
4551 
4552 	return true;
4553 
4554 DISCONNECT:		// Disconnect and session disposal
4555 	DeleteNatTcp(v, n);
4556 
4557 	return false;
4558 }
4559 
4560 // Delete the entry of TCP NAT
DeleteNatTcp(VH * v,NAT_ENTRY * n)4561 void DeleteNatTcp(VH *v, NAT_ENTRY *n)
4562 {
4563 	// Validate arguments
4564 	if (v == NULL || n == NULL)
4565 	{
4566 		return;
4567 	}
4568 
4569 	NLog(v, "LH_NAT_TCP_DELETED", n->Id);
4570 
4571 	// Shutdown of connection thread
4572 	if (n->NatTcpConnectThread != NULL)
4573 	{
4574 		n->NatTcpCancelFlag = true;
4575 
4576 		WaitThread(n->NatTcpConnectThread, INFINITE);
4577 		ReleaseThread(n->NatTcpConnectThread);
4578 		n->NatTcpConnectThread = NULL;
4579 	}
4580 	if (n->Sock != NULL)
4581 	{
4582 		// Disconnect the socket
4583 		Disconnect(n->Sock);
4584 		ReleaseSock(n->Sock);
4585 		n->Sock = NULL;
4586 	}
4587 
4588 	// Release the window memory
4589 	if (n->TcpRecvWindow != NULL)
4590 	{
4591 		ReleaseFifo(n->TcpRecvWindow);
4592 		n->TcpRecvWindow = NULL;
4593 	}
4594 
4595 	// Release the window reception list
4596 	if (n->TcpRecvList != NULL)
4597 	{
4598 		UINT i;
4599 		for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
4600 		{
4601 			IP_PART *p = LIST_DATA(n->TcpRecvList, i);
4602 			Free(p);
4603 		}
4604 		ReleaseList(n->TcpRecvList);
4605 		n->TcpRecvList = NULL;
4606 	}
4607 
4608 	// FIFO release
4609 	ReleaseFifo(n->SendFifo);
4610 	ReleaseFifo(n->RecvFifo);
4611 
4612 	// Delete from the NAT entry
4613 	Delete(v->NatTable, n);
4614 
4615 	DeleteLock(n->lock);
4616 
4617 	// Release the memory
4618 	Free(n);
4619 
4620 	Debug("NAT_ENTRY: DeleteNatTcp\n");
4621 }
4622 
4623 // NAT processing thread
NatThread(THREAD * t,void * param)4624 void NatThread(THREAD *t, void *param)
4625 {
4626 	// Validate arguments
4627 	if (t == NULL || param == NULL)
4628 	{
4629 		return;
4630 	}
4631 
4632 	// Notify the initialization completion
4633 	NoticeThreadInit(t);
4634 
4635 	NatThreadMain((VH *)param);
4636 }
4637 
4638 // Send a beacon packet
SendBeacon(VH * v)4639 void SendBeacon(VH *v)
4640 {
4641 	UINT dest_ip;
4642 	ARPV4_HEADER arp;
4643 	static char beacon_str[] =
4644 	    "SecureNAT Virtual TCP/IP Stack Beacon";
4645 	// Validate arguments
4646 	if (v == NULL)
4647 	{
4648 		return;
4649 	}
4650 
4651 	// Send an UDP
4652 	dest_ip = (v->HostIP & v->HostMask) | (~v->HostMask);
4653 	SendUdp(v, dest_ip, 7, v->HostIP, 7, beacon_str, sizeof(beacon_str));
4654 
4655 	// Build the ARP header
4656 	arp.HardwareType = Endian16(ARP_HARDWARE_TYPE_ETHERNET);
4657 	arp.ProtocolType = Endian16(MAC_PROTO_IPV4);
4658 	arp.HardwareSize = 6;
4659 	arp.ProtocolSize = 4;
4660 	arp.Operation = Endian16(ARP_OPERATION_RESPONSE);
4661 	Copy(arp.SrcAddress, v->MacAddress, 6);
4662 	arp.SrcIP = v->HostIP;
4663 	arp.TargetAddress[0] =
4664 	    arp.TargetAddress[1] =
4665 	        arp.TargetAddress[2] =
4666 	            arp.TargetAddress[3] =
4667 	                arp.TargetAddress[4] =
4668 	                    arp.TargetAddress[5] = 0xff;
4669 	arp.TargetIP = dest_ip;
4670 
4671 	// Transmission
4672 	VirtualLayer2Send(v, broadcast, v->MacAddress, MAC_PROTO_ARPV4, &arp, sizeof(arp));
4673 }
4674 
4675 // Send a TCP packet
SendTcp(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,UINT seq,UINT ack,UINT flag,UINT window_size,UINT mss,void * data,UINT size)4676 void SendTcp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT seq, UINT ack, UINT flag, UINT window_size, UINT mss, void *data, UINT size)
4677 {
4678 	static UCHAR tcp_mss_option[] = {0x02, 0x04, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00};
4679 	IPV4_PSEUDO_HEADER *vh;
4680 	TCP_HEADER *tcp;
4681 	UINT header_size = TCP_HEADER_SIZE;
4682 	UINT total_size;
4683 	// Validate arguments
4684 	if (v == NULL || (size != 0 && data == NULL))
4685 	{
4686 		return;
4687 	}
4688 
4689 	// Memory allocation
4690 	vh = Malloc(sizeof(IPV4_PSEUDO_HEADER) + TCP_HEADER_SIZE + size + 32);
4691 	tcp = (TCP_HEADER *)(((UCHAR *)vh) + sizeof(IPV4_PSEUDO_HEADER));
4692 
4693 	if (mss != 0)
4694 	{
4695 		USHORT *mss_size;
4696 		mss_size = (USHORT *)(&tcp_mss_option[2]);
4697 		*mss_size = Endian16((USHORT)mss);
4698 		header_size += sizeof(tcp_mss_option);
4699 	}
4700 
4701 	total_size = header_size + size;
4702 	if (total_size > 65536)
4703 	{
4704 		// Packet is too long
4705 		Free(vh);
4706 		return;
4707 	}
4708 
4709 	// Pseudo header generation
4710 	vh->SrcIP = src_ip;
4711 	vh->DstIP = dest_ip;
4712 	vh->Reserved = 0;
4713 	vh->Protocol = IP_PROTO_TCP;
4714 	vh->PacketLength = Endian16((USHORT)total_size);
4715 
4716 	// TCP header generation
4717 	tcp->SrcPort = Endian16((USHORT)src_port);
4718 	tcp->DstPort = Endian16((USHORT)dest_port);
4719 	tcp->SeqNumber = Endian32(seq);
4720 	tcp->AckNumber = Endian32(ack);
4721 	tcp->HeaderSizeAndReserved = 0;
4722 	TCP_SET_HEADER_SIZE(tcp, (UCHAR)(header_size / 4));
4723 	tcp->Flag = (UCHAR)flag;
4724 	tcp->WindowSize = Endian16((USHORT)window_size);
4725 	tcp->Checksum = 0;
4726 	tcp->UrgentPointer = 0;
4727 
4728 	// Copy the option values
4729 	if (mss != 0)
4730 	{
4731 		Copy(((UCHAR *)tcp) + TCP_HEADER_SIZE, tcp_mss_option, sizeof(tcp_mss_option));
4732 	}
4733 
4734 	// Data copy
4735 	Copy(((UCHAR *)tcp) + header_size, data, size);
4736 
4737 	// Checksum calculation
4738 	tcp->Checksum = IpChecksum(vh, total_size + 12);
4739 
4740 	// Submit as an IP packet
4741 	SendIp(v, dest_ip, src_ip, IP_PROTO_TCP, tcp, total_size);
4742 
4743 	// Release the memory
4744 	Free(vh);
4745 }
4746 
4747 // Polling process of TCP
PollingNatTcp(VH * v,NAT_ENTRY * n)4748 void PollingNatTcp(VH *v, NAT_ENTRY *n)
4749 {
4750 	// Validate arguments
4751 	if (v == NULL || n == NULL)
4752 	{
4753 		return;
4754 	}
4755 
4756 	switch (n->TcpStatus)
4757 	{
4758 	case NAT_TCP_CONNECTING:		// Socket connecting: nothing to do
4759 		break;
4760 
4761 	case NAT_TCP_CONNECTED:			// The socket connected: process SYN + ACK, ACK
4762 		if ((n->LastSynAckSentTime > v->Now) || n->LastSynAckSentTime == 0 || ((n->LastSynAckSentTime + (UINT64)(NAT_TCP_SYNACK_SEND_TIMEOUT * (UINT64)(n->SynAckSentCount + 1)) <= v->Now)))
4763 		{
4764 			n->LastSynAckSentTime = v->Now;
4765 			// Send a SYN + ACK
4766 			SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort,
4767 			        (UINT)(n->SendSeqInit + n->SendSeq),
4768 			        (UINT)(n->RecvSeqInit + n->RecvSeq),
4769 			        TCP_SYN | TCP_ACK, n->TcpRecvWindowSize,
4770 			        v->TcpMss, NULL, 0);
4771 			n->SynAckSentCount++;
4772 		}
4773 		break;
4774 
4775 	case NAT_TCP_SEND_RESET:		// Reset the connection
4776 		// Send a RST
4777 		if (n->TcpFinished == false || n->TcpForceReset)
4778 		{
4779 			SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort,
4780 			        (UINT)(n->SendSeq + n->SendSeqInit),
4781 			        (UINT)(n->SendSeq + n->SendSeqInit),
4782 			        TCP_RST, 0,
4783 			        0, NULL, 0);
4784 			// Disconnect
4785 			n->TcpStatus = NAT_TCP_WAIT_DISCONNECT;
4786 			n->DisconnectNow = true;
4787 		}
4788 		else
4789 		{
4790 			// Send FINs for NAT_FIN_SEND_MAX_COUNT times
4791 			if (n->FinSentTime == 0 || (n->FinSentTime > v->Now) || (n->FinSentTime + NAT_FIN_SEND_INTERVAL * (n->FinSentCount + 1)) < v->Now)
4792 			{
4793 				SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort,
4794 				        (UINT)(n->SendSeq + n->SendSeqInit),
4795 				        (UINT)(n->RecvSeq + n->RecvSeqInit),
4796 				        TCP_ACK | TCP_FIN, 0,
4797 				        0, NULL, 0);
4798 				n->FinSentTime = v->Now;
4799 				n->FinSentSeq = (UINT)(n->SendSeq + n->SendSeqInit);
4800 				n->FinSentCount++;
4801 				if (n->FinSentCount >= NAT_FIN_SEND_MAX_COUNT)
4802 				{
4803 					n->TcpFinished = false;
4804 				}
4805 			}
4806 		}
4807 		break;
4808 
4809 	case NAT_TCP_ESTABLISHED:		// Connection established
4810 	{
4811 		UINT send_data_size;
4812 		UINT current_pointer;
4813 		UINT notice_window_size_value = 0;
4814 		UINT buf_free_bytes = 0;
4815 		// Determine the value of the window size to be notified
4816 		if (FifoSize(n->RecvFifo) < NAT_RECV_BUF_SIZE)
4817 		{
4818 			buf_free_bytes = NAT_RECV_BUF_SIZE - FifoSize(n->RecvFifo);
4819 		}
4820 		notice_window_size_value = MIN(n->TcpRecvWindowSize, buf_free_bytes);
4821 		if (n->LastSentKeepAliveTime == 0 ||
4822 		        (n->LastSentKeepAliveTime + (UINT64)NAT_ACK_KEEPALIVE_SPAN) < v->Now ||
4823 		        (n->LastSentKeepAliveTime > v->Now))
4824 		{
4825 			if (n->LastSentKeepAliveTime != 0)
4826 			{
4827 				// Send an ACK packet for Keep-Alive
4828 				SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort,
4829 				        (UINT)(n->SendSeqInit + n->SendSeq),
4830 				        (UINT)(n->RecvSeqInit + n->RecvSeq) - 1,
4831 				        TCP_ACK,
4832 				        notice_window_size_value,
4833 				        0,
4834 				        NULL,
4835 				        0);
4836 			}
4837 			n->LastSentKeepAliveTime = v->Now;
4838 		}
4839 		if (n->TcpLastSentTime == 0 ||
4840 		        (n->TcpLastSentTime > v->Now) ||
4841 		        ((n->TcpLastSentTime + (UINT64)n->TcpSendTimeoutSpan) < v->Now) ||
4842 		        n->SendAckNext)
4843 		{
4844 			// If there is data to send, send the data
4845 			// Calculate the segment size to be transmitted
4846 			send_data_size = n->TcpSendWindowSize;
4847 			if (send_data_size > (n->TcpSendCWnd * n->TcpSendMaxSegmentSize))
4848 			{
4849 				// Apply the cwnd value
4850 				send_data_size = n->TcpSendCWnd * n->TcpSendMaxSegmentSize;
4851 			}
4852 			if (send_data_size > n->SendFifo->size)
4853 			{
4854 				// Can not be sent over the data that is currently held
4855 				send_data_size = n->SendFifo->size;
4856 			}
4857 			if (send_data_size >= 1)
4858 			{
4859 				// Transmit the fragmented segments
4860 				current_pointer = 0;
4861 				while (send_data_size > 0)
4862 				{
4863 					UINT send_segment_size = MIN(n->TcpSendMaxSegmentSize, send_data_size);
4864 					void *send_segment = (void *)(((UCHAR *)n->SendFifo->p) + n->SendFifo->pos + current_pointer);
4865 					SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort,
4866 					        (UINT)(n->SendSeqInit + n->SendSeq + (UINT64)current_pointer),
4867 					        (UINT)(n->RecvSeqInit + n->RecvSeq),
4868 					        TCP_ACK | TCP_PSH,
4869 					        notice_window_size_value,
4870 					        0,
4871 					        send_segment,
4872 					        send_segment_size);
4873 					current_pointer += send_segment_size;
4874 					send_data_size -= send_segment_size;
4875 				}
4876 				// Record the transmission time
4877 				n->TcpLastSentTime = v->Now;
4878 				// Record the stream size to be transmitted this time
4879 				n->SendMissionSize = current_pointer;
4880 				n->CurrentSendingMission = true;
4881 				// RTT measurement
4882 				if (n->CalcRTTStartTime == 0)
4883 				{
4884 					n->CalcRTTStartTime = v->Now;
4885 					n->CalcRTTStartValue = n->SendSeq + current_pointer - 1;
4886 				}
4887 				if (n->RetransmissionUsedFlag == false)
4888 				{
4889 					n->RetransmissionUsedFlag = true;
4890 				}
4891 				else
4892 				{
4893 					// Congestion is detected
4894 					if (n->TcpSendCWnd > 2)
4895 					{
4896 						n->TcpSendCWnd--;
4897 					}
4898 				}
4899 			}
4900 			else if (n->SendAckNext)
4901 			{
4902 				// Send only an ACK
4903 				SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort,
4904 				        (UINT)(n->SendSeqInit + n->SendSeq),
4905 				        (UINT)(n->RecvSeqInit + n->RecvSeq),
4906 				        TCP_ACK,
4907 				        notice_window_size_value,
4908 				        0,
4909 				        NULL,
4910 				        0);
4911 			}
4912 			n->SendAckNext = false;
4913 		}
4914 		if (n->TcpFinished)
4915 		{
4916 			// Disconnect if all data transmission has completed
4917 			if (n->SendFifo->size == 0 && n->RecvFifo->size == 0)
4918 			{
4919 				n->TcpStatus = NAT_TCP_SEND_RESET;
4920 			}
4921 		}
4922 	}
4923 	break;
4924 	}
4925 }
4926 
4927 // Reception of TCP packets addressed to the Internet
TcpRecvForInternet(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,TCP_HEADER * tcp,void * data,UINT size,UINT max_l3_size)4928 void TcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, TCP_HEADER *tcp, void *data, UINT size, UINT max_l3_size)
4929 {
4930 	NAT_ENTRY *n, t;
4931 	UINT seq, ack;
4932 	UINT64 seq64 = 0, ack64 = 0;
4933 	// Validate arguments
4934 	if (v == NULL || tcp == NULL || data == NULL)
4935 	{
4936 		return;
4937 	}
4938 
4939 	if (NnIsActive(v))
4940 	{
4941 		NnTcpRecvForInternet(v, src_ip, src_port, dest_ip, dest_port, tcp, data, size, max_l3_size);
4942 		return;
4943 	}
4944 
4945 	seq = Endian32(tcp->SeqNumber);
4946 	ack = Endian32(tcp->AckNumber);
4947 
4948 	if (v->HubOption != NULL && v->HubOption->DisableUserModeSecureNAT)
4949 	{
4950 		// Disable User-mode NAT
4951 		SendTcp(v, dest_ip, dest_port, src_ip, src_port,
4952 		        0, seq + 1, TCP_RST | TCP_ACK, 0, 0, NULL, 0);
4953 		return;
4954 	}
4955 
4956 	// Search for a session for this packet from the NAT table
4957 	SetNat(&t, NAT_TCP, src_ip, src_port, dest_ip, dest_port, 0, 0);
4958 	n = SearchNat(v, &t);
4959 
4960 	if (n == NULL)
4961 	{
4962 		// There is no existing session
4963 		// Allow through only SYN packet
4964 		if ((tcp->Flag & TCP_SYN) && ((tcp->Flag & TCP_ACK) == false))
4965 		{
4966 			TCP_OPTION o;
4967 			// Create a new session
4968 			n = CreateNatTcp(v, src_ip, src_port, dest_ip, dest_port);
4969 			if (n == NULL)
4970 			{
4971 				// Return the RST if it was not possible to create
4972 				SendTcp(v, dest_ip, dest_port, src_ip, src_port,
4973 				        0, seq + 1, TCP_RST | TCP_ACK, 0, 0, NULL, 0);
4974 				return;
4975 			}
4976 
4977 			// Get the options
4978 			ParseTcpOption(&o, ((UCHAR *)tcp) + TCP_HEADER_SIZE, TCP_GET_HEADER_SIZE(tcp) * 4 - TCP_HEADER_SIZE);
4979 			if (o.MaxSegmentSize == 0)
4980 			{
4981 				o.MaxSegmentSize = v->TcpMss;
4982 			}
4983 
4984 			Debug("TCP SYN: MSS=%u, WS=%u\n", o.MaxSegmentSize, o.WindowScaling);
4985 
4986 			// Initial sequence number
4987 			n->RecvSeqInit = (UINT64)Endian32(tcp->SeqNumber);
4988 			n->RecvSeq = 1;
4989 
4990 			n->TcpSendMaxSegmentSize = o.MaxSegmentSize;
4991 			n->TcpRecvWindowSize = NAT_TCP_RECV_WINDOW_SIZE;
4992 			n->TcpSendWindowSize = (UINT)Endian16(tcp->WindowSize);
4993 			if (o.WindowScaling != 0)
4994 			{
4995 				if (o.WindowScaling > 14)
4996 				{
4997 					o.WindowScaling = 14;
4998 				}
4999 				n->TcpSendWindowSize = (n->TcpSendWindowSize << o.WindowScaling);
5000 			}
5001 		}
5002 	}
5003 
5004 	if (n == NULL)
5005 	{
5006 		// Return a RST since a packet which is not registered in the NAT entry arrived
5007 		SendTcp(v, dest_ip, dest_port, src_ip, src_port,
5008 		        ack, ack, TCP_RST, 0, 0, NULL, 0);
5009 		return;
5010 	}
5011 
5012 	n->TcpLastRecvAckTime = v->Now;
5013 
5014 	switch (n->TcpStatus)
5015 	{
5016 	case NAT_TCP_SEND_RESET:		// Disconnect the connection by sending a RST
5017 		if ((tcp->Flag & TCP_ACK) && ((tcp->Flag & TCP_SYN) == false))
5018 		{
5019 			if (n->FinSentCount >= 1)
5020 			{
5021 				if (ack == (n->FinSentSeq + 1))
5022 				{
5023 					n->TcpForceReset = true;
5024 				}
5025 			}
5026 		}
5027 		break;
5028 
5029 	case NAT_TCP_CONNECTED:			// Socket connection completion: SYN + ACK, ACK processing
5030 		if ((tcp->Flag & TCP_ACK) && ((tcp->Flag & TCP_SYN) == false))
5031 		{
5032 			if (seq == (UINT)(n->RecvSeqInit + n->RecvSeq) &&
5033 			        ack == (UINT)(n->SendSeqInit + n->SendSeq + 1))
5034 			{
5035 				// Handshake complete since the ACK packet came back
5036 				n->SendSeq++;		// SYN packet consumes the seq by 1
5037 				Debug("TCP Connection Established.\n");
5038 				n->TcpStatus = NAT_TCP_ESTABLISHED;
5039 				// Initialize the congestion window size
5040 				n->TcpSendCWnd = 1;
5041 				n->LastCommTime = v->Now;
5042 			}
5043 			else
5044 			{
5045 				goto TCP_RESET;
5046 			}
5047 		}
5048 		else if (tcp->Flag & TCP_RST)
5049 		{
5050 TCP_RESET:
5051 			// Receive a RST
5052 			Debug("TCP Connection Reseted.\n");
5053 			n->TcpStatus = NAT_TCP_SEND_RESET;
5054 		}
5055 		break;
5056 
5057 	case NAT_TCP_ESTABLISHED:		// Connection established
5058 		if (tcp->Flag & TCP_FIN)
5059 		{
5060 			// Complete the connection
5061 			n->TcpFinished = true;
5062 		}
5063 		if (tcp->Flag & TCP_RST)
5064 		{
5065 			// Receive a RST
5066 			goto TCP_RESET;
5067 		}
5068 		else if (tcp->Flag & TCP_ACK)
5069 		{
5070 			TCP_OPTION opt;
5071 			n->LastCommTime = v->Now;
5072 			// Get the options, such as window size
5073 			n->TcpSendWindowSize = Endian16(tcp->WindowSize);
5074 			ParseTcpOption(&opt, ((UCHAR *)tcp) + TCP_HEADER_SIZE, TCP_GET_HEADER_SIZE(tcp) * 4 - TCP_HEADER_SIZE);
5075 			if (opt.WindowScaling != 0)
5076 			{
5077 				if (opt.WindowScaling > 14)
5078 				{
5079 					opt.WindowScaling = 14;
5080 				}
5081 				n->TcpSendWindowSize = (n->TcpSendWindowSize << opt.WindowScaling);
5082 			}
5083 			// First, process the received ACK
5084 			// Store the end position of the stream that has received the acknowledgment to ack64
5085 			ack64 = n->SendSeq + (UINT64)ack - (n->SendSeqInit + n->SendSeq) % X32;
5086 			if ((n->SendSeqInit + n->SendSeq) % X32 > ack)
5087 			{
5088 				if (((n->SendSeqInit + n->SendSeq) % X32 - ack) >= 0x80000000)
5089 				{
5090 					ack64 = n->SendSeq + (UINT64)ack + X32 - (n->SendSeqInit + n->SendSeq) % X32;
5091 				}
5092 			}
5093 			if (ack64 > n->SendSeq)
5094 			{
5095 				// Reception of 1 byte or more seems to have been completed by the client
5096 				UINT slide_offset = (UINT)(ack64 - n->SendSeq);	// Sliding size of the window
5097 				if (slide_offset == 0 || slide_offset > n->TcpSendWindowSize || slide_offset > n->SendFifo->size)
5098 				{
5099 					// Ignore because the offset value of acknowledgment is
5100 					// larger than the size that should have been sent so far
5101 				}
5102 				else
5103 				{
5104 					// RTT measurement
5105 					if (n->CalcRTTStartTime != 0)
5106 					{
5107 						if (n->CalcRTTStartValue < ack64)
5108 						{
5109 							UINT time_span;
5110 							if (v->Now > n->CalcRTTStartTime)
5111 							{
5112 								time_span = (UINT)(v->Now - n->CalcRTTStartTime);
5113 							}
5114 							else
5115 							{
5116 								time_span = 100;
5117 							}
5118 							n->CalcRTTStartTime = 0;
5119 
5120 							// Smoothing
5121 							n->CurrentRTT =
5122 							    (UINT)
5123 							    (
5124 							        ((UINT64)n->CurrentRTT * (UINT64)9 +
5125 							         (UINT64)time_span * (UINT64)1) / (UINT64)10
5126 							    );
5127 							n->TcpSendTimeoutSpan = n->CurrentRTT * 2;
5128 						}
5129 					}
5130 					// Reduce the transmission size
5131 					n->SendMissionSize -= slide_offset;
5132 					if (n->SendMissionSize == 0)
5133 					{
5134 						// Try to increase the transmission segment size because
5135 						// all segments to be sent this time have been sent
5136 						if (n->TcpSendCWnd < 65536)
5137 						{
5138 							n->TcpSendCWnd++;
5139 						}
5140 						n->CurrentSendingMission = false;
5141 						n->TcpLastSentTime = 0;
5142 						n->RetransmissionUsedFlag = false;
5143 					}
5144 					// Slide the buffer
5145 					n->SendSeq += slide_offset;
5146 					ReadFifo(n->SendFifo, NULL, slide_offset);
5147 					// Send further by the size of confirmed transmission completion by the ACK this time
5148 					if (n->SendMissionSize != 0 && false)
5149 					{
5150 						UINT notice_window_size_value = 0;
5151 						UINT send_data_size;
5152 						UINT buf_free_bytes;
5153 						UINT send_offset = n->SendMissionSize;
5154 						// Determine the value of the window size to be notified
5155 						if (FifoSize(n->RecvFifo) < NAT_RECV_BUF_SIZE)
5156 						{
5157 							buf_free_bytes = NAT_RECV_BUF_SIZE - FifoSize(n->RecvFifo);
5158 						}
5159 						notice_window_size_value = MIN(n->TcpRecvWindowSize, buf_free_bytes);
5160 						// Calculate the segment size to be transmitted
5161 						send_data_size = n->TcpSendWindowSize;
5162 						if (send_data_size > (n->TcpSendCWnd * n->TcpSendMaxSegmentSize))
5163 						{
5164 							// Apply the cwnd value
5165 							send_data_size = n->TcpSendCWnd * n->TcpSendMaxSegmentSize;
5166 						}
5167 						if (n->SendFifo->size > send_offset)
5168 						{
5169 							send_data_size = MIN(send_data_size, n->SendFifo->size - send_offset);
5170 							send_data_size = MIN(send_data_size, slide_offset);
5171 						}
5172 						else
5173 						{
5174 							send_data_size = 0;
5175 						}
5176 						if (send_data_size >= 1)
5177 						{
5178 							// Transmit the fragmented segments
5179 							UINT current_pointer = 0;
5180 							while (send_data_size > 0)
5181 							{
5182 								UINT send_segment_size = MIN(n->TcpSendMaxSegmentSize, send_data_size);
5183 								void *send_segment = (void *)((
5184 								                                  (UCHAR *)n->SendFifo->p) + n->SendFifo->pos +
5185 								                              current_pointer + send_offset);
5186 
5187 								SendTcp(v, n->DestIp, n->DestPort, n->SrcIp, n->SrcPort,
5188 								        (UINT)(n->SendSeqInit + n->SendSeq + (UINT64)current_pointer
5189 								               + (UINT)send_offset),
5190 								        (UINT)(n->RecvSeqInit + n->RecvSeq),
5191 								        TCP_ACK | TCP_PSH,
5192 								        notice_window_size_value,
5193 								        0,
5194 								        send_segment,
5195 								        send_segment_size);
5196 								current_pointer += send_segment_size;
5197 								send_data_size -= send_segment_size;
5198 							}
5199 							n->SendMissionSize += current_pointer;
5200 							n->CurrentSendingMission = true;
5201 							n->TcpLastSentTime = v->Now;
5202 							// RTT measurement
5203 							if (n->CalcRTTStartTime == 0)
5204 							{
5205 								n->CalcRTTStartTime = v->Now;
5206 								n->CalcRTTStartValue = n->SendSeq + current_pointer - 1;
5207 							}
5208 						}
5209 					}
5210 					// Event occurs
5211 					SetSockEvent(v->SockEvent);
5212 				}
5213 			}
5214 			// Next, receive the data
5215 			seq64 = n->RecvSeq + (UINT64)seq - (n->RecvSeqInit + n->RecvSeq) % X32;
5216 			if ((n->RecvSeqInit + n->RecvSeq) % X32 > seq)
5217 			{
5218 				if (((n->RecvSeqInit + n->RecvSeq) % X32 - seq) >= 0x80000000)
5219 				{
5220 					seq64 = n->RecvSeq + (UINT64)seq + X32 - (n->RecvSeqInit + n->RecvSeq) % X32;
5221 				}
5222 			}
5223 			// Position of the starting point of the data from the client is in the seq64 at this time
5224 			if (seq64 >= n->RecvSeq && (seq64 + size) <= (n->RecvSeq + n->TcpRecvWindowSize))
5225 			{
5226 				if (size >= 1)
5227 				{
5228 					// One or more bytes of data has been received within the receive window
5229 					UINT offset = (UINT)(seq64 - n->RecvSeq);
5230 					UINT i;
5231 					IP_PART *me;
5232 					if (n->TcpRecvWindow == NULL)
5233 					{
5234 						n->TcpRecvWindow = NewFifo();
5235 					}
5236 					if (n->TcpRecvList == NULL)
5237 					{
5238 						n->TcpRecvList = NewListFast(NULL);
5239 					}
5240 					// Add to the list by overwriting arriving packets to the buffer
5241 					if (FifoSize(n->TcpRecvWindow) < (offset + size))
5242 					{
5243 						// Buffer size expansion
5244 						WriteFifo(n->TcpRecvWindow, NULL, offset + size - FifoSize(n->TcpRecvWindow));
5245 					}
5246 					Copy(((UCHAR *)n->TcpRecvWindow->p) + n->TcpRecvWindow->pos +
5247 					     offset, data, size);
5248 					me = ZeroMalloc(sizeof(IP_PART));
5249 					me->Offset = offset;
5250 					me->Size = size;
5251 					for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
5252 					{
5253 						IP_PART *p = LIST_DATA(n->TcpRecvList, i);
5254 						// If there are overlapped region, remove these
5255 						if (p->Size != 0)
5256 						{
5257 							if (me->Offset <= p->Offset && (me->Offset + me->Size) >= (p->Offset + p->Size))
5258 							{
5259 								// This packet completely overwrite the existing packet
5260 								p->Size = 0;
5261 							}
5262 							else if (me->Offset >= p->Offset && (me->Offset + me->Size) <= (p->Offset + p->Size))
5263 							{
5264 								// Existing packet completely override this packet
5265 								me->Size = 0;
5266 							}
5267 							else if (me->Offset > p->Offset && me->Offset < (p->Offset + p->Size) &&
5268 							         (me->Offset + me->Size) > (p->Offset + p->Size))
5269 							{
5270 								// Partially overlapped
5271 								p->Size -= p->Offset + p->Size - me->Offset;
5272 							}
5273 							else if (me->Offset < p->Offset && (me->Offset + size) > p->Offset && (me->Offset + size) < (p->Offset + p->Size))
5274 							{
5275 								// Partially overlapped
5276 								me->Size -= me->Offset + me->Size - p->Offset;
5277 							}
5278 						}
5279 					}
5280 					if (me->Size == 0)
5281 					{
5282 						Free(me);
5283 					}
5284 					else
5285 					{
5286 						Add(n->TcpRecvList, me);
5287 					}
5288 KILL_NULL_FIRST:
5289 					// Remove all blank items from reception list
5290 					for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
5291 					{
5292 						IP_PART *p = LIST_DATA(n->TcpRecvList, i);
5293 						if (p->Size == 0)
5294 						{
5295 							Delete(n->TcpRecvList, p);
5296 							Free(p);
5297 							goto KILL_NULL_FIRST;
5298 						}
5299 					}
5300 SCAN_FIRST:
5301 					// Extract if there is something starting at offset 0 in the received list
5302 					for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
5303 					{
5304 						IP_PART *p = LIST_DATA(n->TcpRecvList, i);
5305 						UINT sz;
5306 						if (p->Offset == 0)
5307 						{
5308 							// Since a data block starts with 0 is found,
5309 							// slide it left by that amount and write the buffer
5310 							// for extracting data to the FIFO
5311 							sz = p->Size;
5312 							WriteFifo(n->RecvFifo, ((UCHAR *)n->TcpRecvWindow->p) + n->TcpRecvWindow->pos, sz);
5313 							// Release from the list
5314 							Delete(n->TcpRecvList, p);
5315 							Free(p);
5316 							ReadFifo(n->TcpRecvWindow, NULL, sz);
5317 							// Slide all the items to the left
5318 							for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
5319 							{
5320 								p = LIST_DATA(n->TcpRecvList, i);
5321 								p->Offset -= sz;
5322 							}
5323 							// Update the parameters of the TCB
5324 							n->RecvSeq += (UINT64)sz;
5325 							SetSockEvent(v->SockEvent);
5326 							n->SendAckNext = true;
5327 							// Re-scan from the beginning
5328 							goto SCAN_FIRST;
5329 						}
5330 					}
5331 				}
5332 			}
5333 		}
5334 		break;
5335 	}
5336 
5337 	SetSockEvent(v->SockEvent);
5338 }
5339 
5340 // Parse the TCP options
ParseTcpOption(TCP_OPTION * o,void * data,UINT size)5341 void ParseTcpOption(TCP_OPTION *o, void *data, UINT size)
5342 {
5343 	UCHAR *buf = (UCHAR *)data;
5344 	UINT i = 0;
5345 	UINT value_size = 0;
5346 	UINT value_id = 0;
5347 	UCHAR value[128];
5348 	// Validate arguments
5349 	if (o == NULL || data == NULL)
5350 	{
5351 		return;
5352 	}
5353 
5354 	Zero(o, sizeof(TCP_OPTION));
5355 
5356 	while(i < size)
5357 	{
5358 		if (buf[i] == 0)
5359 		{
5360 			return;
5361 		}
5362 		else if (buf[i] == 1)
5363 		{
5364 			i++;
5365 			continue;
5366 		}
5367 		else
5368 		{
5369 			value_id = buf[i];
5370 			i++;
5371 			if (i >= size)
5372 			{
5373 				return;
5374 			}
5375 			value_size = buf[i];
5376 			if (value_size <= 1 || value_size > sizeof(value))
5377 			{
5378 				return;
5379 			}
5380 			i++;
5381 			if (i >= size)
5382 			{
5383 				return;
5384 			}
5385 			value_size -= 2;
5386 
5387 			Copy(value, &buf[i], value_size);
5388 			i += value_size;
5389 			if (i > size)
5390 			{
5391 				return;
5392 			}
5393 
5394 			switch (value_id)
5395 			{
5396 			case 2:	// MSS
5397 				if (value_size == 2)
5398 				{
5399 					USHORT *mss = (USHORT *)value;
5400 					o->MaxSegmentSize = Endian16(*mss);
5401 				}
5402 				break;
5403 
5404 			case 3: // WSS
5405 				if (value_size == 1)
5406 				{
5407 					UCHAR *wss = (UCHAR *)value;
5408 					o->WindowScaling = *wss;
5409 				}
5410 				break;
5411 
5412 			}
5413 		}
5414 	}
5415 }
5416 
5417 // Create a new NAT TCP session
CreateNatTcp(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port)5418 NAT_ENTRY *CreateNatTcp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port)
5419 {
5420 	NAT_ENTRY *n;
5421 	HUB_OPTION *o;
5422 	// Validate arguments
5423 	if (v == NULL)
5424 	{
5425 		return NULL;
5426 	}
5427 
5428 	if (CanCreateNewNatEntry(v) == false)
5429 	{
5430 		return NULL;
5431 	}
5432 
5433 	o = NatGetHubOption(v);
5434 
5435 	// Fail immediately if the connection with SYN_SENT are too many
5436 	if (o != NULL && o->SecureNAT_MaxTcpSynSentPerIp != 0)
5437 	{
5438 		if (GetNumNatEntriesPerIp(v, src_ip, NAT_TCP, true) >= o->SecureNAT_MaxTcpSynSentPerIp)
5439 		{
5440 			return NULL;
5441 		}
5442 	}
5443 
5444 	// If the connections other than SYN_SENT are too many, delete old ones
5445 	if (o != NULL && o->SecureNAT_MaxTcpSessionsPerIp != 0)
5446 	{
5447 		if (GetNumNatEntriesPerIp(v, src_ip, NAT_TCP, false) >= o->SecureNAT_MaxTcpSessionsPerIp)
5448 		{
5449 			NAT_ENTRY *oldest = GetOldestNatEntryOfIp(v, src_ip, NAT_TCP);
5450 
5451 			if (oldest != NULL)
5452 			{
5453 				DisconnectNatEntryNow(v, oldest);
5454 			}
5455 		}
5456 	}
5457 
5458 	// Create a NAT entry
5459 	n = ZeroMalloc(sizeof(NAT_ENTRY));
5460 	n->Id = Inc(v->Counter);
5461 	n->v = v;
5462 	n->lock = NewLock();
5463 	n->Protocol = NAT_TCP;
5464 	n->SrcIp = src_ip;
5465 	n->SrcPort = src_port;
5466 	n->DestIp = dest_ip;
5467 	n->DestPort = dest_port;
5468 	n->CreatedTime = n->LastCommTime = v->Now;
5469 	n->TcpLastRecvAckTime = v->Now;
5470 	n->Sock = NULL;
5471 	n->DisconnectNow = false;
5472 	n->TcpSendMaxSegmentSize = n->TcpRecvMaxSegmentSize = v->TcpMss;
5473 
5474 	n->SendFifo = NewFifo();
5475 	n->RecvFifo = NewFifo();
5476 
5477 	n->TcpStatus = NAT_TCP_CONNECTING;
5478 
5479 	n->SendSeqInit = Rand32();
5480 	n->CurrentRTT = NAT_INITIAL_RTT_VALUE;
5481 	n->TcpSendTimeoutSpan = n->CurrentRTT * 2;
5482 
5483 	// Add to the NAT table
5484 	Add(v->NatTable, n);
5485 
5486 
5487 #if	1
5488 	{
5489 		IP ip1, ip2;
5490 		char s1[MAX_SIZE], s2[MAX_SIZE];
5491 		UINTToIP(&ip1, src_ip);
5492 		UINTToIP(&ip2, dest_ip);
5493 		IPToStr(s1, 0, &ip1);
5494 		IPToStr(s2, 0, &ip2);
5495 		Debug("NAT_ENTRY: CreateNatTcp %s %u -> %s %u\n", s1, src_port, s2, dest_port);
5496 
5497 		NLog(v, "LH_NAT_TCP_CREATED", n->Id, s1, src_port, s2, dest_port);
5498 	}
5499 #endif
5500 
5501 	return n;
5502 }
5503 
5504 // Received TCP packets from the virtual network
VirtualTcpReceived(VH * v,UINT src_ip,UINT dest_ip,void * data,UINT size,UINT max_l3_size)5505 void VirtualTcpReceived(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, UINT max_l3_size)
5506 {
5507 	TCP_HEADER *tcp;
5508 	UINT src_port, dest_port;
5509 	UINT header_size, buf_size;
5510 	void *buf;
5511 	IP ip1, ip2;
5512 	// Validate arguments
5513 	if (v == NULL || data == NULL)
5514 	{
5515 		return;
5516 	}
5517 
5518 	// Get the header
5519 	if (size < TCP_HEADER_SIZE)
5520 	{
5521 		// Size is too small
5522 		return;
5523 	}
5524 	tcp = (TCP_HEADER *)data;
5525 	src_port = Endian16(tcp->SrcPort);
5526 	dest_port = Endian16(tcp->DstPort);
5527 	if (src_port == 0 || dest_port == 0)
5528 	{
5529 		// Port number is invalid
5530 		return;
5531 	}
5532 	if (src_ip == dest_ip || src_ip == 0 || src_ip == 0xffffffff || dest_ip == 0 || dest_ip == 0xffffffff)
5533 	{
5534 		// IP address is invalid
5535 		return;
5536 	}
5537 	UINTToIP(&ip1, src_ip);
5538 	UINTToIP(&ip2, dest_ip);
5539 	if (IsLocalHostIP4(&ip1) || IsLocalHostIP4(&ip2))
5540 	{
5541 		// Loopback IP address can not be specified
5542 		return;
5543 	}
5544 	if (IsInNetwork(dest_ip, v->HostIP, v->HostMask))
5545 	{
5546 		// Ignore the packets toward the network of the virtual LAN side
5547 		return;
5548 	}
5549 	// Get the header size
5550 	header_size = TCP_GET_HEADER_SIZE(tcp) * 4;
5551 	if (size < header_size)
5552 	{
5553 		// Header size is invalid
5554 		return;
5555 	}
5556 	// Get the address and size of the buffer
5557 	buf_size = size - header_size;
5558 	buf = (void *)(((UCHAR *)data) + header_size);
5559 
5560 	TcpRecvForInternet(v, src_ip, src_port, dest_ip, dest_port, tcp, buf, buf_size, max_l3_size);
5561 }
5562 
5563 // NAT ICMP polling
PollingNatIcmp(VH * v,NAT_ENTRY * n)5564 void PollingNatIcmp(VH *v, NAT_ENTRY *n)
5565 {
5566 	// Validate arguments
5567 	if (v == NULL || n == NULL)
5568 	{
5569 		return;
5570 	}
5571 
5572 	// Process if there are any packets in the receive queue
5573 	if (n->UdpRecvQueue->num_item != 0)
5574 	{
5575 		BLOCK *block;
5576 
5577 		// Send all ICMP packets to the virtual network
5578 		while (block = GetNext(n->UdpRecvQueue))
5579 		{
5580 			// Rewrite the destination IP address of the returned packet to the IP address of the client
5581 			UCHAR *data;
5582 			UINT size;
5583 
5584 			data = (UCHAR *)block->Buf;
5585 			size = block->Size;
5586 
5587 			if (size >= sizeof(IPV4_HEADER))
5588 			{
5589 				IPV4_HEADER *ipv4 = (IPV4_HEADER *)data;
5590 				UINT ipv4_header_size = GetIpHeaderSize((UCHAR *)ipv4, size);
5591 
5592 				if (ipv4_header_size >= sizeof(IPV4_HEADER) && (Endian16(ipv4->TotalLength) >= ipv4_header_size))
5593 				{
5594 					UCHAR *ipv4_payload = data + ipv4_header_size;
5595 					UINT ipv4_payload_size = Endian16(ipv4->TotalLength) - ipv4_header_size;
5596 
5597 					if (ipv4_payload_size >= sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO))
5598 					{
5599 						ICMP_HEADER *icmp = (ICMP_HEADER *)(data + ipv4_header_size);
5600 						UINT icmp_size = ipv4_payload_size;
5601 
5602 						if (icmp->Type == ICMP_TYPE_DESTINATION_UNREACHABLE || icmp->Type == ICMP_TYPE_TIME_EXCEEDED)
5603 						{
5604 							// Rewrite the Src IP of the IPv4 header of the ICMP response packet
5605 							if (icmp_size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + sizeof(IPV4_HEADER)))
5606 							{
5607 								IPV4_HEADER *orig_ipv4 = (IPV4_HEADER *)(data + ipv4_header_size + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
5608 								UINT orig_ipv4_size = icmp_size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
5609 
5610 								UINT orig_ipv4_header_size = GetIpHeaderSize((UCHAR *)orig_ipv4, orig_ipv4_size);
5611 
5612 								if (orig_ipv4_header_size >= sizeof(IPV4_HEADER))
5613 								{
5614 									orig_ipv4->SrcIP = n->SrcIp;
5615 									orig_ipv4->Checksum = 0;
5616 									orig_ipv4->Checksum = IpChecksum(orig_ipv4, orig_ipv4_header_size);
5617 								}
5618 							}
5619 						}
5620 
5621 						// Recalculate the checksum of ICMP
5622 						icmp->Checksum = IpChecksum(icmp, icmp_size);
5623 
5624 						SendIpEx(v, n->SrcIp, ipv4->SrcIP, ipv4->Protocol, ipv4_payload, ipv4_payload_size,
5625 						         MAX(ipv4->TimeToLive - 1, 1));
5626 					}
5627 				}
5628 			}
5629 
5630 			FreeBlock(block);
5631 		}
5632 
5633 		if (v->IcmpRawSocketOk == false)
5634 		{
5635 			// Release the NAT entry as soon as the results is received in the case of using ICMP API
5636 			n->DisconnectNow = true;
5637 		}
5638 	}
5639 }
5640 
5641 // NAT UDP polling
PoolingNatUdp(VH * v,NAT_ENTRY * n)5642 void PoolingNatUdp(VH *v, NAT_ENTRY *n)
5643 {
5644 	// Validate arguments
5645 	if (v == NULL || n == NULL)
5646 	{
5647 		return;
5648 	}
5649 
5650 	// Process if there are any packets in the receive queue
5651 	if (n->UdpRecvQueue->num_item != 0)
5652 	{
5653 		BLOCK *block;
5654 
5655 		// Send all UDP packets to the virtual network
5656 		while (block = GetNext(n->UdpRecvQueue))
5657 		{
5658 			UINT src_ip = n->DestIp;
5659 
5660 			if (src_ip == 0xFFFFFFFF)
5661 			{
5662 				src_ip = v->HostIP;
5663 			}
5664 
5665 			if (block->Param1 != 0)
5666 			{
5667 				src_ip = block->Param1;
5668 			}
5669 
5670 			SendUdp(v, n->SrcIp, n->SrcPort, src_ip, n->DestPort,
5671 			        block->Buf, block->Size);
5672 
5673 			FreeBlock(block);
5674 		}
5675 	}
5676 }
5677 
5678 // NAT polling
PoolingNat(VH * v)5679 void PoolingNat(VH *v)
5680 {
5681 	UINT i;
5682 	// Validate arguments
5683 	if (v == NULL)
5684 	{
5685 		return;
5686 	}
5687 
5688 	if (NnIsActive(v))
5689 	{
5690 		// Poll whether the packet comes from native NAT
5691 		NnPoll(v->NativeNat);
5692 	}
5693 
5694 	// Process by scanning the all NAT entries
5695 	for (i = 0; i < LIST_NUM(v->NatTable); i++)
5696 	{
5697 		NAT_ENTRY *n = LIST_DATA(v->NatTable, i);
5698 
5699 		switch (n->Protocol)
5700 		{
5701 		case NAT_TCP:
5702 			PollingNatTcp(v, n);
5703 			break;
5704 
5705 		case NAT_UDP:
5706 			PoolingNatUdp(v, n);
5707 			break;
5708 
5709 		case NAT_ICMP:
5710 			PollingNatIcmp(v, n);
5711 			break;
5712 
5713 		case NAT_DNS:
5714 			PollingNatDns(v, n);
5715 			break;
5716 		}
5717 	}
5718 }
5719 
5720 // Comparison function of the NAT table entry
CompareNat(void * p1,void * p2)5721 int CompareNat(void *p1, void *p2)
5722 {
5723 	NAT_ENTRY *n1, *n2;
5724 	if (p1 == NULL || p2 == NULL)
5725 	{
5726 		return 0;
5727 	}
5728 	n1 = *(NAT_ENTRY **)p1;
5729 	n2 = *(NAT_ENTRY **)p2;
5730 	if (n1 == n2)
5731 	{
5732 		return 0;
5733 	}
5734 
5735 	if (n1->SrcIp > n2->SrcIp) return 1;
5736 	else if (n1->SrcIp < n2->SrcIp) return -1;
5737 	else if (n1->DestIp > n2->DestIp) return 1;
5738 	else if (n1->DestIp < n2->DestIp) return -1;
5739 	else if (n1->SrcPort > n2->SrcPort) return 1;
5740 	else if (n1->SrcPort < n2->SrcPort) return -1;
5741 	else if (n1->DestPort > n2->DestPort) return 1;
5742 	else if (n1->DestPort < n2->DestPort) return -1;
5743 	else if (n1->Protocol > n2->Protocol) return 1;
5744 	else if (n1->Protocol < n2->Protocol) return -1;
5745 	else return 0;
5746 }
5747 
5748 // Configure the NAT structure
SetNat(NAT_ENTRY * n,UINT protocol,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,UINT public_ip,UINT public_port)5749 void SetNat(NAT_ENTRY *n, UINT protocol, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT public_ip, UINT public_port)
5750 {
5751 	// Validate arguments
5752 	if (n == NULL)
5753 	{
5754 		return;
5755 	}
5756 
5757 	n->Protocol = protocol;
5758 	n->SrcIp = src_ip;
5759 	n->SrcPort = src_port;
5760 	n->DestIp = dest_ip;
5761 	n->DestPort = dest_port;
5762 	n->PublicIp = public_ip;
5763 	n->PublicPort = public_port;
5764 }
5765 
5766 // Initialize the NAT
InitNat(VH * v)5767 void InitNat(VH *v)
5768 {
5769 	// Validate arguments
5770 	if (v == NULL)
5771 	{
5772 		return;
5773 	}
5774 
5775 	// Create a NAT table
5776 	v->NatTable = NewList(CompareNat);
5777 
5778 	// Create a socket event
5779 	v->SockEvent = NewSockEvent();
5780 
5781 	// Create the NAT thread
5782 	v->HaltNat = false;
5783 	v->NatThread = NewThread(NatThread, (void *)v);
5784 	WaitThreadInit(v->NatThread);
5785 
5786 	if (IsEthSupported())
5787 	{
5788 		// Start a native NAT if access to the layer 2 Ethernet is supported
5789 		v->NativeNat = NewNativeNat(v);
5790 	}
5791 }
5792 
5793 // Release the NAT
FreeNat(VH * v)5794 void FreeNat(VH *v)
5795 {
5796 	// Validate arguments
5797 	if (v == NULL)
5798 	{
5799 		return;
5800 	}
5801 
5802 	// Stop the native NAT
5803 	if (v->NativeNat != NULL)
5804 	{
5805 		FreeNativeNat(v->NativeNat);
5806 		v->NativeNat = NULL;
5807 	}
5808 
5809 	// Stop the NAT thread
5810 	v->HaltNat = true;
5811 	SetSockEvent(v->SockEvent);
5812 	WaitThread(v->NatThread, INFINITE);
5813 	ReleaseThread(v->NatThread);
5814 	v->NatThread = NULL;
5815 	ReleaseSockEvent(v->SockEvent);
5816 	v->SockEvent = NULL;
5817 
5818 	// Release the NAT table
5819 	ReleaseList(v->NatTable);
5820 }
5821 
5822 // Search the NAT table
SearchNat(VH * v,NAT_ENTRY * target)5823 NAT_ENTRY *SearchNat(VH *v, NAT_ENTRY *target)
5824 {
5825 	NAT_ENTRY *n;
5826 	// Validate arguments
5827 	if (v == NULL || target == NULL)
5828 	{
5829 		return NULL;
5830 	}
5831 
5832 	// Binary search
5833 	n = (NAT_ENTRY *)Search(v->NatTable, target);
5834 
5835 	return n;
5836 }
5837 
5838 // Delete the UDP NAT entry
DeleteNatUdp(VH * v,NAT_ENTRY * n)5839 void DeleteNatUdp(VH *v, NAT_ENTRY *n)
5840 {
5841 	BLOCK *block;
5842 	// Validate arguments
5843 	if (v == NULL || n == NULL)
5844 	{
5845 		return;
5846 	}
5847 
5848 	NLog(v, "LH_NAT_UDP_DELETED", n->Id);
5849 
5850 	// Release all queues
5851 	while (block = GetNext(n->UdpRecvQueue))
5852 	{
5853 		FreeBlock(block);
5854 	}
5855 	ReleaseQueue(n->UdpRecvQueue);
5856 	while (block = GetNext(n->UdpSendQueue))
5857 	{
5858 		FreeBlock(block);
5859 	}
5860 	ReleaseQueue(n->UdpSendQueue);
5861 
5862 	// Release the socket
5863 	if (n->Sock != NULL)
5864 	{
5865 		Disconnect(n->Sock);
5866 		ReleaseSock(n->Sock);
5867 		n->Sock = NULL;
5868 	}
5869 
5870 	DeleteLock(n->lock);
5871 
5872 	// Remove from the table
5873 	Delete(v->NatTable, n);
5874 
5875 	// Release the memory
5876 	Free(n);
5877 
5878 	Debug("NAT: DeleteNatUdp\n");
5879 
5880 }
5881 
5882 // Delete the ICMP NAT entry
DeleteNatIcmp(VH * v,NAT_ENTRY * n)5883 void DeleteNatIcmp(VH *v, NAT_ENTRY *n)
5884 {
5885 	BLOCK *block;
5886 	// Validate arguments
5887 	if (v == NULL || n == NULL)
5888 	{
5889 		return;
5890 	}
5891 
5892 	//NLog(v, "LH_NAT_ICMP_DELETED", n->Id);
5893 
5894 	// Release all queues
5895 	while (block = GetNext(n->UdpRecvQueue))
5896 	{
5897 		FreeBlock(block);
5898 	}
5899 	ReleaseQueue(n->UdpRecvQueue);
5900 	while (block = GetNext(n->UdpSendQueue))
5901 	{
5902 		FreeBlock(block);
5903 	}
5904 	ReleaseQueue(n->UdpSendQueue);
5905 
5906 	if (n->IcmpQueryBlock != NULL)
5907 	{
5908 		FreeBlock(n->IcmpQueryBlock);
5909 	}
5910 
5911 	if (n->IcmpResponseBlock != NULL)
5912 	{
5913 		FreeBlock(n->IcmpResponseBlock);
5914 	}
5915 
5916 	if (n->IcmpOriginalCopy != NULL)
5917 	{
5918 		Free(n->IcmpOriginalCopy);
5919 	}
5920 
5921 	// Release the socket
5922 	if (n->Sock != NULL)
5923 	{
5924 		Disconnect(n->Sock);
5925 		ReleaseSock(n->Sock);
5926 		n->Sock = NULL;
5927 	}
5928 
5929 	DeleteLock(n->lock);
5930 
5931 	// Remove from the table
5932 	Delete(v->NatTable, n);
5933 
5934 	// Release the memory
5935 	Free(n);
5936 
5937 	Debug("NAT: DeleteNatIcmp\n");
5938 
5939 }
5940 
5941 // Create a NAT ICMP entry
CreateNatIcmp(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,UCHAR * original_copy,UINT original_copy_size)5942 NAT_ENTRY *CreateNatIcmp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UCHAR *original_copy, UINT original_copy_size)
5943 {
5944 	NAT_ENTRY *n;
5945 	HUB_OPTION *o;
5946 	// Validate arguments
5947 	if (v == NULL || original_copy == NULL || original_copy_size == 0)
5948 	{
5949 		return NULL;
5950 	}
5951 
5952 	if (CanCreateNewNatEntry(v) == false)
5953 	{
5954 		return NULL;
5955 	}
5956 
5957 	o = NatGetHubOption(v);
5958 	if (o != NULL && o->SecureNAT_MaxIcmpSessionsPerIp != 0)
5959 	{
5960 		if (GetNumNatEntriesPerIp(v, src_ip, NAT_ICMP, false) >= o->SecureNAT_MaxIcmpSessionsPerIp)
5961 		{
5962 			NAT_ENTRY *oldest = GetOldestNatEntryOfIp(v, src_ip, NAT_ICMP);
5963 
5964 			if (oldest != NULL)
5965 			{
5966 				DisconnectNatEntryNow(v, oldest);
5967 			}
5968 		}
5969 	}
5970 
5971 	n = ZeroMalloc(sizeof(NAT_ENTRY));
5972 	n->Id = Inc(v->Counter);
5973 	n->v = v;
5974 	n->lock = NewLock();
5975 	n->Protocol = NAT_ICMP;
5976 	n->SrcIp = src_ip;
5977 	n->SrcPort = src_port;
5978 	n->DestIp = dest_ip;
5979 	n->DestPort = dest_port;
5980 
5981 	n->CreatedTime = n->LastCommTime = v->Now;
5982 
5983 	n->UdpSendQueue = NewQueue();
5984 	n->UdpRecvQueue = NewQueue();
5985 
5986 	n->UdpSocketCreated = false;
5987 
5988 	n->IcmpOriginalCopy = Clone(original_copy, original_copy_size);
5989 	n->IcmpOriginalCopySize = original_copy_size;
5990 
5991 	SetSockEvent(v->SockEvent);
5992 
5993 #if	1
5994 	{
5995 		IP ip1, ip2;
5996 		char s1[MAX_SIZE], s2[MAX_SIZE];
5997 		UINTToIP(&ip1, src_ip);
5998 		UINTToIP(&ip2, dest_ip);
5999 		IPToStr(s1, 0, &ip1);
6000 		IPToStr(s2, 0, &ip2);
6001 		Debug("NAT_ENTRY: CreateNatIcmp %s %u -> %s %u\n", s1, src_port, s2, dest_port);
6002 
6003 		//NLog(v, "LH_NAT_ICMP_CREATED", n->Id, s1, s2, src_port);
6004 	}
6005 #endif
6006 
6007 	Add(v->NatTable, n);
6008 
6009 	return n;
6010 }
6011 
6012 // Create a NAT UDP entry
CreateNatUdp(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,UINT dns_proxy_ip)6013 NAT_ENTRY *CreateNatUdp(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT dns_proxy_ip)
6014 {
6015 	NAT_ENTRY *n;
6016 	HUB_OPTION *o;
6017 	// Validate arguments
6018 	if (v == NULL)
6019 	{
6020 		return NULL;
6021 	}
6022 
6023 	if (CanCreateNewNatEntry(v) == false)
6024 	{
6025 		return NULL;
6026 	}
6027 
6028 	o = NatGetHubOption(v);
6029 	if (o != NULL && o->SecureNAT_MaxTcpSessionsPerIp != 0)
6030 	{
6031 		if (GetNumNatEntriesPerIp(v, src_ip, NAT_UDP, false) >= o->SecureNAT_MaxUdpSessionsPerIp)
6032 		{
6033 			NAT_ENTRY *oldest = GetOldestNatEntryOfIp(v, src_ip, NAT_UDP);
6034 
6035 			if (oldest != NULL)
6036 			{
6037 				DisconnectNatEntryNow(v, oldest);
6038 			}
6039 		}
6040 	}
6041 
6042 	n = ZeroMalloc(sizeof(NAT_ENTRY));
6043 	n->Id = Inc(v->Counter);
6044 	n->v = v;
6045 	n->lock = NewLock();
6046 	n->Protocol = NAT_UDP;
6047 	n->SrcIp = src_ip;
6048 	n->SrcPort = src_port;
6049 	n->DestIp = dest_ip;
6050 	n->DestPort = dest_port;
6051 
6052 	if (dns_proxy_ip != 0)
6053 	{
6054 		n->ProxyDns = true;
6055 		n->DestIpProxy = dns_proxy_ip;
6056 	}
6057 
6058 	n->CreatedTime = n->LastCommTime = v->Now;
6059 
6060 	n->UdpSendQueue = NewQueue();
6061 	n->UdpRecvQueue = NewQueue();
6062 
6063 	n->UdpSocketCreated = false;
6064 
6065 	SetSockEvent(v->SockEvent);
6066 
6067 #if	1
6068 	{
6069 		IP ip1, ip2;
6070 		char s1[MAX_SIZE], s2[MAX_SIZE];
6071 		UINTToIP(&ip1, src_ip);
6072 		UINTToIP(&ip2, dest_ip);
6073 		IPToStr(s1, 0, &ip1);
6074 		IPToStr(s2, 0, &ip2);
6075 		Debug("NAT_ENTRY: CreateNatUdp %s %u -> %s %u\n", s1, src_port, s2, dest_port);
6076 
6077 		NLog(v, "LH_NAT_UDP_CREATED", n->Id, s1, src_port, s2, dest_port);
6078 	}
6079 #endif
6080 
6081 	Add(v->NatTable, n);
6082 
6083 	return n;
6084 }
6085 
6086 // Ignore for NetBIOS name registration packet
IsNetbiosRegistrationPacket(UCHAR * buf,UINT size)6087 bool IsNetbiosRegistrationPacket(UCHAR *buf, UINT size)
6088 {
6089 	// Validate arguments
6090 	if (buf == NULL || size == 0)
6091 	{
6092 		return false;
6093 	}
6094 
6095 	if (size >= 4)
6096 	{
6097 		USHORT us = *((USHORT *)(buf + 2));
6098 
6099 		us = Endian16(us);
6100 
6101 		if (((us & 0x7800) >> 11) == 5)
6102 		{
6103 			return true;
6104 		}
6105 	}
6106 
6107 	return false;
6108 }
6109 
6110 // Generate the encoded NetBIOS name
EncodeNetBiosName(UCHAR * dst,char * src)6111 void EncodeNetBiosName(UCHAR *dst, char *src)
6112 {
6113 	char tmp[17];
6114 	UINT i;
6115 	UINT copy_len;
6116 	UINT wp;
6117 	// Validate arguments
6118 	if (dst == NULL || src == NULL)
6119 	{
6120 		return;
6121 	}
6122 
6123 	for (i = 0; i < 16; i++)
6124 	{
6125 		tmp[i] = ' ';
6126 	}
6127 	tmp[16] = 0;
6128 
6129 	copy_len = StrLen(src);
6130 	if (copy_len > 16)
6131 	{
6132 		copy_len = 16;
6133 	}
6134 
6135 	Copy(tmp, src, copy_len);
6136 
6137 	wp = 0;
6138 
6139 	tmp[15] = 0;
6140 
6141 	for (i = 0; i < 16; i++)
6142 	{
6143 		char c = tmp[i];
6144 		char *s = CharToNetBiosStr(c);
6145 
6146 		dst[wp++] = s[0];
6147 		dst[wp++] = s[1];
6148 	}
6149 }
6150 
6151 // Convert the string to NetBIOS characters
CharToNetBiosStr(char c)6152 char *CharToNetBiosStr(char c)
6153 {
6154 	c = ToUpper(c);
6155 
6156 	switch (c)
6157 	{
6158 	case '\0':
6159 		return "AA";
6160 	case 'A':
6161 		return "EB";
6162 	case 'B':
6163 		return "EC";
6164 	case 'C':
6165 		return "ED";
6166 	case 'D':
6167 		return "EE";
6168 	case 'E':
6169 		return "EF";
6170 	case 'F':
6171 		return "EG";
6172 	case 'G':
6173 		return "EH";
6174 	case 'H':
6175 		return "EI";
6176 	case 'I':
6177 		return "EJ";
6178 	case 'J':
6179 		return "EK";
6180 	case 'K':
6181 		return "EL";
6182 	case 'L':
6183 		return "EM";
6184 	case 'M':
6185 		return "EN";
6186 	case 'N':
6187 		return "EO";
6188 	case 'O':
6189 		return "EP";
6190 	case 'P':
6191 		return "FA";
6192 	case 'Q':
6193 		return "FB";
6194 	case 'R':
6195 		return "FC";
6196 	case 'S':
6197 		return "FD";
6198 	case 'T':
6199 		return "FE";
6200 	case 'U':
6201 		return "FF";
6202 	case 'V':
6203 		return "FG";
6204 	case 'W':
6205 		return "FH";
6206 	case 'X':
6207 		return "FI";
6208 	case 'Y':
6209 		return "FJ";
6210 	case 'Z':
6211 		return "FK";
6212 	case '0':
6213 		return "DA";
6214 	case '1':
6215 		return "DB";
6216 	case '2':
6217 		return "DC";
6218 	case '3':
6219 		return "DD";
6220 	case '4':
6221 		return "DE";
6222 	case '5':
6223 		return "DF";
6224 	case '6':
6225 		return "DG";
6226 	case '7':
6227 		return "DH";
6228 	case '8':
6229 		return "DI";
6230 	case '9':
6231 		return "DJ";
6232 	case ' ':
6233 		return "CA";
6234 	case '!':
6235 		return "CB";
6236 	case '\"':
6237 		return "CC";
6238 	case '#':
6239 		return "CD";
6240 	case '$':
6241 		return "CE";
6242 	case '%':
6243 		return "CF";
6244 	case '&':
6245 		return "CG";
6246 	case '\'':
6247 		return "CH";
6248 	case '(':
6249 		return "CI";
6250 	case ')':
6251 		return "CJ";
6252 	case '*':
6253 		return "CK";
6254 	case '+':
6255 		return "CL";
6256 	case ',':
6257 		return "CM";
6258 	case '-':
6259 		return "CN";
6260 	case '.':
6261 		return "CO";
6262 	case '=':
6263 		return "DN";
6264 	case ':':
6265 		return "DK";
6266 	case ';':
6267 		return "DL";
6268 	case '@':
6269 		return "EA";
6270 	case '^':
6271 		return "FO";
6272 	case '_':
6273 		return "FP";
6274 	case '{':
6275 		return "HL";
6276 	case '}':
6277 		return "HN";
6278 	case '~':
6279 		return "HO";
6280 	}
6281 
6282 	return "CA";
6283 }
6284 
6285 // Process if a NetBIOS name resolution packet for the my host name
ProcessNetBiosNameQueryPacketForMyself(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size)6286 bool ProcessNetBiosNameQueryPacketForMyself(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size)
6287 {
6288 	BUF *rb;
6289 	USHORT tran_id;
6290 	USHORT flags;
6291 	USHORT num_query;
6292 	USHORT zero1, zero2, zero3;
6293 	UCHAR name_size;
6294 	UCHAR encoded_name[32];
6295 	UCHAR node_type;
6296 	USHORT type, classid;
6297 	UCHAR my_pc_encoded_name[32];
6298 	bool ret = false;
6299 	// Validate arguments
6300 	if (v == NULL || data == NULL)
6301 	{
6302 		return false;
6303 	}
6304 
6305 	rb = NewBufFromMemory(data, size);
6306 
6307 	ReadBuf(rb, &tran_id, sizeof(USHORT));
6308 
6309 	ReadBuf(rb, &flags, sizeof(USHORT));
6310 	flags = Endian16(flags);
6311 
6312 	ReadBuf(rb, &num_query, sizeof(USHORT));
6313 	num_query = Endian16(num_query);
6314 
6315 	ReadBuf(rb, &zero1, sizeof(USHORT));
6316 	ReadBuf(rb, &zero2, sizeof(USHORT));
6317 	ReadBuf(rb, &zero3, sizeof(USHORT));
6318 
6319 	ReadBuf(rb, &name_size, 1);
6320 
6321 	ReadBuf(rb, encoded_name, 32);
6322 
6323 	ReadBuf(rb, &node_type, 1);
6324 
6325 	ReadBuf(rb, &type, sizeof(USHORT));
6326 	type = Endian16(type);
6327 
6328 	if (ReadBuf(rb, &classid, sizeof(USHORT)) == sizeof(USHORT))
6329 	{
6330 		classid = Endian16(classid);
6331 
6332 		if (((flags >> 11) & 0x0F) == 0 &&
6333 		        num_query == 1 && name_size == 0x20 &&
6334 		        zero1 == 0 && zero2 == 0 && zero3 == 0 && node_type == 0 && type == 0x0020 && classid == 0x0001)
6335 		{
6336 			char my_pcname[MAX_SIZE];
6337 
6338 			// Get the encoded name of this PC
6339 			Zero(my_pcname, sizeof(my_pcname));
6340 			GetMachineHostName(my_pcname, sizeof(my_pcname));
6341 
6342 			EncodeNetBiosName(my_pc_encoded_name, my_pcname);
6343 
6344 			if (Cmp(my_pc_encoded_name, encoded_name, 30) == 0)
6345 			{
6346 				// Assemble the response packet since the name resolution packet which targets this PC name received
6347 				BUF *sb = NewBuf();
6348 				USHORT us;
6349 				UINT ui;
6350 				LIST *ip_list;
6351 				BUF *ip_list_buf;
6352 				bool found = false;
6353 
6354 				WriteBuf(sb, &tran_id, sizeof(USHORT));
6355 
6356 				flags = Endian16(0x8500);
6357 				WriteBuf(sb, &flags, sizeof(USHORT));
6358 
6359 				num_query = 0;
6360 				WriteBuf(sb, &num_query, sizeof(USHORT));
6361 
6362 				us = Endian16(1);
6363 				WriteBuf(sb, &us, sizeof(USHORT));
6364 
6365 				us = 0;
6366 				WriteBuf(sb, &us, sizeof(USHORT));
6367 				WriteBuf(sb, &us, sizeof(USHORT));
6368 
6369 				name_size = 0x20;
6370 				WriteBuf(sb, &name_size, 1);
6371 
6372 				WriteBuf(sb, encoded_name, 32);
6373 
6374 				node_type = 0;
6375 				WriteBuf(sb, &node_type, 1);
6376 
6377 				type = Endian16(type);
6378 				classid = Endian16(classid);
6379 
6380 				WriteBuf(sb, &type, sizeof(USHORT));
6381 				WriteBuf(sb, &classid, sizeof(USHORT));
6382 
6383 				ui = Endian32((UINT)(Tick64() / 1000ULL));
6384 				WriteBuf(sb, &ui, sizeof(UINT));
6385 
6386 				ip_list_buf = NewBuf();
6387 
6388 				ip_list = GetHostIPAddressList();
6389 				if (ip_list != NULL)
6390 				{
6391 					UINT i;
6392 
6393 					// Return only private IP if there is a private IP
6394 					for (i = 0; i < LIST_NUM(ip_list); i++)
6395 					{
6396 						IP *ip = LIST_DATA(ip_list, i);
6397 
6398 						if (IsIP4(ip) && IsLocalHostIP4(ip) == false && IsZeroIp(ip) == false)
6399 						{
6400 							if (IsIPPrivate(ip))
6401 							{
6402 								USHORT flags = Endian16(0x4000);
6403 								UINT ip_uint = IPToUINT(ip);
6404 
6405 								WriteBuf(ip_list_buf, &flags, sizeof(USHORT));
6406 								WriteBuf(ip_list_buf, &ip_uint, sizeof(UINT));
6407 
6408 								found = true;
6409 							}
6410 						}
6411 					}
6412 
6413 					if (found == false)
6414 					{
6415 						// Return all IP if no private IP are found
6416 						for (i = 0; i < LIST_NUM(ip_list); i++)
6417 						{
6418 							IP *ip = LIST_DATA(ip_list, i);
6419 
6420 							if (IsIP4(ip) && IsLocalHostIP4(ip) == false && IsZeroIp(ip) == false)
6421 							{
6422 								USHORT flags = Endian16(0x4000);
6423 								UINT ip_uint = IPToUINT(ip);
6424 
6425 								WriteBuf(ip_list_buf, &flags, sizeof(USHORT));
6426 								WriteBuf(ip_list_buf, &ip_uint, sizeof(UINT));
6427 
6428 								found = true;
6429 							}
6430 						}
6431 					}
6432 
6433 					FreeHostIPAddressList(ip_list);
6434 				}
6435 
6436 				us = Endian16(ip_list_buf->Size);
6437 				WriteBuf(sb, &us, sizeof(USHORT));
6438 
6439 				WriteBufBuf(sb, ip_list_buf);
6440 
6441 				SendUdp(v, src_ip, src_port, v->HostIP, dest_port, sb->Buf, sb->Size);
6442 
6443 				FreeBuf(ip_list_buf);
6444 
6445 				FreeBuf(sb);
6446 
6447 				WHERE;
6448 			}
6449 		}
6450 	}
6451 
6452 	FreeBuf(rb);
6453 
6454 	return ret;
6455 }
6456 
6457 // Process the NetBIOS broadcast packet
UdpRecvForNetBiosBroadcast(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size,bool dns_proxy,bool unicast)6458 void UdpRecvForNetBiosBroadcast(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, bool dns_proxy, bool unicast)
6459 {
6460 	// Validate arguments
6461 	if (data == NULL || v == NULL)
6462 	{
6463 		return;
6464 	}
6465 
6466 	// Ignore for NetBIOS name registration packet
6467 	if (IsNetbiosRegistrationPacket(data, size) == false)
6468 	{
6469 		if (unicast == false)
6470 		{
6471 			dest_ip = 0xFFFFFFFF;
6472 		}
6473 
6474 		if (ProcessNetBiosNameQueryPacketForMyself(v, src_ip, src_port, dest_ip, dest_port, data, size) == false)
6475 		{
6476 			UdpRecvForInternet(v, src_ip, src_port, dest_ip, dest_port, data, size, false);
6477 		}
6478 	}
6479 }
6480 
6481 // Process the UDP packet to the Internet
UdpRecvForInternet(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size,bool dns_proxy)6482 void UdpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, bool dns_proxy)
6483 {
6484 	NAT_ENTRY *n, t;
6485 	BLOCK *block;
6486 	void *buf;
6487 	UINT dns_ip = 0;
6488 	// Validate arguments
6489 	if (data == NULL || v == NULL)
6490 	{
6491 		return;
6492 	}
6493 
6494 	if (dns_proxy)
6495 	{
6496 		// Get the DNS server of the proxy to connect to
6497 		IP ip;
6498 		char tmp[MAX_SIZE];
6499 		if (GetDefaultDns(&ip) == false)
6500 		{
6501 			// Failure
6502 			Debug("Failed to GetDefaultDns()\n");
6503 			return;
6504 		}
6505 		dns_ip = IPToUINT(&ip);
6506 		IPToStr(tmp, sizeof(tmp), &ip);
6507 		Debug("Redirect to DNS Server %s\n", tmp);
6508 	}
6509 
6510 	// Examine whether the NAT entry for this packet has already been created
6511 	SetNat(&t, NAT_UDP, src_ip, src_port, dest_ip, dest_port, 0, 0);
6512 	n = SearchNat(v, &t);
6513 
6514 	if (n == NULL)
6515 	{
6516 		// Create a NAT entry because it is the first packet
6517 		n = CreateNatUdp(v, src_ip, src_port, dest_ip, dest_port, dns_proxy ? dns_ip : 0);
6518 		if (n == NULL)
6519 		{
6520 			// Entry creation failed
6521 			return;
6522 		}
6523 
6524 		if (dns_proxy)
6525 		{
6526 			n->ProxyDns = true;
6527 			n->DestIpProxy = dns_ip;
6528 		}
6529 	}
6530 
6531 	// Set the event by inserting the packet into the queue
6532 	buf = Malloc(size);
6533 	Copy(buf, data, size);
6534 	block = NewBlock(buf, size, 0);
6535 	InsertQueue(n->UdpSendQueue, block);
6536 
6537 	SetSockEvent(v->SockEvent);
6538 }
6539 
6540 // Attempt to interpret the DNS packet
ParseDnsPacket(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size)6541 bool ParseDnsPacket(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size)
6542 {
6543 	return ParseDnsPacketEx(v, src_ip, src_port, dest_ip, dest_port, data, size, NULL);
6544 }
ParseDnsPacketEx(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size,DNS_PARSED_PACKET * parsed_result)6545 bool ParseDnsPacketEx(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, DNS_PARSED_PACKET *parsed_result)
6546 {
6547 	DNSV4_HEADER *dns;
6548 	NAT_ENTRY *nat;
6549 	UINT transaction_id;
6550 	void *query_data;
6551 	UINT query_data_size;
6552 	char hostname[256];
6553 	// Validate arguments
6554 	if (v == NULL || data == NULL || size == 0)
6555 	{
6556 		return false;
6557 	}
6558 
6559 	// Check the header size
6560 	if (size < sizeof(DNSV4_HEADER))
6561 	{
6562 		// Undersize
6563 		return false;
6564 	}
6565 
6566 	// DNS header acquisition
6567 	dns = (DNSV4_HEADER *)data;
6568 	transaction_id = Endian16(dns->TransactionId);
6569 	if ((dns->Flag1 & 78) != 0 || (dns->Flag1 & 0x80) != 0)
6570 	{
6571 		// Illegal opcode
6572 		return false;
6573 	}
6574 	if (Endian16(dns->NumQuery) != 1)
6575 	{
6576 		// Number of queries is invalid
6577 		return false;
6578 	}
6579 
6580 	query_data = ((UCHAR *)dns) + sizeof(DNSV4_HEADER);
6581 	query_data_size = size - sizeof(DNSV4_HEADER);
6582 
6583 	// Interpret the query
6584 	if (ParseDnsQuery(hostname, sizeof(hostname), query_data, query_data_size) == false)
6585 	{
6586 		// Interpretation fails
6587 		return false;
6588 	}
6589 
6590 	if (parsed_result != NULL)
6591 	{
6592 		// Only analyse without processing
6593 		Zero(parsed_result, sizeof(DNS_PARSED_PACKET));
6594 		StrCpy(parsed_result->Hostname, sizeof(parsed_result->Hostname), hostname);
6595 		parsed_result->TransactionId = transaction_id;
6596 
6597 		return true;
6598 	}
6599 
6600 	// Create a DNS entry
6601 	nat = CreateNatDns(v, src_ip, src_port, dest_ip, dest_port, transaction_id,
6602 	                   false, hostname);
6603 
6604 	if (nat == false)
6605 	{
6606 		return false;
6607 	}
6608 
6609 	return true;
6610 }
6611 
6612 // Send the NAT DNS response packet
SendNatDnsResponse(VH * v,NAT_ENTRY * n)6613 void SendNatDnsResponse(VH *v, NAT_ENTRY *n)
6614 {
6615 	BUF *b;
6616 	UINT dns_header_size;
6617 	DNSV4_HEADER *dns;
6618 	UINT src_ip;
6619 	// Validate arguments
6620 	if (n == NULL || v == NULL)
6621 	{
6622 		return;
6623 	}
6624 
6625 	// Generate the data
6626 	b = NewBuf();
6627 
6628 	// Add a Query
6629 	if (n->DnsGetIpFromHost == false)
6630 	{
6631 		BuildDnsQueryPacket(b, n->DnsTargetHostName, false);
6632 	}
6633 	else
6634 	{
6635 		BuildDnsQueryPacket(b, n->DnsTargetHostName, true);
6636 	}
6637 
6638 	// Add a Response
6639 	if (n->DnsOk)
6640 	{
6641 		if (n->DnsGetIpFromHost == false)
6642 		{
6643 			BuildDnsResponsePacketA(b, &n->DnsResponseIp);
6644 		}
6645 		else
6646 		{
6647 			BuildDnsResponsePacketPtr(b, n->DnsResponseHostName);
6648 		}
6649 	}
6650 
6651 	// Generate a DNS header
6652 	dns_header_size = sizeof(DNSV4_HEADER) + b->Size;
6653 
6654 	dns = ZeroMalloc(dns_header_size);
6655 	dns->TransactionId = Endian16((USHORT)n->DnsTransactionId);
6656 
6657 	// Generate a response flag
6658 	if (n->DnsOk)
6659 	{
6660 		dns->Flag1 = 0x85;
6661 		dns->Flag2 = 0x80;
6662 	}
6663 	else
6664 	{
6665 		dns->Flag1 = 0x85;
6666 		dns->Flag2 = 0x83;
6667 	}
6668 
6669 	dns->NumQuery = Endian16(1);
6670 	dns->AnswerRRs = Endian16(n->DnsOk != false ? 1 : 0);
6671 	dns->AuthorityRRs = 0;
6672 	dns->AdditionalRRs = 0;
6673 
6674 	// Settings, such as the source IP address
6675 	src_ip = n->DestIp;
6676 	if (src_ip == Endian32(SPECIAL_IPV4_ADDR_LLMNR_DEST) && n->DestPort == SPECIAL_UDP_PORT_LLMNR)
6677 	{
6678 		// Make a unicast response in the case of LLMNR packet
6679 		src_ip = v->HostIP;
6680 
6681 		dns->Flag1 = 0x84;
6682 		dns->Flag2 = 0x00;
6683 	}
6684 
6685 	// Copy data
6686 	Copy(((UCHAR *)dns) + sizeof(DNSV4_HEADER), b->Buf, b->Size);
6687 
6688 	// Send this packet
6689 	SendUdp(v, n->SrcIp, n->SrcPort, src_ip, n->DestPort, dns, dns_header_size);
6690 
6691 	// Release the memory
6692 	Free(dns);
6693 	FreeBuf(b);
6694 }
6695 
6696 // Generate a DNS response packet (host name)
BuildDnsResponsePacketPtr(BUF * b,char * hostname)6697 void BuildDnsResponsePacketPtr(BUF *b, char *hostname)
6698 {
6699 	USHORT magic;
6700 	USHORT type, clas;
6701 	UINT ttl;
6702 	USHORT len;
6703 	BUF *c;
6704 	// Validate arguments
6705 	if (b == NULL || hostname == NULL)
6706 	{
6707 		return;
6708 	}
6709 
6710 	magic = Endian16(0xc00c);
6711 	type = Endian16(0x000c);
6712 	clas = Endian16(0x0001);
6713 	ttl = Endian32(NAT_DNS_RESPONSE_TTL);
6714 
6715 	c = BuildDnsHostName(hostname);
6716 	if (c == NULL)
6717 	{
6718 		return;
6719 	}
6720 	len = Endian16((USHORT)c->Size);
6721 
6722 	WriteBuf(b, &magic, 2);
6723 	WriteBuf(b, &type, 2);
6724 	WriteBuf(b, &clas, 2);
6725 	WriteBuf(b, &ttl, 4);
6726 	WriteBuf(b, &len, 2);
6727 	WriteBuf(b, c->Buf, c->Size);
6728 	FreeBuf(c);
6729 }
6730 
6731 // Generate a DNS response packet (host IP address)
BuildDnsResponsePacketA(BUF * b,IP * ip)6732 void BuildDnsResponsePacketA(BUF *b, IP *ip)
6733 {
6734 	UINT ip_addr;
6735 	USHORT magic;
6736 	USHORT type, clas;
6737 	UINT ttl;
6738 	USHORT len;
6739 	// Validate arguments
6740 	if (b == NULL || ip == NULL)
6741 	{
6742 		return;
6743 	}
6744 
6745 	ip_addr = IPToUINT(ip);
6746 	magic = Endian16(0xc00c);
6747 	type = Endian16(0x0001);
6748 	clas = Endian16(0x0001);
6749 	ttl = Endian32(NAT_DNS_RESPONSE_TTL);
6750 	len = Endian16((USHORT)sizeof(ttl));
6751 
6752 	WriteBuf(b, &magic, sizeof(magic));
6753 	WriteBuf(b, &type, sizeof(type));
6754 	WriteBuf(b, &clas, sizeof(clas));
6755 	WriteBuf(b, &ttl, sizeof(ttl));
6756 	WriteBuf(b, &len, sizeof(len));
6757 	WriteBuf(b, &ip_addr, sizeof(ip_addr));
6758 }
6759 
6760 // Generate a DNS query data packet
BuildDnsQueryPacket(BUF * b,char * hostname,bool ptr)6761 void BuildDnsQueryPacket(BUF *b, char *hostname, bool ptr)
6762 {
6763 	USHORT val;
6764 	BUF *c;
6765 	// Validate arguments
6766 	if (b == NULL || hostname == NULL)
6767 	{
6768 		return;
6769 	}
6770 
6771 	// Convert the host name to a buffer
6772 	c = BuildDnsHostName(hostname);
6773 	if (c == NULL)
6774 	{
6775 		return;
6776 	}
6777 
6778 	WriteBuf(b, c->Buf, c->Size);
6779 	FreeBuf(c);
6780 
6781 	// Type and class
6782 	if (ptr == false)
6783 	{
6784 		val = Endian16(0x0001);
6785 	}
6786 	else
6787 	{
6788 		val = Endian16(0x000c);
6789 	}
6790 	WriteBuf(b, &val, 2);
6791 
6792 	val = Endian16(0x0001);
6793 	WriteBuf(b, &val, 2);
6794 }
6795 
6796 // Generate a DNS host name buffer
BuildDnsHostName(char * hostname)6797 BUF *BuildDnsHostName(char *hostname)
6798 {
6799 	UINT i;
6800 	UCHAR size;
6801 	TOKEN_LIST *token;
6802 	BUF *b;
6803 	// Validate arguments
6804 	if (hostname == NULL)
6805 	{
6806 		return NULL;
6807 	}
6808 
6809 	// Split the host name into tokens
6810 	token = ParseToken(hostname, ".");
6811 	if (token == NULL)
6812 	{
6813 		return NULL;
6814 	}
6815 
6816 	b = NewBuf();
6817 
6818 	// Add a host string
6819 	for (i = 0; i < token->NumTokens; i++)
6820 	{
6821 		size = (UCHAR)StrLen(token->Token[i]);
6822 		WriteBuf(b, &size, 1);
6823 		WriteBuf(b, token->Token[i], size);
6824 	}
6825 
6826 	// NULL character
6827 	size = 0;
6828 	WriteBuf(b, &size, 1);
6829 
6830 	SeekBuf(b, 0, 0);
6831 
6832 	FreeToken(token);
6833 
6834 	return b;
6835 }
6836 
6837 // Process the NAT DNS entry
PollingNatDns(VH * v,NAT_ENTRY * n)6838 void PollingNatDns(VH *v, NAT_ENTRY *n)
6839 {
6840 	// Validate arguments
6841 	if (v == NULL || n == NULL)
6842 	{
6843 		return;
6844 	}
6845 
6846 	if (n->DnsFinished)
6847 	{
6848 		if (n->DnsPollingFlag == false)
6849 		{
6850 			n->DnsPollingFlag = true;
6851 			// Process has been completed
6852 			SendNatDnsResponse(v, n);
6853 
6854 			// Terminating
6855 			n->DisconnectNow = true;
6856 		}
6857 	}
6858 }
6859 
6860 // Create a NAT DNS 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)6861 NAT_ENTRY *CreateNatDns(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port,
6862                         UINT transaction_id, bool dns_get_ip_from_host, char *dns_target_host_name)
6863 {
6864 	NAT_ENTRY *n;
6865 	HUB_OPTION *o;
6866 	// Validate arguments
6867 	if (v == NULL || dns_target_host_name == NULL)
6868 	{
6869 		return NULL;
6870 	}
6871 
6872 	if (CanCreateNewNatEntry(v) == false)
6873 	{
6874 		return NULL;
6875 	}
6876 
6877 	o = NatGetHubOption(v);
6878 	if (o != NULL && o->SecureNAT_MaxDnsSessionsPerIp != 0)
6879 	{
6880 		if (GetNumNatEntriesPerIp(v, src_ip, NAT_DNS, false) >= o->SecureNAT_MaxDnsSessionsPerIp)
6881 		{
6882 			NAT_ENTRY *oldest = GetOldestNatEntryOfIp(v, src_ip, NAT_DNS);
6883 
6884 			if (oldest != NULL)
6885 			{
6886 				DisconnectNatEntryNow(v, oldest);
6887 			}
6888 		}
6889 	}
6890 
6891 	n = ZeroMalloc(sizeof(NAT_ENTRY));
6892 	n->Id = Inc(v->Counter);
6893 	n->v = v;
6894 	n->lock = NewLock();
6895 	n->Protocol = NAT_DNS;
6896 	n->SrcIp = src_ip;
6897 	n->SrcPort = src_port;
6898 	n->DestIp = dest_ip;
6899 	n->DestPort = dest_port;
6900 	n->DnsTransactionId = transaction_id;
6901 	n->CreatedTime = n->LastCommTime = v->Now;
6902 	n->DisconnectNow = false;
6903 
6904 	n->DnsGetIpFromHost = false;
6905 	n->DnsTargetHostName = CopyStr(dns_target_host_name);
6906 
6907 	Add(v->NatTable, n);
6908 
6909 #if	1
6910 	{
6911 		IP ip1, ip2;
6912 		char s1[MAX_SIZE], s2[MAX_SIZE];
6913 		UINTToIP(&ip1, src_ip);
6914 		UINTToIP(&ip2, dest_ip);
6915 		IPToStr(s1, 0, &ip1);
6916 		IPToStr(s2, 0, &ip2);
6917 		Debug("NAT_ENTRY: CreateNatDns %s %u -> %s %u\n", s1, src_port, s2, dest_port);
6918 	}
6919 #endif
6920 
6921 
6922 	return n;
6923 }
6924 
6925 // Set the VGS host name
SetDnsProxyVgsHostname(char * hostname)6926 void SetDnsProxyVgsHostname(char *hostname)
6927 {
6928 	// Validate arguments
6929 	if (hostname == NULL)
6930 	{
6931 		return;
6932 	}
6933 
6934 	StrCpy(v_vgs_hostname, sizeof(v_vgs_hostname), hostname);
6935 }
6936 
6937 // Operate as a DNS proxy
DnsProxy(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size)6938 void DnsProxy(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size)
6939 {
6940 	// Validate arguments
6941 	if (v == NULL || data == NULL || size == 0)
6942 	{
6943 		return;
6944 	}
6945 
6946 	if (dest_port == SPECIAL_UDP_PORT_LLMNR)
6947 	{
6948 		// Process by analyzing the DNS query in the case of LLMNR
6949 		ParseDnsPacket(v, src_ip, src_port, dest_ip, dest_port, data, size);
6950 	}
6951 	else
6952 	{
6953 		// Forward the packet as it is in the case of a normal DNS packet
6954 		if (IsEmptyStr(v_vgs_hostname) == false)
6955 		{
6956 			// Response by proxy in the case of trying to get the IP of the VGS
6957 			DNS_PARSED_PACKET p;
6958 
6959 			Zero(&p, sizeof(p));
6960 			if (ParseDnsPacketEx(v, src_ip, src_port, dest_ip, dest_port, data, size, &p))
6961 			{
6962 				if (StrCmpi(p.Hostname, "254.254.211.10.in-addr.arpa") == 0)
6963 				{
6964 					NAT_ENTRY n;
6965 
6966 					Zero(&n, sizeof(n));
6967 					n.DnsTargetHostName = p.Hostname;
6968 					n.DnsGetIpFromHost = true;
6969 					n.DnsResponseHostName = v_vgs_hostname;
6970 					n.DnsTransactionId = p.TransactionId;
6971 					n.DnsOk = true;
6972 					n.DestIp = dest_ip;
6973 					n.SrcIp = src_ip;
6974 					n.DestPort = dest_port;
6975 					n.SrcPort = src_port;
6976 
6977 					SendNatDnsResponse(v, &n);
6978 					return;
6979 				}
6980 			}
6981 		}
6982 
6983 		UdpRecvForInternet(v, src_ip, src_port, dest_ip, dest_port, data, size, true);
6984 	}
6985 }
6986 
6987 // Process the LLMNR query
UdpRecvLlmnr(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size)6988 void UdpRecvLlmnr(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size)
6989 {
6990 	// Validate arguments
6991 	if (data == NULL || v == NULL)
6992 	{
6993 		return;
6994 	}
6995 
6996 	if (dest_port == SPECIAL_UDP_PORT_LLMNR)
6997 	{
6998 		// DNS proxy start
6999 		DnsProxy(v, src_ip, src_port, dest_ip, dest_port, data, size);
7000 	}
7001 }
7002 
7003 // Process the UDP packet to the virtual host
UdpRecvForMe(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size)7004 void UdpRecvForMe(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size)
7005 {
7006 	// Validate arguments
7007 	if (data == NULL || v == NULL)
7008 	{
7009 		return;
7010 	}
7011 
7012 	if (dest_port == NAT_DNS_PROXY_PORT)
7013 	{
7014 		// DNS proxy start
7015 		DnsProxy(v, src_ip, src_port, dest_ip, dest_port, data, size);
7016 	}
7017 }
7018 
7019 // Process the UDP broadcast packet
UdpRecvForBroadcast(VH * v,UINT src_ip,UINT src_port,UINT dest_ip,UINT dest_port,void * data,UINT size)7020 void UdpRecvForBroadcast(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size)
7021 {
7022 	// Validate arguments
7023 	if (data == NULL || v == NULL)
7024 	{
7025 		return;
7026 	}
7027 }
7028 
7029 // An UDP packet has been received
VirtualUdpReceived(VH * v,UINT src_ip,UINT dest_ip,void * data,UINT size,bool mac_broadcast,bool is_localmac,UINT max_l3_size)7030 void VirtualUdpReceived(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, bool mac_broadcast, bool is_localmac, UINT max_l3_size)
7031 {
7032 	UDP_HEADER *udp;
7033 	UINT packet_length;
7034 	void *buf;
7035 	UINT buf_size;
7036 	UINT src_port, dest_port;
7037 	// Validate arguments
7038 	if (v == NULL || data == NULL)
7039 	{
7040 		return;
7041 	}
7042 
7043 	// Check the header
7044 	udp = (UDP_HEADER *)data;
7045 	if (size < UDP_HEADER_SIZE)
7046 	{
7047 		return;
7048 	}
7049 	packet_length = Endian16(udp->PacketLength);
7050 	if (packet_length != size)
7051 	{
7052 		return;
7053 	}
7054 	buf = ((UCHAR *)data) + UDP_HEADER_SIZE;
7055 	buf_size = size - UDP_HEADER_SIZE;
7056 	src_port = Endian16(udp->SrcPort);
7057 	dest_port = Endian16(udp->DstPort);
7058 	// Check the port number
7059 	if (dest_port == 0)
7060 	{
7061 		// Port number is invalid
7062 		return;
7063 	}
7064 
7065 	// Determine whether it's broadcast packet or packet addressed to myself
7066 	if (dest_ip == v->HostIP)
7067 	{
7068 		// IP packet addressed to myself has arrived
7069 		UdpRecvForMe(v, src_ip, src_port, dest_ip, dest_port, buf, buf_size);
7070 	}
7071 	else if ((mac_broadcast || dest_ip == Endian32(0xE00000FC)) && dest_port == SPECIAL_UDP_PORT_LLMNR)
7072 	{
7073 		if (is_localmac == false)
7074 		{
7075 			// Packet addressed to 224.0.0.252 (LLMNR) arrives
7076 			UdpRecvLlmnr(v, src_ip, src_port, dest_ip, dest_port, buf, buf_size);
7077 		}
7078 	}
7079 	else if (mac_broadcast && (dest_port == SPECIAL_UDP_PORT_WSD || dest_port == SPECIAL_UDP_PORT_SSDP))
7080 	{
7081 		if (is_localmac == false)
7082 		{
7083 			// WS-Discovery packet arrives
7084 			UdpRecvForInternet(v, src_ip, src_port, 0xFFFFFFFF, dest_port, buf, buf_size, false);
7085 		}
7086 	}
7087 	else if (mac_broadcast && (dest_port == SPECIAL_UDP_PORT_NBTDGM || dest_port == SPECIAL_UDP_PORT_NBTNS))
7088 	{
7089 		if (is_localmac == false)
7090 		{
7091 			// NetBIOS Broadcast packet arrived
7092 			UdpRecvForNetBiosBroadcast(v, src_ip, src_port, dest_ip, dest_port, buf, buf_size, false, false);
7093 		}
7094 	}
7095 	else if (mac_broadcast || dest_ip == 0xffffffff || dest_ip == GetBroadcastAddress(v->HostIP, v->HostMask))
7096 	{
7097 		if (is_localmac == false)
7098 		{
7099 			// Broadcast packet arrived
7100 			UdpRecvForBroadcast(v, src_ip, src_port, dest_ip, dest_port, buf, buf_size);
7101 		}
7102 	}
7103 	else if (IsInNetwork(dest_ip, v->HostIP, v->HostMask) == false)
7104 	{
7105 		// Packets to other than local address (that is on the Internet) has been received
7106 		if (NnIsActive(v) == false)
7107 		{
7108 			if (v->HubOption != NULL && v->HubOption->DisableUserModeSecureNAT)
7109 			{
7110 				// User-mode NAT is disabled
7111 				return;
7112 			}
7113 
7114 			// User-mode NAT
7115 			UdpRecvForInternet(v, src_ip, src_port, dest_ip, dest_port, buf, buf_size, false);
7116 		}
7117 		else
7118 		{
7119 			// Kernel-mode NAT
7120 			NnUdpRecvForInternet(v, src_ip, src_port, dest_ip, dest_port, buf, buf_size, max_l3_size);
7121 		}
7122 	}
7123 	else
7124 	{
7125 		// Local address has arrived. Ignore it
7126 	}
7127 }
7128 
7129 // Determine the network address of the subnet to which the specified IP address belongs
GetNetworkAddress(UINT addr,UINT mask)7130 UINT GetNetworkAddress(UINT addr, UINT mask)
7131 {
7132 	return (addr & mask);
7133 }
7134 
7135 // Determine the broadcast address of the subnet to which the specified IP address belongs
GetBroadcastAddress(UINT addr,UINT mask)7136 UINT GetBroadcastAddress(UINT addr, UINT mask)
7137 {
7138 	return ((addr & mask) | (~mask));
7139 }
GetBroadcastAddress4(IP * dst,IP * addr,IP * mask)7140 void GetBroadcastAddress4(IP *dst, IP *addr, IP *mask)
7141 {
7142 	// Validate arguments
7143 	if (dst == NULL || IsIP4(addr) == false || IsIP4(mask) == false)
7144 	{
7145 		Zero(dst, sizeof(IP));
7146 		return;
7147 	}
7148 
7149 	UINTToIP(dst, GetBroadcastAddress(IPToUINT(addr), IPToUINT(mask)));
7150 }
7151 
7152 // Determine whether the specified IP address belongs to the sub-network that is
7153 // represented by a another specified network address and a subnet mask
IsInNetwork(UINT uni_addr,UINT network_addr,UINT mask)7154 bool IsInNetwork(UINT uni_addr, UINT network_addr, UINT mask)
7155 {
7156 	if (GetNetworkAddress(uni_addr, mask) == GetNetworkAddress(network_addr, mask))
7157 	{
7158 		return true;
7159 	}
7160 	return false;
7161 }
7162 
7163 // Send an UDP packet
SendUdp(VH * v,UINT dest_ip,UINT dest_port,UINT src_ip,UINT src_port,void * data,UINT size)7164 void SendUdp(VH *v, UINT dest_ip, UINT dest_port, UINT src_ip, UINT src_port, void *data, UINT size)
7165 {
7166 	UDPV4_PSEUDO_HEADER *vh;
7167 	UDP_HEADER *udp;
7168 	UINT udp_packet_length = UDP_HEADER_SIZE + size;
7169 	USHORT checksum;
7170 	// Validate arguments
7171 	if (v == NULL || data == NULL)
7172 	{
7173 		return;
7174 	}
7175 	if (udp_packet_length > 65536)
7176 	{
7177 		return;
7178 	}
7179 
7180 	// Generate a virtual header
7181 	vh = Malloc(sizeof(UDPV4_PSEUDO_HEADER) + size);
7182 	udp = (UDP_HEADER *)(((UCHAR *)vh) + 12);
7183 
7184 	vh->SrcIP = src_ip;
7185 	vh->DstIP = dest_ip;
7186 	vh->Reserved = 0;
7187 	vh->Protocol = IP_PROTO_UDP;
7188 	vh->PacketLength1 = Endian16((USHORT)udp_packet_length);
7189 	udp->SrcPort = Endian16((USHORT)src_port);
7190 	udp->DstPort = Endian16((USHORT)dest_port);
7191 	udp->PacketLength = Endian16((USHORT)udp_packet_length);
7192 	udp->Checksum = 0;
7193 
7194 	// Copy data
7195 	Copy(((UCHAR *)udp) + UDP_HEADER_SIZE, data, size);
7196 
7197 	// Calculate the checksum
7198 	checksum = IpChecksum(vh, udp_packet_length + 12);
7199 	if (checksum == 0x0000)
7200 	{
7201 		checksum = 0xffff;
7202 	}
7203 	udp->Checksum = checksum;
7204 
7205 	// Send a packet
7206 	SendIp(v, dest_ip, src_ip, IP_PROTO_UDP, udp, udp_packet_length);
7207 
7208 	// Release the memory
7209 	Free(vh);
7210 }
7211 
7212 // Poll the IP combining object
PollingIpCombine(VH * v)7213 void PollingIpCombine(VH *v)
7214 {
7215 	LIST *o;
7216 	UINT i;
7217 	// Validate arguments
7218 	if (v == NULL)
7219 	{
7220 		return;
7221 	}
7222 
7223 	// Discard the old combining object
7224 	o = NULL;
7225 	for (i = 0; i < LIST_NUM(v->IpCombine); i++)
7226 	{
7227 		IP_COMBINE *c = LIST_DATA(v->IpCombine, i);
7228 
7229 		if (c->Expire < v->Now)
7230 		{
7231 			if (o == NULL)
7232 			{
7233 				o = NewListFast(NULL);
7234 			}
7235 			Add(o, c);
7236 		}
7237 	}
7238 
7239 	if (o != NULL)
7240 	{
7241 		for (i = 0; i < LIST_NUM(o); i++)
7242 		{
7243 			IP_COMBINE *c = LIST_DATA(o, i);
7244 
7245 			// Remove from the list
7246 			Delete(v->IpCombine, c);
7247 
7248 			// Release the memory
7249 			FreeIpCombine(v, c);
7250 		}
7251 		ReleaseList(o);
7252 	}
7253 }
7254 
7255 // Send an ICMP packet
VirtualIcmpSend(VH * v,UINT src_ip,UINT dst_ip,void * data,UINT size)7256 void VirtualIcmpSend(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size)
7257 {
7258 	ICMP_HEADER *icmp;
7259 	void *data_buf;
7260 	// Validate arguments
7261 	if (v == NULL || data == NULL)
7262 	{
7263 		return;
7264 	}
7265 
7266 	// Build the header
7267 	icmp = ZeroMalloc(sizeof(ICMP_HEADER) + size);
7268 	// Data copy
7269 	data_buf = ((UCHAR *)icmp) + sizeof(ICMP_HEADER);
7270 	Copy(data_buf, data, size);
7271 	// Other
7272 	icmp->Checksum = 0;
7273 	icmp->Code = 0;
7274 	icmp->Type = ICMP_TYPE_ECHO_RESPONSE;
7275 	// Checksum
7276 	icmp->Checksum = IpChecksum(icmp, sizeof(ICMP_HEADER) + size);
7277 
7278 	// IP packet transmission
7279 	SendIp(v, dst_ip, src_ip, IP_PROTO_ICMPV4, icmp, sizeof(ICMP_HEADER) + size);
7280 
7281 	// Release the memory
7282 	Free(icmp);
7283 }
7284 
7285 // Send the ICMP Echo Response packet
VirtualIcmpEchoSendResponse(VH * v,UINT src_ip,UINT dst_ip,USHORT id,USHORT seq_no,void * data,UINT size)7286 void VirtualIcmpEchoSendResponse(VH *v, UINT src_ip, UINT dst_ip, USHORT id, USHORT seq_no, void *data, UINT size)
7287 {
7288 	ICMP_ECHO *e;
7289 	// Validate arguments
7290 	if (v == NULL || data == NULL)
7291 	{
7292 		return;
7293 	}
7294 
7295 	// Build the header
7296 	e = ZeroMalloc(sizeof(ICMP_ECHO) + size);
7297 	e->Identifier = Endian16(id);
7298 	e->SeqNo = Endian16(seq_no);
7299 
7300 	// Data copy
7301 	Copy(((UCHAR *)e) + sizeof(ICMP_ECHO), data, size);
7302 
7303 	// Send an ICMP
7304 	VirtualIcmpSend(v, src_ip, dst_ip, e, sizeof(ICMP_ECHO) + size);
7305 
7306 	// Release the memory
7307 	Free(e);
7308 }
7309 
7310 // Treat the ICMP Echo Request packet with a Raw Socket
VirtualIcmpEchoRequestReceivedRaw(VH * v,UINT src_ip,UINT dst_ip,void * data,UINT size,UCHAR ttl,void * icmp_data,UINT icmp_size,UCHAR * ip_header,UINT ip_header_size)7311 void VirtualIcmpEchoRequestReceivedRaw(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size)
7312 {
7313 	ICMP_ECHO *echo;
7314 	UINT data_size;
7315 	void *data_buf;
7316 	USHORT id, seq_no;
7317 	void *buf;
7318 	BLOCK *block;
7319 	// Validate arguments
7320 	if (v == NULL || data == NULL || icmp_data == NULL || ip_header == NULL)
7321 	{
7322 		return;
7323 	}
7324 	if (ttl == 0)
7325 	{
7326 		ttl = 1;
7327 	}
7328 
7329 	echo = (ICMP_ECHO *)data;
7330 
7331 	// Echo size check
7332 	if (size < sizeof(ICMP_ECHO))
7333 	{
7334 		// Insufficient data
7335 		return;
7336 	}
7337 
7338 	id = Endian16(echo->Identifier);
7339 	seq_no = Endian16(echo->SeqNo);
7340 
7341 	// Data size
7342 	data_size = size - sizeof(ICMP_ECHO);
7343 
7344 	// Data body
7345 	data_buf = ((UCHAR *)data) + sizeof(ICMP_ECHO);
7346 
7347 	if (dst_ip == v->HostIP)
7348 	{
7349 		// Respond because it is addressed to me
7350 		VirtualIcmpEchoSendResponse(v, v->HostIP, src_ip, id, seq_no, data_buf, data_size);
7351 	}
7352 	else if (IsInNetwork(dst_ip, v->HostIP, v->HostMask) == false)
7353 	{
7354 		NAT_ENTRY *n = NULL, t;
7355 		// Process by creating a NAT entry because it is addressed to the Internet
7356 
7357 		if (ttl <= 1)
7358 		{
7359 			// Reply the Time Exceeded immediately for the packet whose TTL is 1
7360 			UINT reply_size = sizeof(ICMP_HEADER) + 4 + ip_header_size + 8;
7361 			UCHAR *reply_data = ZeroMalloc(reply_size);
7362 			ICMP_HEADER *icmp = (ICMP_HEADER *)reply_data;
7363 			icmp->Type = ICMP_TYPE_TIME_EXCEEDED;
7364 			icmp->Code = ICMP_CODE_TTL_EXCEEDED_IN_TRANSIT;
7365 			Copy(reply_data + sizeof(ICMP_HEADER) + 4, ip_header, ip_header_size);
7366 			Copy(reply_data + sizeof(ICMP_HEADER) + 4 + ip_header_size, icmp_data, MIN(icmp_size, 8));
7367 
7368 			icmp->Checksum = IpChecksum(icmp, reply_size);
7369 
7370 			SendIp(v, src_ip, v->HostIP, IP_PROTO_ICMPV4, reply_data, reply_size);
7371 
7372 			Free(reply_data);
7373 		}
7374 		else
7375 		{
7376 			SetNat(&t, NAT_ICMP, src_ip, id, dst_ip, id, 0, 0);
7377 
7378 			if (v->IcmpRawSocketOk)
7379 			{
7380 				// Examine whether a NAT entry for this packet has already been created
7381 				n = SearchNat(v, &t);
7382 			}
7383 
7384 			if (n == NULL)
7385 			{
7386 				// Create a NAT entry because it is the first packet
7387 				n = CreateNatIcmp(v, src_ip, id, dst_ip, id, (UCHAR *)ip_header, ip_header_size + 8);
7388 
7389 				if (n == NULL)
7390 				{
7391 					// Entry creation failed
7392 					return;
7393 				}
7394 			}
7395 
7396 			// Set the event by inserting the packet into the queue
7397 			buf = Malloc(icmp_size);
7398 			Copy(buf, icmp_data, icmp_size);
7399 			block = NewBlock(buf, icmp_size, 0);
7400 			block->Ttl = MAKESURE(ttl - 1, 1, 255);
7401 			InsertQueue(n->UdpSendQueue, block);
7402 
7403 			SetSockEvent(v->SockEvent);
7404 		}
7405 	}
7406 }
7407 
7408 // Receive an ICMP Echo Request packet
VirtualIcmpEchoRequestReceived(VH * v,UINT src_ip,UINT dst_ip,void * data,UINT size,UCHAR ttl,void * icmp_data,UINT icmp_size,UCHAR * ip_header,UINT ip_header_size,UINT max_l3_size)7409 void VirtualIcmpEchoRequestReceived(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size)
7410 {
7411 	ICMP_ECHO *echo;
7412 	UINT data_size;
7413 	void *data_buf;
7414 	USHORT id, seq_no;
7415 	// Validate arguments
7416 	if (v == NULL || data == NULL || icmp_data == NULL)
7417 	{
7418 		return;
7419 	}
7420 
7421 	//Debug("ICMP: %u\n", size);
7422 
7423 	if (NnIsActive(v))
7424 	{
7425 		// Process by the Native NAT
7426 		NnIcmpEchoRecvForInternet(v, src_ip, dst_ip, data, size, ttl, icmp_data, icmp_size,
7427 		                          ip_header, ip_header_size, max_l3_size);
7428 		return;
7429 	}
7430 
7431 	if (v->HubOption != NULL && v->HubOption->DisableUserModeSecureNAT)
7432 	{
7433 		// User-mode NAT is disabled
7434 		return;
7435 	}
7436 
7437 	if (v->IcmpRawSocketOk || v->IcmpApiOk)
7438 	{
7439 		// Process in the Raw Socket
7440 		VirtualIcmpEchoRequestReceivedRaw(v, src_ip, dst_ip, data, size, ttl, icmp_data, icmp_size,
7441 		                                  ip_header, ip_header_size);
7442 		return;
7443 	}
7444 
7445 	// Returns the fake ICMP forcibly if any of Native NAT or Raw Socket can not be used
7446 
7447 	echo = (ICMP_ECHO *)data;
7448 
7449 	// Echo size check
7450 	if (size < sizeof(ICMP_ECHO))
7451 	{
7452 		// Insufficient data
7453 		return;
7454 	}
7455 
7456 	id = Endian16(echo->Identifier);
7457 	seq_no = Endian16(echo->SeqNo);
7458 
7459 	// Data size
7460 	data_size = size - sizeof(ICMP_ECHO);
7461 
7462 	// Data body
7463 	data_buf = ((UCHAR *)data) + sizeof(ICMP_ECHO);
7464 
7465 	// Return the ICMP Echo Response
7466 	VirtualIcmpEchoSendResponse(v, dst_ip, src_ip, id, seq_no, data_buf, data_size);
7467 }
7468 
7469 // An ICMP packet has been received
VirtualIcmpReceived(VH * v,UINT src_ip,UINT dst_ip,void * data,UINT size,UCHAR ttl,UCHAR * ip_header,UINT ip_header_size,UINT max_l3_size)7470 void VirtualIcmpReceived(VH *v, UINT src_ip, UINT dst_ip, void *data, UINT size, UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size)
7471 {
7472 	ICMP_HEADER *icmp;
7473 	UINT msg_size;
7474 	USHORT checksum_calc, checksum_original;
7475 	// Validate arguments
7476 	if (v == NULL || data == NULL)
7477 	{
7478 		return;
7479 	}
7480 
7481 	// Size check
7482 	if (size < sizeof(ICMP_HEADER))
7483 	{
7484 		return;
7485 	}
7486 
7487 	// ICMP header
7488 	icmp = (ICMP_HEADER *)data;
7489 
7490 	// Get the ICMP message size
7491 	msg_size = size - sizeof(ICMP_HEADER);
7492 
7493 	// Check the checksum of the ICMP header
7494 	checksum_original = icmp->Checksum;
7495 	icmp->Checksum = 0;
7496 	checksum_calc = IpChecksum(data, size);
7497 	icmp->Checksum = checksum_original;
7498 
7499 	if (checksum_calc != checksum_original)
7500 	{
7501 		// Checksum is invalid
7502 		Debug("ICMP CheckSum Failed.\n");
7503 		return;
7504 	}
7505 
7506 	// Identified by the opcode
7507 	switch (icmp->Type)
7508 	{
7509 	case ICMP_TYPE_ECHO_REQUEST:	// ICMP Echo request
7510 		VirtualIcmpEchoRequestReceived(v, src_ip, dst_ip, ((UCHAR *)data) + sizeof(ICMP_HEADER), msg_size, ttl,
7511 		                               icmp, size, ip_header, ip_header_size, max_l3_size);
7512 		break;
7513 
7514 	case ICMP_TYPE_ECHO_RESPONSE:	// ICMP Echo response
7515 		// Do Nothing
7516 		break;
7517 	}
7518 }
7519 
7520 // Received an IP packet
IpReceived(VH * v,UINT src_ip,UINT dest_ip,UINT protocol,void * data,UINT size,bool mac_broadcast,UCHAR ttl,UCHAR * ip_header,UINT ip_header_size,bool is_local_mac,UINT max_l3_size)7521 void IpReceived(VH *v, UINT src_ip, UINT dest_ip, UINT protocol, void *data, UINT size, bool mac_broadcast, UCHAR ttl, UCHAR *ip_header, UINT ip_header_size, bool is_local_mac, UINT max_l3_size)
7522 {
7523 	// Validate arguments
7524 	if (v == NULL || data == NULL)
7525 	{
7526 		return;
7527 	}
7528 
7529 	// Deliver the data to the supported high-level protocol
7530 	switch (protocol)
7531 	{
7532 	case IP_PROTO_ICMPV4:	// ICMPv4
7533 		if (mac_broadcast == false)
7534 		{
7535 			VirtualIcmpReceived(v, src_ip, dest_ip, data, size, ttl, ip_header, ip_header_size, max_l3_size);
7536 		}
7537 		break;
7538 
7539 	case IP_PROTO_TCP:		// TCP
7540 		if (mac_broadcast == false)
7541 		{
7542 			VirtualTcpReceived(v, src_ip, dest_ip, data, size, max_l3_size);
7543 		}
7544 		break;
7545 
7546 	case IP_PROTO_UDP:		// UDP
7547 		VirtualUdpReceived(v, src_ip, dest_ip, data, size, mac_broadcast, is_local_mac, max_l3_size);
7548 		break;
7549 	}
7550 }
7551 
7552 // Combine the IP packet received to the IP combining object
CombineIp(VH * v,IP_COMBINE * c,UINT offset,void * data,UINT size,bool last_packet,UCHAR * head_ip_header_data,UINT head_ip_header_size)7553 void CombineIp(VH *v, IP_COMBINE *c, UINT offset, void *data, UINT size, bool last_packet, UCHAR *head_ip_header_data, UINT head_ip_header_size)
7554 {
7555 	UINT i;
7556 	IP_PART *p;
7557 	UINT need_size;
7558 	UINT data_size_delta;
7559 	// Validate arguments
7560 	if (c == NULL || data == NULL)
7561 	{
7562 		return;
7563 	}
7564 
7565 	// Check the size and offset
7566 	if ((offset + size) > 65535)
7567 	{
7568 		// Do not process packet larger than 64Kbytes
7569 		return;
7570 	}
7571 
7572 	if (last_packet == false && c->Size != 0)
7573 	{
7574 		if ((offset + size) > c->Size)
7575 		{
7576 			// Do not process the packet larger than the packet size
7577 			return;
7578 		}
7579 	}
7580 
7581 	if (head_ip_header_data != NULL && head_ip_header_size >= sizeof(IPV4_HEADER))
7582 	{
7583 		if (c->HeadIpHeaderData == NULL)
7584 		{
7585 			c->HeadIpHeaderData = Clone(head_ip_header_data, head_ip_header_size);
7586 			c->HeadIpHeaderDataSize = head_ip_header_size;
7587 		}
7588 	}
7589 
7590 	need_size = offset + size;
7591 	data_size_delta = c->DataReserved;
7592 	// Ensure sufficient if the buffer is insufficient
7593 	while (c->DataReserved < need_size)
7594 	{
7595 		c->DataReserved = c->DataReserved * 4;
7596 		c->Data = ReAlloc(c->Data, c->DataReserved);
7597 	}
7598 	data_size_delta = c->DataReserved - data_size_delta;
7599 	v->CurrentIpQuota += data_size_delta;
7600 
7601 	// Overwrite the data into the buffer
7602 	Copy(((UCHAR *)c->Data) + offset, data, size);
7603 
7604 	if (last_packet)
7605 	{
7606 		// If No More Fragment packet arrives, the size of this datagram is finalized
7607 		c->Size = offset + size;
7608 	}
7609 
7610 	// Check the overlap between the region which is represented by the offset and size of the
7611 	// existing received list and the region which is represented by the offset and size
7612 	for (i = 0; i < LIST_NUM(c->IpParts); i++)
7613 	{
7614 		UINT moving_size;
7615 		IP_PART *p = LIST_DATA(c->IpParts, i);
7616 
7617 		// Check the overlapping between the existing area and head area
7618 		if ((p->Offset <= offset) && ((p->Offset + p->Size) > offset))
7619 		{
7620 			// Compress behind the offset of this packet since a duplication is
7621 			// found in the first part with the existing packet and this packet
7622 
7623 			if ((offset + size) <= (p->Offset + p->Size))
7624 			{
7625 				// This packet is buried in the existing packet
7626 				size = 0;
7627 			}
7628 			else
7629 			{
7630 				// Retral region is not overlapped
7631 				moving_size = p->Offset + p->Size - offset;
7632 				offset += moving_size;
7633 				size -= moving_size;
7634 			}
7635 		}
7636 		if ((p->Offset < (offset + size)) && ((p->Offset + p->Size) >= (offset + size)))
7637 		{
7638 			// Compress the size of this packet forward because a duplication is
7639 			// found between the posterior portion the existing packet and this packet
7640 
7641 			moving_size = p->Offset + p->Size - offset - size;
7642 			size -= moving_size;
7643 		}
7644 
7645 		if ((p->Offset >= offset) && ((p->Offset + p->Size) <= (offset + size)))
7646 		{
7647 			// This packet was overwritten to completely cover an existing packet
7648 			p->Size = 0;
7649 		}
7650 	}
7651 
7652 	if (size != 0)
7653 	{
7654 		// Register this packet
7655 		p = ZeroMalloc(sizeof(IP_PART));
7656 
7657 		p->Offset = offset;
7658 		p->Size = size;
7659 
7660 		Add(c->IpParts, p);
7661 	}
7662 
7663 	if (c->Size != 0)
7664 	{
7665 		// Get the total size of the data portion list already received
7666 		UINT total_size = 0;
7667 		UINT i;
7668 
7669 		for (i = 0; i < LIST_NUM(c->IpParts); i++)
7670 		{
7671 			IP_PART *p = LIST_DATA(c->IpParts, i);
7672 
7673 			total_size += p->Size;
7674 		}
7675 
7676 		if (total_size == c->Size)
7677 		{
7678 			// Received all of the IP packet
7679 			IpReceived(v, c->SrcIP, c->DestIP, c->Protocol, c->Data, c->Size, c->MacBroadcast, c->Ttl,
7680 			           c->HeadIpHeaderData, c->HeadIpHeaderDataSize, c->SrcIsLocalMacAddr, c->MaxL3Size);
7681 
7682 			// Release the combining object
7683 			FreeIpCombine(v, c);
7684 
7685 			// Remove from the combining object list
7686 			Delete(v->IpCombine, c);
7687 		}
7688 	}
7689 }
7690 
7691 // Release the IP combining object
FreeIpCombine(VH * v,IP_COMBINE * c)7692 void FreeIpCombine(VH *v, IP_COMBINE *c)
7693 {
7694 	UINT i;
7695 	// Validate arguments
7696 	if (c == NULL)
7697 	{
7698 		return;
7699 	}
7700 
7701 	// Release the data
7702 	v->CurrentIpQuota -= c->DataReserved;
7703 	Free(c->Data);
7704 
7705 	// Release the partial list
7706 	for (i = 0; i < LIST_NUM(c->IpParts); i++)
7707 	{
7708 		IP_PART *p = LIST_DATA(c->IpParts, i);
7709 
7710 		Free(p);
7711 	}
7712 
7713 	Free(c->HeadIpHeaderData);
7714 
7715 	ReleaseList(c->IpParts);
7716 	Free(c);
7717 }
7718 
7719 // Search the IP combining list
SearchIpCombine(VH * v,UINT src_ip,UINT dest_ip,USHORT id,UCHAR protocol)7720 IP_COMBINE *SearchIpCombine(VH *v, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol)
7721 {
7722 	IP_COMBINE *c, t;
7723 	// Validate arguments
7724 	if (v == NULL)
7725 	{
7726 		return NULL;
7727 	}
7728 
7729 	t.DestIP = dest_ip;
7730 	t.SrcIP = src_ip;
7731 	t.Id = id;
7732 	t.Protocol = protocol;
7733 
7734 	c = Search(v->IpCombine, &t);
7735 
7736 	return c;
7737 }
7738 
7739 // Insert by creating a new object to the IP combining list
InsertIpCombine(VH * v,UINT src_ip,UINT dest_ip,USHORT id,UCHAR protocol,bool mac_broadcast,UCHAR ttl,bool src_is_localmac)7740 IP_COMBINE *InsertIpCombine(VH *v, UINT src_ip, UINT dest_ip, USHORT id, UCHAR protocol, bool mac_broadcast, UCHAR ttl, bool src_is_localmac)
7741 {
7742 	IP_COMBINE *c;
7743 	// Validate arguments
7744 	if (v == NULL)
7745 	{
7746 		return NULL;
7747 	}
7748 
7749 	// Examine the quota
7750 	if ((v->CurrentIpQuota + IP_COMBINE_INITIAL_BUF_SIZE) > IP_COMBINE_WAIT_QUEUE_SIZE_QUOTA)
7751 	{
7752 		// IP packet can not be stored any more
7753 		return NULL;
7754 	}
7755 
7756 	c = ZeroMalloc(sizeof(IP_COMBINE));
7757 	c->SrcIsLocalMacAddr = src_is_localmac;
7758 	c->DestIP = dest_ip;
7759 	c->SrcIP = src_ip;
7760 	c->Id = id;
7761 	c->Expire = v->Now + (UINT64)IP_COMBINE_TIMEOUT;
7762 	c->Size = 0;
7763 	c->IpParts = NewList(NULL);
7764 	c->Protocol = protocol;
7765 	c->MacBroadcast = mac_broadcast;
7766 	c->Ttl = ttl;
7767 
7768 	// Secure the memory
7769 	c->DataReserved = IP_COMBINE_INITIAL_BUF_SIZE;
7770 	c->Data = Malloc(c->DataReserved);
7771 	v->CurrentIpQuota += c->DataReserved;
7772 
7773 	Insert(v->IpCombine, c);
7774 
7775 	return c;
7776 }
7777 
7778 // Initialize the IP combining list
InitIpCombineList(VH * v)7779 void InitIpCombineList(VH *v)
7780 {
7781 	// Validate arguments
7782 	if (v == NULL)
7783 	{
7784 		return;
7785 	}
7786 
7787 	v->IpCombine = NewList(CompareIpCombine);
7788 }
7789 
7790 // Release the IP combining list
FreeIpCombineList(VH * v)7791 void FreeIpCombineList(VH *v)
7792 {
7793 	UINT i;
7794 	// Validate arguments
7795 	if (v == NULL)
7796 	{
7797 		return;
7798 	}
7799 
7800 	for (i = 0; i < LIST_NUM(v->IpCombine); i++)
7801 	{
7802 		IP_COMBINE *c = LIST_DATA(v->IpCombine, i);
7803 
7804 		FreeIpCombine(v, c);
7805 	}
7806 
7807 	ReleaseList(v->IpCombine);
7808 }
7809 
7810 // Comparison of IP combining list entry
CompareIpCombine(void * p1,void * p2)7811 int CompareIpCombine(void *p1, void *p2)
7812 {
7813 	IP_COMBINE *c1, *c2;
7814 	if (p1 == NULL || p2 == NULL)
7815 	{
7816 		return 0;
7817 	}
7818 	c1 = *(IP_COMBINE **)p1;
7819 	c2 = *(IP_COMBINE **)p2;
7820 	if (c1 == NULL || c2 == NULL)
7821 	{
7822 		return 0;
7823 	}
7824 	if (c1->Id > c2->Id)
7825 	{
7826 		return 1;
7827 	}
7828 	else if (c1->Id < c2->Id)
7829 	{
7830 		return -1;
7831 	}
7832 	else if (c1->DestIP > c2->DestIP)
7833 	{
7834 		return 1;
7835 	}
7836 	else if (c1->DestIP < c2->DestIP)
7837 	{
7838 		return -1;
7839 	}
7840 	else if (c1->SrcIP > c2->SrcIP)
7841 	{
7842 		return 1;
7843 	}
7844 	else if (c1->SrcIP < c2->SrcIP)
7845 	{
7846 		return -1;
7847 	}
7848 	else if (c1->Protocol > c2->Protocol)
7849 	{
7850 		return 1;
7851 	}
7852 	else if (c1->Protocol < c2->Protocol)
7853 	{
7854 		return -1;
7855 	}
7856 	return 0;
7857 }
7858 
7859 // Received an IP packet
VirtualIpReceived(VH * v,PKT * packet)7860 void VirtualIpReceived(VH *v, PKT *packet)
7861 {
7862 	IPV4_HEADER *ip;
7863 	void *data;
7864 	UINT data_size_recved;
7865 	UINT size;
7866 	UINT ipv4_header_size;
7867 	bool last_packet;
7868 	UCHAR *head_ip_header_data = NULL;
7869 	UINT head_ip_header_size = 0;
7870 	bool is_local_mac = false;
7871 	UINT ip_l3_size;
7872 	// Validate arguments
7873 	if (v == NULL || packet == NULL)
7874 	{
7875 		return;
7876 	}
7877 
7878 	ip = packet->L3.IPv4Header;
7879 
7880 	if (packet->BroadcastPacket)
7881 	{
7882 		is_local_mac = IsMacAddressLocalFast(packet->MacAddressSrc);
7883 	}
7884 
7885 	// Get the size of the IPv4 header
7886 	ipv4_header_size = IPV4_GET_HEADER_LEN(packet->L3.IPv4Header) * 4;
7887 	head_ip_header_size = ipv4_header_size;
7888 
7889 	// Calculate the checksum of the IPv4 header
7890 	if (IpCheckChecksum(ip) == false)
7891 	{
7892 		return;
7893 	}
7894 
7895 	// Get a pointer to the data
7896 	data = ((UCHAR *)packet->L3.PointerL3) + ipv4_header_size;
7897 
7898 	// Register to the ARP table
7899 	ArpIpWasKnown(v, packet->L3.IPv4Header->SrcIP, packet->MacAddressSrc);
7900 
7901 	// Get the data size
7902 	size = ip_l3_size = Endian16(ip->TotalLength);
7903 	if (size <= ipv4_header_size)
7904 	{
7905 		// There is no data
7906 		return;
7907 	}
7908 	size -= ipv4_header_size;
7909 
7910 	// Get the size of data actually received
7911 	data_size_recved = packet->PacketSize - (ipv4_header_size + MAC_HEADER_SIZE);
7912 	if (data_size_recved < size)
7913 	{
7914 		// Data insufficient (It may be missing on the way)
7915 		return;
7916 	}
7917 
7918 	if (IPV4_GET_OFFSET(ip) == 0 && (IPV4_GET_FLAGS(ip) & 0x01) == 0)
7919 	{
7920 		// Because this packet has not been fragmented, it can be delivered to the upper layer immediately
7921 		head_ip_header_data = (UCHAR *)packet->L3.IPv4Header;
7922 		IpReceived(v, ip->SrcIP, ip->DstIP, ip->Protocol, data, size, packet->BroadcastPacket, ip->TimeToLive,
7923 		           head_ip_header_data, head_ip_header_size, is_local_mac, ip_l3_size);
7924 	}
7925 	else
7926 	{
7927 		// This packet is necessary to combine because it is fragmented
7928 		UINT offset = IPV4_GET_OFFSET(ip) * 8;
7929 		IP_COMBINE *c = SearchIpCombine(v, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol);
7930 
7931 		if (offset == 0)
7932 		{
7933 			head_ip_header_data = (UCHAR *)packet->L3.IPv4Header;
7934 		}
7935 
7936 		last_packet = ((IPV4_GET_FLAGS(ip) & 0x01) == 0 ? true : false);
7937 
7938 		if (c != NULL)
7939 		{
7940 			// It is the second or subsequent packet
7941 			c->MaxL3Size = MAX(c->MaxL3Size, ip_l3_size);
7942 			CombineIp(v, c, offset, data, size, last_packet, head_ip_header_data, head_ip_header_size);
7943 		}
7944 		else
7945 		{
7946 			// Create a combining object because it is the first packet
7947 			c = InsertIpCombine(
7948 			        v, ip->SrcIP, ip->DstIP, Endian16(ip->Identification), ip->Protocol, packet->BroadcastPacket,
7949 			        ip->TimeToLive, is_local_mac);
7950 			if (c != NULL)
7951 			{
7952 				c->MaxL3Size = ip_l3_size;
7953 
7954 				CombineIp(v, c, offset, data, size, last_packet, head_ip_header_data, head_ip_header_size);
7955 			}
7956 		}
7957 	}
7958 }
7959 
7960 // Send the waiting IP packets from the specified IP address
SendWaitingIp(VH * v,UCHAR * mac,UINT dest_ip)7961 void SendWaitingIp(VH *v, UCHAR *mac, UINT dest_ip)
7962 {
7963 	UINT i;
7964 	LIST *o = NULL;
7965 	// Validate arguments
7966 	if (v == NULL || mac == NULL)
7967 	{
7968 		return;
7969 	}
7970 
7971 	// Get a target list
7972 	for (i = 0; i < LIST_NUM(v->IpWaitTable); i++)
7973 	{
7974 		IP_WAIT *w = LIST_DATA(v->IpWaitTable, i);
7975 
7976 		if (w->DestIP == dest_ip)
7977 		{
7978 			if (o == NULL)
7979 			{
7980 				o = NewListFast(NULL);
7981 			}
7982 			Add(o, w);
7983 		}
7984 	}
7985 
7986 	// Send the target packets at once
7987 	if (o != NULL)
7988 	{
7989 		for (i = 0; i < LIST_NUM(o); i++)
7990 		{
7991 			IP_WAIT *w = LIST_DATA(o, i);
7992 
7993 			// Transmission processing
7994 			VirtualIpSend(v, mac, w->Data, w->Size);
7995 
7996 			// Remove from the list
7997 			Delete(v->IpWaitTable, w);
7998 
7999 			// Release the memory
8000 			Free(w->Data);
8001 			Free(w);
8002 		}
8003 
8004 		ReleaseList(o);
8005 	}
8006 }
8007 
8008 // Remove the old IP waiting table entries
DeleteOldIpWaitTable(VH * v)8009 void DeleteOldIpWaitTable(VH *v)
8010 {
8011 	UINT i;
8012 	LIST *o = NULL;
8013 	// Validate arguments
8014 	if (v == NULL)
8015 	{
8016 		return;
8017 	}
8018 
8019 	// Get the deleting list
8020 	for (i = 0; i < LIST_NUM(v->IpWaitTable); i++)
8021 	{
8022 		IP_WAIT *w = LIST_DATA(v->IpWaitTable, i);
8023 
8024 		if (w->Expire < v->Now)
8025 		{
8026 			if (o == NULL)
8027 			{
8028 				o = NewListFast(NULL);
8029 			}
8030 			Add(o, w);
8031 		}
8032 	}
8033 
8034 	// Delete all at once
8035 	if (o != NULL)
8036 	{
8037 		for (i = 0; i < LIST_NUM(o); i++)
8038 		{
8039 			IP_WAIT *w = LIST_DATA(o, i);
8040 
8041 			// Remove from the list
8042 			Delete(v->IpWaitTable, w);
8043 
8044 			// Release the memory
8045 			Free(w->Data);
8046 			Free(w);
8047 		}
8048 		ReleaseList(o);
8049 	}
8050 }
8051 
8052 // Poll the IP waiting table
PollingIpWaitTable(VH * v)8053 void PollingIpWaitTable(VH *v)
8054 {
8055 	// Delete the old table entries
8056 	DeleteOldIpWaitTable(v);
8057 }
8058 
8059 // Insert the IP packet to the IP waiting table
InsertIpWaitTable(VH * v,UINT dest_ip,UINT src_ip,void * data,UINT size)8060 void InsertIpWaitTable(VH *v, UINT dest_ip, UINT src_ip, void *data, UINT size)
8061 {
8062 	IP_WAIT *w;
8063 	// Validate arguments
8064 	if (v == NULL || data == NULL || size == 0)
8065 	{
8066 		return;
8067 	}
8068 
8069 	w = ZeroMalloc(sizeof(IP_WAIT));
8070 	w->Data = data;
8071 	w->Size = size;
8072 	w->SrcIP = src_ip;
8073 	w->DestIP = dest_ip;
8074 	w->Expire = v->Now + (UINT64)IP_WAIT_FOR_ARP_TIMEOUT;
8075 
8076 	Add(v->IpWaitTable, w);
8077 }
8078 
8079 // Initialize the IP waiting table
InitIpWaitTable(VH * v)8080 void InitIpWaitTable(VH *v)
8081 {
8082 	// Validate arguments
8083 	if (v == NULL)
8084 	{
8085 		return;
8086 	}
8087 
8088 	v->IpWaitTable = NewList(NULL);
8089 }
8090 
8091 // Release the IP waiting table
FreeIpWaitTable(VH * v)8092 void FreeIpWaitTable(VH *v)
8093 {
8094 	UINT i;
8095 	// Validate arguments
8096 	if (v == NULL)
8097 	{
8098 		return;
8099 	}
8100 
8101 	for (i = 0; i < LIST_NUM(v->IpWaitTable); i++)
8102 	{
8103 		IP_WAIT *w = LIST_DATA(v->IpWaitTable, i);
8104 
8105 		Free(w->Data);
8106 		Free(w);
8107 	}
8108 
8109 	ReleaseList(v->IpWaitTable);
8110 }
8111 
8112 // MAC address for the IP address is found because something such as an ARP Response arrives
ArpIpWasKnown(VH * v,UINT ip,UCHAR * mac)8113 void ArpIpWasKnown(VH *v, UINT ip, UCHAR *mac)
8114 {
8115 	// Validate arguments
8116 	if (v == NULL || mac == NULL)
8117 	{
8118 		return;
8119 	}
8120 
8121 	// If there is a query for this IP address in the ARP queue, delete it
8122 	DeleteArpWaitTable(v, ip);
8123 
8124 	// Update or register in the ARP table
8125 	InsertArpTable(v, mac, ip);
8126 
8127 	// Send the IP packets waiting in the IP waiting list
8128 	SendWaitingIp(v, mac, ip);
8129 }
8130 
8131 // Re-issue ARPs by checking the ARP waiting list
PollingArpWaitTable(VH * v)8132 void PollingArpWaitTable(VH *v)
8133 {
8134 	UINT i;
8135 	LIST *o;
8136 	// Validate arguments
8137 	if (v == NULL)
8138 	{
8139 		return;
8140 	}
8141 
8142 	// Initialize the deletion list
8143 	o = NULL;
8144 
8145 	// Scan whole ARP waiting list
8146 	for (i = 0; i < LIST_NUM(v->ArpWaitTable); i++)
8147 	{
8148 		ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i);
8149 
8150 		if (w->GiveupTime < v->Now || (w->GiveupTime - 100 * 1000) > v->Now)
8151 		{
8152 			// Give up the sending of ARP
8153 			if (o == NULL)
8154 			{
8155 				o = NewListFast(NULL);
8156 			}
8157 			Add(o, w);
8158 		}
8159 		else
8160 		{
8161 			if (w->TimeoutTime < v->Now)
8162 			{
8163 				// Send an ARP again
8164 				VirtualArpSendRequest(v, w->IpAddress);
8165 
8166 				// Set the next timeout time
8167 				w->TimeoutTime = v->Now + (UINT64)w->NextTimeoutTimeValue;
8168 				// Increase the ARP transmission interval of the second and subsequent
8169 				w->NextTimeoutTimeValue = w->NextTimeoutTimeValue + ARP_REQUEST_TIMEOUT;
8170 			}
8171 		}
8172 	}
8173 
8174 	// Remove if there is a ARP waiting record to be deleted
8175 	if (o != NULL)
8176 	{
8177 		for (i = 0; i < LIST_NUM(o); i++)
8178 		{
8179 			ARP_WAIT *w = LIST_DATA(o, i);
8180 
8181 			DeleteArpWaitTable(v, w->IpAddress);
8182 		}
8183 		ReleaseList(o);
8184 	}
8185 }
8186 
8187 // Issue an ARP
SendArp(VH * v,UINT ip)8188 void SendArp(VH *v, UINT ip)
8189 {
8190 	ARP_WAIT *w;
8191 	// Validate arguments
8192 	if (v == NULL)
8193 	{
8194 		return;
8195 	}
8196 
8197 	// Examine whether the destination IP address has been registered in the ARP waiting list first
8198 	w = SearchArpWaitTable(v, ip);
8199 	if (w != NULL)
8200 	{
8201 		// Do not do anything because it is already registered
8202 		return;
8203 	}
8204 
8205 	// Send an ARP packet first
8206 	VirtualArpSendRequest(v, ip);
8207 
8208 	// Register in the ARP waiting list
8209 	w = ZeroMalloc(sizeof(ARP_WAIT));
8210 	w->GiveupTime = v->Now + (UINT64)ARP_REQUEST_GIVEUP;
8211 	w->TimeoutTime = v->Now + (UINT64)ARP_REQUEST_TIMEOUT;
8212 	w->NextTimeoutTimeValue = ARP_REQUEST_TIMEOUT;
8213 	w->IpAddress = ip;
8214 
8215 	InsertArpWaitTable(v, w);
8216 }
8217 
8218 // Delete the ARP waiting table
DeleteArpWaitTable(VH * v,UINT ip)8219 void DeleteArpWaitTable(VH *v, UINT ip)
8220 {
8221 	ARP_WAIT *w;
8222 	// Validate arguments
8223 	if (v == NULL)
8224 	{
8225 		return;
8226 	}
8227 
8228 	w = SearchArpWaitTable(v, ip);
8229 	if (w == NULL)
8230 	{
8231 		return;
8232 	}
8233 	Delete(v->ArpWaitTable, w);
8234 
8235 	Free(w);
8236 }
8237 
8238 // Search the ARP waiting table
SearchArpWaitTable(VH * v,UINT ip)8239 ARP_WAIT *SearchArpWaitTable(VH *v, UINT ip)
8240 {
8241 	ARP_WAIT *w, t;
8242 	// Validate arguments
8243 	if (v == NULL)
8244 	{
8245 		return NULL;
8246 	}
8247 
8248 	t.IpAddress = ip;
8249 	w = Search(v->ArpWaitTable, &t);
8250 
8251 	return w;
8252 }
8253 
8254 // Register in the ARP waiting table
InsertArpWaitTable(VH * v,ARP_WAIT * w)8255 void InsertArpWaitTable(VH *v, ARP_WAIT *w)
8256 {
8257 	// Validate arguments
8258 	if (v == NULL || w == NULL)
8259 	{
8260 		return;
8261 	}
8262 
8263 	Add(v->ArpWaitTable, w);
8264 }
8265 
8266 // Initialize the ARP waiting table
InitArpWaitTable(VH * v)8267 void InitArpWaitTable(VH *v)
8268 {
8269 	// Validate arguments
8270 	if (v == NULL)
8271 	{
8272 		return;
8273 	}
8274 
8275 	v->ArpWaitTable = NewList(CompareArpWaitTable);
8276 }
8277 
8278 // Release the ARP waiting table
FreeArpWaitTable(VH * v)8279 void FreeArpWaitTable(VH *v)
8280 {
8281 	UINT i;
8282 	// Validate arguments
8283 	if (v == NULL)
8284 	{
8285 		return;
8286 	}
8287 
8288 	for (i = 0; i < LIST_NUM(v->ArpWaitTable); i++)
8289 	{
8290 		ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i);
8291 
8292 		Free(w);
8293 	}
8294 
8295 	ReleaseList(v->ArpWaitTable);
8296 }
8297 
8298 // Insert an entry in the ARP table
InsertArpTable(VH * v,UCHAR * mac,UINT ip)8299 void InsertArpTable(VH *v, UCHAR *mac, UINT ip)
8300 {
8301 	ARP_ENTRY *e, t;
8302 	// Validate arguments
8303 	if (v == NULL || mac == NULL || ip == 0 || ip == 0xffffffff || IsMacBroadcast(mac) || IsMacInvalid(mac))
8304 	{
8305 		return;
8306 	}
8307 
8308 	// Check whether the same IP address is not already registered
8309 	t.IpAddress = ip;
8310 	e = Search(v->ArpTable, &t);
8311 	if (e != NULL)
8312 	{
8313 		// Override this simply because it was registered
8314 		if (Cmp(e->MacAddress, mac, 6) != 0)
8315 		{
8316 			e->Created = v->Now;
8317 			Copy(e->MacAddress, mac, 6);
8318 		}
8319 		e->Expire = v->Now + (UINT64)ARP_ENTRY_EXPIRES;
8320 	}
8321 	else
8322 	{
8323 		// Create a new entry
8324 		e = ZeroMalloc(sizeof(ARP_ENTRY));
8325 
8326 		e->Created = v->Now;
8327 		e->Expire = v->Now + (UINT64)ARP_ENTRY_EXPIRES;
8328 		Copy(e->MacAddress, mac, 6);
8329 		e->IpAddress = ip;
8330 
8331 		Add(v->ArpTable, e);
8332 	}
8333 }
8334 
8335 // Poll the ARP table
PollingArpTable(VH * v)8336 void PollingArpTable(VH *v)
8337 {
8338 	// Validate arguments
8339 	if (v == NULL)
8340 	{
8341 		return;
8342 	}
8343 
8344 	if (v->Now > v->NextArpTablePolling)
8345 	{
8346 		v->NextArpTablePolling = v->Now + (UINT64)ARP_ENTRY_POLLING_TIME;
8347 		RefreshArpTable(v);
8348 	}
8349 }
8350 
8351 // Remove the old ARP entries
RefreshArpTable(VH * v)8352 void RefreshArpTable(VH *v)
8353 {
8354 	UINT i;
8355 	LIST *o;
8356 	// Validate arguments
8357 	if (v == NULL)
8358 	{
8359 		return;
8360 	}
8361 
8362 	o = NewListFast(NULL);
8363 	for (i = 0; i < LIST_NUM(v->ArpTable); i++)
8364 	{
8365 		ARP_ENTRY *e = LIST_DATA(v->ArpTable, i);
8366 
8367 		// Check for expired
8368 		if (e->Expire < v->Now)
8369 		{
8370 			// Expired
8371 			Add(o, e);
8372 		}
8373 	}
8374 
8375 	// Remove expired entries at once
8376 	for (i = 0; i < LIST_NUM(o); i++)
8377 	{
8378 		ARP_ENTRY *e = LIST_DATA(o, i);
8379 
8380 		Delete(v->ArpTable, e);
8381 		Free(e);
8382 	}
8383 
8384 	ReleaseList(o);
8385 }
8386 
8387 // Search the ARP table
SearchArpTable(VH * v,UINT ip)8388 ARP_ENTRY *SearchArpTable(VH *v, UINT ip)
8389 {
8390 	ARP_ENTRY *e, t;
8391 	// Validate arguments
8392 	if (v == NULL)
8393 	{
8394 		return NULL;
8395 	}
8396 
8397 	t.IpAddress = ip;
8398 	e = Search(v->ArpTable, &t);
8399 
8400 	return e;
8401 }
8402 
8403 // Initialize the ARP table
InitArpTable(VH * v)8404 void InitArpTable(VH *v)
8405 {
8406 	// Validate arguments
8407 	if (v == NULL)
8408 	{
8409 		return;
8410 	}
8411 
8412 	v->ArpTable = NewList(CompareArpTable);
8413 }
8414 
8415 // Release the ARP table
FreeArpTable(VH * v)8416 void FreeArpTable(VH *v)
8417 {
8418 	UINT i;
8419 	// Validate arguments
8420 	if (v == NULL)
8421 	{
8422 		return;
8423 	}
8424 
8425 	// Delete all entries
8426 	for (i = 0; i < LIST_NUM(v->ArpTable); i++)
8427 	{
8428 		ARP_ENTRY *e = LIST_DATA(v->ArpTable, i);
8429 		Free(e);
8430 	}
8431 	ReleaseList(v->ArpTable);
8432 }
8433 
8434 // Comparison of the ARP waiting table entry
CompareArpWaitTable(void * p1,void * p2)8435 int CompareArpWaitTable(void *p1, void *p2)
8436 {
8437 	ARP_WAIT *e1, *e2;
8438 	if (p1 == NULL || p2 == NULL)
8439 	{
8440 		return 0;
8441 	}
8442 	e1 = *(ARP_WAIT **)p1;
8443 	e2 = *(ARP_WAIT **)p2;
8444 	if (e1 == NULL || e2 == NULL)
8445 	{
8446 		return 0;
8447 	}
8448 
8449 	if (e1->IpAddress > e2->IpAddress)
8450 	{
8451 		return 1;
8452 	}
8453 	else if (e1->IpAddress < e2->IpAddress)
8454 	{
8455 		return -1;
8456 	}
8457 	return 0;
8458 }
8459 
8460 // Comparison of the ARP table entry
CompareArpTable(void * p1,void * p2)8461 int CompareArpTable(void *p1, void *p2)
8462 {
8463 	ARP_ENTRY *e1, *e2;
8464 	if (p1 == NULL || p2 == NULL)
8465 	{
8466 		return 0;
8467 	}
8468 	e1 = *(ARP_ENTRY **)p1;
8469 	e2 = *(ARP_ENTRY **)p2;
8470 	if (e1 == NULL || e2 == NULL)
8471 	{
8472 		return 0;
8473 	}
8474 
8475 	if (e1->IpAddress > e2->IpAddress)
8476 	{
8477 		return 1;
8478 	}
8479 	else if (e1->IpAddress < e2->IpAddress)
8480 	{
8481 		return -1;
8482 	}
8483 	return 0;
8484 }
8485 
8486 // Initialize the virtual host
VirtualInit(VH * v)8487 bool VirtualInit(VH *v)
8488 {
8489 	// Initialize the log
8490 	v->Logger = NULL;
8491 
8492 	LockVirtual(v);
8493 	{
8494 		// Initialize
8495 		v->Cancel = NewCancel();
8496 		v->SendQueue = NewQueue();
8497 	}
8498 	UnlockVirtual(v);
8499 
8500 	// Counter reset
8501 	v->Counter->c = 0;
8502 	v->DhcpId = 0;
8503 
8504 	// Initialize the ARP table
8505 	InitArpTable(v);
8506 
8507 	// Initialize the ARP waiting table
8508 	InitArpWaitTable(v);
8509 
8510 	// Initialize the IP waiting table
8511 	InitIpWaitTable(v);
8512 
8513 	// Initialize the IP combining list
8514 	InitIpCombineList(v);
8515 
8516 	// Initialize the NAT
8517 	InitNat(v);
8518 
8519 	// Initialize the DHCP server
8520 	InitDhcpServer(v);
8521 
8522 	// Other initialization
8523 	v->flag1 = false;
8524 	v->NextArpTablePolling = Tick64() + (UINT64)ARP_ENTRY_POLLING_TIME;
8525 	v->CurrentIpQuota = 0;
8526 	v->Active = true;
8527 
8528 	return true;
8529 }
VirtualPaInit(SESSION * s)8530 bool VirtualPaInit(SESSION *s)
8531 {
8532 	VH *v;
8533 	// Validate arguments
8534 	if (s == NULL || (v = (VH *)s->PacketAdapter->Param) == NULL)
8535 	{
8536 		return false;
8537 	}
8538 
8539 	return VirtualInit(v);
8540 }
8541 
8542 // Get the cancel object of the virtual host
VirtualPaGetCancel(SESSION * s)8543 CANCEL *VirtualPaGetCancel(SESSION *s)
8544 {
8545 	VH *v;
8546 	// Validate arguments
8547 	if (s == NULL || (v = (VH *)s->PacketAdapter->Param) == NULL)
8548 	{
8549 		return NULL;
8550 	}
8551 
8552 	AddRef(v->Cancel->ref);
8553 	return v->Cancel;
8554 }
8555 
8556 // Get the next packet from the virtual host
VirtualGetNextPacket(VH * v,void ** data)8557 UINT VirtualGetNextPacket(VH *v, void **data)
8558 {
8559 	UINT ret = 0;
8560 
8561 START:
8562 	// Examine the transmission queue
8563 	LockQueue(v->SendQueue);
8564 	{
8565 		BLOCK *block = GetNext(v->SendQueue);
8566 
8567 		if (block != NULL)
8568 		{
8569 			// There is a packet
8570 			ret = block->Size;
8571 			*data = block->Buf;
8572 			// Discard the structure
8573 			Free(block);
8574 		}
8575 	}
8576 	UnlockQueue(v->SendQueue);
8577 
8578 	if (ret == 0)
8579 	{
8580 		LockVirtual(v);
8581 		{
8582 			v->Now = Tick64();
8583 			// Polling process
8584 			VirtualPolling(v);
8585 		}
8586 		UnlockVirtual(v);
8587 		if (v->SendQueue->num_item != 0)
8588 		{
8589 			goto START;
8590 		}
8591 	}
8592 
8593 	return ret;
8594 }
VirtualPaGetNextPacket(SESSION * s,void ** data)8595 UINT VirtualPaGetNextPacket(SESSION *s, void **data)
8596 {
8597 	VH *v;
8598 	// Validate arguments
8599 	if (s == NULL || (v = (VH *)s->PacketAdapter->Param) == NULL)
8600 	{
8601 		return INFINITE;
8602 	}
8603 
8604 	return VirtualGetNextPacket(v, data);
8605 }
8606 
8607 // Polling process (Always called once in a SessionMain loop)
VirtualPolling(VH * v)8608 void VirtualPolling(VH *v)
8609 {
8610 	// Validate arguments
8611 	if (v == NULL)
8612 	{
8613 		return;
8614 	}
8615 
8616 	// DHCP polling
8617 	PollingDhcpServer(v);
8618 
8619 	// NAT polling
8620 	PoolingNat(v);
8621 
8622 	// Clear the old ARP table entries
8623 	PollingArpTable(v);
8624 
8625 	// Poll the ARP waiting list
8626 	PollingArpWaitTable(v);
8627 
8628 	// Poll the IP waiting list
8629 	PollingIpWaitTable(v);
8630 
8631 	// Poll the IP combining list
8632 	PollingIpCombine(v);
8633 
8634 	// Beacon transmission procedure
8635 	PollingBeacon(v);
8636 }
8637 
8638 // Beacon transmission procedure
PollingBeacon(VH * v)8639 void PollingBeacon(VH *v)
8640 {
8641 	// Validate arguments
8642 	if (v == NULL)
8643 	{
8644 		return;
8645 	}
8646 
8647 	if (v->LastSendBeacon == 0 ||
8648 	        ((v->LastSendBeacon + BEACON_SEND_INTERVAL) <= Tick64()))
8649 	{
8650 		v->LastSendBeacon = Tick64();
8651 
8652 		SendBeacon(v);
8653 	}
8654 }
8655 
8656 // Send a Layer-2 packet
VirtualLayer2Send(VH * v,UCHAR * dest_mac,UCHAR * src_mac,USHORT protocol,void * data,UINT size)8657 void VirtualLayer2Send(VH *v, UCHAR *dest_mac, UCHAR *src_mac, USHORT protocol, void *data, UINT size)
8658 {
8659 	MAC_HEADER *mac_header;
8660 	UCHAR *buf;
8661 	BLOCK *block;
8662 	// Validate arguments
8663 	if (v == NULL || dest_mac == NULL || src_mac == NULL || data == NULL || size > (MAX_PACKET_SIZE - sizeof(MAC_HEADER)))
8664 	{
8665 		return;
8666 	}
8667 
8668 	// Create buffer
8669 	buf = Malloc(MAC_HEADER_SIZE + size);
8670 
8671 	// MAC header
8672 	mac_header = (MAC_HEADER *)&buf[0];
8673 	Copy(mac_header->DestAddress, dest_mac, 6);
8674 	Copy(mac_header->SrcAddress, src_mac, 6);
8675 	mac_header->Protocol = Endian16(protocol);
8676 
8677 	// Copy data
8678 	Copy(&buf[sizeof(MAC_HEADER)], data, size);
8679 
8680 	// Size
8681 	size += sizeof(MAC_HEADER);
8682 
8683 	// Generate the packet
8684 	block = NewBlock(buf, size, 0);
8685 
8686 	// Insert into the queue
8687 	LockQueue(v->SendQueue);
8688 	{
8689 		InsertQueue(v->SendQueue, block);
8690 	}
8691 	UnlockQueue(v->SendQueue);
8692 
8693 	// Cancel
8694 	Cancel(v->Cancel);
8695 }
8696 
8697 // Send an IP packet (with automatic fragmentation)
SendIp(VH * v,UINT dest_ip,UINT src_ip,UCHAR protocol,void * data,UINT size)8698 void SendIp(VH *v, UINT dest_ip, UINT src_ip, UCHAR protocol, void *data, UINT size)
8699 {
8700 	SendIpEx(v, dest_ip, src_ip, protocol, data, size, 0);
8701 }
SendIpEx(VH * v,UINT dest_ip,UINT src_ip,UCHAR protocol,void * data,UINT size,UCHAR ttl)8702 void SendIpEx(VH *v, UINT dest_ip, UINT src_ip, UCHAR protocol, void *data, UINT size, UCHAR ttl)
8703 {
8704 	UINT mss;
8705 	UCHAR *buf;
8706 	USHORT offset;
8707 	USHORT id;
8708 	USHORT total_size;
8709 	UINT size_of_this_packet;
8710 	// Validate arguments
8711 	if (v == NULL || data == NULL || size == 0 || size > MAX_IP_DATA_SIZE_TOTAL)
8712 	{
8713 		return;
8714 	}
8715 
8716 	// Maximum segment size
8717 	mss = v->IpMss;
8718 
8719 	// Buffer
8720 	buf = (UCHAR *)data;
8721 
8722 	// ID
8723 	id = (v->NextId++);
8724 
8725 	// Total size
8726 	total_size = (USHORT)size;
8727 
8728 	// Start to split
8729 	offset = 0;
8730 
8731 	while (true)
8732 	{
8733 		bool last_packet = false;
8734 		// Gets the size of this packet
8735 		size_of_this_packet = MIN((USHORT)mss, (total_size - offset));
8736 		if ((offset + (USHORT)size_of_this_packet) == total_size)
8737 		{
8738 			last_packet = true;
8739 		}
8740 
8741 		// Transmit the fragmented packet
8742 		SendFragmentedIp(v, dest_ip, src_ip, id,
8743 		                 total_size, offset, protocol, buf + offset, size_of_this_packet, NULL, ttl);
8744 		if (last_packet)
8745 		{
8746 			break;
8747 		}
8748 
8749 		offset += (USHORT)size_of_this_packet;
8750 	}
8751 }
8752 
8753 // Reserve to send the fragmented IP packet
SendFragmentedIp(VH * v,UINT dest_ip,UINT src_ip,USHORT id,USHORT total_size,USHORT offset,UCHAR protocol,void * data,UINT size,UCHAR * dest_mac,UCHAR ttl)8754 void SendFragmentedIp(VH *v, UINT dest_ip, UINT src_ip, USHORT id, USHORT total_size, USHORT offset, UCHAR protocol, void *data, UINT size, UCHAR *dest_mac, UCHAR ttl)
8755 {
8756 	UCHAR *buf;
8757 	IPV4_HEADER *ip;
8758 	ARP_ENTRY *arp;
8759 	// Validate arguments
8760 	if (v == NULL || data == NULL || size == 0)
8761 	{
8762 		return;
8763 	}
8764 
8765 	// Memory allocation
8766 	buf = Malloc(size + IP_HEADER_SIZE);
8767 	ip = (IPV4_HEADER *)&buf[0];
8768 
8769 	// IP header construction
8770 	ip->VersionAndHeaderLength = 0;
8771 	IPV4_SET_VERSION(ip, 4);
8772 	IPV4_SET_HEADER_LEN(ip, (IP_HEADER_SIZE / 4));
8773 	ip->TypeOfService = DEFAULT_IP_TOS;
8774 	ip->TotalLength = Endian16((USHORT)(size + IP_HEADER_SIZE));
8775 	ip->Identification = Endian16(id);
8776 	ip->FlagsAndFragmentOffset[0] = ip->FlagsAndFragmentOffset[1] = 0;
8777 	IPV4_SET_OFFSET(ip, (offset / 8));
8778 	if ((offset + size) >= total_size)
8779 	{
8780 		IPV4_SET_FLAGS(ip, 0x00);
8781 	}
8782 	else
8783 	{
8784 		IPV4_SET_FLAGS(ip, 0x01);
8785 	}
8786 	ip->TimeToLive = (ttl == 0 ? DEFAULT_IP_TTL : ttl);
8787 	ip->Protocol = protocol;
8788 	ip->Checksum = 0;
8789 	ip->SrcIP = src_ip;
8790 	ip->DstIP = dest_ip;
8791 
8792 	// Checksum calculation
8793 	ip->Checksum = IpChecksum(ip, IP_HEADER_SIZE);
8794 
8795 	// Data copy
8796 	Copy(buf + IP_HEADER_SIZE, data, size);
8797 
8798 	if (dest_mac == NULL)
8799 	{
8800 		if (ip->DstIP == 0xffffffff ||
8801 		        (IsInNetwork(ip->DstIP, v->HostIP, v->HostMask) && (ip->DstIP & (~v->HostMask)) == (~v->HostMask)))
8802 		{
8803 			// Broadcast address
8804 			dest_mac = broadcast;
8805 		}
8806 		else
8807 		{
8808 			// Send an ARP query if the destination MAC address is unknown
8809 			arp = SearchArpTable(v, dest_ip);
8810 			if (arp != NULL)
8811 			{
8812 				dest_mac = arp->MacAddress;
8813 			}
8814 		}
8815 	}
8816 	if (dest_mac != NULL)
8817 	{
8818 		// Send the packet immediately
8819 		VirtualIpSend(v, dest_mac, buf, size + IP_HEADER_SIZE);
8820 
8821 		// Packet data may be released
8822 		Free(buf);
8823 	}
8824 	else
8825 	{
8826 		// Because this packet still can not be transferred, add it to the IP waiting table
8827 		InsertIpWaitTable(v, dest_ip, src_ip, buf, size + IP_HEADER_SIZE);
8828 
8829 		// Issue an ARP
8830 		SendArp(v, dest_ip);
8831 	}
8832 }
8833 
8834 // Send an IP packet (fragmented)
VirtualIpSend(VH * v,UCHAR * dest_mac,void * data,UINT size)8835 void VirtualIpSend(VH *v, UCHAR *dest_mac, void *data, UINT size)
8836 {
8837 	// Validate arguments
8838 	if (v == NULL || dest_mac == NULL || data == NULL || size == 0)
8839 	{
8840 		return;
8841 	}
8842 
8843 	// Transmission
8844 	VirtualLayer2Send(v, dest_mac, v->MacAddress, MAC_PROTO_IPV4, data, size);
8845 }
8846 
8847 // Send an ARP request packet
VirtualArpSendRequest(VH * v,UINT dest_ip)8848 void VirtualArpSendRequest(VH *v, UINT dest_ip)
8849 {
8850 	ARPV4_HEADER arp;
8851 	// Validate arguments
8852 	if (v == NULL)
8853 	{
8854 		return;
8855 	}
8856 
8857 	// Build the ARP header
8858 	arp.HardwareType = Endian16(ARP_HARDWARE_TYPE_ETHERNET);
8859 	arp.ProtocolType = Endian16(MAC_PROTO_IPV4);
8860 	arp.HardwareSize = 6;
8861 	arp.ProtocolSize = 4;
8862 	arp.Operation = Endian16(ARP_OPERATION_REQUEST);
8863 	Copy(arp.SrcAddress, v->MacAddress, 6);
8864 	arp.SrcIP = v->HostIP;
8865 	Zero(&arp.TargetAddress, 6);
8866 	arp.TargetIP = dest_ip;
8867 
8868 	// Transmission
8869 	VirtualLayer2Send(v, broadcast, v->MacAddress, MAC_PROTO_ARPV4, &arp, sizeof(arp));
8870 }
8871 
8872 // Send an ARP response packet
VirtualArpSendResponse(VH * v,UCHAR * dest_mac,UINT dest_ip,UINT src_ip)8873 void VirtualArpSendResponse(VH *v, UCHAR *dest_mac, UINT dest_ip, UINT src_ip)
8874 {
8875 	ARPV4_HEADER arp;
8876 	// Validate arguments
8877 	if (v == NULL || dest_mac == NULL)
8878 	{
8879 		return;
8880 	}
8881 
8882 	// Build the ARP header
8883 	arp.HardwareType = Endian16(ARP_HARDWARE_TYPE_ETHERNET);
8884 	arp.ProtocolType = Endian16(MAC_PROTO_IPV4);
8885 	arp.HardwareSize = 6;
8886 	arp.ProtocolSize = 4;
8887 	arp.Operation = Endian16(ARP_OPERATION_RESPONSE);
8888 	Copy(arp.SrcAddress, v->MacAddress, 6);
8889 	Copy(arp.TargetAddress, dest_mac, 6);
8890 	arp.SrcIP = src_ip;
8891 	arp.TargetIP = dest_ip;
8892 
8893 	// Transmission
8894 	VirtualLayer2Send(v, dest_mac, v->MacAddress, MAC_PROTO_ARPV4, &arp, sizeof(ARPV4_HEADER));
8895 }
8896 
8897 // An ARP request packet was received
VirtualArpResponseRequest(VH * v,PKT * packet)8898 void VirtualArpResponseRequest(VH *v, PKT *packet)
8899 {
8900 	ARPV4_HEADER *arp;
8901 	// Validate arguments
8902 	if (v == NULL || packet == NULL)
8903 	{
8904 		return;
8905 	}
8906 
8907 	arp = packet->L3.ARPv4Header;
8908 
8909 	// Memory the information of the host IP address and the MAC address of the other party
8910 	ArpIpWasKnown(v, arp->SrcIP, arp->SrcAddress);
8911 
8912 	// Search whether it matches with the IP address of this host
8913 	if (v->HostIP == arp->TargetIP)
8914 	{
8915 		// Respond since the match
8916 		VirtualArpSendResponse(v, arp->SrcAddress, arp->SrcIP, v->HostIP);
8917 		return;
8918 	}
8919 	// Do nothing if it doesn't match
8920 }
8921 
8922 // An ARP response packet is received
VirtualArpResponseReceived(VH * v,PKT * packet)8923 void VirtualArpResponseReceived(VH *v, PKT *packet)
8924 {
8925 	ARPV4_HEADER *arp;
8926 	// Validate arguments
8927 	if (v == NULL || packet == NULL)
8928 	{
8929 		return;
8930 	}
8931 
8932 	arp = packet->L3.ARPv4Header;
8933 
8934 	// Regard this information as known information
8935 	ArpIpWasKnown(v, arp->SrcIP, arp->SrcAddress);
8936 }
8937 
8938 // Received an ARP packet
VirtualArpReceived(VH * v,PKT * packet)8939 void VirtualArpReceived(VH *v, PKT *packet)
8940 {
8941 	ARPV4_HEADER *arp;
8942 	// Validate arguments
8943 	if (v == NULL || packet == NULL)
8944 	{
8945 		return;
8946 	}
8947 
8948 	arp = packet->L3.ARPv4Header;
8949 
8950 	if (Endian16(arp->HardwareType) != ARP_HARDWARE_TYPE_ETHERNET)
8951 	{
8952 		// Ignore if hardware type is other than Ethernet
8953 		return;
8954 	}
8955 	if (Endian16(arp->ProtocolType) != MAC_PROTO_IPV4)
8956 	{
8957 		// Ignore if the protocol type is a non-IPv4
8958 		return;
8959 	}
8960 	if (arp->HardwareSize != 6 || arp->ProtocolSize != 4)
8961 	{
8962 		// Ignore because the size of protocol address or hardware address is invalid
8963 		return;
8964 	}
8965 	// Check the source MAC address
8966 	if (Cmp(arp->SrcAddress, packet->MacAddressSrc, 6) != 0)
8967 	{
8968 		// MAC address in the MAC header and the MAC address of the ARP packet are different
8969 		return;
8970 	}
8971 
8972 	switch (Endian16(arp->Operation))
8973 	{
8974 	case ARP_OPERATION_REQUEST:		// ARP request
8975 		VirtualArpResponseRequest(v, packet);
8976 		break;
8977 
8978 	case ARP_OPERATION_RESPONSE:	// ARP response
8979 		VirtualArpResponseReceived(v, packet);
8980 		break;
8981 	}
8982 }
8983 
8984 // Release the DHCP server
FreeDhcpServer(VH * v)8985 void FreeDhcpServer(VH *v)
8986 {
8987 	UINT i;
8988 	// Validate arguments
8989 	if (v == NULL)
8990 	{
8991 		return;
8992 	}
8993 
8994 	// Empty the leases lists
8995 	for (i = 0; i < LIST_NUM(v->DhcpLeaseList); ++i)
8996 	{
8997 		DHCP_LEASE *d = LIST_DATA(v->DhcpLeaseList, i);
8998 		FreeDhcpLease(d);
8999 	}
9000 
9001 	ReleaseList(v->DhcpLeaseList);
9002 	v->DhcpLeaseList = NULL;
9003 
9004 	for (i = 0; i < LIST_NUM(v->DhcpPendingLeaseList); ++i)
9005 	{
9006 		DHCP_LEASE *d = LIST_DATA(v->DhcpPendingLeaseList, i);
9007 		FreeDhcpLease(d);
9008 	}
9009 
9010 	ReleaseList(v->DhcpPendingLeaseList);
9011 	v->DhcpPendingLeaseList = NULL;
9012 }
9013 
9014 // Initialize the DHCP server
InitDhcpServer(VH * v)9015 void InitDhcpServer(VH *v)
9016 {
9017 	// Validate arguments
9018 	if (v == NULL)
9019 	{
9020 		return;
9021 	}
9022 
9023 	// Create a list
9024 	v->DhcpLeaseList = NewList(CompareDhcpLeaseList);
9025 	v->DhcpPendingLeaseList = NewList(CompareDhcpLeaseList);
9026 }
9027 
9028 // Search for a pending DHCP lease item by the IP address
SearchDhcpPendingLeaseByIp(VH * v,UINT ip)9029 DHCP_LEASE *SearchDhcpPendingLeaseByIp(VH *v, UINT ip)
9030 {
9031 	UINT i;
9032 	// Validate arguments
9033 	if (v == NULL)
9034 	{
9035 		return NULL;
9036 	}
9037 
9038 	for (i = 0; i < LIST_NUM(v->DhcpPendingLeaseList); ++i)
9039 	{
9040 		DHCP_LEASE *d = LIST_DATA(v->DhcpPendingLeaseList, i);
9041 		if (d->IpAddress == ip)
9042 		{
9043 			return d;
9044 		}
9045 	}
9046 
9047 	return NULL;
9048 }
9049 
9050 // Search for a DHCP lease item by the IP address
SearchDhcpLeaseByIp(VH * v,UINT ip)9051 DHCP_LEASE *SearchDhcpLeaseByIp(VH *v, UINT ip)
9052 {
9053 	UINT i;
9054 	// Validate arguments
9055 	if (v == NULL)
9056 	{
9057 		return NULL;
9058 	}
9059 
9060 	for (i = 0; i < LIST_NUM(v->DhcpLeaseList); ++i)
9061 	{
9062 		DHCP_LEASE *d = LIST_DATA(v->DhcpLeaseList, i);
9063 		if (d->IpAddress == ip)
9064 		{
9065 			return d;
9066 		}
9067 	}
9068 
9069 	return NULL;
9070 }
9071 
9072 // Search for a pending DHCP lease item by the MAC address
SearchDhcpPendingLeaseByMac(VH * v,UCHAR * mac)9073 DHCP_LEASE *SearchDhcpPendingLeaseByMac(VH *v, UCHAR *mac)
9074 {
9075 	DHCP_LEASE *d, t;
9076 	// Validate arguments
9077 	if (v == NULL || mac == NULL)
9078 	{
9079 		return NULL;
9080 	}
9081 
9082 	Copy(&t.MacAddress, mac, 6);
9083 	d = Search(v->DhcpPendingLeaseList, &t);
9084 
9085 	return d;
9086 }
9087 
9088 // Search for a DHCP lease item by the MAC address
SearchDhcpLeaseByMac(VH * v,UCHAR * mac)9089 DHCP_LEASE *SearchDhcpLeaseByMac(VH *v, UCHAR *mac)
9090 {
9091 	DHCP_LEASE *d, t;
9092 	// Validate arguments
9093 	if (v == NULL || mac == NULL)
9094 	{
9095 		return NULL;
9096 	}
9097 
9098 	Copy(&t.MacAddress, mac, 6);
9099 	d = Search(v->DhcpLeaseList, &t);
9100 
9101 	return d;
9102 }
9103 
9104 // Release the DHCP lease item
FreeDhcpLease(DHCP_LEASE * d)9105 void FreeDhcpLease(DHCP_LEASE *d)
9106 {
9107 	// Validate arguments
9108 	if (d == NULL)
9109 	{
9110 		return;
9111 	}
9112 
9113 	Free(d->Hostname);
9114 	Free(d);
9115 }
9116 
9117 // Create a DHCP lease item
NewDhcpLease(UINT expire,UCHAR * mac_address,UINT ip,UINT mask,char * hostname)9118 DHCP_LEASE *NewDhcpLease(UINT expire, UCHAR *mac_address, UINT ip, UINT mask, char *hostname)
9119 {
9120 	DHCP_LEASE *d;
9121 	// Validate arguments
9122 	if (mac_address == NULL || hostname == NULL)
9123 	{
9124 		return NULL;
9125 	}
9126 
9127 	d = ZeroMalloc(sizeof(DHCP_LEASE));
9128 	d->LeasedTime = (UINT64)Tick64();
9129 	if (expire == INFINITE)
9130 	{
9131 		d->ExpireTime = INFINITE;
9132 	}
9133 	else
9134 	{
9135 		d->ExpireTime = d->LeasedTime + (UINT64)expire;
9136 	}
9137 	d->IpAddress = ip;
9138 	d->Mask = mask;
9139 	d->Hostname = CopyStr(hostname);
9140 	Copy(d->MacAddress, mac_address, 6);
9141 
9142 
9143 	return d;
9144 }
9145 
9146 // Comparison of the items in the DHCP list
CompareDhcpLeaseList(void * p1,void * p2)9147 int CompareDhcpLeaseList(void *p1, void *p2)
9148 {
9149 	DHCP_LEASE *d1, *d2;
9150 	// Validate arguments
9151 	if (p1 == NULL || p2 == NULL)
9152 	{
9153 		return 0;
9154 	}
9155 	d1 = *(DHCP_LEASE **)p1;
9156 	d2 = *(DHCP_LEASE **)p2;
9157 	if (d1 == NULL || d2 == NULL)
9158 	{
9159 		return 0;
9160 	}
9161 
9162 	return Cmp(d1->MacAddress, d2->MacAddress, 6);
9163 }
9164 
9165 // Poll the DHCP server
PollingDhcpServer(VH * v)9166 void PollingDhcpServer(VH *v)
9167 {
9168 	UINT i;
9169 	// Validate arguments
9170 	if (v == NULL)
9171 	{
9172 		return;
9173 	}
9174 
9175 	if (v->LastDhcpPolling != 0)
9176 	{
9177 		if ((v->LastDhcpPolling + (UINT64)DHCP_POLLING_INTERVAL) > v->Now &&
9178 		        v->LastDhcpPolling < v->Now)
9179 		{
9180 			return;
9181 		}
9182 	}
9183 	v->LastDhcpPolling = v->Now;
9184 
9185 LIST_CLEANUP:
9186 	for (i = 0; i < LIST_NUM(v->DhcpLeaseList); ++i)
9187 	{
9188 		DHCP_LEASE *d = LIST_DATA(v->DhcpLeaseList, i);
9189 
9190 		if (d->ExpireTime < v->Now)
9191 		{
9192 			FreeDhcpLease(d);
9193 			Delete(v->DhcpLeaseList, d);
9194 			goto LIST_CLEANUP;
9195 		}
9196 	}
9197 
9198 PENDING_LIST_CLEANUP:
9199 	// Remove expired entries
9200 	for (i = 0; i < LIST_NUM(v->DhcpPendingLeaseList); ++i)
9201 	{
9202 		DHCP_LEASE *d = LIST_DATA(v->DhcpPendingLeaseList, i);
9203 
9204 		if (d->ExpireTime < v->Now)
9205 		{
9206 			FreeDhcpLease(d);
9207 			Delete(v->DhcpPendingLeaseList, d);
9208 			goto PENDING_LIST_CLEANUP;
9209 		}
9210 	}
9211 }
9212 
9213 // Correspond to the DHCP REQUEST
ServeDhcpRequest(VH * v,UCHAR * mac,UINT request_ip)9214 UINT ServeDhcpRequest(VH *v, UCHAR *mac, UINT request_ip)
9215 {
9216 	return ServeDhcpRequestEx(v, mac, request_ip, false);
9217 }
9218 
ServeDhcpRequestEx(VH * v,UCHAR * mac,UINT request_ip,bool is_static_ip)9219 UINT ServeDhcpRequestEx(VH *v, UCHAR *mac, UINT request_ip, bool is_static_ip)
9220 {
9221 	UINT ret;
9222 	// Validate arguments
9223 	if (v == NULL || mac == NULL)
9224 	{
9225 		return 0;
9226 	}
9227 
9228 	ret = ServeDhcpDiscoverEx(v, mac, request_ip, is_static_ip);
9229 	if (ret != request_ip)
9230 	{
9231 		if (request_ip != 0)
9232 		{
9233 			// Raise an error if the requested IP address cannot to be assigned
9234 			return 0;
9235 		}
9236 	}
9237 
9238 	return ret;
9239 }
9240 
9241 // Correspond to the DHCP DISCOVER
ServeDhcpDiscover(VH * v,UCHAR * mac,UINT request_ip)9242 UINT ServeDhcpDiscover(VH *v, UCHAR *mac, UINT request_ip)
9243 {
9244 	UINT ret = 0;
9245 	// Validate arguments
9246 	if (v == NULL || mac == NULL)
9247 	{
9248 		return 0;
9249 	}
9250 
9251 	if (request_ip != 0)
9252 	{
9253 		// IP address is specified
9254 		DHCP_LEASE *d = SearchDhcpLeaseByIp(v, request_ip);
9255 		if (d == NULL)
9256 		{
9257 			d = SearchDhcpPendingLeaseByIp(v, request_ip);
9258 		}
9259 
9260 		if (d != NULL)
9261 		{
9262 			// If an entry for the same IP address already exists,
9263 			// check whether it is a request from the same MAC address
9264 			if (Cmp(mac, d->MacAddress, 6) == 0)
9265 			{
9266 				// Examine whether the specified IP address is within the range of assignment
9267 				if (Endian32(v->DhcpIpStart) <= Endian32(request_ip) &&
9268 				        Endian32(request_ip) <= Endian32(v->DhcpIpEnd))
9269 				{
9270 					// Accept if within the range
9271 					ret = request_ip;
9272 				}
9273 			}
9274 		}
9275 		else
9276 		{
9277 			// Examine whether the specified IP address is within the range of assignment
9278 			if (Endian32(v->DhcpIpStart) <= Endian32(request_ip) &&
9279 			        Endian32(request_ip) <= Endian32(v->DhcpIpEnd))
9280 			{
9281 				// Accept if within the range
9282 				ret = request_ip;
9283 			}
9284 			else
9285 			{
9286 				// Propose an IP in the range since it's a Discover although It is out of range
9287 			}
9288 		}
9289 	}
9290 
9291 	if (ret == 0)
9292 	{
9293 		// If there is any entry with the same MAC address
9294 		// that are already registered, use it with priority
9295 		DHCP_LEASE *d = SearchDhcpLeaseByMac(v, mac);
9296 		if (d == NULL)
9297 		{
9298 			d = SearchDhcpPendingLeaseByMac(v, mac);
9299 		}
9300 
9301 		if (d != NULL)
9302 		{
9303 			// Examine whether the found IP address is in the allocation region
9304 			if (Endian32(v->DhcpIpStart) <= Endian32(d->IpAddress) &&
9305 			        Endian32(d->IpAddress) <= Endian32(v->DhcpIpEnd))
9306 			{
9307 				// Use the IP address if it's found within the range
9308 				ret = d->IpAddress;
9309 			}
9310 		}
9311 	}
9312 
9313 	if (ret == 0)
9314 	{
9315 		// Take an appropriate IP addresses that can be assigned newly
9316 		HUB_OPTION *opt = NatGetHubOption(v);
9317 
9318 		if (opt != NULL && opt->SecureNAT_RandomizeAssignIp)
9319 		{
9320 			ret = GetFreeDhcpIpAddressByRandom(v, mac);
9321 		}
9322 		else
9323 		{
9324 			ret = GetFreeDhcpIpAddress(v);
9325 		}
9326 	}
9327 
9328 	return ret;
9329 }
9330 
ServeDhcpDiscoverEx(VH * v,UCHAR * mac,UINT request_ip,bool is_static_ip)9331 UINT ServeDhcpDiscoverEx(VH *v, UCHAR *mac, UINT request_ip, bool is_static_ip)
9332 {
9333 	if (is_static_ip == false)
9334 	{
9335 		return ServeDhcpDiscover(v, mac, request_ip );
9336 	}
9337 
9338 	if (v == NULL || mac == NULL || request_ip == 0)
9339 	{
9340 		return 0;
9341 	}
9342 
9343 	DHCP_LEASE *d = SearchDhcpLeaseByIp(v, request_ip);
9344 	if (d != NULL)
9345 	{
9346 		// The requested IP address is used already
9347 		return 0;
9348 	}
9349 
9350 	// For static IP, the requested IP address must NOT be within the range of the DHCP pool
9351 	if (Endian32(request_ip) < Endian32(v->DhcpIpStart) || Endian32(request_ip) > Endian32(v->DhcpIpEnd))
9352 	{
9353 		return request_ip;
9354 	}
9355 
9356 	return 0;
9357 }
9358 
9359 // Take an appropriate IP addresses that can be assigned newly
GetFreeDhcpIpAddress(VH * v)9360 UINT GetFreeDhcpIpAddress(VH *v)
9361 {
9362 	UINT ip_start, ip_end;
9363 	UINT i;
9364 	// Validate arguments
9365 	if (v == NULL)
9366 	{
9367 		return 0;
9368 	}
9369 
9370 	ip_start = Endian32(v->DhcpIpStart);
9371 	ip_end = Endian32(v->DhcpIpEnd);
9372 
9373 	for (i = ip_start; i <= ip_end; i++)
9374 	{
9375 		UINT ip = Endian32(i);
9376 		if (SearchDhcpLeaseByIp(v, ip) == NULL && SearchDhcpPendingLeaseByIp(v, ip) == NULL)
9377 		{
9378 			// A free IP address is found
9379 			return ip;
9380 		}
9381 	}
9382 
9383 	// There is no free address
9384 	return 0;
9385 }
9386 
9387 // Take an appropriate IP addresses that can be assigned newly (random)
GetFreeDhcpIpAddressByRandom(VH * v,UCHAR * mac)9388 UINT GetFreeDhcpIpAddressByRandom(VH *v, UCHAR *mac)
9389 {
9390 	UINT ip_start, ip_end;
9391 	UINT i;
9392 	UINT num_retry;
9393 	// Validate arguments
9394 	if (v == NULL || mac == NULL)
9395 	{
9396 		return 0;
9397 	}
9398 
9399 	ip_start = Endian32(v->DhcpIpStart);
9400 	ip_end = Endian32(v->DhcpIpEnd);
9401 
9402 	if (ip_start > ip_end)
9403 	{
9404 		return 0;
9405 	}
9406 
9407 	num_retry = (ip_end - ip_start + 1) * 2;
9408 	num_retry = MIN(num_retry, 65536 * 2);
9409 
9410 	for (i = 0; i < num_retry; i++)
9411 	{
9412 		UCHAR rand_seed[sizeof(UINT) + 6];
9413 		UCHAR hash[16];
9414 		UINT rand_int;
9415 		UINT new_ip;
9416 
9417 		WRITE_UINT(&rand_seed[0], i);
9418 		Copy(rand_seed + sizeof(UINT), mac, 6);
9419 
9420 		Md5(hash, rand_seed, sizeof(rand_seed));
9421 
9422 		rand_int = READ_UINT(hash);
9423 
9424 		new_ip = Endian32(ip_start + (rand_int % (ip_end - ip_start + 1)));
9425 
9426 		if (SearchDhcpLeaseByIp(v, new_ip) == NULL && SearchDhcpPendingLeaseByIp(v, new_ip) == NULL)
9427 		{
9428 			// A free IP address is found
9429 			return new_ip;
9430 		}
9431 	}
9432 
9433 	// There is no free address
9434 	return 0;
9435 }
9436 
9437 // Virtual DHCP Server
VirtualDhcpServer(VH * v,PKT * p)9438 void VirtualDhcpServer(VH *v, PKT *p)
9439 {
9440 	DHCPV4_HEADER *dhcp;
9441 	UCHAR *data;
9442 	UINT size;
9443 	UINT dhcp_header_size;
9444 	UINT dhcp_data_offset;
9445 	UINT tran_id;
9446 	UINT magic_cookie = Endian32(DHCP_MAGIC_COOKIE);
9447 	bool ok;
9448 	DHCP_OPTION_LIST *opt;
9449 	// Validate arguments
9450 	if (v == NULL || p == NULL)
9451 	{
9452 		return;
9453 	}
9454 
9455 	if (v->NativeNat != NULL)
9456 	{
9457 		if (Cmp(p->MacAddressSrc, v->NativeNat->CurrentMacAddress, 6) == 0)
9458 		{
9459 			// DHCP server is kept from responding for the native NAT interface
9460 			// ** Not be needed to return yet **
9461 			//return;
9462 		}
9463 	}
9464 
9465 	dhcp = p->L7.DHCPv4Header;
9466 
9467 	tran_id = Endian32(dhcp->TransactionId);
9468 
9469 	// Get the DHCP data and size
9470 	dhcp_header_size = sizeof(DHCPV4_HEADER);
9471 	dhcp_data_offset = (UINT)(((UCHAR *)p->L7.DHCPv4Header) - ((UCHAR *)p->MacHeader) + dhcp_header_size);
9472 	data = ((UCHAR *)dhcp) + dhcp_header_size;
9473 	size = p->PacketSize - dhcp_data_offset;
9474 	if (dhcp_header_size < 5)
9475 	{
9476 		// Data size is invalid
9477 		return;
9478 	}
9479 
9480 	// Search for Magic Cookie
9481 	ok = false;
9482 	while (size >= 5)
9483 	{
9484 		if (Cmp(data, &magic_cookie, sizeof(magic_cookie)) == 0)
9485 		{
9486 			// Found
9487 			data += 4;
9488 			size -= 4;
9489 			ok = true;
9490 			break;
9491 		}
9492 		data++;
9493 		size--;
9494 	}
9495 
9496 	if (ok == false)
9497 	{
9498 		// The packet is invalid
9499 		return;
9500 	}
9501 
9502 	// Parse DHCP options list
9503 	opt = ParseDhcpOptionList(data, size);
9504 	if (opt == NULL)
9505 	{
9506 		// The packet is invalid
9507 		return;
9508 	}
9509 
9510 	if (StartWith(opt->Hostname, NN_HOSTNAME_STARTWITH) || StartWith(opt->Hostname, NN_HOSTNAME_STARTWITH2))
9511 	{
9512 		Free(opt);
9513 		return;
9514 	}
9515 
9516 	if (dhcp->OpCode == 1 && (opt->Opcode == DHCP_DISCOVER || opt->Opcode == DHCP_REQUEST || opt->Opcode == DHCP_INFORM))
9517 	{
9518 		// Operate as the server
9519 		UINT ip = 0, ip_static = dhcp->ServerIP;
9520 		dhcp->ServerIP = 0;
9521 
9522 		if (opt->RequestedIp == 0)
9523 		{
9524 			opt->RequestedIp = (ip_static ? ip_static : p->L3.IPv4Header->SrcIP);
9525 		}
9526 		if (opt->Opcode == DHCP_DISCOVER)
9527 		{
9528 			// Return an IP address that can be used
9529 			ip = ServeDhcpDiscoverEx(v, p->MacAddressSrc, opt->RequestedIp, ip_static);
9530 		}
9531 		else if (opt->Opcode == DHCP_REQUEST)
9532 		{
9533 			// Determine the IP address
9534 			if (ip_static && opt->RequestedIp != ip_static)
9535 			{
9536 				// Don't allow opt->RequestedIp other than the IP written in user's note
9537 				ip = 0;
9538 			}
9539 			else
9540 			{
9541 				ip = ServeDhcpRequestEx(v, p->MacAddressSrc, opt->RequestedIp, ip_static);
9542 			}
9543 		}
9544 
9545 		if (ip != 0 || opt->Opcode == DHCP_INFORM)
9546 		{
9547 			// Respond if there is providable IP address
9548 
9549 			if (opt->Opcode == DHCP_REQUEST)
9550 			{
9551 				DHCP_LEASE *d;
9552 				char client_mac[MAX_SIZE];
9553 				char client_ip[MAX_SIZE];
9554 
9555 				// Remove old records with the same IP address
9556 				d = SearchDhcpLeaseByIp(v, ip);
9557 				if (d != NULL)
9558 				{
9559 					FreeDhcpLease(d);
9560 					Delete(v->DhcpLeaseList, d);
9561 				}
9562 
9563 				d = SearchDhcpPendingLeaseByIp(v, ip);
9564 				if (d != NULL)
9565 				{
9566 					FreeDhcpLease(d);
9567 					Delete(v->DhcpPendingLeaseList, d);
9568 				}
9569 
9570 				// Create a new entry
9571 				d = NewDhcpLease(v->DhcpExpire, p->MacAddressSrc, ip, v->DhcpMask, opt->Hostname);
9572 				d->Id = ++v->DhcpId;
9573 				Add(v->DhcpLeaseList, d);
9574 
9575 				MacToStr(client_mac, sizeof(client_mac), d->MacAddress);
9576 				IPToStr32(client_ip, sizeof(client_ip), d->IpAddress);
9577 
9578 				NLog(v, "LH_NAT_DHCP_CREATED", d->Id, client_mac, client_ip, d->Hostname, v->DhcpExpire / 1000);
9579 			}
9580 
9581 			// Respond
9582 			if (true)
9583 			{
9584 				DHCP_OPTION_LIST ret;
9585 				LIST *o;
9586 				Zero(&ret, sizeof(ret));
9587 
9588 				ret.Opcode = (opt->Opcode == DHCP_DISCOVER ? DHCP_OFFER : DHCP_ACK);
9589 				ret.ServerAddress = v->HostIP;
9590 				if (v->DhcpExpire == INFINITE)
9591 				{
9592 					ret.LeaseTime = INFINITE;
9593 				}
9594 				else
9595 				{
9596 					ret.LeaseTime = Endian32(v->DhcpExpire / 1000);
9597 				}
9598 
9599 				if (opt->Opcode == DHCP_INFORM)
9600 				{
9601 					ret.LeaseTime = 0;
9602 				}
9603 
9604 				StrCpy(ret.DomainName, sizeof(ret.DomainName), v->DhcpDomain);
9605 				ret.SubnetMask = v->DhcpMask;
9606 				ret.DnsServer = v->DhcpDns;
9607 				ret.DnsServer2 = v->DhcpDns2;
9608 				ret.Gateway = v->DhcpGateway;
9609 
9610 				if (GetGlobalServerFlag(GSF_DISABLE_PUSH_ROUTE) == 0)
9611 				{
9612 					Copy(&ret.ClasslessRoute, &v->PushRoute, sizeof(DHCP_CLASSLESS_ROUTE_TABLE));
9613 
9614 					if (IsIpcMacAddress(p->MacAddressSrc))
9615 					{
9616 						if (ret.Gateway == 0)
9617 						{
9618 							// If the default gateway is not specified, add the static routing table
9619 							// entry for the local IP subnet
9620 							// (for PPP clients)
9621 							IP dhcp_ip;
9622 							IP dhcp_mask;
9623 							IP dhcp_network;
9624 
9625 							UINTToIP(&dhcp_ip, ip);
9626 
9627 							if (ip == 0)
9628 							{
9629 								UINTToIP(&dhcp_ip, p->L3.IPv4Header->SrcIP);
9630 							}
9631 
9632 							UINTToIP(&dhcp_mask, v->DhcpMask);
9633 
9634 							IPAnd4(&dhcp_network, &dhcp_ip, &dhcp_mask);
9635 
9636 							if (GetBestClasslessRoute(&ret.ClasslessRoute, &dhcp_ip) == NULL)
9637 							{
9638 								if (ret.ClasslessRoute.NumExistingRoutes < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES)
9639 								{
9640 									DHCP_CLASSLESS_ROUTE *cr = &ret.ClasslessRoute.Entries[ret.ClasslessRoute.NumExistingRoutes];
9641 
9642 									cr->Exists = true;
9643 
9644 									UINTToIP(&cr->Gateway, v->HostIP);
9645 
9646 									if (v->UseNat == false && ret.ClasslessRoute.NumExistingRoutes >= 1)
9647 									{
9648 										Copy(&cr->Gateway, &ret.ClasslessRoute.Entries[0].Gateway, sizeof(IP));
9649 									}
9650 
9651 									Copy(&cr->Network, &dhcp_network, sizeof(IP));
9652 									Copy(&cr->SubnetMask, &dhcp_mask, sizeof(IP));
9653 									cr->SubnetMaskLen = SubnetMaskToInt(&dhcp_mask);
9654 
9655 									ret.ClasslessRoute.NumExistingRoutes++;
9656 								}
9657 							}
9658 						}
9659 					}
9660 				}
9661 
9662 				if (opt->Opcode != DHCP_INFORM)
9663 				{
9664 					char client_mac[MAX_SIZE];
9665 					char client_ip[64];
9666 					IP ips;
9667 
9668 					BinToStr(client_mac, sizeof(client_mac), p->MacAddressSrc, 6);
9669 					UINTToIP(&ips, ip);
9670 					IPToStr(client_ip, sizeof(client_ip), &ips);
9671 
9672 					if (ret.Opcode == DHCP_OFFER)
9673 					{
9674 						// DHCP_OFFER
9675 						DHCP_LEASE *d = NewDhcpLease(5000, p->MacAddressSrc, ip, v->DhcpMask, opt->Hostname);
9676 						d->Id = LIST_NUM(v->DhcpPendingLeaseList);
9677 						Add(v->DhcpPendingLeaseList, d);
9678 
9679 						Debug("VirtualDhcpServer(): %s has been marked as pending for %s\n", client_ip, client_mac);
9680 					}
9681 					else
9682 					{
9683 						// DHCP_ACK
9684 						Debug("VirtualDhcpServer(): %s has been assigned to %s\n", client_ip, client_mac);
9685 					}
9686 				}
9687 
9688 				// Build a DHCP option
9689 				o = BuildDhcpOption(&ret);
9690 				if (o != NULL)
9691 				{
9692 					BUF *b = BuildDhcpOptionsBuf(o);
9693 					if (b != NULL)
9694 					{
9695 						UINT dest_ip = p->L3.IPv4Header->SrcIP;
9696 						if (dest_ip == 0)
9697 						{
9698 							dest_ip = 0xffffffff;
9699 						}
9700 						// Transmission
9701 						VirtualDhcpSend(v, tran_id, dest_ip, Endian16(p->L4.UDPHeader->SrcPort),
9702 						                ip, dhcp->ClientMacAddress, b, dhcp->HardwareType, dhcp->HardwareAddressSize);
9703 
9704 						// Release the memory
9705 						FreeBuf(b);
9706 					}
9707 					FreeDhcpOptions(o);
9708 				}
9709 			}
9710 		}
9711 		else
9712 		{
9713 			// There is no IP address that can be provided
9714 			DHCP_OPTION_LIST ret;
9715 			LIST *o;
9716 			Zero(&ret, sizeof(ret));
9717 
9718 			ret.Opcode = DHCP_NACK;
9719 			ret.ServerAddress = v->HostIP;
9720 			StrCpy(ret.DomainName, sizeof(ret.DomainName), v->DhcpDomain);
9721 			ret.SubnetMask = v->DhcpMask;
9722 
9723 			// Build the DHCP option
9724 			o = BuildDhcpOption(&ret);
9725 			if (o != NULL)
9726 			{
9727 				BUF *b = BuildDhcpOptionsBuf(o);
9728 				if (b != NULL)
9729 				{
9730 					UINT dest_ip = p->L3.IPv4Header->SrcIP;
9731 					if (dest_ip == 0)
9732 					{
9733 						dest_ip = 0xffffffff;
9734 					}
9735 					// Transmission
9736 					VirtualDhcpSend(v, tran_id, dest_ip, Endian16(p->L4.UDPHeader->SrcPort),
9737 					                ip, dhcp->ClientMacAddress, b, dhcp->HardwareType, dhcp->HardwareAddressSize);
9738 
9739 					// Release the memory
9740 					FreeBuf(b);
9741 				}
9742 				FreeDhcpOptions(o);
9743 			}
9744 		}
9745 	}
9746 
9747 	// Release the memory
9748 	Free(opt);
9749 }
9750 
9751 // Submit the DHCP response packet
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)9752 void VirtualDhcpSend(VH *v, UINT tran_id, UINT dest_ip, UINT dest_port,
9753                      UINT new_ip, UCHAR *client_mac, BUF *b, UINT hw_type, UINT hw_addr_size)
9754 {
9755 	UINT blank_size = 128 + 64;
9756 	UINT dhcp_packet_size;
9757 	UINT magic = Endian32(DHCP_MAGIC_COOKIE);
9758 	DHCPV4_HEADER *dhcp;
9759 	void *magic_cookie_addr;
9760 	void *buffer_addr;
9761 	// Validate arguments
9762 	if (v == NULL || b == NULL)
9763 	{
9764 		return;
9765 	}
9766 
9767 	// Calculate the DHCP packet size
9768 	dhcp_packet_size = blank_size + sizeof(DHCPV4_HEADER) + sizeof(magic) + b->Size;
9769 
9770 	if (dhcp_packet_size < DHCP_MIN_SIZE)
9771 	{
9772 		// Padding
9773 		dhcp_packet_size = DHCP_MIN_SIZE;
9774 	}
9775 
9776 	// Create a header
9777 	dhcp = ZeroMalloc(dhcp_packet_size);
9778 
9779 	dhcp->OpCode = 2;
9780 	dhcp->HardwareType = hw_type;
9781 	dhcp->HardwareAddressSize = hw_addr_size;
9782 	dhcp->Hops = 0;
9783 	dhcp->TransactionId = Endian32(tran_id);
9784 	dhcp->Seconds = 0;
9785 	dhcp->Flags = 0;
9786 	dhcp->YourIP = new_ip;
9787 	dhcp->ServerIP = v->HostIP;
9788 	Copy(dhcp->ClientMacAddress, client_mac, 6);
9789 
9790 	// Calculate the address
9791 	magic_cookie_addr = (((UCHAR *)dhcp) + sizeof(DHCPV4_HEADER) + blank_size);
9792 	buffer_addr = ((UCHAR *)magic_cookie_addr) + sizeof(magic);
9793 
9794 	// Magic Cookie
9795 	Copy(magic_cookie_addr, &magic, sizeof(magic));
9796 
9797 	// Buffer
9798 	Copy(buffer_addr, b->Buf, b->Size);
9799 
9800 	// Transmission
9801 	SendUdp(v, dest_ip, dest_port, v->HostIP, NAT_DHCP_SERVER_PORT, dhcp, dhcp_packet_size);
9802 
9803 	Free(dhcp);
9804 }
9805 
9806 // Virtual host: Process the Layer2
VirtualLayer2(VH * v,PKT * packet)9807 void VirtualLayer2(VH *v, PKT *packet)
9808 {
9809 	bool ok;
9810 	// Validate arguments
9811 	if (packet == NULL || v == NULL)
9812 	{
9813 		return;
9814 	}
9815 
9816 	// Packet filter
9817 	if (VirtualLayer2Filter(v, packet) == false)
9818 	{
9819 		// Packet was ignored
9820 		return;
9821 	}
9822 
9823 	ok = false;
9824 	if (packet->TypeL3 == L3_IPV4 && packet->TypeL4 == L4_UDP && packet->TypeL7 == L7_DHCPV4)
9825 	{
9826 		if (v->UseDhcp)
9827 		{
9828 			// A special treatment on the DHCP packet
9829 			if (packet->BroadcastPacket || Cmp(packet->MacAddressDest, v->MacAddress, 6) == 0)
9830 			{
9831 				// Virtual DHCP server processing
9832 				VirtualDhcpServer(v, packet);
9833 				ok = true;
9834 			}
9835 		}
9836 	}
9837 
9838 	if (ok == false)
9839 	{
9840 		// The process for each supported protocol
9841 		switch (packet->TypeL3)
9842 		{
9843 		case L3_ARPV4:	// ARPv4
9844 			VirtualArpReceived(v, packet);
9845 			break;
9846 
9847 		case L3_IPV4:	// IPv4
9848 			VirtualIpReceived(v, packet);
9849 			break;
9850 		}
9851 	}
9852 }
9853 
9854 // Packet filter (Blocking packets to other than me)
VirtualLayer2Filter(VH * v,PKT * packet)9855 bool VirtualLayer2Filter(VH *v, PKT *packet)
9856 {
9857 	// Validate arguments
9858 	if (v == NULL || packet == NULL)
9859 	{
9860 		return false;
9861 	}
9862 
9863 	// Pass through if broadcast packet
9864 	if (packet->BroadcastPacket)
9865 	{
9866 		return true;
9867 	}
9868 
9869 	// Ignore if the sender of the packet is myself
9870 	if (Cmp(packet->MacAddressSrc, v->MacAddress, 6) == 0)
9871 	{
9872 		return false;
9873 	}
9874 	// Pass through in the case of a packet addressed to me
9875 	if (Cmp(packet->MacAddressDest, v->MacAddress, 6) == 0)
9876 	{
9877 		return true;
9878 	}
9879 
9880 	// Discard if the other packets
9881 	return false;
9882 }
9883 
9884 // The virtual host is made to receive a packet
VirtualPutPacket(VH * v,void * data,UINT size)9885 bool VirtualPutPacket(VH *v, void *data, UINT size)
9886 {
9887 	if (data == NULL)
9888 	{
9889 		// Flush
9890 		v->flag1 = false;
9891 
9892 		if (v->NativeNat != NULL)
9893 		{
9894 			if (v->NativeNat->SendStateChanged)
9895 			{
9896 				TUBE *halt_tube = NULL;
9897 
9898 				Lock(v->NativeNat->Lock);
9899 				{
9900 					if (v->NativeNat->HaltTube != NULL)
9901 					{
9902 						halt_tube = v->NativeNat->HaltTube;
9903 
9904 						AddRef(halt_tube->Ref);
9905 					}
9906 				}
9907 				Unlock(v->NativeNat->Lock);
9908 
9909 				if (halt_tube != NULL)
9910 				{
9911 					TubeFlushEx(halt_tube, true);
9912 
9913 					v->NativeNat->SendStateChanged = false;
9914 
9915 					ReleaseTube(halt_tube);
9916 				}
9917 			}
9918 		}
9919 	}
9920 	else
9921 	{
9922 		// Interpret the received packet
9923 		PKT *packet = ParsePacket(data, size);
9924 
9925 		if (v->flag1 == false)
9926 		{
9927 			v->flag1 = true;
9928 			v->Now = Tick64();
9929 		}
9930 
9931 		// Lock the entire virtual machine in here
9932 		LockVirtual(v);
9933 		{
9934 			if (packet != NULL)
9935 			{
9936 				// Process the Layer-2
9937 				VirtualLayer2(v, packet);
9938 
9939 				// Release the packet structure
9940 				FreePacket(packet);
9941 			}
9942 		}
9943 		UnlockVirtual(v);
9944 
9945 		Free(data);
9946 	}
9947 
9948 	return true;
9949 }
VirtualPaPutPacket(SESSION * s,void * data,UINT size)9950 bool VirtualPaPutPacket(SESSION *s, void *data, UINT size)
9951 {
9952 	VH *v;
9953 	// Validate arguments
9954 	if (s == NULL || (v = (VH *)s->PacketAdapter->Param) == NULL)
9955 	{
9956 		return false;
9957 	}
9958 
9959 	return VirtualPutPacket(v, data, size);
9960 }
9961 
9962 // Get the options for the virtual host
GetVirtualHostOption(VH * v,VH_OPTION * o)9963 void GetVirtualHostOption(VH *v, VH_OPTION *o)
9964 {
9965 	// Validate arguments
9966 	if (v == NULL)
9967 	{
9968 		return;
9969 	}
9970 
9971 	LockVirtual(v);
9972 	{
9973 		Zero(o, sizeof(VH_OPTION));
9974 
9975 		// MAC address
9976 		Copy(o->MacAddress, v->MacAddress, 6);
9977 
9978 		// Host information
9979 		UINTToIP(&o->Ip, v->HostIP);
9980 		UINTToIP(&o->Mask, v->HostMask);
9981 
9982 		o->Mtu = v->Mtu;
9983 
9984 		// NAT timeout information
9985 		o->NatTcpTimeout = v->NatTcpTimeout / 1000;
9986 		o->NatUdpTimeout = v->NatUdpTimeout / 1000;
9987 
9988 		// NAT using flag
9989 		o->UseNat = v->UseNat;
9990 
9991 		// DHCP using flag
9992 		o->UseDhcp = v->UseDhcp;
9993 
9994 		// IP address range for DHCP distribution
9995 		UINTToIP(&o->DhcpLeaseIPStart, v->DhcpIpStart);
9996 		UINTToIP(&o->DhcpLeaseIPEnd, v->DhcpIpEnd);
9997 
9998 		// Subnet mask
9999 		UINTToIP(&o->DhcpSubnetMask, v->DhcpMask);
10000 
10001 		// Expiration date
10002 		if (v->DhcpExpire != INFINITE)
10003 		{
10004 			o->DhcpExpireTimeSpan = v->DhcpExpire / 1000;
10005 		}
10006 		else
10007 		{
10008 			o->DhcpExpireTimeSpan = INFINITE;
10009 		}
10010 
10011 		// Gateway address
10012 		UINTToIP(&o->DhcpGatewayAddress, v->DhcpGateway);
10013 
10014 		// DNS server address
10015 		UINTToIP(&o->DhcpDnsServerAddress, v->DhcpDns);
10016 		UINTToIP(&o->DhcpDnsServerAddress2, v->DhcpDns2);
10017 
10018 		// Domain name
10019 		StrCpy(o->DhcpDomainName, sizeof(o->DhcpDomainName), v->DhcpDomain);
10020 
10021 		// Save a log
10022 		o->SaveLog = v->SaveLog;
10023 
10024 		// Pushing route option
10025 		BuildClasslessRouteTableStr(o->DhcpPushRoutes, sizeof(o->DhcpPushRoutes), &v->PushRoute);
10026 		o->ApplyDhcpPushRoutes = true;
10027 	}
10028 	UnlockVirtual(v);
10029 }
10030 
10031 // Set the option to the virtual host
SetVirtualHostOption(VH * v,VH_OPTION * vo)10032 void SetVirtualHostOption(VH *v, VH_OPTION *vo)
10033 {
10034 	UINT i;
10035 	// Validate arguments
10036 	if (v == NULL || vo == NULL)
10037 	{
10038 		return;
10039 	}
10040 
10041 	LockVirtual(v);
10042 	{
10043 		// Set the MAC address
10044 		for (i = 0; i < 6; i++)
10045 		{
10046 			if (vo->MacAddress[i] != 0)
10047 			{
10048 				Copy(v->MacAddress, vo->MacAddress, 6);
10049 				break;
10050 			}
10051 		}
10052 
10053 		// Set the host information list
10054 		v->HostIP = IPToUINT(&vo->Ip);
10055 		v->HostMask = IPToUINT(&vo->Mask);
10056 
10057 		// Set the MTU, MMS
10058 		v->Mtu = MIN(vo->Mtu, MAX_L3_DATA_SIZE);
10059 		if (v->Mtu == 0)
10060 		{
10061 			v->Mtu = MAX_L3_DATA_SIZE;
10062 		}
10063 		v->Mtu = MAX(v->Mtu, TCP_HEADER_SIZE + IP_HEADER_SIZE + MAC_HEADER_SIZE + 8);
10064 		v->IpMss = ((v->Mtu - IP_HEADER_SIZE) / 8) * 8;
10065 		v->TcpMss = ((v->IpMss - TCP_HEADER_SIZE) / 8) * 8;
10066 		v->UdpMss = ((v->IpMss - UDP_HEADER_SIZE) / 8) * 8;
10067 
10068 		if (vo->NatTcpTimeout != 0)
10069 		{
10070 			v->NatTcpTimeout = MIN(vo->NatTcpTimeout, 4000000) * 1000;
10071 		}
10072 		if (vo->NatUdpTimeout != 0)
10073 		{
10074 			v->NatUdpTimeout = MIN(vo->NatUdpTimeout, 4000000) * 1000;
10075 		}
10076 		v->NatTcpTimeout = MAKESURE(v->NatTcpTimeout, NAT_TCP_MIN_TIMEOUT, NAT_TCP_MAX_TIMEOUT);
10077 		v->NatUdpTimeout = MAKESURE(v->NatUdpTimeout, NAT_UDP_MIN_TIMEOUT, NAT_UDP_MAX_TIMEOUT);
10078 		Debug("Timeout: %d , %d\n", v->NatTcpTimeout, v->NatUdpTimeout);
10079 
10080 		// NAT using flag
10081 		v->UseNat = vo->UseNat;
10082 
10083 		// DHCP using flag
10084 		v->UseDhcp = vo->UseDhcp;
10085 
10086 		// Expiration date
10087 		if (vo->DhcpExpireTimeSpan == 0 || vo->DhcpExpireTimeSpan == INFINITE)
10088 		{
10089 			v->DhcpExpire = INFINITE;
10090 		}
10091 		else
10092 		{
10093 			v->DhcpExpire = MAKESURE(DHCP_MIN_EXPIRE_TIMESPAN,
10094 			                         MIN(vo->DhcpExpireTimeSpan * 1000, 2000000000),
10095 			                         INFINITE);
10096 		}
10097 
10098 		// Address range to be distributed
10099 		v->DhcpIpStart = IPToUINT(&vo->DhcpLeaseIPStart);
10100 		v->DhcpIpEnd = IPToUINT(&vo->DhcpLeaseIPEnd);
10101 		if (Endian32(v->DhcpIpEnd) < Endian32(v->DhcpIpStart))
10102 		{
10103 			v->DhcpIpEnd = v->DhcpIpStart;
10104 		}
10105 
10106 		// Subnet mask
10107 		v->DhcpMask = IPToUINT(&vo->DhcpSubnetMask);
10108 
10109 		// Gateway address
10110 		v->DhcpGateway = IPToUINT(&vo->DhcpGatewayAddress);
10111 
10112 		// DNS server address
10113 		v->DhcpDns = IPToUINT(&vo->DhcpDnsServerAddress);
10114 		v->DhcpDns2 = IPToUINT(&vo->DhcpDnsServerAddress2);
10115 
10116 		// Domain name
10117 		StrCpy(v->DhcpDomain, sizeof(v->DhcpDomain), vo->DhcpDomainName);
10118 
10119 		// Save a log
10120 		v->SaveLog = vo->SaveLog;
10121 
10122 		// DHCP routing table pushing setting
10123 		if (vo->ApplyDhcpPushRoutes)
10124 		{
10125 			DHCP_CLASSLESS_ROUTE_TABLE rt;
10126 
10127 			Zero(&rt, sizeof(rt));
10128 
10129 			if (ParseClasslessRouteTableStr(&rt, vo->DhcpPushRoutes))
10130 			{
10131 				Copy(&v->PushRoute, &rt, sizeof(DHCP_CLASSLESS_ROUTE_TABLE));
10132 			}
10133 		}
10134 	}
10135 	UnlockVirtual(v);
10136 }
10137 
10138 // Release the virtual host
Virtual_Free(VH * v)10139 void Virtual_Free(VH *v)
10140 {
10141 	// Release the DHCP server
10142 	FreeDhcpServer(v);
10143 
10144 	// NAT release
10145 	FreeNat(v);
10146 
10147 	LockVirtual(v);
10148 	{
10149 		// Release the IP combining list
10150 		FreeIpCombineList(v);
10151 
10152 		// Release the IP waiting table
10153 		FreeIpWaitTable(v);
10154 
10155 		// Release the ARP waiting table
10156 		FreeArpWaitTable(v);
10157 
10158 		// Release the ARP table
10159 		FreeArpTable(v);
10160 
10161 		// Release the transmission queue
10162 		LockQueue(v->SendQueue);
10163 		{
10164 			BLOCK *block;
10165 
10166 			// Release all queues
10167 			while (block = GetNext(v->SendQueue))
10168 			{
10169 				FreeBlock(block);
10170 			}
10171 		}
10172 		UnlockQueue(v->SendQueue);
10173 		ReleaseQueue(v->SendQueue);
10174 		v->SendQueue = NULL;
10175 
10176 		// Release the cancel object
10177 		ReleaseCancel(v->Cancel);
10178 
10179 		v->Active = false;
10180 	}
10181 	UnlockVirtual(v);
10182 
10183 	// Release the logger
10184 	FreeLog(v->Logger);
10185 }
VirtualPaFree(SESSION * s)10186 void VirtualPaFree(SESSION *s)
10187 {
10188 	VH *v;
10189 	// Validate arguments
10190 	if (s == NULL || (v = (VH *)s->PacketAdapter->Param) == NULL)
10191 	{
10192 		return;
10193 	}
10194 
10195 	Virtual_Free(v);
10196 }
10197 
10198 // Release the virtual host
ReleaseVirtual(VH * v)10199 void ReleaseVirtual(VH *v)
10200 {
10201 	// Validate arguments
10202 	if (v == NULL)
10203 	{
10204 		return;
10205 	}
10206 
10207 	if (Release(v->ref) == 0)
10208 	{
10209 		CleanupVirtual(v);
10210 	}
10211 }
10212 
10213 // Lock the virtual host
LockVirtual(VH * v)10214 void LockVirtual(VH *v)
10215 {
10216 	// Validate arguments
10217 	if (v == NULL)
10218 	{
10219 		return;
10220 	}
10221 
10222 	Lock(v->lock);
10223 }
10224 
10225 // Unlock the virtual host
UnlockVirtual(VH * v)10226 void UnlockVirtual(VH *v)
10227 {
10228 	// Validate arguments
10229 	if (v == NULL)
10230 	{
10231 		return;
10232 	}
10233 
10234 	Unlock(v->lock);
10235 }
10236 
10237 // Cleanup the virtual host
CleanupVirtual(VH * v)10238 void CleanupVirtual(VH *v)
10239 {
10240 	// Validate arguments
10241 	if (v == NULL)
10242 	{
10243 		return;
10244 	}
10245 
10246 	if (v->Session != NULL)
10247 	{
10248 		ReleaseSession(v->Session);
10249 	}
10250 
10251 	DeleteCounter(v->Counter);
10252 	DeleteLock(v->lock);
10253 
10254 	Free(v);
10255 }
10256 
10257 // Stop the virtual host
StopVirtualHost(VH * v)10258 void StopVirtualHost(VH *v)
10259 {
10260 	SESSION *s;
10261 	// Validate arguments
10262 	if (v == NULL)
10263 	{
10264 		return;
10265 	}
10266 
10267 	// Get the session corresponding to the virtual host
10268 	LockVirtual(v);
10269 	{
10270 		s = v->Session;
10271 		if (s != NULL)
10272 		{
10273 			AddRef(s->ref);
10274 		}
10275 	}
10276 	UnlockVirtual(v);
10277 
10278 	if (s == NULL)
10279 	{
10280 		// This session is already stopped
10281 		return;
10282 	}
10283 
10284 	// Stop Session
10285 	StopSession(s);
10286 
10287 	ReleaseSession(s);
10288 }
10289 
10290 // Create a new virtual host
NewVirtualHost(CEDAR * cedar,CLIENT_OPTION * option,CLIENT_AUTH * auth,VH_OPTION * vh_option)10291 VH *NewVirtualHost(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, VH_OPTION *vh_option)
10292 {
10293 	return NewVirtualHostEx(cedar, option, auth, vh_option, NULL);
10294 }
NewVirtualHostEx(CEDAR * cedar,CLIENT_OPTION * option,CLIENT_AUTH * auth,VH_OPTION * vh_option,NAT * nat)10295 VH *NewVirtualHostEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, VH_OPTION *vh_option, NAT *nat)
10296 {
10297 	VH *v;
10298 	SOCK *s;
10299 	// Validate arguments
10300 	if (vh_option == NULL)
10301 	{
10302 		return NULL;
10303 	}
10304 
10305 	// Create a VH
10306 	v = ZeroMalloc(sizeof(VH));
10307 	v->ref = NewRef();
10308 	v->lock = NewLock();
10309 	v->Counter = NewCounter();
10310 
10311 	v->nat = nat;
10312 
10313 	// Examine whether ICMP Raw Socket can be created
10314 	s = NewUDP4(MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4), NULL);
10315 	if (s != NULL)
10316 	{
10317 		if (s->IsTtlSupported)
10318 		{
10319 			v->IcmpRawSocketOk = true;
10320 		}
10321 
10322 		ReleaseSock(s);
10323 	}
10324 
10325 	if (v->IcmpRawSocketOk == false)
10326 	{
10327 		v->IcmpApiOk = true;
10328 	}
10329 
10330 	// Set the options
10331 	SetVirtualHostOption(v, vh_option);
10332 
10333 	return v;
10334 }
10335 
10336 // Generate a random MAC address
GenMacAddress(UCHAR * mac)10337 void GenMacAddress(UCHAR *mac)
10338 {
10339 	UCHAR rand_data[32];
10340 	UINT64 now;
10341 	BUF *b;
10342 	UCHAR hash[SHA1_SIZE];
10343 	// Validate arguments
10344 	if (mac == NULL)
10345 	{
10346 		return;
10347 	}
10348 
10349 	// Get the current time
10350 	now = SystemTime64();
10351 
10352 	// Generate a random number
10353 	Rand(rand_data, sizeof(rand_data));
10354 
10355 	// Add to the buffer
10356 	b = NewBuf();
10357 	WriteBuf(b, &now, sizeof(now));
10358 	WriteBuf(b, rand_data, sizeof(rand_data));
10359 
10360 	// Hash
10361 	Sha0(hash, b->Buf, b->Size);
10362 
10363 	// Generate a MAC address
10364 	mac[0] = 0x5E;
10365 	mac[1] = hash[0];
10366 	mac[2] = hash[1];
10367 	mac[3] = hash[2];
10368 	mac[4] = hash[3];
10369 	mac[5] = hash[4];
10370 
10371 	FreeBuf(b);
10372 }
10373 
10374 // Get a packet of virtual host adapter
VirtualGetPacketAdapter()10375 PACKET_ADAPTER *VirtualGetPacketAdapter()
10376 {
10377 	return NewPacketAdapter(VirtualPaInit, VirtualPaGetCancel,
10378 	                        VirtualPaGetNextPacket, VirtualPaPutPacket, VirtualPaFree);
10379 }
10380 
10381 
10382