int RawSocketDevice::sendPackets(const RawPacketVector& packetVec) { #if defined(WIN32) || defined(WINx64) || defined(PCAPPP_MINGW_ENV) LOG_ERROR("Sending packets with raw socket are not supported on Windows"); return false; #elif LINUX if (!isOpened()) { LOG_ERROR("Device is not open"); return 0; } int fd = ((SocketContainer*)m_Socket)->fd; sockaddr_ll addr; memset(&addr, 0, sizeof(struct sockaddr_ll)); addr.sll_family = htons(PF_PACKET); addr.sll_protocol = htons(ETH_P_ALL); addr.sll_halen = 6; addr.sll_ifindex = ((SocketContainer*)m_Socket)->interfaceIndex; int sendCount = 0; for (RawPacketVector::ConstVectorIterator iter = packetVec.begin(); iter != packetVec.end(); iter++) { Packet packet(*iter, OsiModelDataLinkLayer); if (!packet.isPacketOfType(pcpp::Ethernet)) { LOG_DEBUG("Can't send non-Ethernet packets"); continue; } EthLayer* ethLayer = packet.getLayerOfType<EthLayer>(); MacAddress dstMac = ethLayer->getDestMac(); dstMac.copyTo((uint8_t*)&(addr.sll_addr)); if (::sendto(fd, (*iter)->getRawData(), (*iter)->getRawDataLen(), 0, (struct sockaddr*)&addr, sizeof(addr)) == -1) { LOG_DEBUG("Failed to send packet. Error was: '%s'", strerror(errno)); continue; } sendCount++; } return sendCount; #else LOG_ERROR("Raw socket are not supported on this platform"); return false; #endif }
bool PcapFileWriterDevice::writePackets(const RawPacketVector& packets) { for (RawPacketVector::ConstVectorIterator iter = packets.begin(); iter != packets.end(); iter++) { if (!writePacket(**iter)) return false; } return true; }
int PcapLiveDevice::sendPackets(const RawPacketVector& rawPackets) { int packetsSent = 0; for (RawPacketVector::ConstVectorIterator iter = rawPackets.begin(); iter != rawPackets.end(); iter++) { if (sendPacket(**iter)) packetsSent++; } LOG_DEBUG("%d packets sent successfully. %d packets not sent", packetsSent, rawPackets.size()-packetsSent); return packetsSent; }
int RawSocketDevice::receivePackets(RawPacketVector& packetVec, int timeout, int& failedRecv) { if (!isOpened()) { LOG_ERROR("Device is not open"); return 0; } long curSec, curNsec; clockGetTime(curSec, curNsec); int packetCount = 0; failedRecv = 0; long timeoutSec = curSec + timeout; while (curSec < timeoutSec) { RawPacket* rawPacket = new RawPacket(); if (receivePacket(*rawPacket, true, timeoutSec-curSec) == RecvSuccess) { packetVec.pushBack(rawPacket); packetCount++; } else { failedRecv++; delete rawPacket; } clockGetTime(curSec, curNsec); } return packetCount; }
MacAddress getMacAddress(const IPv4Address& ipAddr, PcapLiveDevice* pDevice) { // Create an ARP packet and change its fields Packet arpRequest(500); MacAddress macSrc = pDevice->getMacAddress(); MacAddress macDst(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); EthLayer ethLayer(macSrc, macDst, (uint16_t)PCPP_ETHERTYPE_ARP); ArpLayer arpLayer(ARP_REQUEST, pDevice->getMacAddress(), pDevice->getMacAddress(), pDevice->getIPv4Address(), ipAddr); arpRequest.addLayer(ðLayer); arpRequest.addLayer(&arpLayer); arpRequest.computeCalculateFields(); //setup arp reply filter ArpFilter arpFilter(ARP_REPLY); pDevice->setFilter(arpFilter); //send the arp request and wait for arp reply pDevice->sendPacket(&arpRequest); RawPacketVector capturedPackets; pDevice->startCapture(capturedPackets); PCAP_SLEEP(2); pDevice->stopCapture(); if (capturedPackets.size() < 1) { printf("No arp reply was captured. Couldn't retrieve MAC address for IP %s\n", ipAddr.toString().c_str()); return MacAddress(""); } //parse arp reply and extract the MAC address Packet arpReply(capturedPackets.front()); if (arpReply.isPacketOfType(ARP)) { return arpReply.getLayerOfType<ArpLayer>()->getSenderMacAddress(); } printf("No arp reply was captured. Couldn't retrieve MAC address for IP %s\n", ipAddr.toString().c_str()); return MacAddress(""); }
int PfRingDevice::sendPackets(const RawPacketVector& rawPackets) { int packetsSent = 0; for (RawPacketVector::ConstVectorIterator iter = rawPackets.begin(); iter != rawPackets.end(); iter++) { if (!sendData((*iter)->getRawDataReadOnly(), (*iter)->getRawDataLen(), false)) break; else packetsSent++; } // The following method isn't supported in PF_RING aware drivers, probably only in DNA and ZC pfring_flush_tx_packets(m_PfRingDescriptors[0]); LOG_DEBUG("%d out of %d raw packets were sent successfully", packetsSent, rawPackets.size()); return packetsSent; }