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