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 // BridgeWin32.c
103 // Ethernet Bridge Program (Win32)
104 
105 #include <GlobalConst.h>
106 
107 #ifdef	BRIDGE_C
108 
109 #include <winsock2.h>
110 #include <Ws2tcpip.h>
111 #include <windows.h>
112 #include <stdio.h>
113 #include <stdlib.h>
114 #include <string.h>
115 #include <wchar.h>
116 #include <stdarg.h>
117 #include <time.h>
118 #include <errno.h>
119 #include <Packet32.h>
120 #include <Mayaqua/Mayaqua.h>
121 #include <Cedar/Cedar.h>
122 
123 
124 static WP *wp = NULL;
125 static LIST *eth_list = NULL;
126 
127 static LOCK *eth_list_lock = NULL;
128 static bool is_see_mode = false;
129 static bool is_using_selow = false;
130 static bool enable_selow = true;
131 
132 static bool g_bridge_win32_show_all_if = false;
133 
134 #define	LOAD_DLL_ADDR(name)				\
135 	{									\
136 		void *addr = GetProcAddress(h, #name);	\
137 		Copy(&wp->name, &addr, sizeof(void *));	\
138 	}
139 
140 // Set the flag which indicates whether using SeLow
Win32SetEnableSeLow(bool b)141 void Win32SetEnableSeLow(bool b)
142 {
143 	enable_selow = b;
144 }
145 
146 // Get the flag which indicates whether using SeLow
Win32GetEnableSeLow()147 bool Win32GetEnableSeLow()
148 {
149 	return enable_selow;
150 }
151 
152 // Set the flag which indicates whether enumerating all interfaces
Win32EthSetShowAllIf(bool b)153 void Win32EthSetShowAllIf(bool b)
154 {
155 	g_bridge_win32_show_all_if = b;
156 }
157 
158 // Get the flag which indicates whether enumerating all interfaces
Win32EthGetShowAllIf()159 bool Win32EthGetShowAllIf()
160 {
161 	return g_bridge_win32_show_all_if;
162 }
163 
164 // Compare Ethernet device list
CmpRpcEnumEthVLan(void * p1,void * p2)165 int CmpRpcEnumEthVLan(void *p1, void *p2)
166 {
167 	RPC_ENUM_ETH_VLAN_ITEM *v1, *v2;
168 	if (p1 == NULL || p2 == NULL)
169 	{
170 		return 0;
171 	}
172 	v1 = *((RPC_ENUM_ETH_VLAN_ITEM **)p1);
173 	v2 = *((RPC_ENUM_ETH_VLAN_ITEM **)p2);
174 	if (v1 == NULL || v2 == NULL)
175 	{
176 		return 0;
177 	}
178 
179 	return StrCmpi(v1->DeviceName, v2->DeviceName);
180 }
181 
182 // Get the value of MTU (Not supported in Windows)
EthGetMtu(ETH * e)183 UINT EthGetMtu(ETH *e)
184 {
185 	return 0;
186 }
187 
188 // Set the value of MTU (Not supported in Windows)
EthSetMtu(ETH * e,UINT mtu)189 bool EthSetMtu(ETH *e, UINT mtu)
190 {
191 	return false;
192 }
193 
194 // Check whether setting MEU value (Not supported in Windows)
EthIsChangeMtuSupported(ETH * e)195 bool EthIsChangeMtuSupported(ETH *e)
196 {
197 	return false;
198 }
199 
200 // Set the state of VLAN tag pass-through
SetVLanEnableStatus(char * title,bool enable)201 bool SetVLanEnableStatus(char *title, bool enable)
202 {
203 	RPC_ENUM_ETH_VLAN t;
204 	RPC_ENUM_ETH_VLAN_ITEM *e;
205 	bool ret = false;
206 	char key[MAX_SIZE];
207 	char tcpkey[MAX_SIZE];
208 	char short_key[MAX_SIZE];
209 	// Validate arguments
210 	if (title == NULL)
211 	{
212 		return false;
213 	}
214 
215 	Zero(&t, sizeof(t));
216 	if (EnumEthVLanWin32(&t) == false)
217 	{
218 		return false;
219 	}
220 
221 	e = FindEthVLanItem(&t, title);
222 
223 	if (e != NULL)
224 	{
225 		if (GetClassRegKeyWin32(key, sizeof(key), short_key, sizeof(short_key), e->Guid))
226 		{
227 			if (StrCmpi(e->DriverType, "Intel") == 0)
228 			{
229 				if (enable)
230 				{
231 					MsRegWriteStr(REG_LOCAL_MACHINE, key, "VlanFiltering", "0");
232 					MsRegWriteStr(REG_LOCAL_MACHINE, key, "TaggingMode", "0");
233 					MsRegWriteInt(REG_LOCAL_MACHINE, key, "MonitorMode", 1);
234 					MsRegWriteInt(REG_LOCAL_MACHINE, key, "MonitorModeEnabled", 1);
235 				}
236 				else
237 				{
238 					if (MsRegReadInt(REG_LOCAL_MACHINE, key, "TaggingMode") == 0)
239 					{
240 						MsRegDeleteValue(REG_LOCAL_MACHINE, key, "TaggingMode");
241 					}
242 
243 					if (MsRegReadInt(REG_LOCAL_MACHINE, key, "MonitorMode") == 1)
244 					{
245 						MsRegDeleteValue(REG_LOCAL_MACHINE, key, "MonitorMode");
246 					}
247 
248 					if (MsRegReadInt(REG_LOCAL_MACHINE, key, "MonitorModeEnabled") == 1)
249 					{
250 						MsRegDeleteValue(REG_LOCAL_MACHINE, key, "MonitorModeEnabled");
251 					}
252 				}
253 
254 				ret = true;
255 			}
256 			else if (StrCmpi(e->DriverType, "Broadcom") == 0)
257 			{
258 				if (enable)
259 				{
260 					MsRegWriteStr(REG_LOCAL_MACHINE, key, "PreserveVlanInfoInRxPacket", "1");
261 				}
262 				else
263 				{
264 					MsRegDeleteValue(REG_LOCAL_MACHINE, key, "PreserveVlanInfoInRxPacket");
265 				}
266 
267 				ret = true;
268 			}
269 			else if (StrCmpi(e->DriverType, "Marvell") == 0)
270 			{
271 				if (enable)
272 				{
273 					MsRegWriteInt(REG_LOCAL_MACHINE, key, "SkDisableVlanStrip", 1);
274 				}
275 				else
276 				{
277 					MsRegDeleteValue(REG_LOCAL_MACHINE, key, "SkDisableVlanStrip");
278 				}
279 
280 				ret = true;
281 			}
282 
283 			Format(tcpkey, sizeof(tcpkey),
284 				"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
285 				e->Guid);
286 
287 			if (enable)
288 			{
289 				if (MsRegIsValue(REG_LOCAL_MACHINE, tcpkey, "MTU") == false)
290 				{
291 					MsRegWriteInt(REG_LOCAL_MACHINE, tcpkey, "MTU", 1500);
292 				}
293 			}
294 			else
295 			{
296 				UINT mtu = MsRegReadInt(REG_LOCAL_MACHINE, tcpkey, "MTU");
297 				if (mtu == 1500)
298 				{
299 					MsRegDeleteValue(REG_LOCAL_MACHINE, tcpkey, "MTU");
300 				}
301 			}
302 		}
303 	}
304 
305 	FreeRpcEnumEthVLan(&t);
306 
307 	return ret;
308 }
309 
310 // Find Ethernet device
FindEthVLanItem(RPC_ENUM_ETH_VLAN * t,char * name)311 RPC_ENUM_ETH_VLAN_ITEM *FindEthVLanItem(RPC_ENUM_ETH_VLAN *t, char *name)
312 {
313 	UINT i;
314 	// Validate arguments
315 	if (t == NULL || name == NULL)
316 	{
317 		return NULL;
318 	}
319 
320 	for (i = 0;i < t->NumItem;i++)
321 	{
322 		if (StrCmpi(t->Items[i].DeviceName, name) == 0)
323 		{
324 			return &t->Items[i];
325 		}
326 	}
327 
328 	return NULL;
329 }
330 
331 // Get the state of VLAN tag pass-through
GetVLanEnableStatus(RPC_ENUM_ETH_VLAN_ITEM * e)332 void GetVLanEnableStatus(RPC_ENUM_ETH_VLAN_ITEM *e)
333 {
334 	char key[MAX_SIZE];
335 	char short_key[MAX_SIZE];
336 	char tcpkey[MAX_SIZE];
337 	// Validate arguments
338 	if (e == NULL)
339 	{
340 		return;
341 	}
342 
343 	e->Enabled = false;
344 
345 	if (e->Support == false)
346 	{
347 		return;
348 	}
349 
350 	if (GetClassRegKeyWin32(key, sizeof(key), short_key, sizeof(short_key), e->Guid) == false)
351 	{
352 		return;
353 	}
354 
355 	Format(tcpkey, sizeof(tcpkey),
356 		"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
357 		e->Guid);
358 
359 	if (StrCmpi(e->DriverType, "Intel") == 0)
360 	{
361 		char *VlanFiltering = MsRegReadStr(REG_LOCAL_MACHINE, key, "VlanFiltering");
362 		UINT MonitorMode = MsRegReadInt(REG_LOCAL_MACHINE, key, "MonitorMode");
363 		UINT MonitorModeEnabled = MsRegReadInt(REG_LOCAL_MACHINE, key, "MonitorModeEnabled");
364 		char *TaggingMode = MsRegReadStr(REG_LOCAL_MACHINE, key, "TaggingMode");
365 
366 		if (StrCmpi(VlanFiltering, "0") == 0 &&
367 			MonitorMode == 1 &&
368 			MonitorModeEnabled == 1 &&
369 			StrCmpi(TaggingMode, "0") == 0)
370 		{
371 			e->Enabled = true;
372 		}
373 
374 		Free(VlanFiltering);
375 		Free(TaggingMode);
376 	}
377 	else if (StrCmpi(e->DriverType, "Broadcom") == 0)
378 	{
379 		char *PreserveVlanInfoInRxPacket = MsRegReadStr(REG_LOCAL_MACHINE,
380 			key, "PreserveVlanInfoInRxPacket");
381 
382 		if (StrCmpi(PreserveVlanInfoInRxPacket, "1") == 0)
383 		{
384 			e->Enabled = true;
385 		}
386 
387 		Free(PreserveVlanInfoInRxPacket);
388 	}
389 	else if (StrCmpi(e->DriverType, "Marvell") == 0)
390 	{
391 		DWORD SkDisableVlanStrip = MsRegReadInt(REG_LOCAL_MACHINE,
392 			key, "SkDisableVlanStrip");
393 
394 		if (SkDisableVlanStrip == 1)
395 		{
396 			e->Enabled = true;
397 		}
398 	}
399 
400 	if (MsRegIsValue(REG_LOCAL_MACHINE, tcpkey, "MTU") == false)
401 	{
402 		e->Enabled = false;
403 	}
404 }
405 
406 // Get VLAN tag pass-through availability of the device
GetVLanSupportStatus(RPC_ENUM_ETH_VLAN_ITEM * e)407 void GetVLanSupportStatus(RPC_ENUM_ETH_VLAN_ITEM *e)
408 {
409 	BUF *b;
410 	char filename[MAX_SIZE];
411 	void *wow;
412 	// Validate arguments
413 	if (e == NULL)
414 	{
415 		return;
416 	}
417 
418 	wow = MsDisableWow64FileSystemRedirection();
419 
420 	// Read the device driver file
421 	CombinePath(filename, sizeof(filename), MsGetSystem32Dir(), "drivers");
422 	CombinePath(filename, sizeof(filename), filename, e->DriverName);
423 
424 	b = ReadDump(filename);
425 
426 	if (b != NULL)
427 	{
428 		char intel1[] = "VlanFiltering";
429 		char intel2[] = "V\0l\0a\0n\0F\0i\0l\0t\0e\0r\0i\0n\0g";
430 		char intel3[] = "MonitorMode";
431 		char intel4[] = "M\0o\0n\0i\0t\0o\0r\0M\0o\0d\0e";
432 		char intel5[] = "TaggingMode";
433 		char intel6[] = "T\0a\0g\0g\0i\0n\0g\0M\0o\0d\0e";
434 		char broadcom1[] = "PreserveVlanInfoInRxPacket";
435 		char broadcom2[] = "P\0r\0e\0s\0e\0r\0v\0e\0V\0l\0a\0n\0I\0n\0f\0o\0I\0n\0R\0x\0P\0a\0c\0k\0e\0t";
436 		char marvell1[] = "SkDisableVlanStrip";
437 		char marvell2[] = "S\0k\0D\0i\0s\0a\0b\0l\0e\0V\0l\0a\0n\0S\0t\0r\0i\0p";
438 		char *driver_type = "";
439 
440 		if (SearchBin(b->Buf, 0, b->Size, intel1, sizeof(intel1)) != INFINITE
441 			|| SearchBin(b->Buf, 0, b->Size, intel2, sizeof(intel2)) != INFINITE
442 			|| SearchBin(b->Buf, 0, b->Size, intel3, sizeof(intel3)) != INFINITE
443 			|| SearchBin(b->Buf, 0, b->Size, intel4, sizeof(intel4)) != INFINITE
444 			|| SearchBin(b->Buf, 0, b->Size, intel5, sizeof(intel5)) != INFINITE
445 			|| SearchBin(b->Buf, 0, b->Size, intel6, sizeof(intel6)) != INFINITE)
446 		{
447 			driver_type = "Intel";
448 		}
449 		else if (SearchBin(b->Buf, 0, b->Size, broadcom1, sizeof(broadcom1)) != INFINITE
450 			|| SearchBin(b->Buf, 0, b->Size, broadcom2, sizeof(broadcom2)) != INFINITE)
451 		{
452 			driver_type = "Broadcom";
453 		}
454 		else if (SearchBin(b->Buf, 0, b->Size, marvell1, sizeof(marvell1)) != INFINITE
455 			|| SearchBin(b->Buf, 0, b->Size, marvell2, sizeof(marvell2)) != INFINITE)
456 		{
457 			driver_type = "Marvell";
458 		}
459 
460 		if (IsEmptyStr(driver_type) == false)
461 		{
462 			StrCpy(e->DriverType, sizeof(e->DriverType), driver_type);
463 			e->Support = true;
464 		}
465 
466 		FreeBuf(b);
467 	}
468 
469 	MsRestoreWow64FileSystemRedirection(wow);
470 }
471 
472 // Get the device instance id from short_key
SearchDeviceInstanceIdFromShortKey(char * short_key)473 char *SearchDeviceInstanceIdFromShortKey(char *short_key)
474 {
475 	char *ret = NULL;
476 	TOKEN_LIST *t1;
477 	// Validate arguments
478 	if (short_key == NULL)
479 	{
480 		return NULL;
481 	}
482 
483 	t1 = MsRegEnumKey(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Enum");
484 
485 	if (t1 != NULL)
486 	{
487 		TOKEN_LIST *t2;
488 		char tmp[MAX_SIZE];
489 		UINT i;
490 
491 		for (i = 0;i < t1->NumTokens;i++)
492 		{
493 			Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Enum\\%s", t1->Token[i]);
494 
495 			t2 = MsRegEnumKey(REG_LOCAL_MACHINE, tmp);
496 
497 			if (t2 != NULL)
498 			{
499 				TOKEN_LIST *t3;
500 				UINT i;
501 
502 				for (i = 0;i < t2->NumTokens;i++)
503 				{
504 					char tmp2[MAX_SIZE];
505 
506 					Format(tmp2, sizeof(tmp2), "%s\\%s", tmp, t2->Token[i]);
507 
508 					t3 = MsRegEnumKey(REG_LOCAL_MACHINE, tmp2);
509 
510 					if (t3 != NULL)
511 					{
512 						UINT i;
513 
514 						for (i = 0;i < t3->NumTokens;i++)
515 						{
516 							char tmp3[MAX_SIZE];
517 							char *s;
518 
519 							Format(tmp3, sizeof(tmp3), "%s\\%s", tmp2, t3->Token[i]);
520 
521 							s = MsRegReadStr(REG_LOCAL_MACHINE, tmp3, "Driver");
522 
523 							if (s != NULL)
524 							{
525 								if (StrCmpi(s, short_key) == 0)
526 								{
527 									if (ret != NULL)
528 									{
529 										Free(ret);
530 									}
531 
532 									ret = CopyStr(tmp3 + StrLen("SYSTEM\\CurrentControlSet\\Enum\\"));
533 								}
534 
535 								Free(s);
536 							}
537 						}
538 
539 						FreeToken(t3);
540 					}
541 				}
542 
543 				FreeToken(t2);
544 			}
545 		}
546 
547 		FreeToken(t1);
548 	}
549 
550 	return ret;
551 }
552 
553 // Get VLAN tag pass-through availability of all devices
EnumEthVLanWin32(RPC_ENUM_ETH_VLAN * t)554 bool EnumEthVLanWin32(RPC_ENUM_ETH_VLAN *t)
555 {
556 	UINT i;
557 	LIST *o;
558 	// Validate arguments
559 	if (t == NULL)
560 	{
561 		return false;
562 	}
563 
564 	Zero(t, sizeof(RPC_ENUM_ETH_VLAN));
565 
566 	if (MsIsWin2000OrGreater() == false)
567 	{
568 		return false;
569 	}
570 
571 	if (IsEthSupported() == false)
572 	{
573 		return false;
574 	}
575 
576 	// Get device list
577 	Lock(eth_list_lock);
578 
579 	InitEthAdaptersList();
580 
581 	o = NewListFast(CmpRpcEnumEthVLan);
582 
583 	for (i = 0;i < LIST_NUM(eth_list);i++)
584 	{
585 		WP_ADAPTER *a = LIST_DATA(eth_list, i);
586 
587 		if (IsEmptyStr(a->Guid) == false)
588 		{
589 			char class_key[MAX_SIZE];
590 			char short_key[MAX_SIZE];
591 
592 			if (GetClassRegKeyWin32(class_key, sizeof(class_key),
593 				short_key, sizeof(short_key), a->Guid))
594 			{
595 				char *device_instance_id = MsRegReadStr(REG_LOCAL_MACHINE, class_key, "DeviceInstanceID");
596 
597 				if (IsEmptyStr(device_instance_id))
598 				{
599 					Free(device_instance_id);
600 					device_instance_id = SearchDeviceInstanceIdFromShortKey(short_key);
601 				}
602 
603 				if (IsEmptyStr(device_instance_id) == false)
604 				{
605 					char device_key[MAX_SIZE];
606 					char *service_name;
607 
608 					Format(device_key, sizeof(device_key), "SYSTEM\\CurrentControlSet\\Enum\\%s",
609 						device_instance_id);
610 
611 					service_name = MsRegReadStr(REG_LOCAL_MACHINE, device_key, "Service");
612 					if (IsEmptyStr(service_name) == false)
613 					{
614 						char service_key[MAX_SIZE];
615 						char *sys;
616 
617 						Format(service_key, sizeof(service_key),
618 							"SYSTEM\\CurrentControlSet\\services\\%s",
619 							service_name);
620 
621 						sys = MsRegReadStr(REG_LOCAL_MACHINE, service_key, "ImagePath");
622 
623 						if (IsEmptyStr(sys) == false)
624 						{
625 							char sysname[MAX_PATH];
626 
627 							GetFileNameFromFilePath(sysname, sizeof(sysname), sys);
628 
629 							Trim(sysname);
630 
631 							if (EndWith(sysname, ".sys"))
632 							{
633 								// device found
634 								RPC_ENUM_ETH_VLAN_ITEM *e = ZeroMalloc(sizeof(RPC_ENUM_ETH_VLAN_ITEM));
635 
636 								StrCpy(e->DeviceName, sizeof(e->DeviceName), a->Title);
637 								StrCpy(e->Guid, sizeof(e->Guid), a->Guid);
638 								StrCpy(e->DeviceInstanceId, sizeof(e->DeviceInstanceId), device_instance_id);
639 								StrCpy(e->DriverName, sizeof(e->DriverName), sysname);
640 
641 								// Get VLAN tag pass-through availability of the device
642 								GetVLanSupportStatus(e);
643 
644 								// Get current pass-through setting of the device
645 								GetVLanEnableStatus(e);
646 
647 								Insert(o, e);
648 							}
649 						}
650 
651 						Free(sys);
652 					}
653 
654 					Free(service_name);
655 				}
656 
657 				Free(device_instance_id);
658 			}
659 		}
660 	}
661 
662 	t->NumItem = LIST_NUM(o);
663 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_ETH_VLAN_ITEM) * i);
664 
665 	for (i = 0;i < LIST_NUM(o);i++)
666 	{
667 		RPC_ENUM_ETH_VLAN_ITEM *e = LIST_DATA(o, i);
668 
669 		Copy(&t->Items[i], e, sizeof(RPC_ENUM_ETH_VLAN_ITEM));
670 
671 		Free(e);
672 	}
673 
674 	ReleaseList(o);
675 
676 	Unlock(eth_list_lock);
677 
678 	return true;
679 }
680 
681 // Get registry key of the network class data by GUID
GetClassRegKeyWin32(char * key,UINT key_size,char * short_key,UINT short_key_size,char * guid)682 bool GetClassRegKeyWin32(char *key, UINT key_size, char *short_key, UINT short_key_size, char *guid)
683 {
684 	TOKEN_LIST *t;
685 	bool ret = false;
686 	UINT i;
687 	// Validate arguments
688 	if (key == NULL || short_key == NULL || guid == NULL)
689 	{
690 		return false;
691 	}
692 
693 	t = MsRegEnumKey(REG_LOCAL_MACHINE,
694 		"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
695 	if (t == NULL)
696 	{
697 		return false;
698 	}
699 
700 	for (i = 0;i < t->NumTokens;i++)
701 	{
702 		char keyname[MAX_SIZE];
703 		char *value;
704 
705 		Format(keyname, sizeof(keyname),
706 			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s",
707 			t->Token[i]);
708 
709 		value = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "NetCfgInstanceId");
710 
711 		if (StrCmpi(value, guid) == 0)
712 		{
713 			ret = true;
714 
715 			StrCpy(key, key_size, keyname);
716 
717 			Format(short_key, short_key_size, "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s",
718 				t->Token[i]);
719 		}
720 
721 		Free(value);
722 	}
723 
724 	FreeToken(t);
725 
726 	return ret;
727 }
728 
729 // Send multiple packets
EthPutPackets(ETH * e,UINT num,void ** datas,UINT * sizes)730 void EthPutPackets(ETH *e, UINT num, void **datas, UINT *sizes)
731 {
732 	UINT i, total_size;
733 	UCHAR *buf;
734 	UINT write_pointer;
735 	UINT err = 0;
736 	// Validate arguments
737 	if (e == NULL || num == 0 || datas == NULL || sizes == NULL)
738 	{
739 		return;
740 	}
741 	if (e->HasFatalError)
742 	{
743 		return;
744 	}
745 
746 	if (e->SuAdapter != NULL)
747 	{
748 		bool ok = true;
749 
750 		// Send packets with SeLow
751 		for (i = 0;i < num;i++)
752 		{
753 			UCHAR *data = datas[i];
754 			UINT size = sizes[i];
755 
756 			if (ok)
757 			{
758 				// Actually, only enqueuing
759 				ok = SuPutPacket(e->SuAdapter, data, size);
760 			}
761 
762 			if (ok == false)
763 			{
764 				// Free memory on write error
765 				Free(data);
766 			}
767 		}
768 
769 		if (ok)
770 		{
771 			// Send all data in queue at once
772 			ok = SuPutPacket(e->SuAdapter, NULL, 0);
773 		}
774 
775 		if (ok == false)
776 		{
777 			// Error occurred
778 			e->HasFatalError = true;
779 		}
780 
781 		return;
782 	}
783 
784 	if (IsWin32BridgeWithSee() == false)
785 	{
786 		if (e->LastSetSingleCpu == 0 || (e->LastSetSingleCpu + 10000) <= Tick64())
787 		{
788 			e->LastSetSingleCpu = Tick64();
789 			MsSetThreadSingleCpu();
790 		}
791 	}
792 
793 	// Calculate buffer size
794 	total_size = 0;
795 	for (i = 0;i < num;i++)
796 	{
797 		void *data = datas[i];
798 		UINT size = sizes[i];
799 		if (data != NULL && size >= 14 && size <= MAX_PACKET_SIZE)
800 		{
801 			total_size += size + sizeof(struct dump_bpf_hdr);
802 		}
803 	}
804 
805 	buf = MallocFast(total_size * 100 / 75 + 1600);
806 
807 	write_pointer = 0;
808 	// Enqueue
809 	for (i = 0;i < num;i++)
810 	{
811 		void *data = datas[i];
812 		UINT size = sizes[i];
813 		if (data != NULL && size >= 14 && size <= MAX_PACKET_SIZE)
814 		{
815 			struct dump_bpf_hdr *h;
816 
817 			h = (struct dump_bpf_hdr *)(buf + write_pointer);
818 			Zero(h, sizeof(struct dump_bpf_hdr));
819 			h->caplen = h->len = size;
820 			write_pointer += sizeof(struct dump_bpf_hdr);
821 			Copy(buf + write_pointer, data, size);
822 			write_pointer += size;
823 
824 			PROBE_DATA2("EthPutPackets", data, size);
825 		}
826 		// Free original buffer
827 		Free(data);
828 	}
829 
830 	// Send
831 	if (total_size != 0)
832 	{
833 		err = wp->PacketSendPackets(e->Adapter, buf, total_size, true);
834 	}
835 
836 	Free(buf);
837 
838 	if (err == 0x7FFFFFFF)
839 	{
840 		// Critical error (infinite loop) occurred on sending
841 		e->HasFatalError = true;
842 	}
843 }
844 
845 // Send a packet
EthPutPacket(ETH * e,void * data,UINT size)846 void EthPutPacket(ETH *e, void *data, UINT size)
847 {
848 	// Validate arguments
849 	if (e == NULL || data == NULL || size == 0)
850 	{
851 		return;
852 	}
853 
854 	EthPutPackets(e, 1, &data, &size);
855 }
856 
857 // Read next packet
EthGetPacket(ETH * e,void ** data)858 UINT EthGetPacket(ETH *e, void **data)
859 {
860 	BLOCK *b;
861 	bool flag = false;
862 	// Validate arguments
863 	if (e == NULL || data == NULL)
864 	{
865 		return INFINITE;
866 	}
867 	if (e->HasFatalError)
868 	{
869 		return INFINITE;
870 	}
871 
872 	if (e->SuAdapter != NULL)
873 	{
874 		// Read packet with SeLow
875 		UINT size;
876 		if (SuGetNextPacket(e->SuAdapter, data, &size) == false)
877 		{
878 			// Error occurred
879 			e->HasFatalError = true;
880 			return INFINITE;
881 		}
882 
883 		return size;
884 	}
885 
886 RETRY:
887 	// Check the presence of the packet in queue
888 	b = GetNext(e->PacketQueue);
889 	if (b != NULL)
890 	{
891 		UINT size;
892 		size = b->Size;
893 		*data = b->Buf;
894 		Free(b);
895 
896 		if (e->PacketQueue->num_item == 0)
897 		{
898 			e->Empty = true;
899 		}
900 
901 		return size;
902 	}
903 
904 	if (e->Empty)
905 	{
906 		e->Empty = false;
907 		return 0;
908 	}
909 
910 	if (flag == false)
911 	{
912 		// Try to get next packet
913 		PROBE_STR("EthGetPacket: PacketInitPacket");
914 		wp->PacketInitPacket(e->Packet, e->Buffer, e->BufferSize);
915 		PROBE_STR("EthGetPacket: PacketReceivePacket");
916 		if (wp->PacketReceivePacket(e->Adapter, e->Packet, false) == false)
917 		{
918 			// Failed
919 			return INFINITE;
920 		}
921 		else
922 		{
923 			UCHAR *buf;
924 			UINT total;
925 			UINT offset;
926 
927 			buf = (UCHAR *)e->Packet->Buffer;
928 			total = e->Packet->ulBytesReceived;
929 			offset = 0;
930 
931 			while (offset < total)
932 			{
933 				struct bpf_hdr *header;
934 				UINT packet_size;
935 				UCHAR *packet_data;
936 
937 				header = (struct bpf_hdr *)(buf + offset);
938 				packet_size = header->bh_caplen;
939 				offset += header->bh_hdrlen;
940 				packet_data = buf + offset;
941 				offset = Packet_WORDALIGN(offset + packet_size);
942 
943 				if (packet_size >= 14)
944 				{
945 					UCHAR *tmp;
946 					BLOCK *b;
947 
948 					PROBE_DATA2("EthGetPacket: NewBlock", packet_data, packet_size);
949 
950 					tmp = MallocFast(packet_size);
951 
952 					Copy(tmp, packet_data, packet_size);
953 					b = NewBlock(tmp, packet_size, 0);
954 					InsertQueue(e->PacketQueue, b);
955 				}
956 			}
957 
958 			flag = true;
959 			goto RETRY;
960 		}
961 	}
962 
963 	// No more packet
964 	return 0;
965 }
966 
967 // Get cancel object
EthGetCancel(ETH * e)968 CANCEL *EthGetCancel(ETH *e)
969 {
970 	// Validate arguments
971 	if (e == NULL)
972 	{
973 		return NULL;
974 	}
975 
976 	AddRef(e->Cancel->ref);
977 
978 	return e->Cancel;
979 }
980 
981 // Close adapter
CloseEth(ETH * e)982 void CloseEth(ETH *e)
983 {
984 	BLOCK *b;
985 	// Validate arguments
986 	if (e == NULL)
987 	{
988 		return;
989 	}
990 
991 	ReleaseCancel(e->Cancel);
992 
993 	if (e->SuAdapter != NULL)
994 	{
995 		// Close SeLow adapter
996 		SuCloseAdapter(e->SuAdapter);
997 		SuFree(e->Su);
998 	}
999 	else
1000 	{
1001 		// Close SEE adapter
1002 		wp->PacketCloseAdapter(e->Adapter);
1003 		wp->PacketFreePacket(e->Packet);
1004 		wp->PacketFreePacket(e->PutPacket);
1005 	}
1006 
1007 	while (b = GetNext(e->PacketQueue))
1008 	{
1009 		FreeBlock(b);
1010 	}
1011 	ReleaseQueue(e->PacketQueue);
1012 
1013 	Free(e->Name);
1014 	Free(e->Title);
1015 	Free(e->Buffer);
1016 
1017 	Free(e);
1018 }
1019 
1020 // Search adapter with the name
Win32EthSearch(char * name)1021 struct WP_ADAPTER *Win32EthSearch(char *name)
1022 {
1023 	UINT i;
1024 	UINT id;
1025 	char simple_name[MAX_SIZE];
1026 	WP_ADAPTER *ret = NULL;
1027 
1028 	id = Win32EthGetNameAndIdFromCombinedName(simple_name, sizeof(simple_name), name);
1029 
1030 	if (id != 0)
1031 	{
1032 		UINT num_match = 0;
1033 		// Search with ID when ID is specified
1034 		for (i = 0;i < LIST_NUM(eth_list);i++)
1035 		{
1036 			WP_ADAPTER *a = LIST_DATA(eth_list, i);
1037 
1038 			if (a->Id != 0 && a->Id == id)
1039 			{
1040 				ret = a;
1041 				num_match++;
1042 			}
1043 		}
1044 
1045 		if (num_match >= 2)
1046 		{
1047 			// If the ID matches to 2 or more devices, search with the name
1048 			for (i = 0;i < LIST_NUM(eth_list);i++)
1049 			{
1050 				WP_ADAPTER *a = LIST_DATA(eth_list, i);
1051 
1052 				if (a->Id != 0 && a->Id == id)
1053 				{
1054 					if (StrCmpi(a->Title, name) == 0)
1055 					{
1056 						ret = a;
1057 						break;
1058 					}
1059 				}
1060 			}
1061 		}
1062 	}
1063 	else
1064 	{
1065 		// Search with name when ID is not specified
1066 		for (i = 0;i < LIST_NUM(eth_list);i++)
1067 		{
1068 			WP_ADAPTER *a = LIST_DATA(eth_list, i);
1069 
1070 			if (StrCmpi(a->Title, name) == 0)
1071 			{
1072 				ret = a;
1073 				break;
1074 			}
1075 		}
1076 	}
1077 
1078 	return ret;
1079 }
1080 
1081 // Open adapter
OpenEth(char * name,bool local,bool tapmode,char * tapaddr)1082 ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr)
1083 {
1084 	ETH *ret;
1085 	void *p;
1086 
1087 	p = MsDisableWow64FileSystemRedirection();
1088 
1089 	ret = OpenEthInternal(name, local, tapmode, tapaddr);
1090 
1091 	MsRestoreWow64FileSystemRedirection(p);
1092 
1093 	return ret;
1094 }
OpenEthInternal(char * name,bool local,bool tapmode,char * tapaddr)1095 ETH *OpenEthInternal(char *name, bool local, bool tapmode, char *tapaddr)
1096 {
1097 	WP_ADAPTER *t;
1098 	ETH *e;
1099 	ADAPTER *a = NULL;
1100 	HANDLE h;
1101 	CANCEL *c;
1102 	MS_ADAPTER *ms;
1103 	char name_with_id[MAX_SIZE];
1104 	SU *su = NULL;
1105 	SU_ADAPTER *su_adapter = NULL;
1106 	// Validate arguments
1107 	if (name == NULL || IsEthSupported() == false)
1108 	{
1109 		return NULL;
1110 	}
1111 
1112 	if (tapmode)
1113 	{
1114 		// Tap is not supported in Windows
1115 		return NULL;
1116 	}
1117 
1118 	Lock(eth_list_lock);
1119 
1120 	InitEthAdaptersList();
1121 
1122 	t = Win32EthSearch(name);
1123 
1124 	if (t == NULL)
1125 	{
1126 		Unlock(eth_list_lock);
1127 		return NULL;
1128 	}
1129 
1130 	Debug("OpenEthInternal: %s\n", t->Name);
1131 
1132 	if (StartWith(t->Name, SL_ADAPTER_ID_PREFIX))
1133 	{
1134 		// Open with SU
1135 		su = SuInit();
1136 		if (su == NULL)
1137 		{
1138 			// Fail to initialize SU
1139 			Unlock(eth_list_lock);
1140 			return NULL;
1141 		}
1142 
1143 		su_adapter = SuOpenAdapter(su, t->Name);
1144 
1145 		if (su_adapter == NULL)
1146 		{
1147 			// Fail to get adapter
1148 			SuFree(su);
1149 			Unlock(eth_list_lock);
1150 			return NULL;
1151 		}
1152 
1153 		is_using_selow = true;
1154 	}
1155 	else
1156 	{
1157 		// Open with SEE
1158 		a = wp->PacketOpenAdapter(t->Name);
1159 		if (a == NULL)
1160 		{
1161 			Unlock(eth_list_lock);
1162 			return NULL;
1163 		}
1164 
1165 		if (IsWin32BridgeWithSee() == false)
1166 		{
1167 			MsSetThreadSingleCpu();
1168 		}
1169 
1170 		is_using_selow = false;
1171 	}
1172 
1173 	e = ZeroMalloc(sizeof(ETH));
1174 	e->Name = CopyStr(t->Name);
1175 
1176 	Win32EthMakeCombinedName(name_with_id, sizeof(name_with_id), t->Title, t->Guid);
1177 	e->Title = CopyStr(name_with_id);
1178 
1179 	if (su_adapter != NULL)
1180 	{
1181 		// SU
1182 		e->SuAdapter = su_adapter;
1183 		e->Su = su;
1184 
1185 		// Get event object
1186 		h = e->SuAdapter->hEvent;
1187 
1188 		c = NewCancelSpecial(h);
1189 		e->Cancel = c;
1190 	}
1191 	else
1192 	{
1193 		// SEE
1194 		e->Adapter = a;
1195 
1196 		wp->PacketSetBuff(e->Adapter, BRIDGE_WIN32_ETH_BUFFER);
1197 		wp->PacketSetHwFilter(e->Adapter, local ? 0x0080 : 0x0020);
1198 		wp->PacketSetMode(e->Adapter, PACKET_MODE_CAPT);
1199 		wp->PacketSetReadTimeout(e->Adapter, -1);
1200 		wp->PacketSetNumWrites(e->Adapter, 1);
1201 
1202 		if (wp->PacketSetLoopbackBehavior != NULL)
1203 		{
1204 			// Filter loopback packet in kernel
1205 			if (GET_KETA(GetOsType(), 100) >= 3)
1206 			{
1207 				if (MsIsWindows8() == false)
1208 				{
1209 					// Enable for Windows XP, Server 2003 or later
1210 					// But disable for Windows 8 or later
1211 					bool ret = wp->PacketSetLoopbackBehavior(e->Adapter, 1);
1212 					Debug("*** PacketSetLoopbackBehavior: %u\n", ret);
1213 
1214 					e->LoopbackBlock = ret;
1215 				}
1216 			}
1217 		}
1218 
1219 		// Get event object
1220 		h = wp->PacketGetReadEvent(e->Adapter);
1221 
1222 		c = NewCancelSpecial(h);
1223 		e->Cancel = c;
1224 
1225 		e->Packet = wp->PacketAllocatePacket();
1226 
1227 		e->PutPacket = wp->PacketAllocatePacket();
1228 	}
1229 
1230 	e->Buffer = Malloc(BRIDGE_WIN32_ETH_BUFFER);
1231 	e->BufferSize = BRIDGE_WIN32_ETH_BUFFER;
1232 
1233 	e->PacketQueue = NewQueue();
1234 
1235 	// Get MAC address by GUID
1236 	ms = MsGetAdapterByGuid(t->Guid);
1237 	if (ms != NULL)
1238 	{
1239 		if (ms->AddressSize == 6)
1240 		{
1241 			Copy(e->MacAddress, ms->Address, 6);
1242 		}
1243 
1244 		MsFreeAdapter(ms);
1245 	}
1246 
1247 	Unlock(eth_list_lock);
1248 
1249 	return e;
1250 }
1251 
1252 // Generate a combined name from NIC name and GUID
Win32EthMakeCombinedName(char * dst,UINT dst_size,char * nicname,char * guid)1253 void Win32EthMakeCombinedName(char *dst, UINT dst_size, char *nicname, char *guid)
1254 {
1255 	// Validate arguments
1256 	if (dst == NULL || nicname == NULL || guid == NULL)
1257 	{
1258 		return;
1259 	}
1260 
1261 	if (IsEmptyStr(guid) == false)
1262 	{
1263 		Format(dst, dst_size, "%s (ID=%010u)", nicname, Win32EthGenIdFromGuid(guid));
1264 	}
1265 	else
1266 	{
1267 		StrCpy(dst, dst_size, nicname);
1268 	}
1269 }
1270 
1271 // Decompose combined name
Win32EthGetNameAndIdFromCombinedName(char * name,UINT name_size,char * str)1272 UINT Win32EthGetNameAndIdFromCombinedName(char *name, UINT name_size, char *str)
1273 {
1274 	UINT ret = 0;
1275 	char id_str[MAX_SIZE];
1276 	UINT len;
1277 	// Validate arguments
1278 	ClearStr(name, name_size);
1279 	StrCpy(name, name_size, str);
1280 	if (name == NULL || str == NULL)
1281 	{
1282 		return 0;
1283 	}
1284 
1285 	len = StrLen(str);
1286 
1287 	if (len >= 16)
1288 	{
1289 		StrCpy(id_str, sizeof(id_str), str + len - 16);
1290 
1291 		if (StartWith(id_str, " (ID="))
1292 		{
1293 			if (EndWith(id_str, ")"))
1294 			{
1295 				char num[MAX_SIZE];
1296 
1297 				Zero(num, sizeof(num));
1298 				StrCpy(num, sizeof(num), id_str + 5);
1299 
1300 				num[StrLen(num) - 1] = 0;
1301 
1302 				ret = ToInt(num);
1303 
1304 				if (ret != 0)
1305 				{
1306 					name[len - 16] = 0;
1307 				}
1308 			}
1309 		}
1310 	}
1311 
1312 	return ret;
1313 }
1314 
1315 // Generate an ID from GUID
Win32EthGenIdFromGuid(char * guid)1316 UINT Win32EthGenIdFromGuid(char *guid)
1317 {
1318 	char tmp[MAX_SIZE];
1319 	UCHAR hash[SHA1_SIZE];
1320 	UINT i;
1321 	// Validate arguments
1322 	if (guid == NULL)
1323 	{
1324 		return 0;
1325 	}
1326 
1327 	StrCpy(tmp, sizeof(tmp), guid);
1328 	Trim(tmp);
1329 	StrUpper(tmp);
1330 
1331 	HashSha1(hash, tmp, StrLen(tmp));
1332 
1333 	Copy(&i, hash, sizeof(UINT));
1334 
1335 	i = Endian32(i);
1336 
1337 	if (i == 0)
1338 	{
1339 		i = 1;
1340 	}
1341 
1342 	return i;
1343 }
1344 
1345 // Get Ethernet adapter list
GetEthList()1346 TOKEN_LIST *GetEthList()
1347 {
1348 	UINT v;
1349 
1350 	return GetEthListEx(&v, true, false);
1351 }
GetEthListEx(UINT * total_num_including_hidden,bool enum_normal,bool enum_rawip)1352 TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip)
1353 {
1354 	TOKEN_LIST *ret;
1355 	UINT i;
1356 	UINT j;
1357 	UINT dummy_int;
1358 	MS_ADAPTER_LIST *adapter_list;
1359 
1360 	if (IsEthSupported() == false)
1361 	{
1362 		return NULL;
1363 	}
1364 
1365 	if (enum_normal == false)
1366 	{
1367 		return NullToken();
1368 	}
1369 
1370 	if (total_num_including_hidden == NULL)
1371 	{
1372 		total_num_including_hidden = &dummy_int;
1373 	}
1374 
1375 	*total_num_including_hidden = 0;
1376 
1377 	Lock(eth_list_lock);
1378 
1379 	InitEthAdaptersList();
1380 
1381 	adapter_list = MsCreateAdapterList();
1382 
1383 	ret = ZeroMalloc(sizeof(TOKEN_LIST));
1384 	ret->NumTokens = LIST_NUM(eth_list);
1385 	ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
1386 	j = 0;
1387 	for (i = 0;i < ret->NumTokens;i++)
1388 	{
1389 		char tmp[MAX_SIZE];
1390 		WP_ADAPTER *a = LIST_DATA(eth_list, i);
1391 		MS_ADAPTER *msa = NULL;
1392 		bool show = true;
1393 
1394 		if (Win32EthGetShowAllIf() == false)
1395 		{
1396 			msa = MsGetAdapterByGuidFromList(adapter_list, a->Guid);
1397 
1398 			if (InStr(a->Title, "vpn client adapter"))
1399 			{
1400 				// Hide virtual NIC for VPN client
1401 				show = false;
1402 			}
1403 
1404 			if (InStr(a->Title, "tunnel adapter"))
1405 			{
1406 				// Hide tunnel adapter
1407 				show = false;
1408 			}
1409 
1410 			if (InStr(a->Title, "teredo tunnel"))
1411 			{
1412 				// Hide tunnel adapter
1413 				show = false;
1414 			}
1415 
1416 			if (InStr(a->Title, "MS Tunnel Interface"))
1417 			{
1418 				// Hide tunnel adapter
1419 				show = false;
1420 			}
1421 
1422 			if (InStr(a->Title, "pseudo-interface"))
1423 			{
1424 				// Hide tunnel adapter
1425 				show = false;
1426 			}
1427 		}
1428 
1429 		if (msa != NULL)
1430 		{
1431 			// Hide except physical Ethernet NIC
1432 			if (msa->IsNotEthernetLan)
1433 			{
1434 				show = false;
1435 			}
1436 
1437 			MsFreeAdapter(msa);
1438 		}
1439 
1440 		Win32EthMakeCombinedName(tmp, sizeof(tmp), a->Title, a->Guid);
1441 
1442 		if (show)
1443 		{
1444 			ret->Token[j++] = CopyStr(tmp);
1445 
1446 			Debug("%s - %s\n", a->Guid, a->Title);
1447 		}
1448 	}
1449 
1450 	*total_num_including_hidden = ret->NumTokens;
1451 
1452 	ret->NumTokens = j;
1453 
1454 	Unlock(eth_list_lock);
1455 
1456 	MsFreeAdapterList(adapter_list);
1457 
1458 	return ret;
1459 }
1460 
1461 // Compare the name of WP_ADAPTER
CompareWpAdapter(void * p1,void * p2)1462 int CompareWpAdapter(void *p1, void *p2)
1463 {
1464 	int i;
1465 	WP_ADAPTER *a1, *a2;
1466 	if (p1 == NULL || p2 == NULL)
1467 	{
1468 		return 0;
1469 	}
1470 	a1 = *(WP_ADAPTER **)p1;
1471 	a2 = *(WP_ADAPTER **)p2;
1472 	if (a1 == NULL || a2 == NULL)
1473 	{
1474 		return 0;
1475 	}
1476 	i = StrCmpi(a1->Title, a2->Title);
1477 	return i;
1478 }
1479 
1480 // Get whether the SeLow is used
Win32IsUsingSeLow()1481 bool Win32IsUsingSeLow()
1482 {
1483 	return is_using_selow;
1484 }
1485 
1486 // Get Ethernet adapter list
GetEthAdapterList()1487 LIST *GetEthAdapterList()
1488 {
1489 	void *p;
1490 	LIST *o;
1491 
1492 	p = MsDisableWow64FileSystemRedirection();
1493 
1494 	o = GetEthAdapterListInternal();
1495 
1496 	MsRestoreWow64FileSystemRedirection(p);
1497 
1498 	return o;
1499 }
GetEthAdapterListInternal()1500 LIST *GetEthAdapterListInternal()
1501 {
1502 	LIST *o;
1503 	LIST *ret;
1504 	UINT size;
1505 	char *buf;
1506 	UINT i, j;
1507 	char *qos_tag = " (Microsoft's Packet Scheduler)";
1508 	SU *su = NULL;
1509 	LIST *su_adapter_list = NULL;
1510 
1511 	// Try to use SeLow
1512 	if (enable_selow)
1513 	{
1514 		su = SuInit();
1515 	}
1516 
1517 	o = NewListFast(CompareWpAdapter);
1518 
1519 	size = 200000;
1520 	buf = ZeroMalloc(size);
1521 
1522 	// Try to enumerate with SeLow
1523 	if (su != NULL)
1524 	{
1525 		su_adapter_list = SuGetAdapterList(su);
1526 
1527 		if (su_adapter_list == NULL)
1528 		{
1529 			// Fail to enumerate
1530 			SuFree(su);
1531 			su = NULL;
1532 			//WHERE;
1533 			is_using_selow = false;
1534 		}
1535 		else
1536 		{
1537 			//WHERE;
1538 			is_using_selow = true;
1539 		}
1540 	}
1541 	else
1542 	{
1543 		is_using_selow = false;
1544 	}
1545 
1546 	if (su_adapter_list != NULL)
1547 	{
1548 		// If 1 or more adapters are enumerated by SeLow, create adapter list object
1549 		UINT i;
1550 
1551 		for (i = 0;i < LIST_NUM(su_adapter_list);i++)
1552 		{
1553 			SU_ADAPTER_LIST *t = LIST_DATA(su_adapter_list, i);
1554 			WP_ADAPTER *a = ZeroMalloc(sizeof(WP_ADAPTER));
1555 
1556 			StrCpy(a->Name, sizeof(a->Name), t->Name);
1557 			StrCpy(a->Guid, sizeof(a->Guid), t->Guid);
1558 			StrCpy(a->Title, sizeof(a->Title), t->Info.FriendlyName);
1559 
1560 			TrimCrlf(a->Title);
1561 			Trim(a->Title);
1562 			TrimCrlf(a->Title);
1563 			Trim(a->Title);
1564 
1565 			if (EndWith(a->Title, qos_tag))
1566 			{
1567 				a->Title[StrLen(a->Title) - StrLen(qos_tag)] = 0;
1568 				TrimCrlf(a->Title);
1569 				Trim(a->Title);
1570 				TrimCrlf(a->Title);
1571 				Trim(a->Title);
1572 			}
1573 
1574 			Add(o, a);
1575 		}
1576 	}
1577 	else
1578 	{
1579 		// When SeLow is not used, create adapter list with SEE or WinPcap
1580 		if (wp->PacketGetAdapterNames(buf, &size) == false)
1581 		{
1582 			Free(buf);
1583 			return o;
1584 		}
1585 
1586 		i = 0;
1587 
1588 		if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
1589 		{
1590 			// Windows NT
1591 			if (size >= 2 && buf[0] != 0 && buf[1] != 0)
1592 			{
1593 				goto ANSI_STR;
1594 			}
1595 
1596 			while (true)
1597 			{
1598 				wchar_t tmp[MAX_SIZE];
1599 				WP_ADAPTER *a;
1600 				UniStrCpy(tmp, sizeof(tmp), L"");
1601 
1602 				if (*((wchar_t *)(&buf[i])) == 0)
1603 				{
1604 					i += sizeof(wchar_t);
1605 					break;
1606 				}
1607 
1608 				for (;*((wchar_t *)(&buf[i])) != 0;i += sizeof(wchar_t))
1609 				{
1610 					wchar_t str[2];
1611 					str[0] = *((wchar_t *)(&buf[i]));
1612 					str[1] = 0;
1613 					UniStrCat(tmp, sizeof(tmp), str);
1614 				}
1615 
1616 				i += sizeof(wchar_t);
1617 
1618 				a = ZeroMalloc(sizeof(WP_ADAPTER));
1619 				UniToStr(a->Name, sizeof(a->Name), tmp);
1620 
1621 				Add(o, a);
1622 			}
1623 		}
1624 		else
1625 		{
1626 			// Windows 9x
1627 ANSI_STR:
1628 			while (true)
1629 			{
1630 				char tmp[MAX_SIZE];
1631 				WP_ADAPTER *a;
1632 				StrCpy(tmp, sizeof(tmp), "");
1633 
1634 				if (*((char *)(&buf[i])) == 0)
1635 				{
1636 					i += sizeof(char);
1637 					break;
1638 				}
1639 
1640 				for (;*((char *)(&buf[i])) != 0;i += sizeof(char))
1641 				{
1642 					char str[2];
1643 					str[0] = *((char *)(&buf[i]));
1644 					str[1] = 0;
1645 					StrCat(tmp, sizeof(tmp), str);
1646 				}
1647 
1648 				i += sizeof(char);
1649 
1650 				a = ZeroMalloc(sizeof(WP_ADAPTER));
1651 				StrCpy(a->Name, sizeof(a->Name), tmp);
1652 
1653 				Add(o, a);
1654 			}
1655 		}
1656 
1657 		for (j = 0;j < LIST_NUM(o);j++)
1658 		{
1659 			WP_ADAPTER *a = LIST_DATA(o, j);
1660 
1661 			StrCpy(a->Title, sizeof(a->Title), &buf[i]);
1662 			i += StrSize(a->Title);
1663 
1664 			// If device description is "Unknown" in Win9x, skip 1 byte
1665 			if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType))
1666 			{
1667 				if (StrCmp(a->Title, "Unknown") == 0)
1668 				{
1669 					if (buf[i] == 0)
1670 					{
1671 						i+=sizeof(char);
1672 					}
1673 				}
1674 			}
1675 
1676 			TrimCrlf(a->Title);
1677 			Trim(a->Title);
1678 			TrimCrlf(a->Title);
1679 			Trim(a->Title);
1680 
1681 			if (EndWith(a->Title, qos_tag))
1682 			{
1683 				a->Title[StrLen(a->Title) - StrLen(qos_tag)] = 0;
1684 				TrimCrlf(a->Title);
1685 				Trim(a->Title);
1686 				TrimCrlf(a->Title);
1687 				Trim(a->Title);
1688 			}
1689 		}
1690 	}
1691 
1692 	for (j = 0;j < LIST_NUM(o);j++)
1693 	{
1694 		// Extract GUID
1695 		WP_ADAPTER *a = LIST_DATA(o, j);
1696 
1697 		if (IsEmptyStr(a->Guid))
1698 		{
1699 			StrCpy(a->Guid, sizeof(a->Guid), a->Name);
1700 			ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\SEE_", "");
1701 			ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\NPF_", "");
1702 			ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\PCD_", "");
1703 		}
1704 	}
1705 
1706 	// Sort
1707 	if (su_adapter_list != NULL)
1708 	{
1709 		// Since adapter list made by SeLow is already sorted, don't sort here
1710 		Sort(o);
1711 	}
1712 
1713 	ret = NewListFast(CompareWpAdapter);
1714 
1715 	for (i = 0;i < LIST_NUM(o);i++)
1716 	{
1717 		WP_ADAPTER *a = LIST_DATA(o, i);
1718 		ADAPTER *ad;
1719 		bool is_ethernet = false;
1720 		bool ok = false;
1721 
1722 		if (SearchStrEx(a->Title, "ppp", 0, false) != INFINITE ||
1723 			SearchStrEx(a->Title, "wan", 0, false) != INFINITE ||
1724 			SearchStrEx(a->Title, "dialup", 0, false) != INFINITE ||
1725 			SearchStrEx(a->Title, "pptp", 0, false) != INFINITE ||
1726 			SearchStrEx(a->Title, "telepho", 0, false) != INFINITE ||
1727 			SearchStrEx(a->Title, "modem", 0, false) != INFINITE ||
1728 			SearchStrEx(a->Title, "ras", 0, false) != INFINITE)
1729 		{
1730 			Free(a);
1731 			continue;
1732 		}
1733 
1734 		// Determine whether the adapter type is Ethernet
1735 		if (su == NULL)
1736 		{
1737 			// Determine with See
1738 			ad = wp->PacketOpenAdapter(a->Name);
1739 			if (ad != NULL)
1740 			{
1741 				NetType type;
1742 				if (wp->PacketGetNetType(ad, &type))
1743 				{
1744 					if (type.LinkType == 0)
1745 					{
1746 						is_ethernet = true;
1747 					}
1748 				}
1749 
1750 				wp->PacketCloseAdapter(ad);
1751 			}
1752 		}
1753 		else
1754 		{
1755 			// In using SeLow, all devices should be Ethernet device
1756 			is_ethernet = true;
1757 		}
1758 
1759 		if (is_ethernet)
1760 		{
1761 			// Add only Ethernet device
1762 			char tmp[MAX_SIZE];
1763 			UINT k;
1764 
1765 			StrCpy(tmp, sizeof(tmp), a->Title);
1766 
1767 			for (k = 0;;k++)
1768 			{
1769 				if (k == 0)
1770 				{
1771 					StrCpy(tmp, sizeof(tmp), a->Title);
1772 				}
1773 				else
1774 				{
1775 					Format(tmp, sizeof(tmp), "%s (%u)", a->Title, k + 1);
1776 				}
1777 
1778 				ok = true;
1779 				for (j = 0;j < LIST_NUM(ret);j++)
1780 				{
1781 					WP_ADAPTER *aa = LIST_DATA(ret, j);
1782 					if (StrCmpi(aa->Title, tmp) == 0)
1783 					{
1784 						ok = false;
1785 					}
1786 				}
1787 
1788 				if (ok)
1789 				{
1790 					break;
1791 				}
1792 			}
1793 
1794 			StrCpy(a->Title, sizeof(a->Title), tmp);
1795 			a->Id = Win32EthGenIdFromGuid(a->Guid);
1796 			Add(ret, a);
1797 		}
1798 
1799 		if (ok == false)
1800 		{
1801 			Free(a);
1802 		}
1803 	}
1804 
1805 	Free(buf);
1806 
1807 	Sort(ret);
1808 
1809 	ReleaseList(o);
1810 
1811 	if (su != NULL)
1812 	{
1813 		SuFreeAdapterList(su_adapter_list);
1814 
1815 		SuFree(su);
1816 	}
1817 
1818 	return ret;
1819 }
1820 
1821 // Initialize Ethernet adapter list
InitEthAdaptersList()1822 void InitEthAdaptersList()
1823 {
1824 	if (eth_list != NULL)
1825 	{
1826 		FreeEthAdaptersList();
1827 		eth_list = NULL;
1828 	}
1829 	eth_list = GetEthAdapterList();
1830 }
1831 
1832 // Free Ethernet adapter list
FreeEthAdaptersList()1833 void FreeEthAdaptersList()
1834 {
1835 	UINT i;
1836 	if (eth_list == NULL)
1837 	{
1838 		return;
1839 	}
1840 	for (i = 0;i < LIST_NUM(eth_list);i++)
1841 	{
1842 		WP_ADAPTER *a = LIST_DATA(eth_list, i);
1843 		Free(a);
1844 	}
1845 	ReleaseList(eth_list);
1846 	eth_list = NULL;
1847 }
1848 
1849 // Is the SU supported
Win32EthIsSuSupported()1850 bool Win32EthIsSuSupported()
1851 {
1852 	bool ret = false;
1853 	SU *su = SuInit();
1854 
1855 	if (su != NULL)
1856 	{
1857 		ret = true;
1858 	}
1859 
1860 	SuFree(su);
1861 
1862 	return ret;
1863 }
1864 
1865 // Is the Ethernet supported
IsEthSupported()1866 bool IsEthSupported()
1867 {
1868 	bool ret = IsEthSupportedInner();
1869 
1870 	if (ret == false)
1871 	{
1872 		ret = Win32EthIsSuSupported();
1873 	}
1874 
1875 	return ret;
1876 }
IsEthSupportedInner()1877 bool IsEthSupportedInner()
1878 {
1879 	if (wp == NULL)
1880 	{
1881 		return false;
1882 	}
1883 
1884 	return wp->Inited;
1885 }
1886 
1887 // Is the PCD driver supported in current OS
IsPcdSupported()1888 bool IsPcdSupported()
1889 {
1890 	UINT type;
1891 	OS_INFO *info = GetOsInfo();
1892 
1893 	if (MsIsWindows10())
1894 	{
1895 		// Windows 10 or later never supports PCD driver.
1896 		return false;
1897 	}
1898 
1899 	type = info->OsType;
1900 
1901 	if (OS_IS_WINDOWS_NT(type) == false)
1902 	{
1903 		// Only on Windows NT series
1904 		return false;
1905 	}
1906 
1907 	if (GET_KETA(type, 100) >= 2)
1908 	{
1909 		// Good for Windows 2000 or later
1910 		return true;
1911 	}
1912 
1913 	// Not good for Windows NT 4.0 or Longhorn
1914 	return false;
1915 }
1916 
1917 // Save build number of PCD driver
SavePcdDriverBuild(UINT build)1918 void SavePcdDriverBuild(UINT build)
1919 {
1920 	MsRegWriteInt(REG_LOCAL_MACHINE, BRIDGE_WIN32_PCD_REGKEY, BRIDGE_WIN32_PCD_BUILDVALUE,
1921 		build);
1922 }
1923 
1924 // Load build number of PCD driver
LoadPcdDriverBuild()1925 UINT LoadPcdDriverBuild()
1926 {
1927 	return MsRegReadInt(REG_LOCAL_MACHINE, BRIDGE_WIN32_PCD_REGKEY, BRIDGE_WIN32_PCD_BUILDVALUE);
1928 }
1929 
1930 // Try to install PCD driver
InstallPcdDriver()1931 HINSTANCE InstallPcdDriver()
1932 {
1933 	HINSTANCE ret;
1934 	void *p = MsDisableWow64FileSystemRedirection();
1935 
1936 	ret = InstallPcdDriverInternal();
1937 
1938 	MsRestoreWow64FileSystemRedirection(p);
1939 
1940 	return ret;
1941 }
InstallPcdDriverInternal()1942 HINSTANCE InstallPcdDriverInternal()
1943 {
1944 	char tmp[MAX_PATH];
1945 	bool install_driver = true;
1946 	HINSTANCE h;
1947 	char *dll_filename;
1948 
1949 	// Confirm whether the see.sys is installed in system32\drivers folder
1950 	Format(tmp, sizeof(tmp), "%s\\drivers\\see.sys", MsGetSystem32Dir());
1951 
1952 	if (IsFileExists(tmp))
1953 	{
1954 		// If driver file is exist, try to get build number from registry
1955 		if (LoadPcdDriverBuild() >= CEDAR_BUILD)
1956 		{
1957 			// Already latest driver is installed
1958 			install_driver = false;
1959 		}
1960 	}
1961 
1962 	if (install_driver)
1963 	{
1964 		char *src_filename = BRIDGE_WIN32_PCD_SYS;
1965 		// If need to install the driver, confirm user is administrator
1966 		if (MsIsAdmin() == false)
1967 		{
1968 			// Non administrator can't install driver
1969 			return NULL;
1970 		}
1971 
1972 		if (MsIsX64())
1973 		{
1974 			src_filename = BRIDGE_WIN32_PCD_SYS_X64;
1975 		}
1976 
1977 		// Copy see.sys
1978 		if (FileCopy(src_filename, tmp) == false)
1979 		{
1980 			return NULL;
1981 		}
1982 
1983 		// Save build number
1984 		SavePcdDriverBuild(CEDAR_BUILD);
1985 	}
1986 
1987 	dll_filename = BRIDGE_WIN32_PCD_DLL;
1988 
1989 	if (Is64())
1990 	{
1991 		if (MsIsX64())
1992 		{
1993 			dll_filename = BRIDGE_WIN32_PCD_DLL_X64;
1994 		}
1995 	}
1996 
1997 	// Try to load see.dll and initialize
1998 	h = MsLoadLibrary(dll_filename);
1999 	if (h == NULL)
2000 	{
2001 		return NULL;
2002 	}
2003 
2004 	return h;
2005 }
2006 
2007 // Initialize Ethernet
InitEth()2008 void InitEth()
2009 {
2010 	HINSTANCE h;
2011 	if (wp != NULL)
2012 	{
2013 		// Already initialized
2014 		return;
2015 	}
2016 
2017 	eth_list_lock = NewLock();
2018 
2019 	wp = ZeroMalloc(sizeof(WP));
2020 
2021 	is_see_mode = false;
2022 
2023 	if (IsPcdSupported())
2024 	{
2025 		// PCD is supported in this OS
2026 		h = InstallPcdDriver();
2027 		if (h != NULL)
2028 		{
2029 			// Try to initialize with PCD
2030 			if (InitWpWithLoadLibrary(wp, h) == false)
2031 			{
2032 				Debug("InitEth: SEE Failed.\n");
2033 				FreeLibrary(h);
2034 			}
2035 			else
2036 			{
2037 				Debug("InitEth: SEE Loaded.\n");
2038 				is_see_mode = true;
2039 			}
2040 		}
2041 	}
2042 
2043 	if (wp->Inited == false)
2044 	{
2045 		// Try to initialize with Packet.dll of WinPcap
2046 		h = LoadLibrary(BRIDGE_WIN32_PACKET_DLL);
2047 		if (h != NULL)
2048 		{
2049 			if (InitWpWithLoadLibrary(wp, h) == false)
2050 			{
2051 				Debug("InitEth: Packet.dll Failed.\n");
2052 				FreeLibrary(h);
2053 			}
2054 			else
2055 			{
2056 				Debug("InitEth: Packet.dll Loaded.\n");
2057 			}
2058 		}
2059 	}
2060 }
2061 
2062 // Get whether local-bridge uses see.sys
IsWin32BridgeWithSee()2063 bool IsWin32BridgeWithSee()
2064 {
2065 	return is_see_mode;
2066 }
2067 
2068 // Initialize WP structure with DLL
InitWpWithLoadLibrary(WP * wp,HINSTANCE h)2069 bool InitWpWithLoadLibrary(WP *wp, HINSTANCE h)
2070 {
2071 	TOKEN_LIST *o;
2072 	UINT total_num = 0;
2073 	// Validate arguments
2074 	if (wp == NULL || h == NULL)
2075 	{
2076 		return false;
2077 	}
2078 	wp->Inited = true;
2079 	wp->hPacketDll = h;
2080 
2081 	LOAD_DLL_ADDR(PacketGetVersion);
2082 	LOAD_DLL_ADDR(PacketGetDriverVersion);
2083 	LOAD_DLL_ADDR(PacketSetMinToCopy);
2084 	LOAD_DLL_ADDR(PacketSetNumWrites);
2085 	LOAD_DLL_ADDR(PacketSetMode);
2086 	LOAD_DLL_ADDR(PacketSetReadTimeout);
2087 	LOAD_DLL_ADDR(PacketSetBpf);
2088 	LOAD_DLL_ADDR(PacketSetSnapLen);
2089 	LOAD_DLL_ADDR(PacketGetStats);
2090 	LOAD_DLL_ADDR(PacketGetStatsEx);
2091 	LOAD_DLL_ADDR(PacketSetBuff);
2092 	LOAD_DLL_ADDR(PacketGetNetType);
2093 	LOAD_DLL_ADDR(PacketOpenAdapter);
2094 	LOAD_DLL_ADDR(PacketSendPacket);
2095 	LOAD_DLL_ADDR(PacketSendPackets);
2096 	LOAD_DLL_ADDR(PacketAllocatePacket);
2097 	LOAD_DLL_ADDR(PacketInitPacket);
2098 	LOAD_DLL_ADDR(PacketFreePacket);
2099 	LOAD_DLL_ADDR(PacketReceivePacket);
2100 	LOAD_DLL_ADDR(PacketSetHwFilter);
2101 	LOAD_DLL_ADDR(PacketGetAdapterNames);
2102 	LOAD_DLL_ADDR(PacketGetNetInfoEx);
2103 	LOAD_DLL_ADDR(PacketRequest);
2104 	LOAD_DLL_ADDR(PacketGetReadEvent);
2105 	LOAD_DLL_ADDR(PacketSetDumpName);
2106 	LOAD_DLL_ADDR(PacketSetDumpLimits);
2107 	LOAD_DLL_ADDR(PacketSetDumpLimits);
2108 	LOAD_DLL_ADDR(PacketIsDumpEnded);
2109 	LOAD_DLL_ADDR(PacketStopDriver);
2110 	LOAD_DLL_ADDR(PacketCloseAdapter);
2111 	LOAD_DLL_ADDR(PacketSetLoopbackBehavior);
2112 
2113 	if (wp->PacketSetMinToCopy == NULL ||
2114 		wp->PacketSetNumWrites == NULL ||
2115 		wp->PacketSetMode == NULL ||
2116 		wp->PacketSetReadTimeout == NULL ||
2117 		wp->PacketSetBuff == NULL ||
2118 		wp->PacketGetNetType == NULL ||
2119 		wp->PacketOpenAdapter == NULL ||
2120 		wp->PacketSendPacket == NULL ||
2121 		wp->PacketSendPackets == NULL ||
2122 		wp->PacketAllocatePacket == NULL ||
2123 		wp->PacketInitPacket == NULL ||
2124 		wp->PacketFreePacket == NULL ||
2125 		wp->PacketReceivePacket == NULL ||
2126 		wp->PacketSetHwFilter == NULL ||
2127 		wp->PacketGetAdapterNames == NULL ||
2128 		wp->PacketGetNetInfoEx == NULL ||
2129 		wp->PacketCloseAdapter == NULL)
2130 	{
2131 RELEASE:
2132 		wp->Inited = false;
2133 		wp->hPacketDll = NULL;
2134 
2135 		return false;
2136 	}
2137 
2138 	o = GetEthListEx(&total_num, true, false);
2139 	if (o == NULL || total_num == 0)
2140 	{
2141 		FreeToken(o);
2142 		goto RELEASE;
2143 	}
2144 
2145 	FreeToken(o);
2146 
2147 	return true;
2148 }
2149 
2150 // Free Ethernet
FreeEth()2151 void FreeEth()
2152 {
2153 	if (wp == NULL)
2154 	{
2155 		// Not initialized
2156 		return;
2157 	}
2158 
2159 	// Free adapter list
2160 	FreeEthAdaptersList();
2161 
2162 	if (wp->Inited)
2163 	{
2164 		// Free DLL
2165 		FreeLibrary(wp->hPacketDll);
2166 	}
2167 
2168 	Free(wp);
2169 	wp = NULL;
2170 
2171 	DeleteLock(eth_list_lock);
2172 	eth_list_lock = NULL;
2173 }
2174 
2175 // Get network connection name from Ethernet device name
GetEthNetworkConnectionName(wchar_t * dst,UINT size,char * device_name)2176 void GetEthNetworkConnectionName(wchar_t *dst, UINT size, char *device_name)
2177 {
2178 	WP_ADAPTER *t;
2179 	char *tmp = NULL, guid[MAX_SIZE];
2180 	wchar_t *ncname = NULL;
2181 
2182 	UniStrCpy(dst, size, L"");
2183 
2184 	// Validate arguments
2185 	if (device_name == NULL || IsEthSupported() == false ||
2186 		IsNt() == false || MsIsWin2000OrGreater() == false)
2187 	{
2188 		return;
2189 	}
2190 
2191 	Lock(eth_list_lock);
2192 
2193 	InitEthAdaptersList();
2194 
2195 	t = Win32EthSearch(device_name);
2196 
2197 	if (t == NULL)
2198 	{
2199 		Unlock(eth_list_lock);
2200 		return;
2201 	}
2202 
2203 	tmp = CopyStr(t->Name);
2204 	Unlock(eth_list_lock);
2205 
2206 	if (IsEmptyStr(t->Guid) == false)
2207 	{
2208 		StrCpy(guid, sizeof(guid), t->Guid);
2209 
2210 		Free(tmp);
2211 	}
2212 	else
2213 	{
2214 		ReplaceStr(guid, sizeof(guid), tmp, "\\Device\\SEE_", "");
2215 		Free(tmp);
2216 
2217 		ReplaceStr(guid, sizeof(guid), guid, "\\Device\\NPF_", "");
2218 		ReplaceStr(guid, sizeof(guid), guid, "\\Device\\PCD_", "");
2219 	}
2220 
2221 	if(guid == NULL)
2222 	{
2223 		return;
2224 	}
2225 
2226 	ncname = MsGetNetworkConnectionName(guid);
2227 	if(ncname != NULL)
2228 	{
2229 		UniStrCpy(dst, size, ncname);
2230 	}
2231 	Free(ncname);
2232 }
2233 
2234 #endif	// BRIDGE_C
2235 
2236 
2237