コード例 #1
0
// Ethernet device list by BPF API
TOKEN_LIST *GetEthListBpf()
{
	struct ifaddrs *ifadrs;
	struct sockaddr_dl *sockadr;
	LIST *o;
	TOKEN_LIST *t;
	int i;

	o = NewListFast(CompareStr);

	// Enumerate network devices
	if(getifaddrs( &ifadrs ) == 0)
	{
		struct ifaddrs *ifadr = ifadrs;
		while(ifadr)
		{
			sockadr = (struct sockaddr_dl*)ifadr->ifa_addr;
			if(sockadr->sdl_family == AF_LINK && sockadr->sdl_type == IFT_ETHER)
			{
				// Is this Ethernet device?
				if(!IsInListStr(o,ifadr->ifa_name))
				{
					// Ignore the foregoing device (for device which have multiple MAC address)
					Add(o, CopyStr(ifadr->ifa_name));
				}
			}
			ifadr = ifadr -> ifa_next;
		}
		freeifaddrs(ifadrs);
	}

	Sort(o);
	t = ZeroMalloc(sizeof(TOKEN_LIST));
	t->NumTokens = LIST_NUM(o);
	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
	for (i = 0;i < LIST_NUM(o);i++)
	{
		t->Token[i] = LIST_DATA(o, i);
	}
	ReleaseList(o);
	return t;
}
コード例 #2
0
ファイル: BridgeUnix.c プロジェクト: falcon8823/utvpn
// アダプタ一覧を取得 (BPF)
TOKEN_LIST *GetEthListBpf()
{
	struct ifaddrs *ifadrs;
	struct sockaddr_dl *sockadr;
	LIST *o;
	TOKEN_LIST *t;
	int i;

	o = NewListFast(CompareStr);

	// ネットワークデバイスの一覧を取得
	if(getifaddrs( &ifadrs ) == 0)
	{
		struct ifaddrs *ifadr = ifadrs;
		while(ifadr)
		{
			sockadr = (struct sockaddr_dl*)ifadr->ifa_addr;
			if(sockadr->sdl_family == AF_LINK && sockadr->sdl_type == IFT_ETHER)
			{
				// Ethernet デバイスか?
				if(!IsInListStr(o,ifadr->ifa_name))
				{
					// 既存でなければ追加(複数のMACアドレスを持つインターフェースへの対策)
					Add(o, CopyStr(ifadr->ifa_name));
				}
			}
			ifadr = ifadr -> ifa_next;
		}
		freeifaddrs(ifadrs);
	}

	Sort(o);
	t = ZeroMalloc(sizeof(TOKEN_LIST));
	t->NumTokens = LIST_NUM(o);
	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
	for (i = 0;i < LIST_NUM(o);i++)
	{
		t->Token[i] = LIST_DATA(o, i);
	}
	ReleaseList(o);
	return t;
}
コード例 #3
0
// Get Ethernet device list on Linux
TOKEN_LIST *GetEthListLinux()
{
	struct ifreq ifr;
	TOKEN_LIST *t;
	UINT i, n;
	int s;
	LIST *o;
	char name[MAX_SIZE];

	o = NewListFast(CompareStr);

	s = UnixEthOpenRawSocket();
	if (s != INVALID_SOCKET)
	{
		n = 0;
		for (i = 0;;i++)
		{
			Zero(&ifr, sizeof(ifr));
			ifr.ifr_ifindex = i;

			if (ioctl(s, SIOCGIFNAME, &ifr) >= 0)
			{
				n = 0;
				StrCpy(name, sizeof(name), ifr.ifr_name);

				Zero(&ifr, sizeof(ifr));
				StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), name);
				if (ioctl(s, SIOCGIFHWADDR, &ifr) >= 0)
				{
					UINT type = ifr.ifr_hwaddr.sa_family;
					if (type == 1 || type == 2 || type == 6 || type == 800 || type == 801)
					{
						if (IsInListStr(o, name) == false)
						{
							if (StartWith(name, "tap_") == false)
							{
								Add(o, CopyStr(name));
							}
						}
					}
				}
			}
			else
			{
				n++;
				if (n >= 64)
				{
					break;
				}
			}
		}
		closesocket(s);
	}

	Sort(o);

	t = ZeroMalloc(sizeof(TOKEN_LIST));
	t->NumTokens = LIST_NUM(o);
	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);

	for (i = 0;i < LIST_NUM(o);i++)
	{
		char *name = LIST_DATA(o, i);
		t->Token[i] = name;
	}

	ReleaseList(o);

	return t;
}
コード例 #4
0
ファイル: BridgeUnix.c プロジェクト: 2Quico/SoftEtherVPN
// Open Ethernet device (Linux)
ETH *OpenEthLinux(char *name, bool local, bool tapmode, char *tapaddr)
{
	ETH *e;
	struct ifreq ifr;
	struct sockaddr_ll addr;
	int s;
	int index;
	bool aux_ok = false;
	CANCEL *c;
	// Validate arguments
	if (name == NULL)
	{
		return NULL;
	}

	if (tapmode)
	{
#ifndef	NO_VLAN
		// In tap mode
		VLAN *v = NewTap(name, tapaddr);
		if (v == NULL)
		{
			return NULL;
		}

		e = ZeroMalloc(sizeof(ETH));
		e->Name = CopyStr(name);
		e->Title = CopyStr(name);
		e->Cancel = VLanGetCancel(v);
		e->IfIndex = 0;
		e->Socket = INVALID_SOCKET;
		e->Tap = v;

		return e;
#else	// NO_VLAN
		return NULL;
#endif	// NO_VLAN
	}

	s = UnixEthOpenRawSocket();
	if (s == INVALID_SOCKET)
	{
		return NULL;
	}

	Zero(&ifr, sizeof(ifr));
	StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), name);

	if (ioctl(s, SIOCGIFINDEX, &ifr) < 0)
	{
		closesocket(s);
		return NULL;
	}

	index = ifr.ifr_ifindex;

	Zero(&addr, sizeof(addr));
	addr.sll_family = PF_PACKET;
	addr.sll_protocol = htons(ETH_P_ALL);
	addr.sll_ifindex = index;

	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		closesocket(s);
		return NULL;
	}

	if (local == false)
	{
		// Enable promiscious mode
		Zero(&ifr, sizeof(ifr));
		StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), name);
		if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
		{
			// Failed
			closesocket(s);
			return NULL;
		}

		ifr.ifr_flags |= IFF_PROMISC;

		if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
		{
			// Failed
			closesocket(s);
			return NULL;
		}
	}

	if (true)
	{
		int val = 1;
		int ss_ret = setsockopt(s, SOL_PACKET, MY_PACKET_AUXDATA, &val, sizeof(val));

		if (ss_ret < 0)
		{
			Debug("eth(%s): setsockopt: PACKET_AUXDATA failed.\n", name);
		}
		else
		{
			Debug("eth(%s): setsockopt: PACKET_AUXDATA ok.\n", name);
			aux_ok = true;
		}
	}

	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);
	e->IfIndex = index;
	e->Socket = s;

	e->Linux_IsAuxDataSupported = aux_ok;

	c = NewCancel();
	UnixDeletePipe(c->pipe_read, c->pipe_write);
	c->pipe_read = c->pipe_write = -1;

	UnixSetSocketNonBlockingMode(s, true);

	c->SpecialFlag = true;
	c->pipe_read = s;

	e->Cancel = c;

	// Get MTU
	e->InitialMtu = EthGetMtu(e);

	if (tapmode == false)
	{
		if (GetGlobalServerFlag(GSF_LOCALBRIDGE_NO_DISABLE_OFFLOAD) == false)
		{
			bool b = false;

			LockList(eth_offload_list);
			{
				if (IsInListStr(eth_offload_list, name) == false)
				{
					b = true;

					Add(eth_offload_list, CopyStr(name));
				}
			}
			UnlockList(eth_offload_list);

			if (b)
			{
				// Disable hardware offloading
				UnixDisableInterfaceOffload(name);
			}
		}
	}

	return e;
}