pplayer(packet player)是我写的一款小工具,支持主流协议,专门用来测试IPS和防火墙设备,经长时间验证,简单可靠,故发布。

程序的原理很简单,首先加载pcap包中的数据包,保存在内存中,然后在回放环境中回放数据包。

拓扑:

原理:

防火墙的两个网卡和linux pc的两个网卡分别对接形成环路,pplayer程序运行在linux pc中。

1,加载pcap文件中网路数据包,识别出数据包发送方向(client to server or server to client)

2,修改数据包内容(源/目的ip地址,校验和)

3,按顺序发送数据包,同时接收数据包

4,打印log,提示发送和接收情况,回放完毕。

使用方法:

pplayer -f filename [ -t time] | [-m] | [-v ipversion] | [-p portnum]

可用参数:

-f:  必选,参数是pcap文件名。

-t:  可选,参数是等待接收一个已发送的数据报的时间;如不选默认30(微秒)。

-m: 可选,理想情况下pcap包中只包含两个ip地址的数据包,但是如果存在第3方或3个以上ip地址,就形成了若干的回放关系。

默认情况下,只选择数据包数量最多得一对ip进行回放。如需回放其他ip对的数据包,需要使用-m参数,会以ip对为顺序来回放数据包。

-v: 可选,4或6, 回放IPV4/6数据包, 默认4.

-p: 可选,选择只回放指定端口的数据包,例如,指定回访HTTP包, -p 80。

另外pplayer支持nat环境回放,使用方法见下面配置文件。

举例:

1,./pplayer -f http.pcap(回放http.pcap的数据包)

2, ./pplayer -f http.pcap -v 6 (回放http.pcap的数据包,数据包格式是ipv6)

3,./pplayer -f http.pcap -v 6 -t 50 (回放http.pcap的数据包,数据包格式是ipv6, 每个数据包的等待接收时间设为50微秒)

配置文件:

配置名是conf,和pplayer程序在同一目录下。

格式:

device1:eth0

device2:eth1

device1ip:1.1.1.1

device2ip:2.2.2.2

device1nat:3.3.3.3

device2nat:4.4.4.4

fwmac1:00:0C:29:25:63:6E

fwmac2:00:0C:29:25:63:78

注:冒号后面紧接内容,不能有空格或换行

1.device1和device2表示linxu pc的两个网卡

2.device1ip和device2ip表示linux pc的两个网卡的ip地址

3.device1nat和device2nat是用来支持nat环境回放的。

例如:设备1的ip是1.1.1.1,设备1处于nat环境,转换后的ip是3.3.3.3;

设备2的ip是2.2.2.2,设备2处于nat环境,转换后的ip是4.4.4.4;

如果设备不处于nat环境之中,对应的nat配置项填0.0.0.0(ipv6的填::)

并发/批量回放:

目前pplayer只支持一次回放一个IP对,一次只能回放一个pcap文件,不支持并发和批量回放这两种功能,后续我可能会以shell脚本调用pplayer的方式实现

这两个功能。

核心代码:void LoadPacket (const struct pcap_pkthdr *pcap_hdr, Trace *trace, Flow *flow, const u_char * data, int pkt_id)

