1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Cedar Communication Module
3
4
5 // VLanWin32.c
6 // Virtual device driver library for Win32
7
8 #ifdef OS_WIN32
9
10 #include "VLanWin32.h"
11
12 #include "Admin.h"
13 #include "Connection.h"
14 #include "UdpAccel.h"
15
16 #include "Mayaqua/Memory.h"
17 #include "Mayaqua/Microsoft.h"
18 #include "Mayaqua/Object.h"
19 #include "Mayaqua/Str.h"
20 #include "Mayaqua/Tick64.h"
21 #include "Mayaqua/Win32.h"
22
23 #include "Neo/Neo.h"
24
25 typedef DWORD(CALLBACK* OPENVXDHANDLE)(HANDLE);
26
27 // Get the version information of Windows
Win32GetWinVer(RPC_WINVER * v)28 void Win32GetWinVer(RPC_WINVER *v)
29 {
30 // Validate arguments
31 if (v == NULL)
32 {
33 return;
34 }
35
36 Zero(v, sizeof(RPC_WINVER));
37
38 v->IsWindows = true;
39
40 if (true)
41 {
42 OSVERSIONINFOEX os;
43 Zero(&os, sizeof(os));
44 os.dwOSVersionInfoSize = sizeof(os);
45 Win32GetVersionExInternal((LPOSVERSIONINFOA)&os);
46
47 v->IsNT = true;
48 v->Build = os.dwBuildNumber;
49 v->ServicePack = os.wServicePackMajor;
50
51 if (os.wProductType != VER_NT_WORKSTATION)
52 {
53 v->IsServer = true;
54 }
55 v->VerMajor = os.dwMajorVersion;
56 v->VerMinor = os.dwMinorVersion;
57
58 if (GetOsInfo()->OsServicePack == 0)
59 {
60 StrCpy(v->Title, sizeof(v->Title), GetOsInfo()->OsProductName);
61 }
62 else
63 {
64 Format(v->Title, sizeof(v->Title), "%s Service Pack %u",
65 GetOsInfo()->OsProductName,
66 GetOsInfo()->OsServicePack);
67 }
68 Trim(v->Title);
69
70 if (InStr(GetOsInfo()->OsVersion, "rc") ||
71 InStr(GetOsInfo()->OsVersion, "beta"))
72 {
73 v->IsBeta = true;
74 }
75 }
76 }
77
78 // Routing table tracking main
RouteTrackingMain(SESSION * s)79 void RouteTrackingMain(SESSION *s)
80 {
81 ROUTE_TRACKING *t;
82 UINT64 now;
83 ROUTE_TABLE *table;
84 ROUTE_ENTRY *rs;
85 bool changed = false;
86 bool check = false;
87 bool any_modified = false;
88 // Validate arguments
89 if (s == NULL)
90 {
91 return;
92 }
93 if (s->ClientModeAndUseVLan == false)
94 {
95 return;
96 }
97
98 // Get the state
99 t = ((VLAN *)s->PacketAdapter->Param)->RouteState;
100 if (t == NULL)
101 {
102 return;
103 }
104
105 // Current time
106 PROBE_STR("RouteTrackingMain 1");
107 now = Tick64();
108
109 if (t->RouteChange != NULL)
110 {
111 if (t->NextRouteChangeCheckTime == 0 ||
112 t->NextRouteChangeCheckTime <= now)
113 {
114 t->NextRouteChangeCheckTime = now + 1000ULL;
115
116 check = IsRouteChanged(t->RouteChange);
117
118 if (check)
119 {
120 Debug("*** Routing Table Changed ***\n");
121 t->NextTrackingTime = 0;
122 }
123 }
124 }
125 if (t->NextTrackingTime != 0 && t->NextTrackingTime > now)
126 {
127 if (s->UseUdpAcceleration && s->UdpAccel != NULL && s->UdpAccel->NatT_IP_Changed)
128 {
129 // Check always if the IP address of the NAT-T server has changed
130 }
131 else
132 {
133 PROBE_STR("RouteTrackingMain 2");
134 return;
135 }
136 }
137 PROBE_STR("RouteTrackingMain 3");
138
139 if (s->UseUdpAcceleration && s->UdpAccel != NULL)
140 {
141 IP nat_t_ip;
142
143 s->UdpAccel->NatT_IP_Changed = false;
144
145 Zero(&nat_t_ip, sizeof(nat_t_ip));
146
147 Lock(s->UdpAccel->NatT_Lock);
148 {
149 Copy(&nat_t_ip, &s->UdpAccel->NatT_IP, sizeof(IP));
150 }
151 Unlock(s->UdpAccel->NatT_Lock);
152
153 // Add a route to the NAT-T server
154 if (IsZeroIp(&nat_t_ip) == false)
155 {
156 if (t->RouteToNatTServer == NULL)
157 {
158 if (t->RouteToEight != NULL)
159 {
160 ROUTE_ENTRY *e = Clone(t->RouteToEight, sizeof(ROUTE_ENTRY));
161 char ip_str[64];
162 char ip_str2[64];
163
164 Copy(&e->DestIP, &nat_t_ip, sizeof(IP));
165 e->Metric = e->OldIfMetric;
166
167 IPToStr(ip_str, sizeof(ip_str), &e->DestIP);
168 IPToStr(ip_str2, sizeof(ip_str2), &e->GatewayIP);
169
170 t->RouteToNatTServer = e;
171
172 if (AddRouteEntry(t->RouteToNatTServer))
173 {
174 Debug("Adding Static Route to %s via %s metric %u: ok.\n", ip_str, ip_str2, e->Metric);
175 }
176 else
177 {
178 FreeRouteEntry(t->RouteToNatTServer);
179 t->RouteToNatTServer = NULL;
180 }
181 }
182 }
183 }
184 }
185
186 // Get the current routing table
187 table = GetRouteTable();
188 rs = t->RouteToServer;
189 if (table != NULL)
190 {
191 UINT i;
192 bool route_to_server_erased = true;
193 bool is_vlan_want_to_be_default_gateway = false;
194 UINT vlan_default_gateway_metric = 0;
195 UINT other_if_default_gateway_metric_min = INFINITE;
196
197 // Get whether the routing table have been changed
198 if (t->LastRoutingTableHash != table->HashedValue)
199 {
200 t->LastRoutingTableHash = table->HashedValue;
201 changed = true;
202 }
203
204 //DebugPrintRouteTable(table);
205
206 // Scan the routing table
207 for (i = 0;i < table->NumEntry;i++)
208 {
209 ROUTE_ENTRY *e = table->Entry[i];
210
211 if (rs != NULL)
212 {
213 if (CmpIpAddr(&e->DestIP, &rs->DestIP) == 0 &&
214 CmpIpAddr(&e->DestMask, &rs->DestMask) == 0
215 // && CmpIpAddr(&e->GatewayIP, &rs->GatewayIP) == 0
216 // && e->InterfaceID == rs->InterfaceID &&
217 // e->LocalRouting == rs->LocalRouting &&
218 // e->Metric == rs->Metric
219 )
220 {
221 // Routing entry to the server that added at the time of connection is found
222 route_to_server_erased = false;
223 }
224 }
225
226 // Search for the default gateway
227 if (IPToUINT(&e->DestIP) == 0 &&
228 IPToUINT(&e->DestMask) == 0)
229 {
230 Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n",
231 e->InterfaceID, t->VLanInterfaceId);
232
233 if (e->InterfaceID == t->VLanInterfaceId)
234 {
235 // The virtual LAN card think that he want to be a default gateway
236 is_vlan_want_to_be_default_gateway = true;
237 vlan_default_gateway_metric = e->Metric;
238
239 if (vlan_default_gateway_metric >= 2 &&
240 t->OldDefaultGatewayMetric == (vlan_default_gateway_metric - 1))
241 {
242 // Restore because the PPP server rewrites
243 // the routing table selfishly
244 DeleteRouteEntry(e);
245 e->Metric--;
246 AddRouteEntry(e);
247 Debug("** Restore metric destroyed by PPP.\n");
248
249 any_modified = true;
250 }
251
252 // Keep this entry
253 if (t->DefaultGatewayByVLan != NULL)
254 {
255 // Delete if there is one added last time
256 FreeRouteEntry(t->DefaultGatewayByVLan);
257 }
258
259 t->DefaultGatewayByVLan = ZeroMalloc(sizeof(ROUTE_ENTRY));
260 Copy(t->DefaultGatewayByVLan, e, sizeof(ROUTE_ENTRY));
261
262 t->OldDefaultGatewayMetric = vlan_default_gateway_metric;
263 }
264 else
265 {
266 // There are default gateway other than the virtual LAN card
267 // Save the metric value of the default gateway
268 if (other_if_default_gateway_metric_min > e->Metric)
269 {
270 // Ignore the metric value of all PPP connection in the case of Windows Vista
271 if (e->PPPConnection == false)
272 {
273 other_if_default_gateway_metric_min = e->Metric;
274 }
275 else
276 {
277 // a PPP is used to Connect to the network
278 // in using Windows Vista
279 t->VistaAndUsingPPP = true;
280 }
281 }
282 }
283 }
284 }
285
286 if (t->VistaAndUsingPPP)
287 {
288 if (t->DefaultGatewayByVLan != NULL)
289 {
290 if (is_vlan_want_to_be_default_gateway)
291 {
292 if (t->VistaOldDefaultGatewayByVLan == NULL || Cmp(t->VistaOldDefaultGatewayByVLan, t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY)) != 0)
293 {
294 ROUTE_ENTRY *e;
295 // Add the route of 0.0.0.0/1 and 128.0.0.0/1
296 // to the system if the virtual LAN card should be
297 // the default gateway in the case of the connection
298 // using PPP in Windows Vista
299
300 if (t->VistaOldDefaultGatewayByVLan != NULL)
301 {
302 FreeRouteEntry(t->VistaOldDefaultGatewayByVLan);
303 }
304
305 if (t->VistaDefaultGateway1 != NULL)
306 {
307 DeleteRouteEntry(t->VistaDefaultGateway1);
308 FreeRouteEntry(t->VistaDefaultGateway1);
309
310 DeleteRouteEntry(t->VistaDefaultGateway2);
311 FreeRouteEntry(t->VistaDefaultGateway2);
312 }
313
314 t->VistaOldDefaultGatewayByVLan = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));
315
316 e = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));
317 SetIP(&e->DestIP, 0, 0, 0, 0);
318 SetIP(&e->DestMask, 128, 0, 0, 0);
319 t->VistaDefaultGateway1 = e;
320
321 e = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));
322 SetIP(&e->DestIP, 128, 0, 0, 0);
323 SetIP(&e->DestMask, 128, 0, 0, 0);
324 t->VistaDefaultGateway2 = e;
325
326 AddRouteEntry(t->VistaDefaultGateway1);
327 AddRouteEntry(t->VistaDefaultGateway2);
328
329 Debug("Vista PPP Fix Route Table Added.\n");
330
331 any_modified = true;
332 }
333 }
334 else
335 {
336 if (t->VistaOldDefaultGatewayByVLan != NULL)
337 {
338 FreeRouteEntry(t->VistaOldDefaultGatewayByVLan);
339 t->VistaOldDefaultGatewayByVLan = NULL;
340 }
341
342 if (t->VistaDefaultGateway1 != NULL)
343 {
344 Debug("Vista PPP Fix Route Table Deleted.\n");
345 DeleteRouteEntry(t->VistaDefaultGateway1);
346 FreeRouteEntry(t->VistaDefaultGateway1);
347
348 DeleteRouteEntry(t->VistaDefaultGateway2);
349 FreeRouteEntry(t->VistaDefaultGateway2);
350
351 any_modified = true;
352
353 t->VistaDefaultGateway1 = t->VistaDefaultGateway2 = NULL;
354 }
355 }
356 }
357 }
358
359 // If the virtual LAN card want to be the default gateway and
360 // there is no LAN card with smaller metric of 0.0.0.0/0 than
361 // the virtual LAN card, delete other default gateway entries
362 // to elect the virtual LAN card as the default gateway
363 // Debug("is_vlan_want_to_be_default_gateway = %u, rs = %u, route_to_server_erased = %u, other_if_default_gateway_metric_min = %u, vlan_default_gateway_metric = %u\n",
364 // is_vlan_want_to_be_default_gateway, rs, route_to_server_erased, other_if_default_gateway_metric_min, vlan_default_gateway_metric);
365 if (is_vlan_want_to_be_default_gateway && (rs != NULL && route_to_server_erased == false) &&
366 other_if_default_gateway_metric_min >= vlan_default_gateway_metric)
367 {
368 // Scan the routing table again
369 for (i = 0;i < table->NumEntry;i++)
370 {
371 ROUTE_ENTRY *e = table->Entry[i];
372
373 if (e->InterfaceID != t->VLanInterfaceId)
374 {
375 if (IPToUINT(&e->DestIP) == 0 &&
376 IPToUINT(&e->DestMask) == 0)
377 {
378 char str[64];
379 // Default gateway is found
380 ROUTE_ENTRY *r = ZeroMalloc(sizeof(ROUTE_ENTRY));
381
382 Copy(r, e, sizeof(ROUTE_ENTRY));
383
384 // Put in the queue
385 InsertQueue(t->DeletedDefaultGateway, r);
386
387 // Delete this gateway entry once
388 DeleteRouteEntry(e);
389
390 IPToStr(str, sizeof(str), &e->GatewayIP);
391 Debug("Default Gateway %s Deleted.\n", str);
392
393 any_modified = true;
394 }
395 }
396 }
397 }
398
399 if (rs != NULL && route_to_server_erased)
400 {
401 // Physical entry to the server has disappeared
402 Debug("Route to Server entry ERASED !!!\n");
403
404 // Forced disconnection (reconnection enabled)
405 s->RetryFlag = true;
406 s->Halt = true;
407 }
408
409 // Release the routing table
410 FreeRouteTable(table);
411 }
412
413 // Set the time to perform the next track
414 if (t->NextTrackingTimeAdd == 0 || changed)
415 {
416 t->NextTrackingTimeAdd = TRACKING_INTERVAL_INITIAL;
417 }
418 else
419 {
420 UINT64 max_value = TRACKING_INTERVAL_MAX;
421 if (t->RouteChange != NULL)
422 {
423 max_value = TRACKING_INTERVAL_MAX_RC;
424 }
425
426 t->NextTrackingTimeAdd += TRACKING_INTERVAL_ADD;
427
428 if (t->NextTrackingTimeAdd >= max_value)
429 {
430 t->NextTrackingTimeAdd = max_value;
431 }
432 }
433 //Debug("t->NextTrackingTimeAdd = %I64u\n", t->NextTrackingTimeAdd);
434 t->NextTrackingTime = now + t->NextTrackingTimeAdd;
435
436 if (any_modified)
437 {
438 // Clear the DNS cache
439 Win32FlushDnsCache();
440 }
441 }
442
443 // Start tracking of the routing table
RouteTrackingStart(SESSION * s)444 void RouteTrackingStart(SESSION *s)
445 {
446 VLAN *v;
447 ROUTE_TRACKING *t;
448 UINT if_id = 0;
449 ROUTE_ENTRY *e;
450 ROUTE_ENTRY *dns = NULL;
451 ROUTE_ENTRY *route_to_real_server_global = NULL;
452 char tmp[64];
453 UINT exclude_if_id = 0;
454 bool already_exists = false;
455 bool already_exists_by_other_account = false;
456 IP eight;
457 // Validate arguments
458 if (s == NULL)
459 {
460 return;
461 }
462
463 v = (VLAN *)s->PacketAdapter->Param;
464 if (v->RouteState != NULL)
465 {
466 return;
467 }
468
469 // Get the interface ID of the virtual LAN card
470 if_id = GetInstanceId(v->InstanceName);
471 Debug("[InstanceId of %s] = 0x%x\n", v->InstanceName, if_id);
472
473 // The routing table by the virtual LAN card body should be
474 // excluded explicitly in Windows Vista
475 exclude_if_id = if_id;
476
477 // Get the route to the server
478 e = GetBestRouteEntryEx(&s->ServerIP, exclude_if_id);
479 if (e == NULL)
480 {
481 // Acquisition failure
482 Debug("Failed to get GetBestRouteEntry().\n");
483 return;
484 }
485 IPToStr(tmp, sizeof(tmp), &e->GatewayIP);
486 Debug("GetBestRouteEntry() Succeed. [Gateway: %s]\n", tmp);
487
488 // Add a route
489 e->Metric = e->OldIfMetric;
490
491 if (AddRouteEntryEx(e, &already_exists) == false)
492 {
493 FreeRouteEntry(e);
494 e = NULL;
495 }
496 Debug("already_exists: %u\n", already_exists);
497
498 if (already_exists)
499 {
500 if (s->Cedar->Client != NULL && s->Account != NULL)
501 {
502 UINT i;
503 ACCOUNT *a;
504 for (i = 0;i < LIST_NUM(s->Cedar->Client->AccountList);i++)
505 {
506 a = LIST_DATA(s->Cedar->Client->AccountList, i);
507 Lock(a->lock);
508 {
509 SESSION *sess = a->ClientSession;
510 if (sess != NULL && sess != s)
511 {
512 VLAN *v = sess->PacketAdapter->Param;
513 if (v != NULL)
514 {
515 ROUTE_TRACKING *tr = v->RouteState;
516 if (tr != NULL && e != NULL)
517 {
518 if (Cmp(tr->RouteToServer, e, sizeof(ROUTE_ENTRY)) == 0)
519 {
520 already_exists_by_other_account = true;
521 }
522 }
523 }
524 }
525 }
526 Unlock(a->lock);
527 }
528 }
529
530 if (already_exists_by_other_account)
531 {
532 Debug("already_exists_by_other_account = %u\n", already_exists_by_other_account);
533 already_exists = false;
534 }
535 }
536
537 // Get the routing table to the DNS server
538 // (If the DNS server is this PC itself, there's no need to get)
539 if (IsZeroIP(&s->DefaultDns) == false)
540 {
541 if (IsMyIPAddress(&s->DefaultDns) == false)
542 {
543 dns = GetBestRouteEntryEx(&s->DefaultDns, exclude_if_id);
544 if (dns == NULL)
545 {
546 // Getting failure
547 Debug("Failed to get GetBestRouteEntry DNS.\n");
548 }
549 else
550 {
551 // Add a route
552 dns->Metric = dns->OldIfMetric;
553
554 if (AddRouteEntry(dns) == false)
555 {
556 FreeRouteEntry(dns);
557 dns = NULL;
558 }
559 }
560 }
561 }
562
563 if (s->IsAzureSession && IsZeroIP(&s->AzureRealServerGlobalIp) == false)
564 {
565 // Add also a static route to the real server in the case of via VPN Azure
566 if (IsMyIPAddress(&s->AzureRealServerGlobalIp) == false)
567 {
568 route_to_real_server_global = GetBestRouteEntryEx(&s->AzureRealServerGlobalIp, exclude_if_id);
569
570 if (route_to_real_server_global != NULL)
571 {
572 route_to_real_server_global->Metric = route_to_real_server_global->OldIfMetric;
573
574 if (AddRouteEntry(route_to_real_server_global) == false)
575 {
576 FreeRouteEntry(route_to_real_server_global);
577 route_to_real_server_global = NULL;
578 }
579 }
580 }
581 }
582
583 // Initialize
584 if (s->Cedar->Client != NULL && s->Account != NULL)
585 {
586 Lock(s->Account->lock);
587 }
588
589 t = ZeroMalloc(sizeof(ROUTE_TRACKING));
590 v->RouteState = t;
591
592 t->RouteToServerAlreadyExists = already_exists;
593 t->RouteToServer = e;
594 t->RouteToDefaultDns = dns;
595 t->RouteToRealServerGlobal = route_to_real_server_global;
596 t->VLanInterfaceId = if_id;
597 t->NextTrackingTime = 0;
598 t->DeletedDefaultGateway = NewQueue();
599 t->OldDefaultGatewayMetric = 0x7fffffff;
600
601 if (s->Cedar->Client != NULL && s->Account != NULL)
602 {
603 Unlock(s->Account->lock);
604 }
605
606 // Get the route to 8.8.8.8
607 SetIP(&eight, 8, 8, 8, 8);
608 t->RouteToEight = GetBestRouteEntryEx(&eight, exclude_if_id);
609
610 // Get the current default DNS server to detect network changes
611 GetDefaultDns(&t->OldDnsServer);
612
613 // Get as soon as releasing the IP address in the case of using DHCP
614 if (IsNt())
615 {
616 char tmp[MAX_SIZE];
617 MS_ADAPTER *a;
618
619 Format(tmp, sizeof(tmp), VLAN_ADAPTER_NAME_TAG, v->InstanceName);
620 a = MsGetAdapter(tmp);
621
622 if (a != NULL)
623 {
624 if (a->UseDhcp)
625 {
626 bool ret = Win32ReleaseAddressByGuidEx(a->Guid, 100);
627 Debug("*** Win32ReleaseAddressByGuidEx = %u\n", ret);
628
629 ret = Win32RenewAddressByGuidEx(a->Guid, 100);
630 Debug("*** Win32RenewAddressByGuidEx = %u\n", ret);
631 }
632
633 MsFreeAdapter(a);
634 }
635 }
636 else
637 {
638 // For Win9x
639 Win32RenewDhcp9x(if_id);
640 }
641
642 // Clear the DNS cache
643 Win32FlushDnsCache();
644
645 // Detect a change in the routing table (for only supported OS)
646 t->RouteChange = NewRouteChange();
647 Debug("t->RouteChange = 0x%p\n", t->RouteChange);
648 }
649
650 // End the tracking of the routing table
RouteTrackingStop(SESSION * s,ROUTE_TRACKING * t)651 void RouteTrackingStop(SESSION *s, ROUTE_TRACKING *t)
652 {
653 ROUTE_ENTRY *e;
654 ROUTE_TABLE *table;
655 IP dns_ip;
656 bool network_has_changed = false;
657 bool do_not_delete_routing_entry = false;
658 // Validate arguments
659 if (s == NULL || t == NULL)
660 {
661 return;
662 }
663
664 Zero(&dns_ip, sizeof(dns_ip));
665
666 if (t->DefaultGatewayByVLan != NULL)
667 {
668 FreeRouteEntry(t->DefaultGatewayByVLan);
669 t->DefaultGatewayByVLan = NULL;
670 }
671
672 if (t->VistaDefaultGateway1 != NULL)
673 {
674 Debug("Vista PPP Fix Route Table Deleted.\n");
675 DeleteRouteEntry(t->VistaDefaultGateway1);
676 FreeRouteEntry(t->VistaDefaultGateway1);
677
678 DeleteRouteEntry(t->VistaDefaultGateway2);
679 FreeRouteEntry(t->VistaDefaultGateway2);
680 }
681
682 // Clear the DNS cache
683 Win32FlushDnsCache();
684
685 if (s->Cedar->Client != NULL && s->Account != NULL)
686 {
687 UINT i;
688 ACCOUNT *a;
689 for (i = 0;i < LIST_NUM(s->Cedar->Client->AccountList);i++)
690 {
691 a = LIST_DATA(s->Cedar->Client->AccountList, i);
692 Lock(a->lock);
693 {
694 SESSION *sess = a->ClientSession;
695 if (sess != NULL && sess != s)
696 {
697 VLAN *v = sess->PacketAdapter->Param;
698 if (v != NULL)
699 {
700 ROUTE_TRACKING *tr = v->RouteState;
701 if (tr != NULL)
702 {
703 if (Cmp(tr->RouteToServer, t->RouteToServer, sizeof(ROUTE_ENTRY)) == 0)
704 {
705 do_not_delete_routing_entry = true;
706 }
707 }
708 }
709 }
710 }
711 Unlock(a->lock);
712 }
713
714 Lock(s->Account->lock);
715 }
716
717 if (do_not_delete_routing_entry == false)
718 {
719 // Delete the route that is added firstly
720 if (t->RouteToServerAlreadyExists == false)
721 {
722 DeleteRouteEntry(t->RouteToServer);
723 }
724
725 DeleteRouteEntry(t->RouteToDefaultDns);
726
727 DeleteRouteEntry(t->RouteToNatTServer);
728
729 DeleteRouteEntry(t->RouteToRealServerGlobal);
730 }
731
732 FreeRouteEntry(t->RouteToDefaultDns);
733 FreeRouteEntry(t->RouteToServer);
734 FreeRouteEntry(t->RouteToEight);
735 FreeRouteEntry(t->RouteToNatTServer);
736 FreeRouteEntry(t->RouteToRealServerGlobal);
737 t->RouteToDefaultDns = t->RouteToServer = t->RouteToEight =
738 t->RouteToNatTServer = t->RouteToRealServerGlobal = NULL;
739
740 if (s->Cedar->Client != NULL && s->Account != NULL)
741 {
742 Unlock(s->Account->lock);
743 }
744
745 #if 0
746 // Get the current DNS server
747 if (GetDefaultDns(&dns_ip))
748 {
749 if (IPToUINT(&t->OldDnsServer) != 0)
750 {
751 if (IPToUINT(&t->OldDnsServer) != IPToUINT(&dns_ip))
752 {
753 char s1[MAX_SIZE], s2[MAX_SIZE];
754 network_has_changed = true;
755 IPToStr(s1, sizeof(s1), &t->OldDnsServer);
756 IPToStr(s2, sizeof(s2), &dns_ip);
757 Debug("Old Dns: %s, New Dns: %s\n",
758 s1, s2);
759 }
760 }
761 }
762
763 if (network_has_changed == false)
764 {
765 Debug("Network: not changed.\n");
766 }
767 else
768 {
769 Debug("Network: Changed.\n");
770 }
771
772 #endif
773
774 // Get the current routing table
775 table = GetRouteTable();
776
777 // Restore the routing table which has been removed so far
778 while (e = GetNext(t->DeletedDefaultGateway))
779 {
780 bool restore = true;
781 UINT i;
782 // If the restoring routing entry is a default gateway and
783 // the existing routing table contains another default gateway
784 // on the interface, give up restoring the entry
785 if (IPToUINT(&e->DestIP) == 0 && IPToUINT(&e->DestMask) == 0)
786 {
787 for (i = 0;i < table->NumEntry;i++)
788 {
789 ROUTE_ENTRY *r = table->Entry[i];
790 if (IPToUINT(&r->DestIP) == 0 && IPToUINT(&r->DestMask) == 0)
791 {
792 if (r->InterfaceID == e->InterfaceID)
793 {
794 restore = false;
795 }
796 }
797 }
798 if (network_has_changed)
799 {
800 restore = false;
801 }
802 }
803
804 if (restore)
805 {
806 // Routing table restoration
807 AddRouteEntry(e);
808 }
809
810 // Memory release
811 FreeRouteEntry(e);
812 }
813
814 // Release
815 FreeRouteTable(table);
816 ReleaseQueue(t->DeletedDefaultGateway);
817
818 FreeRouteChange(t->RouteChange);
819
820 Free(t);
821 }
822
823 // Get the instance ID of the virtual LAN card
GetInstanceId(char * name)824 UINT GetInstanceId(char *name)
825 {
826 char tmp[MAX_SIZE];
827 UINT id = 0;
828 // Validate arguments
829 if (name == NULL)
830 {
831 return 0;
832 }
833
834 Format(tmp, sizeof(tmp), VLAN_ADAPTER_NAME_TAG, name);
835
836 id = GetVLanInterfaceID(tmp);
837 if (id != 0)
838 {
839 return id;
840 }
841 else
842 {
843 Format(tmp, sizeof(tmp), VLAN_ADAPTER_NAME_TAG_OLD, name);
844
845 id = GetVLanInterfaceID(tmp);
846 return id;
847 }
848 }
849
850 // Get the instance list of virtual LAN card
GetInstanceList()851 INSTANCE_LIST *GetInstanceList()
852 {
853 INSTANCE_LIST *n = ZeroMalloc(sizeof(INSTANCE_LIST));
854
855 // Enumeration
856 char **ss = EnumVLan(VLAN_ADAPTER_NAME);
857
858 if (ss == NULL)
859 {
860 // Failure
861 n->NumInstance = 0;
862 n->InstanceName = Malloc(0);
863 return n;
864 }
865 else
866 {
867 UINT i, num;
868 i = num = 0;
869 while (true)
870 {
871 if (ss[i++] == NULL)
872 {
873 break;
874 }
875 num++;
876 }
877 i = 0;
878 n->NumInstance = num;
879 n->InstanceName = (char **)ZeroMalloc(sizeof(char *) * n->NumInstance);
880 for (i = 0;i < num;i++)
881 {
882 char *s = ss[i] + StrLen(VLAN_ADAPTER_NAME) + StrLen(" - ");
883 if (StrLen(ss[i]) > StrLen(VLAN_ADAPTER_NAME) + StrLen(" - "))
884 {
885 n->InstanceName[i] = CopyStr(s);
886 }
887 }
888 FreeEnumVLan(ss);
889 }
890
891 ss = EnumVLan(VLAN_ADAPTER_NAME_OLD);
892 if (ss != NULL)
893 {
894 UINT i, num, j;
895
896 i = num = 0;
897 while (true)
898 {
899 if (ss[i++] == NULL)
900 {
901 break;
902 }
903 num++;
904 }
905 j = n->NumInstance;
906 n->NumInstance += num;
907 n->InstanceName = (char **)ReAlloc(n->InstanceName, sizeof(char) * n->NumInstance);
908 for (i = 0;i < num;i++)
909 {
910 char *s = ss[i] + StrLen(VLAN_ADAPTER_NAME_OLD) + StrLen(" - ");
911 if (StrLen(ss[i]) > StrLen(VLAN_ADAPTER_NAME_OLD) + StrLen(" - "))
912 {
913 n->InstanceName[j] = CopyStr(s);
914 }
915 j++;
916 }
917 FreeEnumVLan(ss);
918 }
919
920 return n;
921 }
922
923 // Release the instance list
FreeInstanceList(INSTANCE_LIST * n)924 void FreeInstanceList(INSTANCE_LIST *n)
925 {
926 UINT i;
927 // Validate arguments
928 if (n == NULL)
929 {
930 return;
931 }
932
933 for (i = 0;i < n->NumInstance;i++)
934 {
935 Free(n->InstanceName[i]);
936 }
937 Free(n->InstanceName);
938 Free(n);
939 }
940
941 // Release the packet adapter
VLanPaFree(SESSION * s)942 void VLanPaFree(SESSION *s)
943 {
944 VLAN *v;
945 ROUTE_TRACKING *t;
946 // Validate arguments
947 if ((s == NULL) || ((v = s->PacketAdapter->Param) == NULL))
948 {
949 return;
950 }
951
952 // Release the IP address if you are using DHCP
953 if (IsNt())
954 {
955 char tmp[MAX_SIZE];
956 MS_ADAPTER *a;
957 UINT64 now = Tick64();
958 UINT64 suspend_tick = MsGetSuspendModeBeginTick();
959
960 if (suspend_tick == 0 || (suspend_tick + (UINT64)(30 * 1000)) < now)
961 {
962 Format(tmp, sizeof(tmp), VLAN_ADAPTER_NAME_TAG, v->InstanceName);
963 a = MsGetAdapter(tmp);
964
965 if (a != NULL)
966 {
967 if (a->UseDhcp)
968 {
969 bool ret = Win32ReleaseAddressByGuidEx(a->Guid, 50);
970 Debug("*** Win32ReleaseAddressByGuid = %u\n", ret);
971 }
972
973 MsFreeAdapter(a);
974 }
975 }
976 }
977
978 t = v->RouteState;
979 // End the virtual LAN card
980 FreeVLan(v);
981
982 // End the routing table tracking
983 if (s->ClientModeAndUseVLan)
984 {
985 RouteTrackingStop(s, t);
986 }
987 s->PacketAdapter->Param = NULL;
988 }
989
990
991 // Write a packet
VLanPaPutPacket(SESSION * s,void * data,UINT size)992 bool VLanPaPutPacket(SESSION *s, void *data, UINT size)
993 {
994 VLAN *v;
995 // Validate arguments
996 if ((s == NULL) || ((v = s->PacketAdapter->Param) == NULL))
997 {
998 return false;
999 }
1000
1001 return VLanPutPacket(v, data, size);
1002 }
1003
1004 // Get the next packet
VLanPaGetNextPacket(SESSION * s,void ** data)1005 UINT VLanPaGetNextPacket(SESSION *s, void **data)
1006 {
1007 VLAN *v;
1008 UINT size;
1009 // Validate arguments
1010 if (data == NULL || (s == NULL) || ((v = s->PacketAdapter->Param) == NULL))
1011 {
1012 return 0;
1013 }
1014
1015 RouteTrackingMain(s);
1016
1017 if (VLanGetNextPacket(v, data, &size) == false)
1018 {
1019 return INFINITE;
1020 }
1021
1022 return size;
1023 }
1024
1025 // Get the cancel object
VLanPaGetCancel(SESSION * s)1026 CANCEL *VLanPaGetCancel(SESSION *s)
1027 {
1028 VLAN *v;
1029 // Validate arguments
1030 if ((s == NULL) || ((v = s->PacketAdapter->Param) == NULL))
1031 {
1032 return NULL;
1033 }
1034
1035 return VLanGetCancel(v);
1036 }
1037
1038 // Initialize the packet adapter
VLanPaInit(SESSION * s)1039 bool VLanPaInit(SESSION *s)
1040 {
1041 VLAN *v;
1042 // Validate arguments
1043 if ((s == NULL)/* || (s->ServerMode != false) || (s->ClientOption == NULL)*/)
1044 {
1045 return false;
1046 }
1047
1048 // Get the IP address of the DNS server at the time just before the connection
1049 if (s->ClientModeAndUseVLan)
1050 {
1051 Zero(&s->DefaultDns, sizeof(IP));
1052 GetDefaultDns(&s->DefaultDns);
1053 }
1054
1055 // Normalize the setting of interface metric of the default gateway
1056 if (s->ClientModeAndUseVLan)
1057 {
1058 MsNormalizeInterfaceDefaultGatewaySettings(VLAN_ADAPTER_NAME_TAG, s->ClientOption->DeviceName);
1059 MsNormalizeInterfaceDefaultGatewaySettings(VLAN_ADAPTER_NAME_TAG_OLD, s->ClientOption->DeviceName);
1060 }
1061
1062 // Connect to the driver
1063 v = NewVLan(s->ClientOption->DeviceName, NULL);
1064 if (v == NULL)
1065 {
1066 // Failure
1067 return false;
1068 }
1069
1070 s->PacketAdapter->Param = v;
1071
1072 // Routing table tracking start
1073 if (s->ClientModeAndUseVLan)
1074 {
1075 RouteTrackingStart(s);
1076 }
1077
1078 return true;
1079 }
1080
1081 // Get the packet adapter of the VLAN
VLanGetPacketAdapter()1082 PACKET_ADAPTER *VLanGetPacketAdapter()
1083 {
1084 PACKET_ADAPTER *pa;
1085
1086 pa = NewPacketAdapter(VLanPaInit, VLanPaGetCancel,
1087 VLanPaGetNextPacket, VLanPaPutPacket, VLanPaFree);
1088 if (pa == NULL)
1089 {
1090 return NULL;
1091 }
1092
1093 pa->Id = PACKET_ADAPTER_ID_VLAN_WIN32;
1094
1095 return pa;
1096 }
1097
1098
1099 // Write the next received packet to the driver
VLanPutPacket(VLAN * v,void * buf,UINT size)1100 bool VLanPutPacket(VLAN *v, void *buf, UINT size)
1101 {
1102 // Validate arguments
1103 if (v == NULL)
1104 {
1105 return false;
1106 }
1107 if (v->Halt)
1108 {
1109 return false;
1110 }
1111 if (size > MAX_PACKET_SIZE)
1112 {
1113 return false;
1114 }
1115
1116 // First, examine whether the current buffer is full
1117 if ((NEO_NUM_PACKET(v->PutBuffer) >= NEO_MAX_PACKET_EXCHANGE) ||
1118 (buf == NULL && NEO_NUM_PACKET(v->PutBuffer) != 0))
1119 {
1120 #ifdef USE_PROBE
1121 {
1122 char tmp[MAX_SIZE];
1123 snprintf(tmp, sizeof(tmp), "VLanPutPacket: NEO_NUM_PACKET(v->PutBuffer) = %u", NEO_NUM_PACKET(v->PutBuffer));
1124 PROBE_DATA2(tmp, NULL, 0);
1125 }
1126 #endif // USE_PROBE
1127 // Write a packet to the driver
1128 if (VLanPutPacketsToDriver(v) == false)
1129 {
1130 return false;
1131 }
1132 NEO_NUM_PACKET(v->PutBuffer) = 0;
1133 }
1134
1135 // Add the next packet to the buffer
1136 if (buf != NULL)
1137 {
1138 UINT i = NEO_NUM_PACKET(v->PutBuffer);
1139 NEO_NUM_PACKET(v->PutBuffer)++;
1140
1141 NEO_SIZE_OF_PACKET(v->PutBuffer, i) = size;
1142 Copy(NEO_ADDR_OF_PACKET(v->PutBuffer, i), buf, size);
1143 Free(buf);
1144 }
1145
1146 return true;
1147 }
1148
1149 // Read the next sent packet from the driver
VLanGetNextPacket(VLAN * v,void ** buf,UINT * size)1150 bool VLanGetNextPacket(VLAN *v, void **buf, UINT *size)
1151 {
1152 // Validate arguments
1153 if (v == NULL || buf == NULL || size == NULL)
1154 {
1155 return false;
1156 }
1157 if (v->Halt)
1158 {
1159 return false;
1160 }
1161
1162 PROBE_STR("VLanGetNextPacket");
1163
1164 while (true)
1165 {
1166 if (v->CurrentPacketCount < NEO_NUM_PACKET(v->GetBuffer))
1167 {
1168 // There are still packets that have been read already
1169 *size = NEO_SIZE_OF_PACKET(v->GetBuffer, v->CurrentPacketCount);
1170 *buf = MallocFast(*size);
1171 Copy(*buf, NEO_ADDR_OF_PACKET(v->GetBuffer, v->CurrentPacketCount), *size);
1172
1173 // Increment the packet number
1174 v->CurrentPacketCount++;
1175
1176 return true;
1177 }
1178 else
1179 {
1180 // Read the next packet from the driver
1181 if (VLanGetPacketsFromDriver(v) == false)
1182 {
1183 return false;
1184 }
1185
1186 if (NEO_NUM_PACKET(v->GetBuffer) == 0)
1187 {
1188 // Packet is not received currently
1189 *buf = NULL;
1190 *size = 0;
1191 return true;
1192 }
1193
1194 v->CurrentPacketCount = 0;
1195 }
1196 }
1197 }
1198
1199 // Write all the current packets to the driver
VLanPutPacketsToDriver(VLAN * v)1200 bool VLanPutPacketsToDriver(VLAN *v)
1201 {
1202 DWORD write_size;
1203 // Validate arguments
1204 if (v == NULL)
1205 {
1206 return false;
1207 }
1208 if (v->Halt)
1209 {
1210 return false;
1211 }
1212
1213 PROBE_STR("VLanPutPacketsToDriver: WriteFile");
1214 if (WriteFile(v->Handle, v->PutBuffer, NEO_EXCHANGE_BUFFER_SIZE, &write_size,
1215 NULL) == false)
1216 {
1217 v->Halt = true;
1218 return false;
1219 }
1220 PROBE_STR("VLanPutPacketsToDriver: WriteFile Completed.");
1221
1222 if (write_size != NEO_EXCHANGE_BUFFER_SIZE)
1223 {
1224 v->Halt = true;
1225 return false;
1226 }
1227
1228 return true;
1229 }
1230
1231 // Read the next packet from the driver
VLanGetPacketsFromDriver(VLAN * v)1232 bool VLanGetPacketsFromDriver(VLAN *v)
1233 {
1234 DWORD read_size;
1235 // Validate arguments
1236 if (v == NULL)
1237 {
1238 return false;
1239 }
1240 if (v->Halt)
1241 {
1242 return false;
1243 }
1244
1245 PROBE_STR("VLanGetPacketsFromDriver: ReadFile");
1246 if (ReadFile(v->Handle, v->GetBuffer, NEO_EXCHANGE_BUFFER_SIZE,
1247 &read_size, NULL) == false)
1248 {
1249 v->Halt = true;
1250 return false;
1251 }
1252
1253 if (read_size != NEO_EXCHANGE_BUFFER_SIZE)
1254 {
1255 v->Halt = true;
1256 return false;
1257 }
1258
1259 return true;
1260 }
1261
1262 // Get the cancel object
VLanGetCancel(VLAN * v)1263 CANCEL *VLanGetCancel(VLAN *v)
1264 {
1265 CANCEL *c;
1266 // Validate arguments
1267 if (v == NULL)
1268 {
1269 return NULL;
1270 }
1271
1272 // Create a cancel object
1273 c = NewCancel();
1274 c->SpecialFlag = true;
1275 CloseHandle(c->hEvent);
1276
1277 c->hEvent = v->Event;
1278
1279 return c;
1280 }
1281
1282 // Release the VLAN object
FreeVLan(VLAN * v)1283 void FreeVLan(VLAN *v)
1284 {
1285 // Validate arguments
1286 if (v == NULL)
1287 {
1288 return;
1289 }
1290
1291 // Close the handle
1292 CloseHandle(v->Event);
1293 CloseHandle(v->Handle);
1294
1295 // Memory release
1296 Free(v->InstanceName);
1297 Free(v->EventNameWin32);
1298 Free(v->DeviceNameWin32);
1299 Free(v->PutBuffer);
1300 Free(v->GetBuffer);
1301 Free(v);
1302 }
1303
1304 // Create a VLAN object
NewVLan(char * instance_name,VLAN_PARAM * param)1305 VLAN *NewVLan(char *instance_name, VLAN_PARAM *param)
1306 {
1307 VLAN *v;
1308 HANDLE h = INVALID_HANDLE_VALUE;
1309 HANDLE e = INVALID_HANDLE_VALUE;
1310 char tmp[MAX_SIZE];
1311 char name_upper[MAX_SIZE];
1312 // Validate arguments
1313 if (instance_name == NULL)
1314 {
1315 return NULL;
1316 }
1317
1318 v = ZeroMalloc(sizeof(VLAN));
1319
1320 // Initialize the name
1321 Format(name_upper, sizeof(name_upper), "%s", instance_name);
1322 StrUpper(name_upper);
1323 v->InstanceName = CopyStr(name_upper);
1324 Format(tmp, sizeof(tmp), NDIS_NEO_DEVICE_FILE_NAME, v->InstanceName);
1325 v->DeviceNameWin32 = CopyStr(tmp);
1326 Format(tmp, sizeof(tmp), NDIS_NEO_EVENT_NAME_WIN32, v->InstanceName);
1327 v->EventNameWin32 = CopyStr(tmp);
1328
1329 // Connect to the device
1330 h = CreateFile(v->DeviceNameWin32,
1331 GENERIC_READ | GENERIC_WRITE,
1332 0,
1333 NULL,
1334 OPEN_EXISTING,
1335 0,
1336 NULL);
1337 if (h == INVALID_HANDLE_VALUE)
1338 {
1339 // Connection failure
1340 goto CLEANUP;
1341 }
1342
1343 // Connect to the event
1344 e = OpenEvent(SYNCHRONIZE, FALSE, v->EventNameWin32);
1345 if (e == INVALID_HANDLE_VALUE)
1346 {
1347 // Connection failure
1348 goto CLEANUP;
1349 }
1350
1351 v->Event = e;
1352 v->Handle = h;
1353
1354 v->GetBuffer = ZeroMalloc(NEO_EXCHANGE_BUFFER_SIZE);
1355 v->PutBuffer = ZeroMalloc(NEO_EXCHANGE_BUFFER_SIZE);
1356
1357 return v;
1358
1359 CLEANUP:
1360 if (h != INVALID_HANDLE_VALUE)
1361 {
1362 CloseHandle(h);
1363 }
1364 if (e != INVALID_HANDLE_VALUE)
1365 {
1366 CloseHandle(e);
1367 }
1368
1369 Free(v->InstanceName);
1370 Free(v->EventNameWin32);
1371 Free(v->DeviceNameWin32);
1372 Free(v);
1373
1374 return NULL;
1375 }
1376
1377 #endif
1378