コード例 #1
0
ファイル: VLanUnix.c プロジェクト: AquilesCrespo/SoftEtherVPN
// Get the next packet
UINT VLanPaGetNextPacket(SESSION *s, void **data)
{
	VLAN *v;
	UINT size;
	// Validate arguments
	if (data == NULL || (s == NULL) || ((v = s->PacketAdapter->Param) == NULL))
	{
		return INFINITE;
	}

	if (VLanGetNextPacket(v, data, &size) == false)
	{
		return INFINITE;
	}

	return size;
}
コード例 #2
0
UINT EthGetPacketLinux(ETH *e, void **data)
{
	int s, ret;
	UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
	// Validate arguments
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}

	if (e->Tap != NULL)
	{
#ifndef	NO_VLAN
		// tap mode
		void *buf;
		UINT size;

		if (VLanGetNextPacket(e->Tap, &buf, &size) == false)
		{
			return INFINITE;
		}

		*data = buf;
		return size;
#else	// NO_VLAN
		return INFINITE;
#endif
	}

	s = e->Socket;

	if (s == INVALID_SOCKET)
	{
		return INFINITE;
	}

	// Read
	ret = read(s, tmp, sizeof(tmp));
	if (ret == 0 || (ret == -1 && errno == EAGAIN))
	{
		// No packet
		*data = NULL;
		return 0;
	}
	else if (ret == -1 || ret > sizeof(tmp))
	{
		// Error
		*data = NULL;
		e->Socket = INVALID_SOCKET;
		return INFINITE;
	}
	else
	{
		// Success to read a packet
		*data = MallocFast(ret);
		Copy(*data, tmp, ret);
		return ret;
	}

	return 0;
}
コード例 #3
0
ファイル: BridgeUnix.c プロジェクト: falcon8823/utvpn
UINT EthGetPacketLinux(ETH *e, void **data)
{
	int s, ret;
	UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
	// 引数チェック
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}

	if (e->Tap != NULL)
	{
#ifndef	NO_VLAN
		// tap モード
		void *buf;
		UINT size;

		if (VLanGetNextPacket(e->Tap, &buf, &size) == false)
		{
			return INFINITE;
		}

		*data = buf;
		return size;
#else	// NO_VLAN
		return INFINITE;
#endif
	}

	s = e->Socket;

	if (s == INVALID_SOCKET)
	{
		return INFINITE;
	}

	// 読み込み
	ret = read(s, tmp, sizeof(tmp));
	if (ret == 0 || (ret == -1 && errno == EAGAIN))
	{
		// パケット無し
		*data = NULL;
		return 0;
	}
	else if (ret == -1 || ret > sizeof(tmp))
	{
		// エラー
		*data = NULL;
		e->Socket = INVALID_SOCKET;
		return INFINITE;
	}
	else
	{
		// パケット読み込み成功
		*data = MallocFast(ret);
		Copy(*data, tmp, ret);
		return ret;
	}

	return 0;
}
コード例 #4
0
ファイル: BridgeUnix.c プロジェクト: 2Quico/SoftEtherVPN
UINT EthGetPacketLinux(ETH *e, void **data)
{
	int s, ret;
	UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
	struct iovec msg_iov;
	struct msghdr msg_header;
	struct cmsghdr *cmsg;
	union
	{
		struct cmsghdr cmsg;
		char buf[CMSG_SPACE(sizeof(struct my_tpacket_auxdata))];
	} cmsg_buf;
	// Validate arguments
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}

	if (e->Tap != NULL)
	{
#ifndef	NO_VLAN
		// tap mode
		void *buf;
		UINT size;

		if (VLanGetNextPacket(e->Tap, &buf, &size) == false)
		{
			return INFINITE;
		}

		*data = buf;
		return size;
#else	// NO_VLAN
		return INFINITE;
#endif
	}

	s = e->Socket;

	if (s == INVALID_SOCKET)
	{
		return INFINITE;
	}

	// Read
	msg_iov.iov_base = tmp;
	msg_iov.iov_len = sizeof(tmp);

	msg_header.msg_name = NULL;
	msg_header.msg_namelen = 0;
	msg_header.msg_iov = &msg_iov;
	msg_header.msg_iovlen = 1;
	if (e->Linux_IsAuxDataSupported)
	{
		memset(&cmsg_buf, 0, sizeof(cmsg_buf));

		msg_header.msg_control = &cmsg_buf;
		msg_header.msg_controllen = sizeof(cmsg_buf);
	}
	else
	{
		msg_header.msg_control = NULL;
		msg_header.msg_controllen = 0;
	}
	msg_header.msg_flags = 0;

	ret = recvmsg(s, &msg_header, 0);
	if (ret == 0 || (ret == -1 && errno == EAGAIN))
	{
		// No packet
		*data = NULL;
		return 0;
	}
	else if (ret == -1 || ret > sizeof(tmp))
	{
		// Error
		*data = NULL;
		e->Socket = INVALID_SOCKET;
		return INFINITE;
	}
	else
	{
		bool flag = false;
		USHORT api_vlan_id = 0;
		USHORT api_vlan_tpid = 0;

		if (e->Linux_IsAuxDataSupported)
		{
			for (cmsg = CMSG_FIRSTHDR(&msg_header); cmsg; cmsg = CMSG_NXTHDR(&msg_header, cmsg))
			{
				struct my_tpacket_auxdata *aux;
				UINT len;
				USHORT vlan_tpid = 0x8100;
				USHORT vlan_id = 0;

				if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct my_tpacket_auxdata)) ||
					cmsg->cmsg_level != SOL_PACKET ||
					cmsg->cmsg_type != MY_PACKET_AUXDATA)
				{
					continue;
				}

				aux = (struct my_tpacket_auxdata *)CMSG_DATA(cmsg);

				if (aux != NULL)
				{
					if (aux->tp_vlan_tci != 0)
					{
						vlan_id = aux->tp_vlan_tci;
					}
				}

				if (vlan_id != 0)
				{
					api_vlan_id = vlan_id;
					api_vlan_tpid = vlan_tpid;
					break;
				}
			}

			if (api_vlan_id != 0 && api_vlan_tpid != 0)
			{
				// VLAN ID has been received with PACKET_AUXDATA.
				// Insert the tag.
				USHORT vlan_id_ne = Endian16(api_vlan_id);
				USHORT vlan_tpid_ne = Endian16(api_vlan_tpid);

				if (ret >= 14)
				{
					if (*((USHORT *)(tmp + 12)) != vlan_tpid_ne)
					{
						*data = MallocFast(ret + 4);
						Copy(*data, tmp, 12);
						Copy(((UCHAR *)*data) + 12, &vlan_tpid_ne, 2);
						Copy(((UCHAR *)*data) + 14, &vlan_id_ne, 2);
						Copy(((UCHAR *)*data) + 16, tmp + 12, ret - 12);

						flag = true;

						ret += 4;
					}
				}
			}
		}

		// Success to read a packet (No VLAN)
		if (flag == false)
		{
			*data = MallocFast(ret);
			Copy(*data, tmp, ret);
		}
		return ret;
	}

	return 0;
}