194 lines
6.2 KiB
C++
194 lines
6.2 KiB
C++
|
#include <iostream>
|
||
|
#include <Packet.h>
|
||
|
#include <PcapFileDevice.h>
|
||
|
#include <UdpLayer.h>
|
||
|
#include <string>
|
||
|
#include <arpa/inet.h>
|
||
|
#include <stdio.h>
|
||
|
#include <sys/socket.h>
|
||
|
#include <sys/select.h>
|
||
|
#include "HuaWei/HWsign.h"
|
||
|
#include "HuaWei/HWsec.h"
|
||
|
|
||
|
using namespace std;
|
||
|
using namespace pcpp;
|
||
|
|
||
|
std::string getProtocolTypeAsString(pcpp::ProtocolType protocolType)
|
||
|
{
|
||
|
switch (protocolType)
|
||
|
{
|
||
|
case pcpp::Ethernet:
|
||
|
return "Ethernet";
|
||
|
case pcpp::IPv4:
|
||
|
return "IPv4";
|
||
|
case pcpp::TCP:
|
||
|
return "TCP";
|
||
|
case pcpp::HTTPRequest:
|
||
|
case pcpp::HTTPResponse:
|
||
|
return "HTTP";
|
||
|
case pcpp::UDP:
|
||
|
return "UDP";
|
||
|
default:
|
||
|
return "Unknown";
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
inline void sleep(timeval & delta){
|
||
|
// delta.tv_sec
|
||
|
select(0,NULL,NULL,NULL,&delta);
|
||
|
}
|
||
|
template<typename T,typename U>
|
||
|
timespec TimeDiff(T && minu,U && sub){
|
||
|
timespec deltatime;
|
||
|
deltatime.tv_nsec=minu.tv_nsec-sub.tv_nsec;
|
||
|
deltatime.tv_sec=minu.tv_sec-sub.tv_sec;
|
||
|
if(deltatime.tv_nsec<0 && deltatime.tv_sec>0){
|
||
|
deltatime.tv_nsec+=1000000000;
|
||
|
deltatime.tv_sec--;
|
||
|
}
|
||
|
return move(deltatime);
|
||
|
}
|
||
|
|
||
|
int ReadPcapAndSend(int socket,sockaddr_in & addr,const string & filename,const string & filter,void * sign_handle){
|
||
|
auto reader=pcpp::IFileReaderDevice::getReader(filename);
|
||
|
// verify that a reader interface was indeed created
|
||
|
if (reader == NULL)
|
||
|
{
|
||
|
std::cerr << "Cannot determine reader for file type" << std::endl;
|
||
|
return 1;
|
||
|
}
|
||
|
// open the reader for reading
|
||
|
if (!reader->open())
|
||
|
{
|
||
|
std::cerr << "Cannot open input.pcap for reading" << std::endl;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (!reader->setFilter(filter))
|
||
|
{
|
||
|
std::cerr << "Cannot set filter for file reader" << std::endl;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
uint8_t * payload;
|
||
|
size_t payload_len;
|
||
|
pcpp::RawPacket rawPacket;
|
||
|
bool first_flag=true;
|
||
|
timespec nowtime,gaptime;
|
||
|
timespec real_now;
|
||
|
timespec inital_time,current_time;
|
||
|
static char sign_out_buf[3096];
|
||
|
unsigned int sign_out_len;
|
||
|
void *param=nullptr;
|
||
|
uint16_t offset_len,append_len;
|
||
|
while (reader->getNextPacket(rawPacket))
|
||
|
{
|
||
|
pcpp::Packet parsedPacket(&rawPacket,OsiModelTransportLayer);
|
||
|
auto layer = parsedPacket.getLayerOfType<UdpLayer>(false);
|
||
|
|
||
|
if(layer){
|
||
|
payload=layer->getLayerPayload();
|
||
|
payload_len=layer->getLayerPayloadSize();
|
||
|
// cout<<" payload_len:" << payload_len<<endl;
|
||
|
nowtime=rawPacket.getPacketTimeStamp();
|
||
|
clock_gettime(CLOCK_MONOTONIC, &real_now);
|
||
|
if(first_flag){
|
||
|
first_flag=false;
|
||
|
inital_time=TimeDiff(nowtime,real_now);
|
||
|
}
|
||
|
current_time.tv_sec=inital_time.tv_sec+real_now.tv_sec;
|
||
|
current_time.tv_nsec=inital_time.tv_nsec+real_now.tv_nsec;
|
||
|
gaptime=TimeDiff(nowtime,current_time);
|
||
|
if (gaptime.tv_nsec>=0 && gaptime.tv_sec>=0)
|
||
|
{
|
||
|
nanosleep(&gaptime,NULL);
|
||
|
}else{
|
||
|
// cout<<" s:" << gaptime.tv_sec<<" ns:" << gaptime.tv_nsec <<endl;
|
||
|
}
|
||
|
// ///////////////calculate send time//////////////////
|
||
|
if(sendto(socket,payload,payload_len,0,(const sockaddr*)&addr,sizeof(addr))==-1){
|
||
|
printf("send failed : %s\n", strerror(errno));
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// cout<<" stamp:" << rawPacket.getPacketTimeStamp().tv_sec<<" len:"<< rawPacket.getRawDataLen()<<endl;
|
||
|
}
|
||
|
|
||
|
|
||
|
// reader->getNextPacket(rawPacket);
|
||
|
|
||
|
// for (pcpp::Layer* curLayer = parsedPacket.getFirstLayer(); curLayer != NULL; curLayer = curLayer->getNextLayer())
|
||
|
// {
|
||
|
// std::cout
|
||
|
// << "Layer type: " <<getProtocolTypeAsString(curLayer->getProtocol()) << "; " // get layer type
|
||
|
// << "Total data: " << curLayer->getDataLen() << " [bytes]; " // get total length of the layer
|
||
|
// << "Layer data: " << curLayer->getHeaderLen() << " [bytes]; " // get the header length of the layer
|
||
|
// << "Layer payload: " << curLayer->getLayerPayloadSize() << " [bytes]" // get the payload length of the layer (equals total length minus header length)
|
||
|
// << std::endl;
|
||
|
// }
|
||
|
// create the stats object
|
||
|
pcpp::IPcapDevice::PcapStats stats;
|
||
|
reader->getStatistics(stats);
|
||
|
std::cout << "Read " << stats.packetsRecv << " packets successfully and " << stats.packetsDrop << " packets could not be read" << std::flush;
|
||
|
return 0;
|
||
|
}
|
||
|
int main(int argc, char *argv[]){
|
||
|
|
||
|
char ip[16] = {0};
|
||
|
int sockfd, port;
|
||
|
if (argc>4)
|
||
|
{
|
||
|
string filename(argv[1]);
|
||
|
strcpy(ip, argv[2]);
|
||
|
port = atoi(argv[3]);
|
||
|
string filter(argv[4]);
|
||
|
printf("filename:%s\nip:%s\nport:%d\nfilter:%s\n", filename.data(), ip,port,filter.data());
|
||
|
|
||
|
sockfd = socket(AF_INET, SOCK_DGRAM , IPPROTO_UDP);//SOCK_STREAM
|
||
|
if (sockfd == -1) {
|
||
|
printf("create socket failed : %s\n", strerror(errno));
|
||
|
return -1;
|
||
|
}
|
||
|
int rcvBufSize = 2097152;
|
||
|
int rcvlen = sizeof(rcvBufSize);
|
||
|
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&rcvBufSize, sizeof(rcvBufSize));
|
||
|
if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&rcvBufSize, (socklen_t *)&rcvlen) >= 0)
|
||
|
{
|
||
|
printf("set udp socket send buff size to : %d\n", rcvBufSize);
|
||
|
if (rcvBufSize < 4194304)
|
||
|
{
|
||
|
printf("socket send buff too small, please set up to 2097152(2M)");
|
||
|
}
|
||
|
}else {
|
||
|
printf("socket failed : %s\n", strerror(errno));
|
||
|
return -1;
|
||
|
}
|
||
|
struct sockaddr_in addr;
|
||
|
addr.sin_family = AF_INET;
|
||
|
addr.sin_port = htons(port);
|
||
|
addr.sin_addr.s_addr =inet_addr(ip);
|
||
|
// if(connect(sockfd, (struct sockaddr*)&addr, sizeof(addr))==-1){
|
||
|
// printf("connection error : %s\n", strerror(errno));
|
||
|
// return -1;
|
||
|
// }
|
||
|
// bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
|
||
|
// while (1)
|
||
|
// {
|
||
|
cout.flush();
|
||
|
ReadPcapAndSend(sockfd,addr,filename,filter,NULL);
|
||
|
// }
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("CMD as: filename.pcap ip port\n");
|
||
|
system("pause");
|
||
|
return 0;
|
||
|
}
|
||
|
return 0;
|
||
|
|
||
|
}
|