268 lines
9.6 KiB
C++
268 lines
9.6 KiB
C++
#include "HuaWei/HWsec.h"
|
|
#include "HuaWei/HWsign.h"
|
|
#include "AWFilter.h"
|
|
#include <Packet.h>
|
|
#include <PcapFileDevice.h>
|
|
#include <UdpLayer.h>
|
|
#include <arpa/inet.h>
|
|
#include <atomic>
|
|
#include <iostream>
|
|
#include <stdio.h>
|
|
#include <string>
|
|
#include <sys/select.h>
|
|
#include <sys/socket.h>
|
|
|
|
using namespace std;
|
|
using namespace pcpp;
|
|
sec_set_info sign_info = {
|
|
2,
|
|
"34020000001320000003",
|
|
"2021-07-06T17:27:19.000",
|
|
32,
|
|
64,
|
|
{0x24, 0x88, 0xc8, 0xdc, 0x7f, 0xd7, 0xe0, 0x91, 0x30, 0x1b, 0x5c, 0x58, 0x2f, 0xe7, 0x44, 0x7d,
|
|
0x2f, 0x43, 0xe4, 0xee, 0xc8, 0x7d, 0xc0, 0xfb, 0xa4, 0xb8, 0x7d, 0x4b, 0x8a, 0x69, 0x7c, 0x4e},
|
|
{
|
|
0xaa, 0xb1, 0x3f, 0xd7, 0x66, 0xe2, 0x75, 0x97, 0xc0, 0x03, 0xe6, 0xe4, 0x1d, 0x77, 0x54, 0x78,
|
|
0xc8, 0x29, 0xb2, 0x0b, 0x9e, 0xd1, 0xff, 0xa3, 0x6a, 0x6f, 0xd2, 0x7f, 0xd6, 0x2d, 0xaa, 0x3f,
|
|
0xc9, 0x24, 0xec, 0x6c, 0x96, 0x0a, 0x7b, 0x73, 0xf6, 0xe6, 0xfc, 0xda, 0x3a, 0x08, 0xfd, 0x92,
|
|
0xfc, 0x00, 0x08, 0x97, 0x78, 0x2c, 0x71, 0x6b, 0xe1, 0x26, 0xf5, 0x1e, 0xba, 0x31, 0xf5, 0xb2,
|
|
}};
|
|
|
|
// void *
|
|
// EncrypInit()
|
|
// {
|
|
// // auto Verify_handle=HWVerify_init();
|
|
//
|
|
// auto sign_handle = HK_udp_init(&sign_info);//HWSign_init(&sign_info);
|
|
// return sign_handle;
|
|
// }
|
|
|
|
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)
|
|
{
|
|
if (minu.tv_sec < sub.tv_sec) {
|
|
return {0, 0};
|
|
} else if (minu.tv_sec == sub.tv_sec && minu.tv_nsec < sub.tv_nsec) {
|
|
return {0, 0};
|
|
}
|
|
|
|
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 deltatime;
|
|
}
|
|
|
|
int
|
|
ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const string &filter, AWFilter *aw_filter)
|
|
{
|
|
// auto sign_h2=EncrypInit();
|
|
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;
|
|
std::shared_ptr<std::thread> output_thread;
|
|
std::atomic<bool> processing{true};
|
|
std::atomic<int> processing_cnt{0};
|
|
if (aw_filter) {
|
|
output_thread = std::shared_ptr<std::thread>(new std::thread([&] {
|
|
while (processing.load(std::memory_order_relaxed)) {
|
|
auto now = std::chrono::steady_clock::now();
|
|
// int ret = HK_udp_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m);
|
|
int ret = aw_filter->output(
|
|
aw_filter->handler, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m);
|
|
auto end = std::chrono::steady_clock::now();
|
|
if (ret != 1) { continue; }
|
|
// WRNGL("HK_udp_out time: %lu ms\n",
|
|
// std::chrono::duration_cast<std::chrono::microseconds>(end - now).count());
|
|
processing_cnt.fetch_sub(1);
|
|
if (append_len == 0) {
|
|
sendto(socket, sign_out_buf, sign_out_len, 0, (const sockaddr *) &addr, sizeof(addr));
|
|
} else {
|
|
sendto(socket, sign_out_buf, offset_len, 0, (const sockaddr *) &addr, sizeof(addr));
|
|
sendto(socket, sign_out_buf + offset_len, sign_out_len - offset_len, 0, (const sockaddr *) &addr,
|
|
sizeof(addr));
|
|
}
|
|
// HK_udp_in(sign_h2,(char*)payload,payload_len,nullptr);
|
|
// HK_udp_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m);
|
|
}
|
|
}));
|
|
}
|
|
|
|
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 (aw_filter) {
|
|
auto cnt = processing_cnt.fetch_add(1);
|
|
// printf("frame processing cnt:%d\n", cnt);
|
|
aw_filter->input(aw_filter->handler, payload, payload_len, nullptr);
|
|
// HK_udp_in(sign_handle, (char *) payload, payload_len, nullptr);
|
|
} else {
|
|
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;
|
|
}
|
|
|
|
if (aw_filter) {
|
|
while (processing_cnt.load(std::memory_order_relaxed) > 0) {
|
|
timeval delta = {0, 100000};
|
|
sleep(delta);
|
|
}
|
|
processing.store(false);
|
|
output_thread->join();
|
|
}
|
|
|
|
// 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();
|
|
// auto sign_h = EncrypInit();
|
|
|
|
AWFilter *aw_filter = CreateAWFilter(AW_FILTER_NAME_HW_ONVIF_UDP);
|
|
aw_filter->handler = aw_filter->init(&sign_info);
|
|
ReadPcapAndSend(sockfd, addr, filename, filter, aw_filter);
|
|
// }
|
|
|
|
} else {
|
|
printf("CMD as: filename.pcap ip port\n");
|
|
system("pause");
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|