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 // BridgeUnix.c
103 // Ethernet Bridge Program (for UNIX)
104 //#define BRIDGE_C
105 //#define UNIX_LINUX
106
107 #include <GlobalConst.h>
108
109 #ifdef BRIDGE_C
110
111 #include <stdio.h>
112 #include <stdlib.h>
113 #include <string.h>
114 #include <wchar.h>
115 #include <stdarg.h>
116 #include <time.h>
117 #include <errno.h>
118 #include <Mayaqua/Mayaqua.h>
119 #include <Cedar/Cedar.h>
120
121 #ifdef UNIX_SOLARIS
122 #include <sys/sockio.h>
123 #endif
124
125 #ifdef BRIDGE_PCAP
126 #include <pcap.h>
127 #endif // BRIDGE_PCAP
128
129 #ifdef BRIDGE_BPF
130 #include <sys/ioctl.h>
131 #include <net/bpf.h>
132 #include <net/if_types.h>
133 #include <net/if_dl.h>
134 #include <ifaddrs.h>
135 #endif // BRIDGE_BPF
136
137 #ifdef UNIX_LINUX
138 struct my_tpacket_auxdata
139 {
140 UINT tp_status;
141 UINT tp_len;
142 UINT tp_snaplen;
143 USHORT tp_mac;
144 USHORT tp_net;
145 USHORT tp_vlan_tci;
146 USHORT tp_vlan_tpid;
147 };
148 #define MY_TP_STATUS_VLAN_VALID (1 << 4)
149 #define MY_TP_STATUS_VLAN_TPID_VALID (1 << 6)
150 #define MY_PACKET_AUXDATA 8
151 #endif // UNIX_LINUX
152
153 static LIST *eth_offload_list = NULL;
154
155 // Initialize
InitEth()156 void InitEth()
157 {
158 eth_offload_list = NewList(NULL);
159 }
160
161 // Free
FreeEth()162 void FreeEth()
163 {
164 if (eth_offload_list != NULL)
165 {
166 FreeStrList(eth_offload_list);
167 eth_offload_list = NULL;
168 }
169 }
170
171 // Check whether interface description string of Ethernet device can be retrieved in this system
EthIsInterfaceDescriptionSupportedUnix()172 bool EthIsInterfaceDescriptionSupportedUnix()
173 {
174 bool ret = false;
175 DIRLIST *d = EnumDir("/etc/sysconfig/networking/devices/");
176
177 if (d == NULL)
178 {
179 return false;
180 }
181
182 if (d->NumFiles >= 1)
183 {
184 ret = true;
185 }
186
187 FreeDir(d);
188
189 return ret;
190 }
191
192 // Get interface description string
EthGetInterfaceDescriptionUnix(char * name,char * str,UINT size)193 bool EthGetInterfaceDescriptionUnix(char *name, char *str, UINT size)
194 {
195 char tmp[MAX_SIZE];
196 bool ret = false;
197 BUF *b;
198 // Validate arguments
199 if (name == NULL || str == NULL)
200 {
201 return false;
202 }
203
204 StrCpy(str, size, name);
205
206 Format(tmp, sizeof(tmp), "/etc/sysconfig/networking/devices/ifcfg-%s", name);
207
208 b = ReadDump(tmp);
209 if (b != NULL)
210 {
211 char *line = CfgReadNextLine(b);
212
213 if (IsEmptyStr(line) == false)
214 {
215 if (StartWith(line, "#"))
216 {
217 char tmp[MAX_SIZE];
218
219 StrCpy(tmp, sizeof(tmp), line + 1);
220
221 Trim(tmp);
222 tmp[60] = 0;
223
224 StrCpy(str, size, tmp);
225
226 ret = true;
227 }
228 }
229
230 Free(line);
231
232 FreeBuf(b);
233 }
234
235 return ret;
236 }
237
238 // Open raw socket
UnixEthOpenRawSocket()239 int UnixEthOpenRawSocket()
240 {
241 #ifdef UNIX_LINUX
242 int s;
243
244 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
245 if (s < 0)
246 {
247 return INVALID_SOCKET;
248 }
249 else
250 {
251 return s;
252 }
253 #else // UNIX_LINUX
254 return -1;
255 #endif // UNIX_LINUX
256 }
257
258 // Is Ethernet device control supported?
IsEthSupported()259 bool IsEthSupported()
260 {
261 bool ret = false;
262
263 #if defined(UNIX_LINUX)
264 ret = IsEthSupportedLinux();
265 #elif defined(UNIX_SOLARIS)
266 ret = IsEthSupportedSolaris();
267 #elif defined(BRIDGE_PCAP)
268 ret = true;
269 #elif defined(BRIDGE_BPF)
270 ret = true;
271 #endif
272 return ret;
273 }
274
275 #ifdef UNIX_LINUX
IsEthSupportedLinux()276 bool IsEthSupportedLinux()
277 {
278 int s;
279
280 // Try to open a raw socket
281 s = UnixEthOpenRawSocket();
282 if (s == INVALID_SOCKET)
283 {
284 // fail
285 return false;
286 }
287
288 // success
289 closesocket(s);
290
291 return true;
292 }
293 #endif // UNIX_LINUX
294
295 #ifdef UNIX_SOLARIS
IsEthSupportedSolaris()296 bool IsEthSupportedSolaris()
297 {
298 return true;
299 }
300 #endif // UNIX_SOLARIS
301
302 #ifdef UNIX_SOLARIS
303 // Get Ethernet device list on Solaris
GetEthListSolaris()304 TOKEN_LIST *GetEthListSolaris()
305 {
306 TOKEN_LIST *t;
307 int i, s;
308 LIST *o;
309
310
311 o = NewListFast(CompareStr);
312 s = socket(AF_INET, SOCK_DGRAM, 0);
313 if (s != INVALID_SOCKET)
314 {
315 struct lifnum lifn;
316 lifn.lifn_family = AF_INET;
317 lifn.lifn_flags = 0;
318 if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) >= 0)
319 {
320 struct lifconf lifc;
321 struct lifreq *buf;
322 UINT numifs;
323 UINT bufsize;
324
325 numifs = lifn.lifn_count;
326 Debug("NumIFs:%d\n",numifs);
327 bufsize = numifs * sizeof(struct lifreq);
328 buf = Malloc(bufsize);
329
330 lifc.lifc_family = AF_INET;
331 lifc.lifc_flags = 0;
332 lifc.lifc_len = bufsize;
333 lifc.lifc_buf = (char*) buf;
334 if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) >= 0)
335 {
336 for (i = 0; i<numifs; i++)
337 {
338 if(StartWith(buf[i].lifr_name, "lo") == false){
339 Add(o, CopyStr(buf[i].lifr_name));
340 }
341 }
342 }
343 Free(buf);
344 }
345 closesocket(s);
346 }
347
348 Sort(o);
349
350 t = ZeroMalloc(sizeof(TOKEN_LIST));
351 t->NumTokens = LIST_NUM(o);
352 t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
353
354 for (i = 0;i < LIST_NUM(o);i++)
355 {
356 char *name = LIST_DATA(o, i);
357 t->Token[i] = name;
358 }
359
360 ReleaseList(o);
361
362 return t;
363 }
364 #endif // UNIX_SOLARIS
365
366 #ifdef UNIX_LINUX
367 // Get Ethernet device list on Linux
GetEthListLinux(bool enum_normal,bool enum_rawip)368 TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip)
369 {
370 struct ifreq ifr;
371 TOKEN_LIST *t;
372 UINT i, n;
373 int s;
374 LIST *o;
375 char name[MAX_SIZE];
376
377 if (enum_normal == false && enum_rawip)
378 {
379 return ParseToken(BRIDGE_SPECIAL_IPRAW_NAME, NULL);
380 }
381
382 o = NewListFast(CompareStr);
383
384 s = UnixEthOpenRawSocket();
385 if (s != INVALID_SOCKET)
386 {
387 n = 0;
388 for (i = 0;;i++)
389 {
390 Zero(&ifr, sizeof(ifr));
391 ifr.ifr_ifindex = i;
392
393 if (ioctl(s, SIOCGIFNAME, &ifr) >= 0)
394 {
395 n = 0;
396 StrCpy(name, sizeof(name), ifr.ifr_name);
397
398 Zero(&ifr, sizeof(ifr));
399 StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), name);
400 if (ioctl(s, SIOCGIFHWADDR, &ifr) >= 0)
401 {
402 UINT type = ifr.ifr_hwaddr.sa_family;
403 if (type == 1 || type == 2 || type == 6 || type == 800 || type == 801)
404 {
405 if (IsInListStr(o, name) == false)
406 {
407 if (StartWith(name, "tap_") == false)
408 {
409 Add(o, CopyStr(name));
410 }
411 }
412 }
413 }
414 }
415 else
416 {
417 n++;
418 if (n >= 64)
419 {
420 break;
421 }
422 }
423 }
424 closesocket(s);
425 }
426
427 Sort(o);
428
429 t = ZeroMalloc(sizeof(TOKEN_LIST));
430 t->NumTokens = LIST_NUM(o) + (enum_rawip ? 1 : 0);
431 t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
432
433 for (i = 0;i < LIST_NUM(o);i++)
434 {
435 char *name = LIST_DATA(o, i);
436 t->Token[i] = name;
437 }
438
439 if (enum_rawip)
440 {
441 t->Token[t->NumTokens - 1] = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
442 }
443
444 ReleaseList(o);
445
446 return t;
447 }
448 #endif // UNIX_LINUX
449
450 #ifdef BRIDGE_PCAP
451 // Ethernet device list by Pcap API
GetEthListPcap()452 TOKEN_LIST *GetEthListPcap()
453 {
454 pcap_if_t *alldevs;
455 char errbuf[PCAP_ERRBUF_SIZE];
456 LIST *o;
457 TOKEN_LIST *t;
458 int i;
459
460 o = NewListFast(CompareStr);
461
462 if( pcap_findalldevs(&alldevs,errbuf) != -1)
463 {
464 pcap_if_t *dev = alldevs;
465 while(dev != NULL)
466 {
467 pcap_t *p;
468 // Device type will be unknown until open the device?
469 p = pcap_open_live(dev->name, 0, false, 0, errbuf);
470 if(p != NULL)
471 {
472 int datalink = pcap_datalink(p);
473 // Debug("type:%s\n",pcap_datalink_val_to_name(datalink));
474 pcap_close(p);
475 if(datalink == DLT_EN10MB){
476 // Enumerate only Ethernet type device
477 Add(o, CopyStr(dev->name));
478 }
479 }
480 dev = dev->next;
481 }
482 pcap_freealldevs(alldevs);
483 }
484
485 Sort(o);
486 t = ZeroMalloc(sizeof(TOKEN_LIST));
487 t->NumTokens = LIST_NUM(o);
488 t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
489 for (i = 0;i < LIST_NUM(o);i++)
490 {
491 t->Token[i] = LIST_DATA(o, i);
492 }
493 ReleaseList(o);
494 return t;
495 }
496 #endif // BRIDGE_PCAP
497
498 #ifdef BRIDGE_BPF
499 // Ethernet device list by BPF API
GetEthListBpf()500 TOKEN_LIST *GetEthListBpf()
501 {
502 struct ifaddrs *ifadrs;
503 struct sockaddr_dl *sockadr;
504 LIST *o;
505 TOKEN_LIST *t;
506 int i;
507
508 o = NewListFast(CompareStr);
509
510 // Enumerate network devices
511 if(getifaddrs( &ifadrs ) == 0)
512 {
513 struct ifaddrs *ifadr = ifadrs;
514 while(ifadr)
515 {
516 sockadr = (struct sockaddr_dl*)ifadr->ifa_addr;
517 if(sockadr->sdl_family == AF_LINK && sockadr->sdl_type == IFT_ETHER)
518 {
519 // Is this Ethernet device?
520 if(!IsInListStr(o,ifadr->ifa_name))
521 {
522 // Ignore the foregoing device (for device which have multiple MAC address)
523 Add(o, CopyStr(ifadr->ifa_name));
524 }
525 }
526 ifadr = ifadr -> ifa_next;
527 }
528 freeifaddrs(ifadrs);
529 }
530
531 Sort(o);
532 t = ZeroMalloc(sizeof(TOKEN_LIST));
533 t->NumTokens = LIST_NUM(o);
534 t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
535 for (i = 0;i < LIST_NUM(o);i++)
536 {
537 t->Token[i] = LIST_DATA(o, i);
538 }
539 ReleaseList(o);
540 return t;
541 }
542 #endif // BRIDGE_BPF
543
544 // Enumerate Ethernet devices
GetEthList()545 TOKEN_LIST *GetEthList()
546 {
547 return GetEthListEx(NULL, true, false);
548 }
GetEthListEx(UINT * total_num_including_hidden,bool enum_normal,bool enum_rawip)549 TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip)
550 {
551 TOKEN_LIST *t = NULL;
552
553 #if defined(UNIX_LINUX)
554 t = GetEthListLinux(enum_normal, enum_rawip);
555 #elif defined(UNIX_SOLARIS)
556 t = GetEthListSolaris();
557 #elif defined(BRIDGE_PCAP)
558 t = GetEthListPcap();
559 #elif defined(BRIDGE_BPF)
560 t = GetEthListBpf();
561 #endif
562
563 return t;
564 }
565
566 #ifdef UNIX_LINUX
567 // Open Ethernet device (Linux)
OpenEthLinux(char * name,bool local,bool tapmode,char * tapaddr)568 ETH *OpenEthLinux(char *name, bool local, bool tapmode, char *tapaddr)
569 {
570 ETH *e;
571 struct ifreq ifr;
572 struct sockaddr_ll addr;
573 int s;
574 int index;
575 bool aux_ok = false;
576 CANCEL *c;
577 // Validate arguments
578 if (name == NULL)
579 {
580 return NULL;
581 }
582
583 if (StrCmpi(name, BRIDGE_SPECIAL_IPRAW_NAME) == 0)
584 {
585 return OpenEthLinuxIpRaw();
586 }
587
588 if (tapmode)
589 {
590 #ifndef NO_VLAN
591 // In tap mode
592 VLAN *v = NewTap(name, tapaddr);
593 if (v == NULL)
594 {
595 return NULL;
596 }
597
598 e = ZeroMalloc(sizeof(ETH));
599 e->Name = CopyStr(name);
600 e->Title = CopyStr(name);
601 e->Cancel = VLanGetCancel(v);
602 e->IfIndex = 0;
603 e->Socket = INVALID_SOCKET;
604 e->Tap = v;
605
606 return e;
607 #else // NO_VLAN
608 return NULL;
609 #endif // NO_VLAN
610 }
611
612 s = UnixEthOpenRawSocket();
613 if (s == INVALID_SOCKET)
614 {
615 return NULL;
616 }
617
618 Zero(&ifr, sizeof(ifr));
619 StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), name);
620
621 if (ioctl(s, SIOCGIFINDEX, &ifr) < 0)
622 {
623 closesocket(s);
624 return NULL;
625 }
626
627 index = ifr.ifr_ifindex;
628
629 Zero(&addr, sizeof(addr));
630 addr.sll_family = PF_PACKET;
631 addr.sll_protocol = htons(ETH_P_ALL);
632 addr.sll_ifindex = index;
633
634 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
635 {
636 closesocket(s);
637 return NULL;
638 }
639
640 if (local == false)
641 {
642 // Enable promiscious mode
643 Zero(&ifr, sizeof(ifr));
644 StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), name);
645 if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
646 {
647 // Failed
648 closesocket(s);
649 return NULL;
650 }
651
652 ifr.ifr_flags |= IFF_PROMISC;
653
654 if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
655 {
656 // Failed
657 closesocket(s);
658 return NULL;
659 }
660 }
661
662 if (true)
663 {
664 int val = 1;
665 int ss_ret = setsockopt(s, SOL_PACKET, MY_PACKET_AUXDATA, &val, sizeof(val));
666
667 if (ss_ret < 0)
668 {
669 Debug("eth(%s): setsockopt: PACKET_AUXDATA failed.\n", name);
670 }
671 else
672 {
673 Debug("eth(%s): setsockopt: PACKET_AUXDATA ok.\n", name);
674 aux_ok = true;
675 }
676 }
677
678 e = ZeroMalloc(sizeof(ETH));
679 e->Name = CopyStr(name);
680 e->Title = CopyStr(name);
681 e->IfIndex = index;
682 e->Socket = s;
683
684 e->Linux_IsAuxDataSupported = aux_ok;
685
686 c = NewCancel();
687 UnixDeletePipe(c->pipe_read, c->pipe_write);
688 c->pipe_read = c->pipe_write = -1;
689
690 UnixSetSocketNonBlockingMode(s, true);
691
692 c->SpecialFlag = true;
693 c->pipe_read = s;
694
695 e->Cancel = c;
696
697 // Get MTU
698 e->InitialMtu = EthGetMtu(e);
699
700 if (tapmode == false)
701 {
702 if (GetGlobalServerFlag(GSF_LOCALBRIDGE_NO_DISABLE_OFFLOAD) == false)
703 {
704 bool b = false;
705
706 LockList(eth_offload_list);
707 {
708 if (IsInListStr(eth_offload_list, name) == false)
709 {
710 b = true;
711
712 Add(eth_offload_list, CopyStr(name));
713 }
714 }
715 UnlockList(eth_offload_list);
716
717 if (b)
718 {
719 // Disable hardware offloading
720 UnixDisableInterfaceOffload(name);
721 }
722 }
723 }
724
725 return e;
726 }
727 #endif // UNIX_LINUX
728
729 // Get the MTU value
EthGetMtu(ETH * e)730 UINT EthGetMtu(ETH *e)
731 {
732 #if defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
733 UINT ret = 0;
734 #ifdef UNIX_SOLARIS
735 struct lifreq ifr;
736 #else // UNIX_SOLARIS
737 struct ifreq ifr;
738 #endif // UNIX_SOLARIS
739 int s;
740 // Validate arguments
741 if (e == NULL || e->Tap != NULL)
742 {
743 return 0;
744 }
745 if (e->IsRawIpMode)
746 {
747 return 0;
748 }
749
750 if (e->CurrentMtu != 0)
751 {
752 return e->CurrentMtu;
753 }
754
755 #if defined(UNIX_BSD) || defined(UNIX_SOLARIS)
756 s = e->SocketBsdIf;
757 #else // defined(UNIX_BSD) || defined(UNIX_SOLARIS)
758 s = e->Socket;
759 #endif // defined(UNIX_BSD) || defined(UNIX_SOLARIS)
760
761 Zero(&ifr, sizeof(ifr));
762
763 #ifdef UNIX_SOLARIS
764 StrCpy(ifr.lifr_name, sizeof(ifr.lifr_name), e->Name);
765 #else // UNIX_SOLARIS
766 StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), e->Name);
767 #endif // UNIX_SOLARIS
768
769 #ifdef UNIX_SOLARIS
770 if (ioctl(s, SIOCGLIFMTU, &ifr) < 0)
771 {
772 // failed
773 return 0;
774 }
775 #else // UNIX_SOLARIS
776 if (ioctl(s, SIOCGIFMTU, &ifr) < 0)
777 {
778 // failed
779 return 0;
780 }
781 #endif // UNIX_SOLARIS
782
783 #ifdef UNIX_SOLARIS
784 ret = ifr.lifr_mtu + 14;
785 #else // UNIX_SOLARIS
786 ret = ifr.ifr_mtu + 14;
787 #endif // UNIX_SOLARIS
788
789 e->CurrentMtu = ret;
790
791 Debug("%s: GetMtu: %u\n", e->Name, ret);
792
793 return ret;
794 #else // defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
795 return 0;
796 #endif // defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
797 }
798
799 // Set the MTU value
EthSetMtu(ETH * e,UINT mtu)800 bool EthSetMtu(ETH *e, UINT mtu)
801 {
802 #if defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
803 UINT ret = 0;
804 #ifdef UNIX_SOLARIS
805 struct lifreq ifr;
806 #else // UNIX_SOLARIS
807 struct ifreq ifr;
808 #endif // UNIX_SOLARIS
809 int s;
810 // Validate arguments
811 if (e == NULL || e->Tap != NULL || (mtu > 1 && mtu < 1514))
812 {
813 return false;
814 }
815 if (mtu == 0 && e->InitialMtu == 0)
816 {
817 return false;
818 }
819 if (e->IsRawIpMode)
820 {
821 return false;
822 }
823
824 if (mtu == 0)
825 {
826 // Restore initial MTU value when parameter mtu == 0
827 mtu = e->InitialMtu;
828 }
829
830 #if defined(UNIX_BSD) || defined(UNIX_SOLARIS)
831 s = e->SocketBsdIf;
832 #else // defined(UNIX_BSD) || defined(UNIX_SOLARIS)
833 s = e->Socket;
834 #endif // defined(UNIX_BSD) || defined(UNIX_SOLARIS)
835
836 if (e->CurrentMtu == mtu)
837 {
838 // No need to change
839 return true;
840 }
841
842 Zero(&ifr, sizeof(ifr));
843
844 #ifdef UNIX_SOLARIS
845 StrCpy(ifr.lifr_name, sizeof(ifr.lifr_name), e->Name);
846 ifr.lifr_mtu = mtu - 14;
847 #else // UNIX_SOLARIS
848 StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), e->Name);
849 ifr.ifr_mtu = mtu - 14;
850 #endif // UNIX_SOLARIS
851
852 #ifdef UNIX_SOLARIS
853 if (ioctl(s, SIOCSLIFMTU, &ifr) < 0)
854 {
855 // Failed
856 return false;
857 }
858 #else // UNIX_SOLARIS
859 if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
860 {
861 // Failed
862 return false;
863 }
864 #endif // UNIX_SOLARIS
865
866 e->CurrentMtu = mtu;
867
868 Debug("%s: SetMtu: %u\n", e->Name, mtu);
869
870 return true;
871 #else // defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
872 return false;
873 #endif // defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
874 }
875
876 // Is changing MTU supported?
EthIsChangeMtuSupported(ETH * e)877 bool EthIsChangeMtuSupported(ETH *e)
878 {
879 #if defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
880 // Validate arguments
881 if (e == NULL || e->Tap != NULL)
882 {
883 return false;
884 }
885
886 if (e->IsRawIpMode)
887 {
888 return false;
889 }
890
891 return true;
892 #else // defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
893 return false;
894 #endif // defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
895 }
896
897 #ifdef UNIX_SOLARIS
898 // Open Ethernet adapter (Solaris)
OpenEthSolaris(char * name,bool local,bool tapmode,char * tapaddr)899 ETH *OpenEthSolaris(char *name, bool local, bool tapmode, char *tapaddr)
900 {
901 char devname[MAX_SIZE];
902 UINT devid;
903 int fd;
904 ETH *e;
905 CANCEL *c;
906 struct strioctl sioc;
907
908 // Validate arguments
909 if (name == NULL || tapmode != false)
910 {
911 return NULL;
912 }
913
914 // Parse device name
915 if (ParseUnixEthDeviceName(devname, sizeof(devname), &devid, name) == false)
916 {
917 return NULL;
918 }
919
920 // Open the device
921 fd = open(devname, O_RDWR);
922 if (fd == -1)
923 {
924 // Failed
925 return NULL;
926 }
927
928 // Attach to the device
929 if (DlipAttatchRequest(fd, devid) == false)
930 {
931 // Failed
932 close(fd);
933 return NULL;
934 }
935
936 // Verify ACK message
937 if (DlipReceiveAck(fd) == false)
938 {
939 // Failed
940 close(fd);
941 return NULL;
942 }
943
944 // Bind to SAP
945 if (DlipBindRequest(fd) == false)
946 {
947 // Failed
948 close(fd);
949 return NULL;
950 }
951
952 // Verify ACK message
953 if (DlipReceiveAck(fd) == false)
954 {
955 // Failed
956 close(fd);
957 return NULL;
958 }
959
960 // Set to ignore SAP and promiscuous mode
961 if (DlipPromiscuous(fd, DL_PROMISC_SAP) == false)
962 {
963 // Failed
964 close(fd);
965 return NULL;
966 }
967
968 // Verify ACK message
969 if (DlipReceiveAck(fd) == false)
970 {
971 // Failed
972 close(fd);
973 return NULL;
974 }
975
976 // Set to the mode to receive self sending packet
977 if (DlipPromiscuous(fd, DL_PROMISC_PHYS) == false)
978 {
979 // Failed
980 close(fd);
981 return NULL;
982 }
983
984 // Verify ACK message
985 if (DlipReceiveAck(fd) == false)
986 {
987 // Failed
988 close(fd);
989 return NULL;
990 }
991
992 // Set to raw mode
993 sioc.ic_cmd = DLIOCRAW;
994 sioc.ic_timout = -1;
995 sioc.ic_len = 0;
996 sioc.ic_dp = NULL;
997 if (ioctl(fd, I_STR, &sioc) < 0)
998 {
999 // Failed
1000 close(fd);
1001 return NULL;
1002 }
1003
1004 if (ioctl(fd, I_FLUSH, FLUSHR) < 0)
1005 {
1006 // Failed
1007 close(fd);
1008 return NULL;
1009 }
1010
1011 e = ZeroMalloc(sizeof(ETH));
1012 e->Name = CopyStr(name);
1013 e->Title = CopyStr(name);
1014
1015 c = NewCancel();
1016 UnixDeletePipe(c->pipe_read, c->pipe_write);
1017 c->pipe_read = c->pipe_write = -1;
1018
1019 c->SpecialFlag = true;
1020 c->pipe_read = fd;
1021
1022 e->Cancel = c;
1023
1024 e->IfIndex = -1;
1025 e->Socket = fd;
1026
1027 UnixSetSocketNonBlockingMode(fd, true);
1028
1029 // Get control interface
1030 e->SocketBsdIf = socket(AF_INET, SOCK_DGRAM, 0);
1031
1032 // Get MTU value
1033 e->InitialMtu = EthGetMtu(e);
1034
1035 return e;
1036 }
1037
1038 // Set to promiscuous mode
DlipPromiscuous(int fd,UINT level)1039 bool DlipPromiscuous(int fd, UINT level)
1040 {
1041 dl_promiscon_req_t req;
1042 struct strbuf ctl;
1043 int flags;
1044 // Validate arguments
1045 if (fd == -1)
1046 {
1047 return false;
1048 }
1049
1050 Zero(&req, sizeof(req));
1051 req.dl_primitive = DL_PROMISCON_REQ;
1052 req.dl_level = level;
1053
1054 Zero(&ctl, sizeof(ctl));
1055 ctl.maxlen = 0;
1056 ctl.len = sizeof(req);
1057 ctl.buf = (char *)&req;
1058
1059 flags = 0;
1060
1061 if (putmsg(fd, &ctl, NULL, flags) < 0)
1062 {
1063 return false;
1064 }
1065
1066 return true;
1067 }
1068
1069 // Bind to a SAP
DlipBindRequest(int fd)1070 bool DlipBindRequest(int fd)
1071 {
1072 dl_bind_req_t req;
1073 struct strbuf ctl;
1074
1075 if (fd == -1)
1076 {
1077 return false;
1078 }
1079
1080 Zero(&req, sizeof(req));
1081 req.dl_primitive = DL_BIND_REQ;
1082 req.dl_service_mode = DL_CLDLS;
1083 req.dl_sap = 0;
1084
1085 Zero(&ctl, sizeof(ctl));
1086 ctl.maxlen = 0;
1087 ctl.len = sizeof(req);
1088 ctl.buf = (char *)&req;
1089
1090 if (putmsg(fd, &ctl, NULL, 0) < 0)
1091 {
1092 return false;
1093 }
1094 return true;
1095 }
1096
1097 // Attach to the device
DlipAttatchRequest(int fd,UINT devid)1098 bool DlipAttatchRequest(int fd, UINT devid)
1099 {
1100 dl_attach_req_t req;
1101 struct strbuf ctl;
1102 int flags;
1103 // Validate arguments
1104 if (fd == -1)
1105 {
1106 return false;
1107 }
1108
1109 Zero(&req, sizeof(req));
1110 req.dl_primitive = DL_ATTACH_REQ;
1111 req.dl_ppa = devid;
1112
1113 Zero(&ctl, sizeof(ctl));
1114 ctl.maxlen = 0;
1115 ctl.len = sizeof(req);
1116 ctl.buf = (char *)&req;
1117
1118 flags = 0;
1119
1120 if (putmsg(fd, &ctl, NULL, flags) < 0)
1121 {
1122 return false;
1123 }
1124
1125 return true;
1126 }
1127
1128 // Verify the ACK message
DlipReceiveAck(int fd)1129 bool DlipReceiveAck(int fd)
1130 {
1131 union DL_primitives *dlp;
1132 struct strbuf ctl;
1133 int flags = 0;
1134 char *buf;
1135 // Validate arguments
1136 if (fd == -1)
1137 {
1138 return false;
1139 }
1140
1141 buf = MallocFast(SOLARIS_MAXDLBUF);
1142
1143 Zero(&ctl, sizeof(ctl));
1144 ctl.maxlen = SOLARIS_MAXDLBUF;
1145 ctl.len = 0;
1146 ctl.buf = buf;
1147
1148 if (getmsg(fd, &ctl, NULL, &flags) < 0)
1149 {
1150 return false;
1151 }
1152
1153 dlp = (union DL_primitives *)ctl.buf;
1154 if (dlp->dl_primitive != (UINT)DL_OK_ACK && dlp->dl_primitive != (UINT)DL_BIND_ACK)
1155 {
1156 Free(buf);
1157 return false;
1158 }
1159
1160 Free(buf);
1161
1162 return true;
1163 }
1164
1165 #endif // UNIX_SOLARIS
1166
1167 // Separate UNIX device name string into device name and id number
ParseUnixEthDeviceName(char * dst_devname,UINT dst_devname_size,UINT * dst_devid,char * src_name)1168 bool ParseUnixEthDeviceName(char *dst_devname, UINT dst_devname_size, UINT *dst_devid, char *src_name)
1169 {
1170 UINT len, i, j;
1171
1172 // Validate arguments
1173 if (dst_devname == NULL || dst_devid == NULL || src_name == NULL)
1174 {
1175 return false;
1176 }
1177
1178 len = strlen(src_name);
1179 // Check string length
1180 if(len == 0)
1181 {
1182 return false;
1183 }
1184
1185 for (i = len-1; i+1 != 0; i--)
1186 {
1187 // Find last non-numeric character
1188 if (src_name[i] < '0' || '9' < src_name[i])
1189 {
1190 // last character must be a number
1191 if(src_name[i+1]==0)
1192 {
1193 return false;
1194 }
1195 *dst_devid = ToInt(src_name + i + 1);
1196 StrCpy(dst_devname, dst_devname_size, "/dev/");
1197 for (j = 0; j<i+1 && j<dst_devname_size-6; j++)
1198 {
1199 dst_devname[j+5] = src_name[j];
1200 }
1201 dst_devname[j+5]=0;
1202 return true;
1203 }
1204 }
1205 // All characters in the string was numeric: error
1206 return false;
1207 }
1208
1209 #if defined(BRIDGE_BPF) || defined(BRIDGE_PCAP)
1210 // Initialize captured packet data structure
NewCaptureBlock(UCHAR * data,UINT size)1211 struct CAPTUREBLOCK *NewCaptureBlock(UCHAR *data, UINT size){
1212 struct CAPTUREBLOCK *block = Malloc(sizeof(struct CAPTUREBLOCK));
1213 block->Buf = data;
1214 block->Size = size;
1215 return block;
1216 }
1217
1218 // Free captured packet data structure
FreeCaptureBlock(struct CAPTUREBLOCK * block)1219 void FreeCaptureBlock(struct CAPTUREBLOCK *block){
1220 Free(block);
1221 }
1222 #endif // BRIDGE_BPF || BRIDGE_PCAP
1223
1224 #ifdef BRIDGE_PCAP
1225 // Callback function to receive arriving packet (Pcap)
PcapHandler(u_char * user,const struct pcap_pkthdr * h,const u_char * bytes)1226 void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
1227 {
1228 ETH *e = (ETH*) user;
1229 struct CAPTUREBLOCK *block;
1230 UCHAR *data;
1231
1232 data = Malloc(h->caplen);
1233 Copy(data, bytes, h->caplen);
1234 block = NewCaptureBlock(data, h->caplen);
1235 LockQueue(e->Queue);
1236 // Discard arriving packet when queue filled
1237 if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
1238 InsertQueue(e->Queue, block);
1239 e->QueueSize += h->caplen;
1240 }
1241 UnlockQueue(e->Queue);
1242 Cancel(e->Cancel);
1243 return;
1244 }
1245
1246 // Relay thread for captured packet (Pcap)
PcapThread(THREAD * thread,void * param)1247 void PcapThread(THREAD *thread, void *param)
1248 {
1249 ETH *e = (ETH*)param;
1250 pcap_t *p = e->Pcap;
1251 int ret;
1252
1253 // Notify initialize completed
1254 NoticeThreadInit(thread);
1255
1256 // Return -1:Error -2:Terminated externally
1257 ret = pcap_loop(p, -1, PcapHandler, (u_char*) e);
1258 if(ret == -1){
1259 e->Socket = INVALID_SOCKET;
1260 pcap_perror(p, "capture");
1261 }
1262 return;
1263 }
1264
1265
1266 // Open Ethernet adapter (Pcap)
OpenEthPcap(char * name,bool local,bool tapmode,char * tapaddr)1267 ETH *OpenEthPcap(char *name, bool local, bool tapmode, char *tapaddr)
1268 {
1269 char errbuf[PCAP_ERRBUF_SIZE];
1270 ETH *e;
1271 pcap_t *p;
1272 CANCEL *c;
1273
1274 // Validate arguments
1275 if (name == NULL || tapmode != false)
1276 {
1277 return NULL;
1278 }
1279
1280 // Initialize error message buffer
1281 errbuf[0] = 0;
1282
1283 // Open capturing device
1284 p = pcap_open_live(name, 65535, (local == false), 1, errbuf);
1285 if(p==NULL)
1286 {
1287 return NULL;
1288 }
1289
1290 // Set to non-block mode
1291 // (In old BSD OSs, 'select(2)' don't block normally for BPF device. To prevent busy loop)
1292 /*
1293 if(pcap_setnonblock(p, true, errbuf) == -1)
1294 {
1295 Debug("pcap_setnonblock:%s\n",errbuf);
1296 pcap_close(p);
1297 return NULL;
1298 }
1299 */
1300
1301 e = ZeroMalloc(sizeof(ETH));
1302 e->Name = CopyStr(name);
1303 e->Title = CopyStr(name);
1304 e->Queue = NewQueue();
1305 e->QueueSize = 0;
1306 e->Cancel = NewCancel();
1307 e->IfIndex = -1;
1308 e->Socket = pcap_get_selectable_fd(p);
1309 e->Pcap = p;
1310
1311 e->CaptureThread = NewThread(PcapThread, e);
1312 WaitThreadInit(e->CaptureThread);
1313
1314 return e;
1315 }
1316 #endif // BRIDGE_PCAP
1317
1318 #ifdef BRIDGE_BPF
1319 #ifdef BRIDGE_BPF_THREAD
1320 // Relay thread for captured packet (BPF)
BpfThread(THREAD * thread,void * param)1321 void BpfThread(THREAD *thread, void *param)
1322 {
1323 ETH *e = (ETH*)param;
1324 int fd = e->Socket;
1325 int len;
1326 int rest; // Rest size in buffer
1327 UCHAR *next; // Head of next packet in buffer
1328 struct CAPTUREBLOCK *block; // Data to enqueue
1329 UCHAR *data;
1330 struct bpf_hdr *hdr;
1331
1332 // Allocate the buffer
1333 UCHAR *buf = Malloc(e->BufSize);
1334
1335 // Notify initialize completed
1336 NoticeThreadInit(thread);
1337
1338 while(1){
1339 // Determining to exit loop
1340 if(e->Socket == INVALID_SOCKET){
1341 break;
1342 }
1343
1344 rest = read(fd, buf, e->BufSize);
1345 if(rest < 0 && errno != EAGAIN){
1346 // Error
1347 close(fd);
1348 e->Socket = INVALID_SOCKET;
1349 Free(buf);
1350 Cancel(e->Cancel);
1351 return;
1352 }
1353 next = buf;
1354 LockQueue(e->Queue);
1355 while(rest>0){
1356 // Cut out a packet
1357 hdr = (struct bpf_hdr*)next;
1358
1359 // Discard arriving packet when queue filled
1360 if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
1361 data = Malloc(hdr->bh_caplen);
1362 Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen);
1363 block = NewCaptureBlock(data, hdr->bh_caplen);
1364 InsertQueue(e->Queue, block);
1365 e->QueueSize += hdr->bh_caplen;
1366 }
1367
1368 // Find the head of next packet
1369 rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
1370 next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
1371 }
1372 UnlockQueue(e->Queue);
1373 Cancel(e->Cancel);
1374 }
1375 Free(buf);
1376 Cancel(e->Cancel);
1377 return;
1378 }
1379 #endif // BRIDGE_BPF_THREAD
1380
1381 // Open Ethernet adapter (BPF)
OpenEthBpf(char * name,bool local,bool tapmode,char * tapaddr)1382 ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
1383 {
1384 ETH *e;
1385 CANCEL *c;
1386 char devname[MAX_SIZE];
1387 int n = 0;
1388 int fd;
1389 int ret;
1390 UINT bufsize;
1391 struct ifreq ifr;
1392 struct timeval to;
1393
1394 // Find unused bpf device and open it
1395 do{
1396 Format(devname, sizeof(devname), "/dev/bpf%d", n++);
1397 fd = open (devname, O_RDWR);
1398 if(fd<0){
1399 perror("open");
1400 }
1401 }while(fd < 0 && errno == EBUSY);
1402
1403 // No free bpf device was found
1404 if(fd < 0){
1405 Debug("BPF: No minor number are free.\n");
1406 return NULL;
1407 }
1408
1409 // Enlarge buffer size
1410 n = 524288; // Somehow(In libpcap, this size is 32768)
1411 while(true){
1412 // Specify buffer size
1413 ioctl(fd, BIOCSBLEN, &n);
1414
1415 // Bind to the network device
1416 StrCpy(ifr.ifr_name, IFNAMSIZ, name);
1417 ret = ioctl(fd, BIOCSETIF, &ifr);
1418 if(ret < 0){
1419 if(ret == ENOBUFS && n>1500){
1420 // Inappropriate buffer size
1421 // Retry with half buffer size
1422 // If buffer size is under 1500 bytes, something goes wrong
1423 n /= 2;
1424 continue;
1425 }
1426 Debug("bpf: binding network failed.\n");
1427 close(fd);
1428 return NULL;
1429 }else{
1430 break;
1431 }
1432 }
1433 bufsize = n;
1434
1435 // Set to promiscuous mode
1436 if(local == false){
1437 if (ioctl(fd, BIOCPROMISC, NULL) < 0){
1438 printf("bpf: promisc mode failed.\n");
1439 close(fd);
1440 return NULL;
1441 }
1442 }
1443
1444
1445 // Set to immediate mode (Return immediately when packet arrives)
1446 n = 1;
1447 if (ioctl(fd, BIOCIMMEDIATE, &n) < 0){
1448 Debug("BPF: non-block mode failed.\n");
1449 close(fd);
1450 return NULL;
1451 }
1452
1453 // Set receiving self sending packet
1454 n = 1;
1455 if (ioctl(fd, BIOCGSEESENT, &n) < 0){
1456 Debug("BPF: see sent mode failed.\n");
1457 close(fd);
1458 return NULL;
1459 }
1460
1461 // Header complete mode (Generate whole header of sending packet)
1462 n = 1;
1463 if (ioctl(fd, BIOCSHDRCMPLT, &n) < 0){
1464 Debug("BPF: Header complete mode failed.\n");
1465 close(fd);
1466 return NULL;
1467 }
1468
1469 // Set timeout delay to 1 second
1470 to.tv_sec = 1;
1471 to.tv_usec = 0;
1472 if (ioctl(fd, BIOCSRTIMEOUT, &to) < 0){
1473 Debug("BPF: Read timeout setting failed.\n");
1474 close(fd);
1475 return NULL;
1476 }
1477
1478 e = ZeroMalloc(sizeof(ETH));
1479 e->Name = CopyStr(name);
1480 e->Title = CopyStr(name);
1481 e->IfIndex = -1;
1482 e->Socket = fd;
1483 e->BufSize = bufsize;
1484
1485 #ifdef BRIDGE_BPF_THREAD
1486 e->Queue = NewQueue();
1487 e->QueueSize = 0;
1488 e->Cancel = NewCancel();
1489
1490 // Start capture thread
1491 e->CaptureThread = NewThread(BpfThread, e);
1492 WaitThreadInit(e->CaptureThread);
1493
1494 #else // BRIDGE_BPF_THREAD
1495 c = NewCancel();
1496 UnixDeletePipe(c->pipe_read, c->pipe_write);
1497 c->pipe_read = c->pipe_write = -1;
1498 c->SpecialFlag = true;
1499 c->pipe_read = fd;
1500 e->Cancel = c;
1501 e->Buffer = Malloc(bufsize);
1502 e->Next = e->Buffer;
1503 e->Rest = 0;
1504
1505 // Set to non-blocking mode
1506 UnixSetSocketNonBlockingMode(fd, true);
1507 #endif // BRIDGE_BPF_THREAD
1508
1509 // Open interface control socket for FreeBSD
1510 e->SocketBsdIf = socket(AF_LOCAL, SOCK_DGRAM, 0);
1511
1512 // Get MTU value
1513 e->InitialMtu = EthGetMtu(e);
1514
1515 return e;
1516 }
1517 #endif // BRIDGE_BPF
1518
1519 // Open Ethernet adapter
OpenEth(char * name,bool local,bool tapmode,char * tapaddr)1520 ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr)
1521 {
1522 ETH *ret = NULL;
1523
1524 #if defined(UNIX_LINUX)
1525 ret = OpenEthLinux(name, local, tapmode, tapaddr);
1526 #elif defined(UNIX_SOLARIS)
1527 ret = OpenEthSolaris(name, local, tapmode, tapaddr);
1528 #elif defined(BRIDGE_PCAP)
1529 ret = OpenEthPcap(name, local, tapmode, tapaddr);
1530 #elif defined(BRIDGE_BPF)
1531 ret = OpenEthBpf(name, local, tapmode, tapaddr);
1532 #endif
1533
1534 return ret;
1535 }
1536
1537 typedef struct UNIXTHREAD
1538 {
1539 pthread_t thread;
1540 bool finished;
1541 } UNIXTHREAD;
1542
1543 // Close Ethernet adapter
CloseEth(ETH * e)1544 void CloseEth(ETH *e)
1545 {
1546 // Validate arguments
1547 if (e == NULL)
1548 {
1549 return;
1550 }
1551
1552 if (e->IsRawIpMode)
1553 {
1554 CloseEthLinuxIpRaw(e);
1555
1556 return;
1557 }
1558
1559 if (e->Tap != NULL)
1560 {
1561 #ifndef NO_VLAN
1562 FreeTap(e->Tap);
1563 #endif // NO_VLAN
1564 }
1565
1566 #ifdef BRIDGE_PCAP
1567 {
1568 struct CAPTUREBLOCK *block;
1569 pcap_breakloop(e->Pcap);
1570 WaitThread(e->CaptureThread, INFINITE);
1571 ReleaseThread(e->CaptureThread);
1572 pcap_close(e->Pcap);
1573 while (block = GetNext(e->Queue)){
1574 Free(block->Buf);
1575 FreeCaptureBlock(block);
1576 }
1577 ReleaseQueue(e->Queue);
1578 }
1579 #endif // BRIDGE_PCAP
1580
1581 #ifdef BRIDGE_BPF
1582 #ifdef BRIDGE_BPF_THREAD
1583 {
1584 struct CAPTUREBLOCK *block;
1585 int fd = e->Socket;
1586 e->Socket = INVALID_SOCKET;
1587 WaitThread(e->CaptureThread, INFINITE);
1588 ReleaseThread(e->CaptureThread);
1589 e->Socket = fd; // restore to close after
1590 while (block = GetNext(e->Queue)){
1591 Free(block->Buf);
1592 FreeCaptureBlock(block);
1593 }
1594 ReleaseQueue(e->Queue);
1595 }
1596 #else // BRIDGE_BPF_THREAD
1597 Free(e->Buffer);
1598 #endif // BRIDGE_BPF_THREAD
1599 #endif // BRIDGE_BPF
1600
1601 ReleaseCancel(e->Cancel);
1602 Free(e->Name);
1603 Free(e->Title);
1604
1605 // Restore MTU value
1606 EthSetMtu(e, 0);
1607
1608 if (e->Socket != INVALID_SOCKET)
1609 {
1610 #if defined(BRIDGE_BPF) || defined(BRIDGE_PCAP) || defined(UNIX_SOLARIS)
1611 close(e->Socket);
1612 #else // BRIDGE_PCAP
1613 closesocket(e->Socket);
1614 #endif // BRIDGE_PCAP
1615 #if defined(BRIDGE_BPF) || defined(UNIX_SOLARIS)
1616 if (e->SocketBsdIf != INVALID_SOCKET)
1617 {
1618 close(e->SocketBsdIf);
1619 }
1620 #endif // BRIDGE_BPF || UNIX_SOLARIS
1621 }
1622
1623 Free(e);
1624 }
1625
1626 // Get cancel object
EthGetCancel(ETH * e)1627 CANCEL *EthGetCancel(ETH *e)
1628 {
1629 CANCEL *c;
1630 // Validate arguments
1631 if (e == NULL)
1632 {
1633 return NULL;
1634 }
1635
1636 c = e->Cancel;
1637 AddRef(c->ref);
1638
1639 return c;
1640 }
1641
1642 // Read a packet
EthGetPacket(ETH * e,void ** data)1643 UINT EthGetPacket(ETH *e, void **data)
1644 {
1645 UINT ret = 0;
1646
1647 #if defined(UNIX_LINUX)
1648 ret = EthGetPacketLinux(e, data);
1649 #elif defined(UNIX_SOLARIS)
1650 ret = EthGetPacketSolaris(e, data);
1651 #elif defined(BRIDGE_PCAP)
1652 ret = EthGetPacketPcap(e, data);
1653 #elif defined(BRIDGE_BPF)
1654 ret = EthGetPacketBpf(e, data);
1655 #endif
1656
1657 return ret;
1658 }
1659
1660 #ifdef UNIX_LINUX
1661
EthGetPacketLinux(ETH * e,void ** data)1662 UINT EthGetPacketLinux(ETH *e, void **data)
1663 {
1664 int s, ret;
1665 UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
1666 struct iovec msg_iov;
1667 struct msghdr msg_header;
1668 struct cmsghdr *cmsg;
1669 union
1670 {
1671 struct cmsghdr cmsg;
1672 char buf[CMSG_SPACE(sizeof(struct my_tpacket_auxdata))];
1673 } cmsg_buf;
1674 // Validate arguments
1675 if (e == NULL || data == NULL)
1676 {
1677 return INFINITE;
1678 }
1679
1680 if (e->IsRawIpMode)
1681 {
1682 return EthGetPacketLinuxIpRaw(e, data);
1683 }
1684
1685 if (e->Tap != NULL)
1686 {
1687 #ifndef NO_VLAN
1688 // tap mode
1689 void *buf;
1690 UINT size;
1691
1692 if (VLanGetNextPacket(e->Tap, &buf, &size) == false)
1693 {
1694 return INFINITE;
1695 }
1696
1697 *data = buf;
1698 return size;
1699 #else // NO_VLAN
1700 return INFINITE;
1701 #endif
1702 }
1703
1704 s = e->Socket;
1705
1706 if (s == INVALID_SOCKET)
1707 {
1708 return INFINITE;
1709 }
1710
1711 // Read
1712 msg_iov.iov_base = tmp;
1713 msg_iov.iov_len = sizeof(tmp);
1714
1715 msg_header.msg_name = NULL;
1716 msg_header.msg_namelen = 0;
1717 msg_header.msg_iov = &msg_iov;
1718 msg_header.msg_iovlen = 1;
1719 if (e->Linux_IsAuxDataSupported)
1720 {
1721 memset(&cmsg_buf, 0, sizeof(cmsg_buf));
1722
1723 msg_header.msg_control = &cmsg_buf;
1724 msg_header.msg_controllen = sizeof(cmsg_buf);
1725 }
1726 else
1727 {
1728 msg_header.msg_control = NULL;
1729 msg_header.msg_controllen = 0;
1730 }
1731 msg_header.msg_flags = 0;
1732
1733 ret = recvmsg(s, &msg_header, 0);
1734 if (ret == 0 || (ret == -1 && errno == EAGAIN))
1735 {
1736 // No packet
1737 *data = NULL;
1738 return 0;
1739 }
1740 else if (ret == -1 || ret > sizeof(tmp))
1741 {
1742 // Error
1743 *data = NULL;
1744 e->Socket = INVALID_SOCKET;
1745 return INFINITE;
1746 }
1747 else
1748 {
1749 bool flag = false;
1750 USHORT api_vlan_id = 0;
1751 USHORT api_vlan_tpid = 0;
1752
1753 if (e->Linux_IsAuxDataSupported)
1754 {
1755 for (cmsg = CMSG_FIRSTHDR(&msg_header); cmsg; cmsg = CMSG_NXTHDR(&msg_header, cmsg))
1756 {
1757 struct my_tpacket_auxdata *aux;
1758 UINT len;
1759 USHORT vlan_tpid = 0x8100;
1760 USHORT vlan_id = 0;
1761
1762 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct my_tpacket_auxdata)) ||
1763 cmsg->cmsg_level != SOL_PACKET ||
1764 cmsg->cmsg_type != MY_PACKET_AUXDATA)
1765 {
1766 continue;
1767 }
1768
1769 aux = (struct my_tpacket_auxdata *)CMSG_DATA(cmsg);
1770
1771 if (aux != NULL)
1772 {
1773 if (aux->tp_vlan_tci != 0)
1774 {
1775 vlan_id = aux->tp_vlan_tci;
1776 }
1777 }
1778
1779 if (vlan_id != 0)
1780 {
1781 api_vlan_id = vlan_id;
1782 api_vlan_tpid = vlan_tpid;
1783 break;
1784 }
1785 }
1786
1787 if (api_vlan_id != 0 && api_vlan_tpid != 0)
1788 {
1789 // VLAN ID has been received with PACKET_AUXDATA.
1790 // Insert the tag.
1791 USHORT vlan_id_ne = Endian16(api_vlan_id);
1792 USHORT vlan_tpid_ne = Endian16(api_vlan_tpid);
1793
1794 if (ret >= 14)
1795 {
1796 if (*((USHORT *)(tmp + 12)) != vlan_tpid_ne)
1797 {
1798 *data = MallocFast(ret + 4);
1799 Copy(*data, tmp, 12);
1800 Copy(((UCHAR *)*data) + 12, &vlan_tpid_ne, 2);
1801 Copy(((UCHAR *)*data) + 14, &vlan_id_ne, 2);
1802 Copy(((UCHAR *)*data) + 16, tmp + 12, ret - 12);
1803
1804 flag = true;
1805
1806 ret += 4;
1807 }
1808 }
1809 }
1810 }
1811
1812 // Success to read a packet (No VLAN)
1813 if (flag == false)
1814 {
1815 *data = MallocFast(ret);
1816 Copy(*data, tmp, ret);
1817 }
1818 return ret;
1819 }
1820
1821 return 0;
1822 }
1823 #endif // UNIX_LINUX
1824
1825 #ifdef UNIX_SOLARIS
EthGetPacketSolaris(ETH * e,void ** data)1826 UINT EthGetPacketSolaris(ETH *e, void **data)
1827 {
1828 UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
1829 struct strbuf buf;
1830 int s;
1831 int flags = 0;
1832 int ret;
1833 // Validate arguments
1834 if (e == NULL || data == NULL)
1835 {
1836 return INFINITE;
1837 }
1838
1839 s = e->Socket;
1840 if (s == INVALID_SOCKET)
1841 {
1842 return INFINITE;
1843 }
1844
1845 Zero(&buf, sizeof(buf));
1846 buf.buf = tmp;
1847 buf.maxlen = sizeof(tmp);
1848
1849 ret = getmsg(s, NULL, &buf, &flags);
1850
1851 if (ret < 0 || ret > sizeof(tmp))
1852 {
1853 if (errno == EAGAIN)
1854 {
1855 // No packet
1856 *data = NULL;
1857 return 0;
1858 }
1859 // Error
1860 *data = NULL;
1861 return INFINITE;
1862 }
1863
1864 ret = buf.len;
1865
1866 *data = MallocFast(ret);
1867 Copy(*data, tmp, ret);
1868 return ret;
1869 }
1870 #endif // UNIX_SOLARIS
1871
1872 #ifdef BRIDGE_PCAP
EthGetPacketPcap(ETH * e,void ** data)1873 UINT EthGetPacketPcap(ETH *e, void **data)
1874 {
1875 struct CAPTUREBLOCK *block;
1876 UINT size;
1877
1878 LockQueue(e->Queue);
1879 block = GetNext(e->Queue);
1880 if(block != NULL){
1881 e->QueueSize -= block->Size;
1882 }
1883 UnlockQueue(e->Queue);
1884
1885 if(block == NULL){
1886 *data = NULL;
1887 if(e->Socket == INVALID_SOCKET){
1888 return INFINITE;
1889 }
1890 return 0;
1891 }
1892
1893 *data = block->Buf;
1894 size = block->Size;
1895 FreeCaptureBlock(block);
1896
1897 return size;
1898 }
1899 #endif // BRIDGE_PCAP
1900
1901 #ifdef BRIDGE_BPF
1902 #ifdef BRIDGE_BPF_THREAD
EthGetPacketBpf(ETH * e,void ** data)1903 UINT EthGetPacketBpf(ETH *e, void **data)
1904 {
1905 struct CAPTUREBLOCK *block;
1906 UINT size;
1907
1908 LockQueue(e->Queue);
1909 block = GetNext(e->Queue);
1910 if(block != NULL){
1911 e->QueueSize -= block->Size;
1912 }
1913 UnlockQueue(e->Queue);
1914
1915 if(block == NULL){
1916 *data = NULL;
1917 if(e->Socket == INVALID_SOCKET){
1918 return INFINITE;
1919 }
1920 return 0;
1921 }
1922
1923 *data = block->Buf;
1924 size = block->Size;
1925 FreeCaptureBlock(block);
1926
1927 return size;
1928 }
1929 #else // BRIDGE_BPF_THREAD
EthGetPacketBpf(ETH * e,void ** data)1930 UINT EthGetPacketBpf(ETH *e, void **data)
1931 {
1932 struct bpf_hdr *hdr;
1933
1934 if(e->Rest<=0){
1935 e->Rest = read(e->Socket, e->Buffer, e->BufSize);
1936 if(e->Rest < 0){
1937 *data = NULL;
1938 if(errno != EAGAIN){
1939 // Error
1940 return INFINITE;
1941 }
1942 // No packet
1943 return 0;
1944 }
1945 e->Next = e->Buffer;
1946 }
1947 // Cut out a packet
1948 hdr = (struct bpf_hdr*)e->Next;
1949 *data = Malloc(hdr->bh_caplen);
1950 Copy(*data, e->Next+(hdr->bh_hdrlen), hdr->bh_caplen);
1951
1952 // Find the head of next packet
1953 e->Rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
1954 e->Next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
1955
1956 return hdr->bh_caplen;
1957 }
1958 #endif // BRIDGE_BPF_THREAD
1959 #endif // BRIDGE_BPF
1960
1961
1962 // Send multiple packets
EthPutPackets(ETH * e,UINT num,void ** datas,UINT * sizes)1963 void EthPutPackets(ETH *e, UINT num, void **datas, UINT *sizes)
1964 {
1965 UINT i;
1966 // Validate arguments
1967 if (e == NULL || num == 0 || datas == NULL || sizes == NULL)
1968 {
1969 return;
1970 }
1971
1972 for (i = 0;i < num;i++)
1973 {
1974 EthPutPacket(e, datas[i], sizes[i]);
1975 }
1976 }
1977
1978 // Send a packet
EthPutPacket(ETH * e,void * data,UINT size)1979 void EthPutPacket(ETH *e, void *data, UINT size)
1980 {
1981 int s, ret;
1982 // Validate arguments
1983 if (e == NULL || data == NULL)
1984 {
1985 return;
1986 }
1987 if (e->IsRawIpMode)
1988 {
1989 EthPutPacketLinuxIpRaw(e, data, size);
1990 return;
1991 }
1992 if (size < 14 || size > MAX_PACKET_SIZE)
1993 {
1994 Free(data);
1995 return;
1996 }
1997
1998 if (e->Tap != NULL)
1999 {
2000 #ifndef NO_VLAN
2001 // tap mode
2002 VLanPutPacket(e->Tap, data, size);
2003 #endif // NO_VLAN
2004 return;
2005 }
2006
2007 s = e->Socket;
2008
2009 if (s == INVALID_SOCKET)
2010 {
2011 Free(data);
2012 return;
2013 }
2014
2015 // Send to device
2016 #ifdef BRIDGE_PCAP
2017 ret = pcap_inject(e->Pcap, data, size);
2018 if( ret == -1 ){
2019 #ifdef _DEBUG
2020 pcap_perror(e->Pcap, "inject");
2021 #endif // _DEBUG
2022 Debug("EthPutPacket: ret:%d size:%d\n", ret, size);
2023 }
2024 #else // BRIDGE_PCAP
2025 #ifndef UNIX_LINUX
2026 ret = write(s, data, size);
2027 if (ret<0)
2028 {
2029 Debug("EthPutPacket: ret:%d errno:%d size:%d\n", ret, errno, size);
2030 }
2031 #else // UNIX_LINUX
2032 {
2033 struct iovec msg_iov;
2034 struct msghdr msg_header;
2035
2036 msg_iov.iov_base = data;
2037 msg_iov.iov_len = size;
2038
2039 msg_header.msg_name = NULL;
2040 msg_header.msg_namelen = 0;
2041 msg_header.msg_iov = &msg_iov;
2042 msg_header.msg_iovlen = 1;
2043 msg_header.msg_control = NULL;
2044 msg_header.msg_controllen = 0;
2045 msg_header.msg_flags = 0;
2046
2047 ret = sendmsg(s, &msg_header, 0);
2048
2049 if (ret<0)
2050 {
2051 Debug("EthPutPacket: ret:%d errno:%d size:%d\n", ret, errno, size);
2052 }
2053 }
2054 #endif // UNIX_LINUX
2055 #endif //BRIDGE_PCAP
2056
2057 Free(data);
2058 }
2059
2060
2061
2062
2063 // Open ETH by using IP raw packets
OpenEthLinuxIpRaw()2064 ETH *OpenEthLinuxIpRaw()
2065 {
2066 ETH *e;
2067
2068 if (IsRawIpBridgeSupported() == false)
2069 {
2070 return NULL;
2071 }
2072
2073 e = ZeroMalloc(sizeof(ETH));
2074
2075 e->IsRawIpMode = true;
2076
2077 e->RawTcp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_TCP), NULL);
2078 e->RawUdp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_UDP), NULL);
2079 e->RawIcmp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_ICMP), NULL);
2080
2081 if (e->RawTcp == NULL || e->RawUdp == NULL || e->RawIcmp == NULL)
2082 {
2083 ReleaseSock(e->RawTcp);
2084 ReleaseSock(e->RawUdp);
2085 ReleaseSock(e->RawIcmp);
2086
2087 Free(e);
2088 return NULL;
2089 }
2090
2091 ClearSockDfBit(e->RawTcp);
2092 ClearSockDfBit(e->RawUdp);
2093 ClearSockDfBit(e->RawIcmp);
2094
2095 SetRawSockHeaderIncludeOption(e->RawTcp, true);
2096 SetRawSockHeaderIncludeOption(e->RawUdp, true);
2097 SetRawSockHeaderIncludeOption(e->RawIcmp, true);
2098
2099 e->Name = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
2100 e->Title = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
2101 e->Cancel = NewCancel();
2102
2103 UnixDeletePipe(e->Cancel->pipe_read, e->Cancel->pipe_write);
2104 e->Cancel->pipe_read = e->Cancel->pipe_write = -1;
2105
2106 UnixSetSocketNonBlockingMode(e->RawTcp->socket, true);
2107 UnixSetSocketNonBlockingMode(e->RawUdp->socket, true);
2108 UnixSetSocketNonBlockingMode(e->RawIcmp->socket, true);
2109
2110 e->Cancel->SpecialFlag = true;
2111 e->Cancel->pipe_read = e->RawTcp->socket;
2112 e->Cancel->pipe_special_read2 = e->RawUdp->socket;
2113 e->Cancel->pipe_special_read3 = e->RawIcmp->socket;
2114
2115 e->RawIpMyMacAddr[2] = 0x01;
2116 e->RawIpMyMacAddr[5] = 0x01;
2117
2118 SetIP(&e->MyIP, 10, 171, 7, 253);
2119 SetIP(&e->YourIP, 10, 171, 7, 254);
2120
2121 e->RawIpSendQueue = NewQueueFast();
2122
2123 e->RawIP_TmpBufferSize = 67000;
2124 e->RawIP_TmpBuffer = Malloc(e->RawIP_TmpBufferSize);
2125
2126 return e;
2127 }
2128
2129 // Close ETH by using IP raw packets
CloseEthLinuxIpRaw(ETH * e)2130 void CloseEthLinuxIpRaw(ETH *e)
2131 {
2132 if (e == NULL)
2133 {
2134 return;
2135 }
2136
2137 while (true)
2138 {
2139 BUF *buf = GetNext(e->RawIpSendQueue);
2140 if (buf == NULL)
2141 {
2142 break;
2143 }
2144
2145 FreeBuf(buf);
2146 }
2147 ReleaseQueue(e->RawIpSendQueue);
2148
2149 Free(e->Name);
2150 Free(e->Title);
2151
2152 ReleaseSock(e->RawTcp);
2153 ReleaseSock(e->RawUdp);
2154 ReleaseSock(e->RawIcmp);
2155
2156 ReleaseCancel(e->Cancel);
2157
2158 Free(e->RawIP_TmpBuffer);
2159
2160 Free(e);
2161 }
2162
2163 // Receive an IP raw packet
EthGetPacketLinuxIpRaw(ETH * e,void ** data)2164 UINT EthGetPacketLinuxIpRaw(ETH *e, void **data)
2165 {
2166 UINT r;
2167 BUF *b;
2168 // Validate arguments
2169 if (e == NULL || data == NULL)
2170 {
2171 return INFINITE;
2172 }
2173 if (e->RawIp_HasError)
2174 {
2175 return INFINITE;
2176 }
2177
2178 b = GetNext(e->RawIpSendQueue);
2179 if (b != NULL)
2180 {
2181 UINT size;
2182
2183 *data = b->Buf;
2184 size = b->Size;
2185
2186 Free(b);
2187
2188 return size;
2189 }
2190
2191 r = EthGetPacketLinuxIpRawForSock(e, data, e->RawTcp, IP_PROTO_TCP);
2192 if (r == 0)
2193 {
2194 r = EthGetPacketLinuxIpRawForSock(e, data, e->RawUdp, IP_PROTO_UDP);
2195 if (r == 0)
2196 {
2197 r = EthGetPacketLinuxIpRawForSock(e, data, e->RawIcmp, IP_PROTO_ICMPV4);
2198 }
2199 }
2200
2201 if (r == INFINITE)
2202 {
2203 e->RawIp_HasError = true;
2204 }
2205
2206 return r;
2207 }
2208
2209 // Receive an IP raw packet for the specified socket
EthGetPacketLinuxIpRawForSock(ETH * e,void ** data,SOCK * s,UINT proto)2210 UINT EthGetPacketLinuxIpRawForSock(ETH *e, void **data, SOCK *s, UINT proto)
2211 {
2212 UCHAR *tmp;
2213 UINT r;
2214 IP src_addr;
2215 UINT src_port;
2216 UINT ret = INFINITE;
2217 UCHAR *retbuf;
2218 PKT *p;
2219 bool ok = false;
2220 // Validate arguments
2221 if (e == NULL || data == NULL)
2222 {
2223 return INFINITE;
2224 }
2225
2226 tmp = e->RawIP_TmpBuffer;
2227
2228 LABEL_RETRY:
2229 *data = NULL;
2230
2231 r = RecvFrom(s, &src_addr, &src_port, tmp, e->RawIP_TmpBufferSize);
2232 if (r == SOCK_LATER)
2233 {
2234 return 0;
2235 }
2236
2237 if (r == 0)
2238 {
2239 if (s->IgnoreRecvErr)
2240 {
2241 return 0;
2242 }
2243 else
2244 {
2245 return INFINITE;
2246 }
2247 }
2248
2249 ret = 14 + r;
2250 retbuf = Malloc(ret);
2251 *data = retbuf;
2252
2253 Copy(retbuf, e->RawIpYourMacAddr, 6);
2254 Copy(retbuf + 6, e->RawIpMyMacAddr, 6);
2255 retbuf[12] = 0x08;
2256 retbuf[13] = 0x00;
2257 Copy(retbuf + 14, tmp, r);
2258
2259 // Mangle packet
2260 p = ParsePacket(retbuf, ret);
2261 if (p != NULL)
2262 {
2263 if (p->TypeL3 == L3_IPV4)
2264 {
2265 IPV4_HEADER *ip;
2266 IP original_dest_ip;
2267
2268 ip = p->L3.IPv4Header;
2269
2270 UINTToIP(&original_dest_ip, ip->DstIP);
2271
2272 if (IsZeroIP(&e->MyPhysicalIPForce) == false && CmpIpAddr(&e->MyPhysicalIPForce, &original_dest_ip) == 0 ||
2273 (IsIPMyHost(&original_dest_ip) && IsLocalHostIP(&original_dest_ip) == false && IsHostIPAddress4(&original_dest_ip)))
2274 {
2275 if (IsZeroIP(&e->MyPhysicalIPForce) && CmpIpAddr(&e->MyPhysicalIP, &original_dest_ip) != 0)
2276 {
2277 // Update MyPhysicalIP
2278 Copy(&e->MyPhysicalIP, &original_dest_ip, sizeof(IP));
2279 // Debug("e->MyPhysicalIP = %r\n", &e->MyPhysicalIP);
2280 }
2281
2282 if (IsZeroIP(&e->MyPhysicalIPForce) == false)
2283 {
2284 Copy(&e->MyPhysicalIP, &e->MyPhysicalIPForce, sizeof(IP));
2285 }
2286
2287 ip->DstIP = IPToUINT(&e->YourIP);
2288 ip->Checksum = 0;
2289 ip->Checksum = IpChecksum(ip, IPV4_GET_HEADER_LEN(ip) * 5);
2290
2291 if (p->TypeL4 == L4_TCP)
2292 {
2293 TCP_HEADER *tcp = p->L4.TCPHeader;
2294 /*
2295 if (Endian16(tcp->SrcPort) == 80)
2296 {
2297 IP a, b;
2298 UINTToIP(&a, ip->SrcIP);
2299 UINTToIP(&b, ip->DstIP);
2300 Debug("%r %r %u %u\n", &a, &b, Endian16(tcp->SrcPort), Endian16(tcp->DstPort));
2301 }*/
2302
2303 ok = true;
2304 }
2305 else if (p->TypeL4 == L4_UDP)
2306 {
2307 UDP_HEADER *udp = p->L4.UDPHeader;
2308
2309 udp->Checksum = 0;
2310
2311 ok = true;
2312 }
2313 else if (p->TypeL4 == L4_ICMPV4)
2314 {
2315 ICMP_HEADER *icmp = p->L4.ICMPHeader;
2316
2317 if (icmp->Type == ICMP_TYPE_DESTINATION_UNREACHABLE || icmp->Type == ICMP_TYPE_TIME_EXCEEDED)
2318 {
2319 // Rewrite the Src IP of the IPv4 header of the ICMP response packet
2320 UINT size = p->PacketSize - ((UCHAR *)icmp - (UCHAR *)p->PacketData);
2321 UCHAR *data = (UCHAR *)icmp;
2322 IPV4_HEADER *orig_ipv4 = (IPV4_HEADER *)(((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
2323 UINT orig_ipv4_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
2324
2325 UINT orig_ipv4_header_size = GetIpHeaderSize((UCHAR *)orig_ipv4, orig_ipv4_size);
2326
2327 if (orig_ipv4_header_size >= sizeof(IPV4_HEADER) && orig_ipv4_size >= orig_ipv4_header_size)
2328 {
2329 if (orig_ipv4->Protocol == IP_PROTO_ICMPV4)
2330 {
2331 // Search the inner ICMP header
2332 UINT inner_icmp_size = orig_ipv4_size - orig_ipv4_header_size;
2333
2334 if (inner_icmp_size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
2335 {
2336 ICMP_HEADER *inner_icmp = (ICMP_HEADER *)(((UCHAR *)data) +
2337 sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + orig_ipv4_header_size);
2338
2339 if (inner_icmp->Type == ICMP_TYPE_ECHO_REQUEST)
2340 {
2341 ICMP_ECHO *inner_echo = (ICMP_ECHO *)(((UCHAR *)inner_icmp) + sizeof(ICMP_HEADER));
2342
2343 inner_icmp->Checksum = 0;
2344 orig_ipv4->SrcIP = IPToUINT(&e->YourIP);
2345 orig_ipv4->Checksum = 0;
2346 orig_ipv4->Checksum = IpChecksum(orig_ipv4, orig_ipv4_header_size);
2347
2348 // Rewrite the outer ICMP header
2349 if (true)
2350 {
2351 UCHAR *payload;
2352 UINT payload_size;
2353 ICMP_ECHO *echo;
2354
2355 // Echo Response
2356 echo = (ICMP_ECHO *)(((UCHAR *)data) + sizeof(ICMP_HEADER));
2357
2358 if (size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
2359 {
2360 payload = ((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
2361 payload_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
2362
2363 // Rewrite the header
2364 icmp->Checksum = 0;
2365 icmp->Checksum = IpChecksum(icmp, size);
2366 }
2367 }
2368 }
2369 }
2370 }
2371 }
2372 }
2373
2374 icmp->Checksum = 0;
2375 icmp->Checksum = IpChecksum(icmp, p->PayloadSize);
2376
2377 ok = true;
2378 }
2379 else if (p->TypeL4 == L4_FRAGMENT)
2380 {
2381 ok = true;
2382 }
2383 }
2384 }
2385
2386 FreePacket(p);
2387 }
2388
2389 if (ok == false)
2390 {
2391 Free(*data);
2392 *data = NULL;
2393
2394 goto LABEL_RETRY;
2395 }
2396
2397 return ret;
2398 }
2399
2400 // Send internal IP packet (insert into the send queue)
EthSendIpPacketInnerIpRaw(ETH * e,void * data,UINT size,USHORT protocol)2401 void EthSendIpPacketInnerIpRaw(ETH *e, void *data, UINT size, USHORT protocol)
2402 {
2403 BUF *b;
2404 if (e == NULL || data == NULL || size == 0)
2405 {
2406 return;
2407 }
2408
2409 if (e->RawIpSendQueue->num_item >= 1024)
2410 {
2411 return;
2412 }
2413
2414 b = NewBuf();
2415 WriteBuf(b, e->RawIpYourMacAddr, 6);
2416 WriteBuf(b, e->RawIpMyMacAddr, 6);
2417 WriteBufShort(b, protocol);
2418 WriteBuf(b, data, size);
2419 SeekBufToBegin(b);
2420
2421 InsertQueue(e->RawIpSendQueue, b);
2422 }
2423
2424 // Process the packet internal if necessary
EthProcessIpPacketInnerIpRaw(ETH * e,PKT * p)2425 bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p)
2426 {
2427 bool ret = false;
2428 if (e == NULL || p == NULL)
2429 {
2430 return false;
2431 }
2432
2433 if (p->TypeL3 == L3_ARPV4)
2434 {
2435 // ARP processing
2436 ARPV4_HEADER *arp = p->L3.ARPv4Header;
2437
2438 if (Endian16(arp->HardwareType) == ARP_HARDWARE_TYPE_ETHERNET &&
2439 Endian16(arp->ProtocolType) == MAC_PROTO_IPV4 &&
2440 arp->HardwareSize == 6 && arp->ProtocolType == 4)
2441 {
2442 if (IPToUINT(&e->MyIP) == arp->TargetIP)
2443 {
2444 if (Endian16(arp->Operation) == ARP_OPERATION_REQUEST)
2445 {
2446 ARPV4_HEADER r;
2447
2448 Zero(&r, sizeof(r));
2449 r.HardwareType = Endian16(ARP_HARDWARE_TYPE_ETHERNET);
2450 r.ProtocolType = Endian16(MAC_PROTO_IPV4);
2451 r.HardwareSize = 6;
2452 r.ProtocolSize = 4;
2453 r.Operation = Endian16(ARP_OPERATION_RESPONSE);
2454 Copy(r.SrcAddress, e->RawIpMyMacAddr, 6);
2455 Copy(r.TargetAddress, arp->SrcAddress, 6);
2456 r.SrcIP = IPToUINT(&e->MyIP);
2457 r.TargetIP = arp->SrcIP;
2458
2459 EthSendIpPacketInnerIpRaw(e, &r, sizeof(ARPV4_HEADER), MAC_PROTO_ARPV4);
2460 }
2461 }
2462 }
2463 }
2464 else if (p->TypeL3 == L3_IPV4 && p->TypeL4 == L4_UDP && p->TypeL7 == L7_DHCPV4)
2465 {
2466 // DHCP processing
2467 DHCPV4_HEADER *dhcp;
2468 UCHAR *data;
2469 UINT size;
2470 UINT dhcp_header_size;
2471 UINT dhcp_data_offset;
2472 UINT tran_id;
2473 UINT magic_cookie = Endian32(DHCP_MAGIC_COOKIE);
2474 bool ok;
2475 DHCP_OPTION_LIST *opt;
2476
2477 dhcp = p->L7.DHCPv4Header;
2478 tran_id = Endian32(dhcp->TransactionId);
2479
2480 // Get the DHCP data and size
2481 dhcp_header_size = sizeof(DHCPV4_HEADER);
2482 dhcp_data_offset = (UINT)(((UCHAR *)p->L7.DHCPv4Header) - ((UCHAR *)p->MacHeader) + dhcp_header_size);
2483 data = ((UCHAR *)dhcp) + dhcp_header_size;
2484 size = p->PacketSize - dhcp_data_offset;
2485 if (dhcp_header_size < 5)
2486 {
2487 // Data size is invalid
2488 return false;
2489 }
2490
2491 // Search for Magic Cookie
2492 ok = false;
2493 while (size >= 5)
2494 {
2495 if (Cmp(data, &magic_cookie, sizeof(magic_cookie)) == 0)
2496 {
2497 // Found
2498 data += 4;
2499 size -= 4;
2500 ok = true;
2501 break;
2502 }
2503 data++;
2504 size--;
2505 }
2506
2507 if (ok == false)
2508 {
2509 // The packet is invalid
2510 return false;
2511 }
2512
2513 // Parse DHCP options list
2514 opt = ParseDhcpOptionList(data, size);
2515 if (opt == NULL)
2516 {
2517 // The packet is invalid
2518 return false;
2519 }
2520
2521 if (dhcp->OpCode == 1 && (opt->Opcode == DHCP_DISCOVER || opt->Opcode == DHCP_REQUEST || opt->Opcode == DHCP_INFORM))
2522 {
2523 // Operate as the server
2524 UINT ip = IPToUINT(&e->YourIP);
2525 if (ip != 0 || opt->Opcode == DHCP_INFORM)
2526 {
2527 // Respond if there is providable IP address
2528 DHCP_OPTION_LIST ret;
2529 LIST *o;
2530 UINT hw_type;
2531 UINT hw_addr_size;
2532 UINT new_ip = ip;
2533 IP default_dns;
2534
2535 Zero(&default_dns, sizeof(default_dns));
2536
2537 Zero(&ret, sizeof(ret));
2538
2539 ret.Opcode = (opt->Opcode == DHCP_DISCOVER ? DHCP_OFFER : DHCP_ACK);
2540 ret.ServerAddress = IPToUINT(&e->MyIP);
2541 ret.LeaseTime = 3600;
2542 if (opt->Opcode == DHCP_INFORM)
2543 {
2544 ret.LeaseTime = 0;
2545 }
2546
2547 ret.SubnetMask = SetIP32(255, 255, 255, 252);
2548
2549 if (UnixGetDefaultDns(&default_dns) && IsZeroIp(&default_dns) == false)
2550 {
2551 ret.DnsServer = IPToUINT(&default_dns);
2552 ret.DnsServer2 = SetIP32(8, 8, 8, 8);
2553 }
2554 else
2555 {
2556 ret.DnsServer = SetIP32(8, 8, 8, 8);
2557 ret.DnsServer2 = SetIP32(8, 8, 4, 4);
2558 }
2559
2560 ret.Gateway = IPToUINT(&e->MyIP);
2561
2562 if (opt->Opcode != DHCP_INFORM)
2563 {
2564 char client_mac[MAX_SIZE];
2565 char client_ip[64];
2566 IP ips;
2567 BinToStr(client_mac, sizeof(client_mac), p->MacAddressSrc, 6);
2568 UINTToIP(&ips, ip);
2569 IPToStr(client_ip, sizeof(client_ip), &ips);
2570 Debug("IP_RAW: DHCP %s : %s given %s\n",
2571 ret.Opcode == DHCP_OFFER ? "DHCP_OFFER" : "DHCP_ACK",
2572 client_mac, client_ip);
2573 }
2574
2575 // Build a DHCP option
2576 o = BuildDhcpOption(&ret);
2577 if (o != NULL)
2578 {
2579 BUF *b = BuildDhcpOptionsBuf(o);
2580 if (b != NULL)
2581 {
2582 UINT dest_ip = p->L3.IPv4Header->SrcIP;
2583 UINT blank_size = 128 + 64;
2584 UINT dhcp_packet_size;
2585 UINT magic = Endian32(DHCP_MAGIC_COOKIE);
2586 DHCPV4_HEADER *dhcp;
2587 void *magic_cookie_addr;
2588 void *buffer_addr;
2589
2590 if (dest_ip == 0)
2591 {
2592 dest_ip = 0xffffffff;
2593 }
2594
2595 // Calculate the DHCP packet size
2596 dhcp_packet_size = blank_size + sizeof(DHCPV4_HEADER) + sizeof(magic) + b->Size;
2597
2598 if (dhcp_packet_size < DHCP_MIN_SIZE)
2599 {
2600 // Padding
2601 dhcp_packet_size = DHCP_MIN_SIZE;
2602 }
2603
2604 // Create a header
2605 dhcp = ZeroMalloc(dhcp_packet_size);
2606
2607 dhcp->OpCode = 2;
2608 dhcp->HardwareType = hw_type;
2609 dhcp->HardwareAddressSize = hw_addr_size;
2610 dhcp->Hops = 0;
2611 dhcp->TransactionId = Endian32(tran_id);
2612 dhcp->Seconds = 0;
2613 dhcp->Flags = 0;
2614 dhcp->YourIP = new_ip;
2615 dhcp->ServerIP = IPToUINT(&e->MyIP);
2616 Copy(dhcp->ClientMacAddress, p->MacAddressSrc, 6);
2617
2618 // Calculate the address
2619 magic_cookie_addr = (((UCHAR *)dhcp) + sizeof(DHCPV4_HEADER) + blank_size);
2620 buffer_addr = ((UCHAR *)magic_cookie_addr) + sizeof(magic);
2621
2622 // Magic Cookie
2623 Copy(magic_cookie_addr, &magic, sizeof(magic));
2624
2625 // Buffer
2626 Copy(buffer_addr, b->Buf, b->Size);
2627
2628 if (true)
2629 {
2630 UCHAR *data = ZeroMalloc(sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size);
2631 IPV4_HEADER *ipv4 = (IPV4_HEADER *)(data);
2632 UDP_HEADER *udp = (UDP_HEADER *)(data + sizeof(IPV4_HEADER));
2633
2634 Copy(data + sizeof(IPV4_HEADER) + sizeof(UDP_HEADER), dhcp, dhcp_packet_size);
2635
2636 IPV4_SET_VERSION(ipv4, 4);
2637 IPV4_SET_HEADER_LEN(ipv4, 5);
2638 ipv4->TotalLength = Endian16(sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size);
2639 ipv4->TimeToLive = 63;
2640 ipv4->Protocol = IP_PROTO_UDP;
2641 ipv4->SrcIP = IPToUINT(&e->MyIP);
2642 ipv4->DstIP = dest_ip;
2643 ipv4->Checksum = IpChecksum(ipv4, sizeof(IPV4_HEADER));
2644
2645 udp->SrcPort = Endian16(NAT_DHCP_SERVER_PORT);
2646 udp->DstPort = Endian16(NAT_DHCP_CLIENT_PORT);
2647 udp->PacketLength = Endian16(sizeof(UDP_HEADER) + dhcp_packet_size);
2648 udp->Checksum = CalcChecksumForIPv4(ipv4->SrcIP, ipv4->DstIP, IP_PROTO_UDP,
2649 dhcp, dhcp_packet_size, 0);
2650 if (udp->Checksum == 0)
2651 {
2652 udp->Checksum = 0xffff;
2653 }
2654
2655 EthSendIpPacketInnerIpRaw(e, data, sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size, MAC_PROTO_IPV4);
2656
2657 Free(data);
2658 }
2659
2660 // Release the memory
2661 Free(dhcp);
2662 FreeBuf(b);
2663 }
2664 FreeDhcpOptions(o);
2665 }
2666 }
2667 }
2668
2669 Free(opt);
2670 }
2671
2672 return ret;
2673 }
2674
2675 // Send an IP raw packet
EthPutPacketLinuxIpRaw(ETH * e,void * data,UINT size)2676 void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size)
2677 {
2678 PKT *p;
2679 // Validate arguments
2680 if (e == NULL || data == NULL)
2681 {
2682 return;
2683 }
2684 if (size < 14 || size > MAX_PACKET_SIZE || e->RawIp_HasError)
2685 {
2686 Free(data);
2687 return;
2688 }
2689
2690 p = ParsePacket(data, size);
2691
2692 if (p != NULL && (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0))
2693 {
2694 if (IsValidUnicastMacAddress(p->MacAddressSrc))
2695 {
2696 Copy(e->RawIpYourMacAddr, p->MacAddressSrc, 6);
2697 }
2698 }
2699
2700 if (IsZero(e->RawIpYourMacAddr, 6) || IsValidUnicastMacAddress(p->MacAddressSrc) == false ||
2701 (p != NULL && p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0))
2702 {
2703 Free(data);
2704 FreePacket(p);
2705 return;
2706 }
2707
2708 if (p != NULL)
2709 {
2710 SOCK *s = NULL;
2711
2712 if (p->TypeL3 == L3_IPV4)
2713 {
2714 if (p->TypeL4 == L4_TCP)
2715 {
2716 if (IsZeroIP(&e->MyPhysicalIP) == false)
2717 {
2718 s = e->RawTcp;
2719 }
2720 }
2721 else if (p->TypeL4 == L4_UDP)
2722 {
2723 if (EthProcessIpPacketInnerIpRaw(e, p) == false)
2724 {
2725 s = e->RawUdp;
2726 }
2727 }
2728 else if (p->TypeL4 == L4_ICMPV4)
2729 {
2730 if (IsZeroIP(&e->MyPhysicalIP) == false)
2731 {
2732 s = e->RawIcmp;
2733 }
2734 }
2735 else if (p->TypeL4 == L4_FRAGMENT)
2736 {
2737 if (IsZeroIP(&e->MyPhysicalIP) == false)
2738 {
2739 s = e->RawIcmp;
2740 }
2741 }
2742 }
2743 else if (p->TypeL3 == L3_ARPV4)
2744 {
2745 EthProcessIpPacketInnerIpRaw(e, p);
2746 }
2747
2748 if (s != NULL && p->L3.IPv4Header->DstIP != 0xffffffff && p->BroadcastPacket == false &&
2749 p->L3.IPv4Header->SrcIP == IPToUINT(&e->YourIP))
2750 {
2751 UCHAR *send_data = p->IPv4PayloadData;
2752 UCHAR *head = p->PacketData;
2753 UINT remove_header_size = (UINT)(send_data - head);
2754
2755 if (p->PacketSize > remove_header_size)
2756 {
2757 IP dest;
2758 UINT send_data_size = p->PacketSize - remove_header_size;
2759
2760 // checksum
2761 if (p->TypeL4 == L4_UDP)
2762 {
2763 p->L4.UDPHeader->Checksum = 0;
2764 }
2765 else if (p->TypeL4 == L4_TCP)
2766 {
2767 p->L4.TCPHeader->Checksum = 0;
2768 p->L4.TCPHeader->Checksum = CalcChecksumForIPv4(IPToUINT(&e->MyPhysicalIP),
2769 p->L3.IPv4Header->DstIP, IP_PROTO_TCP,
2770 p->L4.TCPHeader, p->IPv4PayloadSize, 0);
2771 }
2772
2773 UINTToIP(&dest, p->L3.IPv4Header->DstIP);
2774
2775 if (s->RawIP_HeaderIncludeFlag == false)
2776 {
2777 SendTo(s, &dest, 0, send_data, send_data_size);
2778 }
2779 else
2780 {
2781 IPV4_HEADER *ip = p->L3.IPv4Header;
2782
2783 ip->SrcIP = IPToUINT(&e->MyPhysicalIP);
2784 ip->Checksum = 0;
2785 ip->Checksum = IpChecksum(ip, IPV4_GET_HEADER_LEN(ip) * 4);
2786
2787 SendTo(s, &dest, 0, ip, ((UCHAR *)p->PacketData - (UCHAR *)ip) + p->PacketSize);
2788 }
2789 }
2790 }
2791
2792 FreePacket(p);
2793 }
2794
2795 Free(data);
2796 }
2797
2798
2799 #endif // BRIDGE_C
2800
2801
2802