{

Packet *pkt = NULL;

struct ether_header *ph = NULL;

struct iphdr *iph = NULL;

struct ip6_hdr *iph6 = NULL;

struct tcphdr *tcph = NULL;

struct udphdr *udph = NULL;

if (flow->pkt_cap == 0) {

flow->pkt_cap = 64;

flow->pkt = calloc(64, sizeof(Packet));

} else if (flow->pkt_num == flow->pkt_cap) {

flow->pkt_cap += 64;

flow->pkt = realloc(flow->pkt, (flow->pkt_cap) * sizeof(Packet));

}

pkt = &flow->pkt[flow->pkt_num];

pkt->id = pkt_id;

if (my_file.ipversion == 4) {

iph = (struct iphdr *)(data + ETH_HLEN);

int offset = (iph->ihl << 2) + ETH_HLEN;

tcph = (struct tcphdr *)(data + offset);

if (my_file.port != 0 &&

htons(my_file.port) != tcph->th_dport &&

htons(my_file.port) != tcph->th_sport) {

return;

}

pkt->len = pcap_hdr->caplen;//ntohs(iph->tot_len) + ETH_HLEN;

pkt->buf = malloc(pkt->len + ETHER_CRC_LEN);

memcpy(pkt->buf, data, pkt->len);

iph = (struct iphdr *)(pkt->buf + ETH_HLEN);

} else {

iph6 = (struct ip6_hdr *)(data + ETH_HLEN);

int offset = 40 + ETH_HLEN;

tcph = (struct tcphdr *)(data + offset);

if (my_file.port != 0 &&

htons(my_file.port) != tcph->th_dport &&

htons(my_file.port) != tcph->th_sport) {

return;

}

pkt->len = pcap_hdr->caplen;//ntohs(iph6->ip6_plen) + 40 + ETH_HLEN;

pkt->buf = malloc(pkt->len + ETHER_CRC_LEN);

memcpy(pkt->buf, data, pkt->len);

iph6 = (struct ip6_hdr *)(pkt->buf + ETH_HLEN);

}

flow->pkt_num ++;

trace->total_pkt_num ++;

if (my_file.ipversion == 4) {

if (iph->saddr == flow->sv4) {

if (my_file.device2_in_nat) {

iph->saddr = interface.sv4;

iph->daddr = interface.device2nat4;

} else {

iph->saddr = interface.sv4;

iph->daddr = interface.dv4;

}

pkt->interface = 1;

} else {

if (my_file.device1_in_nat) {

iph->daddr = interface.device1nat4;

iph->saddr = interface.dv4;

} else {

iph->daddr = interface.sv4;

iph->saddr = interface.dv4;

}

pkt->interface = 2;

}

} else {

if (!memcmp(&iph6->ip6_src, flow->sv6, 16)) {

if (my_file.device2_in_nat) {

memcpy(&iph6->ip6_src, interface.sv6, 16);

memcpy(&iph6->ip6_dst, interface.device2nat6, 16);

} else {

memcpy(&iph6->ip6_src, interface.sv6, 16);

memcpy(&iph6->ip6_dst, interface.dv6, 16);

}

pkt->interface = 1;

} else {

if (my_file.device1_in_nat) {

memcpy(&iph6->ip6_src, interface.device1nat6, 16);

memcpy(&iph6->ip6_dst, interface.sv6, 16);

} else {

memcpy(&iph6->ip6_src, interface.dv6, 16);

memcpy(&iph6->ip6_dst, interface.sv6, 16);

}

pkt->interface = 2;

}

}

if (my_file.ipversion == 4) {

ip_csum(iph);

if ((iph->frag_off & htons(0x1fff)) == 0) {

int offset = (iph->ihl << 2) + ETH_HLEN;

if (iph->protocol == IPPROTO_TCP) {

tcp_csum(iph, pkt->buf + offset);

} else if (iph->protocol == IPPROTO_UDP) {

udph = (struct udphdr *)(pkt->buf + offset);

if (udph->uh_sum != 0) {

udp_csum(iph, (uint8_t *)udph);

}

}

}

} else {

int offset = 40 + ETH_HLEN;

if (iph6->ip6_nxt == IPPROTO_TCP) {

tcp_csum6(iph6, pkt->buf + offset, pkt->id);

} else if (iph6->ip6_nxt == IPPROTO_UDP) {

udp_csum6(iph6, pkt->buf + offset, pkt->id);

}

}

/*

* Rewrite the mac addresses on the packet.

*/

ph = (struct ether_header *)pkt->buf;

if (pkt->interface == 1) {

ph->ether_shost[0] = interface.device1_mac[0];

ph->ether_shost[1] = interface.device1_mac[1];

ph->ether_shost[2] = interface.device1_mac[2];

ph->ether_shost[3] = interface.device1_mac[3];

ph->ether_shost[4] = interface.device1_mac[4];

ph->ether_shost[5] = interface.device1_mac[5];

ph->ether_dhost[0] = interface.fw_mac1[0];

ph->ether_dhost[1] = interface.fw_mac1[1];

ph->ether_dhost[2] = interface.fw_mac1[2];

ph->ether_dhost[3] = interface.fw_mac1[3];

ph->ether_dhost[4] = interface.fw_mac1[4];

ph->ether_dhost[5] = interface.fw_mac1[5];

} else {

ph->ether_dhost[0] = interface.fw_mac2[0];

ph->ether_dhost[1] = interface.fw_mac2[1];

ph->ether_dhost[2] = interface.fw_mac2[2];

ph->ether_dhost[3] = interface.fw_mac2[3];

ph->ether_dhost[4] = interface.fw_mac2[4];

ph->ether_dhost[5] = interface.fw_mac2[5];

ph->ether_shost[0] = interface.device2_mac[0];

ph->ether_shost[1] = interface.device2_mac[1];

ph->ether_shost[2] = interface.device2_mac[2];

ph->ether_shost[3] = interface.device2_mac[3];

ph->ether_shost[4] = interface.device2_mac[4];

ph->ether_shost[5] = interface.device2_mac[5];

}

/* Compute the FCS on the Ethernet Frame

* Some people say the hardare should do this, but it does not seem to.

* Also for packets > 1510, the WriteInterface dies with a message too long error

*/

/*

* This section actually calculates the FCS, but it's not currently

* working correctly, so I've commented it out. The CRC32 function

* needs to be verified.

*/

/*

if ( pkt->len <= 15 + ETH_HLEN ) {

uint32_t newFCS = CRC32( pkt->buf , pkt->len );

memcpy(pkt->buf + pkt->len , &newFCS , ETHER_CRC_LEN);

}

*/

}

