// 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; }
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; }
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; }
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; }