bool PcapFileReaderDevice::getNextPacket(RawPacket& rawPacket) { rawPacket.clear(); if (m_PcapDescriptor == NULL) { LOG_ERROR("File device '%s' not opened", m_FileName); return false; } pcap_pkthdr pkthdr; const uint8_t* pPacketData = pcap_next(m_PcapDescriptor, &pkthdr); if (pPacketData == NULL) { LOG_DEBUG("Packet could not be read. Probably end-of-file"); return false; } uint8_t* pMyPacketData = new uint8_t[pkthdr.caplen]; memcpy(pMyPacketData, pPacketData, pkthdr.caplen); if (!rawPacket.setRawData(pMyPacketData, pkthdr.caplen, pkthdr.ts, static_cast<LinkLayerType>(m_PcapLinkLayerType))) { LOG_ERROR("Couldn't set data to raw packet"); return false; } m_NumOfPacketsRead++; return true; }
RawSocketDevice::RecvPacketResult RawSocketDevice::receivePacket(RawPacket& rawPacket, bool blocking, int timeout) { #if defined(WIN32) || defined(WINx64) || defined(PCAPPP_MINGW_ENV) if (!isOpened()) { LOG_ERROR("Device is not open"); return RecvError; } SOCKET fd = ((SocketContainer*)m_Socket)->fd; char* buffer = new char[RAW_SOCKET_BUFFER_LEN]; memset(buffer, 0, RAW_SOCKET_BUFFER_LEN); // value of 0 timeout means disabling timeout if (timeout < 0) timeout = 0; u_long blockingMode = (blocking? 0 : 1); ioctlsocket(fd, FIONBIO, &blockingMode); DWORD timeoutVal = timeout * 1000; setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeoutVal, sizeof(timeoutVal)); //recvfrom(fd, buffer, RAW_SOCKET_BUFFER_LEN, 0, (struct sockaddr*)&sockAddr,(socklen_t*)&sockAddrLen); int bufferLen = recv(fd, buffer, RAW_SOCKET_BUFFER_LEN, 0); if (bufferLen < 0) { delete [] buffer; int errorCode = 0; RecvPacketResult error = getError(errorCode); if (error == RecvError) LOG_ERROR("Error reading from recvfrom. Error code is %d", errorCode); return error; } if (bufferLen > 0) { timeval time; gettimeofday(&time, NULL); rawPacket.setRawData((const uint8_t*)buffer, bufferLen, time, LINKTYPE_DLT_RAW1); return RecvSuccess; } LOG_ERROR("Buffer length is zero"); delete [] buffer; return RecvError; #elif LINUX if (!isOpened()) { LOG_ERROR("Device is not open"); return RecvError; } int fd = ((SocketContainer*)m_Socket)->fd; char* buffer = new char[RAW_SOCKET_BUFFER_LEN]; memset(buffer, 0, RAW_SOCKET_BUFFER_LEN); // value of 0 timeout means disabling timeout if (timeout < 0) timeout = 0; // set blocking or non-blocking flag int flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { LOG_ERROR("Cannot get socket flags"); return RecvError; } flags = (blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK)); if (fcntl(fd, F_SETFL, flags) != 0) { LOG_ERROR("Cannot set socket non-blocking flag"); return RecvError; } // set timeout on socket struct timeval timeoutVal; timeoutVal.tv_sec = timeout; timeoutVal.tv_usec = 0; setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeoutVal, sizeof(timeoutVal)); int bufferLen = recv(fd, buffer, RAW_SOCKET_BUFFER_LEN, 0); if (bufferLen < 0) { delete [] buffer; int errorCode = errno; RecvPacketResult error = getError(errorCode); if (error == RecvError) LOG_ERROR("Error reading from recvfrom. Error code is %d", errorCode); return error; } if (bufferLen > 0) { timeval time; gettimeofday(&time, NULL); rawPacket.setRawData((const uint8_t*)buffer, bufferLen, time, LINKTYPE_ETHERNET); return RecvSuccess; } LOG_ERROR("Buffer length is zero"); delete [] buffer; return RecvError; #else LOG_ERROR("Raw socket are not supported on this platform"); return RecvError; #endif }