100 lines
3.2 KiB
C
100 lines
3.2 KiB
C
#include <stdio.h>
|
||
#include <libnet.h>
|
||
|
||
int main(int argc, char const *argv[])
|
||
{
|
||
if (argc < 2)
|
||
{
|
||
printf("usage: %s <device>\n", argv[0]);
|
||
return -1;
|
||
}
|
||
|
||
// 1. 初始化libnet
|
||
char err_buf[LIBNET_ERRBUF_SIZE] = "";
|
||
libnet_t *net = libnet_init(LIBNET_RAW4, argv[1], err_buf);
|
||
if (net == NULL)
|
||
{
|
||
printf("libnet_init error: %s\n", err_buf);
|
||
return -2;
|
||
}
|
||
printf("libnet_init success\n");
|
||
|
||
// 2. 构建数据
|
||
// 2.1 UDP
|
||
u_char data_buf[64] = "";
|
||
fgets(data_buf, sizeof(data_buf), stdin);
|
||
data_buf[strlen(data_buf) - 1] = '\0';
|
||
int data_len = strlen(data_buf) + strlen(data_buf) % 2; // UDP数据包长度必须为偶数
|
||
|
||
// 2.1.2 构建UDP数据包
|
||
libnet_ptag_t udp_tag = 0;
|
||
udp_tag = libnet_build_udp(
|
||
8001, // 源端口
|
||
8000, // 目的端口
|
||
8 + data_len, // UDP数据包长度
|
||
0, // 校验和,0为自动计算
|
||
data_buf, // 数据
|
||
data_len, // 数据长度
|
||
net, // libnet句柄
|
||
0 // 0 表示构造新的报文,>0表示在已有报文基础上追加
|
||
);
|
||
if (udp_tag != -1)
|
||
{
|
||
printf("udp tag: %d\n", udp_tag);
|
||
}
|
||
|
||
// 2.2 ip 报
|
||
libnet_ptag_t ip_tag = libnet_build_ipv4(
|
||
20 + 8 + data_len, // IP数据包总长度
|
||
0, // tos
|
||
0, // id, 0表示自动计算
|
||
0, // 标志位
|
||
32, // TTL
|
||
17, // 上层协议号,17表示UDP
|
||
0, // 校验和,0表示自动计算
|
||
inet_addr("10.12.156.232"), // 源IP地址,网络序
|
||
inet_addr("10.12.156.178"), // 目的IP地址,网络序
|
||
NULL, // 负载数据,这里不需要
|
||
0, // 负载数据长度
|
||
net, // libnet句柄
|
||
0 // 协议标记,0表示构造新的报文, >0表示在已有报文基础上追加
|
||
); // 构造IP数据包,返回值是新生成的协议块标记
|
||
if (ip_tag != -1)
|
||
{
|
||
printf("ip tag: %d\n", ip_tag);
|
||
}
|
||
|
||
// 2.3 构建以太网数据包
|
||
u_char dst_mac[6] = {0x00, 0xd8, 0x61, 0x03, 0x45, 0x65}; // 目的MAC地址
|
||
u_char src_mac[6] = {0x00, 0x0c, 0x29, 0x4e, 0x4a, 0x4c}; // 源MAC地址
|
||
libnet_ptag_t eth_tag = libnet_build_ethernet(
|
||
dst_mac, // 目的MAC地址
|
||
src_mac, // 源MAC地址
|
||
0x0800, // 上层协议类型,0x0800表示IP
|
||
NULL, // 负载数据,这里不需要
|
||
0, // 负载数据长度
|
||
net, // libnet句柄
|
||
0 // 协议标记,0表示构造新的报文, >0表示在已有报文基础上追加
|
||
);
|
||
if (eth_tag != -1)
|
||
{
|
||
printf("eth tag: %d\n", eth_tag);
|
||
}
|
||
|
||
// 3. 发送数据
|
||
int send_len = libnet_write(net);
|
||
if (send_len == -1)
|
||
{
|
||
printf("libnet_write error: %s\n", libnet_geterror(net));
|
||
}
|
||
else
|
||
{
|
||
printf("libnet_write success, send bytes: %d\n", send_len);
|
||
}
|
||
|
||
// 释放资源
|
||
libnet_destroy(net);
|
||
|
||
return 0;
|
||
}
|