可用版本:

linux下udp数据包接收工具,linux环境下数据包回放工具--pplayer分享相关推荐

  1. Linux离线安装NTP服务,内网环境下配置本地时间同步

    参考文章:Linux离线安装NTP服务,无外网环境下配置本地时间同步 | 航行学园 1.常用命令 rpm -qa | grep ntp #查询已安装的ntp版本信息等 rpm -e --nodeps ...

  2. 缺少nst linux.mbr文件,用EasyBCD2.0在Windows环境下引导Linux启动

    用EasyBCD2.0在Windows环境下引导Linux启动 以在Win7环境下用EasyBCD2.0.2引导Ubuntu启动为例(Ubuntu安装在Win7之前,倘若反了进不去Win7,可以用Wi ...

  3. linux 包管理工具dnf,CentOS8启用DNF包管理工具

    DNF包管理工具介绍 CentOS8启用了DNF作为系统软件包管理工具,Yum也不是被放弃,因为DNF应该说是Yum的一个更新的版本. DNF stands for Dandified yum. DN ...

  4. linux下ipv6地址如何ping,IPv6地址环境下如何使用ping、telnet命令

    IPv6地址环境下如何使用ping.telnet命令 日期:2020-08-12 10:46 浏览次数: 分类:知识库 来源:郑州冰川网络技术有限公 本文主要介绍IPV6通信时,IPv6地址的ping ...

  5. python捷豹_图像处理基本工具——Python 环境下的 Pillow( PIL )

    由于笔者近期的研究课题与图像后处理有关,需要通过图像处理工具对图像进行变换和处理,进而生成合适的训练图像数据.该系列文章即主要记录笔者在不同的环境下进行图像处理时常用的工具和库.在 Python 环境 ...

  6. tensorflow环境下的识别食物_在win10环境下进行tensorflow物体识别(ObjectDetection)训练...

    安装ObjectDetection,CPU和GPU都需要 解压module.rar放到C:\TFWS\models目录 地址:https://github.com/tensorflow/models ...

  7. iar环境下c语言编程,STM8在IAR环境下的C语言开发.doc

    STM8在IAR环境下的C语言开发 STM8单片机在IAR环境下的C语言开发 头文件搜索路径设置 在工程管理窗口按右键,选择option,打开选项设置窗口如下 选择C/C++ compiler选项,然 ...

  8. LINUX下UDP实现消息镜像通信,linux环境下基于udp socket简单聊天通信

    客户端代码:client.c /* * File: main.c * Author: guanyy * * Created on 20161202 * * 主要实现:客户端和服务端相互通信 */ #i ...

  9. [Linux实用工具]Ubuntu环境下SSH的安装及使用

    SSH分为客户端和服务端. 服务端是一个守护进程,一般是sshd进程,在后台运行并响应来自客户端的请求.提供了对远程请求的处理,一般包括公共密钥认证.密钥交换.对称密钥加密和非安全连接. 客户端一般是 ...

最新文章

  1. MongoDB 正则表达式
  2. python 相关性分析_数据分析---用Python进行相关性分析(兼谈假设检验)
  3. 解决Winform程序在不同分辨率系统下界面混乱问题
  4. cassandra入门
  5. Java中introduce方法_Java基础—继承
  6. wpf 修改label值_c# – 在WPF中绑定Setter属性的值
  7. 有关计算机程序的论文,有关计算机程序的论文范文.doc
  8. java powermockrunner_java – PowerMock从@RunWith(PowerMockRunner.class)注释中抛出异常
  9. django、tornado、flask对比
  10. github 出现无法连接成功问题终极详解
  11. 老男孩python作业_老男孩python学习之作业一购物小程序
  12. Windows 10 打印机驱动安装(以惠普M136 MFP为例)
  13. PNP与NPN的转换电路
  14. 【ROS入门21讲】订阅者Subscriber的编程使用
  15. Introduction to OOC Programming Language
  16. v-inline-date,类似携程,飞猪,带价格的时间选择
  17. 深度解析服务器科普知识
  18. 炒菜,我把厨房烧了!
  19. leetcode 1217. Play with Chips 解法 python
  20. 干货!如何建立数据标签体系

热门文章

  1. 《颠覆营销》读书笔记
  2. 有爱的存在,再远的距离也阻止不了
  3. 对接支付宝人脸识别和获取用户信息接口
  4. GLFW+Ubuntu20.04安装
  5. 当 IT 直男约女生去看电影
  6. 【人工智能】机器学习的持续交付 (CD4ML)
  7. Java并发编程的艺术
  8. 金字塔池化系列的理解SPP、ASPP
  9. Java基于JSP野生动物保护网
  10. [Swift]LeetCode741. 摘樱桃 | Cherry Pickup