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