Skip to content

Instantly share code, notes, and snippets.

@jackyliu16
Created August 16, 2023 07:30
Show Gist options
  • Save jackyliu16/d943b60f5164c3d088eff0686e255d5d to your computer and use it in GitHub Desktop.
Save jackyliu16/d943b60f5164c3d088eff0686e255d5d to your computer and use it in GitHub Desktop.
send udp from pcap file with interval
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pcap.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX_PACKET_SIZE 65536
void packet_handler(u_char *user_data, const struct pcap_pkthdr *pkthdr, const u_char *packet) {
struct ip *iph;
struct udphdr *udph;
// 解析IP头部
iph = (struct ip *)(packet + 14); // 偏移以跳过以太网头部
// 确保是UDP数据包
if (iph->ip_p == IPPROTO_UDP) {
// 解析UDP头部
udph = (struct udphdr *)(packet + 14 + iph->ip_hl * 4); // 偏移以跳过以太网和IP头部
// 获取UDP数据部分
char *data = (char *)(packet + 14 + iph->ip_hl * 4 + sizeof(struct udphdr));
// 获取UDP数据部分的长度,用作sendto的终止
int data_len = ntohs(udph->len) - sizeof(struct udphdr);
// 转发UDP数据包
// 创建发送套接字
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置目标地址
struct sockaddr_in dest_addr;
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = udph->dest;
dest_addr.sin_addr.s_addr = iph->ip_dst.s_addr;
// 发送数据
if (sendto(sockfd, data, data_len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) {
perror("sendto failed");
exit(EXIT_FAILURE);
}
close(sockfd);
}
}
int main(int argc, char** argv) {
pcap_t *handle;
char errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr header;
const u_char *packet;
if (argc != 3) {
printf("you should input args as <pcap file> <num of sleep second>");
return EXIT_FAILURE;
}
// 打开PCAP文件
// handle = pcap_open_offline(trim(argv[2]), errbuf);
handle = pcap_open_offline(argv[1], errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open pcap file: %s\n", errbuf);
return EXIT_FAILURE;
}
// 读取和处理每个数据包
while ((packet = pcap_next(handle, &header)) != NULL) {
packet_handler(NULL, &header, packet);
sleep(atoi(argv[2])); // 睡眠秒数
}
// 关闭PCAP句柄
pcap_close(handle);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment