linux下libnet编程 亲自测试可用
linux下libnet编程 亲自测试可用
亲自测试 如果build包的时候 只要把类型改了 就能改成相应的协议。
0x0800 ip
0x0806 arp
0x86DD IPv6
0x86ee idmp了
至于ipv6的包的话 在那就不需要改了
只有协议号需要改
我最后安装的是libnet-1.1.4.tar.gz
可用编译的时候gcc -o libnet libnet.c -lnet
安装完了 /usr/include/libnet.h里面就有了
除了下面这个例子中一次一个数据包libnet也提供了多数据包内存初始化
int libnet_init_packet_arena(struct libnet_arena **arena,
u_short packet_num, u_short packet_size);
/************************************************************
补充1 ARP包的格式
一个ARP包是分为两个部分的,前面一个是物理帧头,后面一个才是ARP帧。
首先,物理帧头,它将存在于任何一个协议数据包的前面,我们称之为DLC Header,因为这个帧头是在数据链路层构造的,并且其主要内容为收发双方的物理地址,以便硬件设备识别。
DLC Header
字段 长度(Byte) 默认值 备注
接收方MAC 6 广播时,为ff-ff-ff-ff-ff-ff
发送方MAC 6
Ethertype 2 0x0806 0x0806是ARP帧的类型值

以上是需要我们填充的物理帧头的格式,我们可以看到需要我们填充的仅仅是发送端和接
收端的物理地址,接下来我们看一下ARP帧的格式.
ARP Frame
字段 长度(Byte) 默认值 备注
硬件类型 2 0x1 以太网类型值
上层协议类型 2 0x0800 上层协议为IP协议
MAC地址长度 1 0x6 以太网MAC地址长度为 6
IP地址长度 1 0x4 IP地址长度为 4
操作码 2 0x1表示ARP请求包,0x2表示应答包
发送方MAC 6
发送方IP 4
接收方MAC 6
接收方IP 4
填充数据 18


************************************************************
/
/************************************************************
文档:linux下libnet编程
作者:Alanx
Email:zhangsuozhu@tom.com
版本: 0.01
本文档Alanx所有,转载请注明!!!
本文源代码参考libnet例子代码及arpoison源代码
**************************************************************/
一、下载安装libnet
我下的是1.13RC01版的。很简单,下载下来解开.
./configure
make
make install
即可(注意,在root权根下安装)
二、编程
1、#include <libnet.h>把库导入进来!
2、关于IP的数据结构。
IP为32位无符号整型、可以用以下类型:
u_int32_t 或u_long
可以用 inet_addr("192.168.0.1")把字符型的指针或数组转换成IP地址。
3、关于MAC的数据结构
MAC的数据结构是6个8位的数组,每个数组中记录的一个十六进制的数据,共48位的硬件地址。
struct macaddr
{
u_char MAC[6]; /* 或u_int8_t MAC[6] */
};
4、初始化libnet,分配内存函数 libnet_init( )
char device[ ]="eth0";/*这是网卡的名子*/
char errbuf[LIBNET_ERRBUF_SIZE];//如果程序中出错。出错信息都保存在该数据中。
libnet_t *plibnet_app;
plibnet_app=libnet_init(LIBNET_LINK_ADV, device, errbuf);//第一个参数设定这个实列是在链路层工作,还是在IP层工作。
/*出错处理*/
if (NULL ==plibnet_app)
{
printf("libnet_init: error %s\n", errbuf);
exit(1);
}
/*出错处理*/
该函数返回一个libnet的实例指针,以后听数据包的构建及发送都要用到该实例指针。也许实例不准确,也可以说是句柄。随他怎么说吧。反证以是分配了内存。并提供给我们了一个指针。其它函数可以调用这个指针,向libnet_t这个数扰结构里写一些内存。
5、制造数据包
本着先高层后低层的顺序。比如ARP数据包。我们先构造ARP包。然后在构造ETHERNET的数据包。
这里我们以新建一个ARP数据包为例:
首先先调用:libnet_build_arp()该函数返回一个libnet_ptag_t类型的值。来表示是否建立成功。不成功返回-1。其实libnet_ptag_t的数据类型估计是整型啥的。可以不考虑。只要不是返回-1,就说明APR数据包构造成功了。
例如下:
libnet_ptag_t ptag;
ptag = libnet_build_arp(
1, /* hardware type */
0x0800, /* proto type */
6, /* hw addr size */
4, /* proto addr size */
ARPOP_REPLY, /* ARP OPCODE */
SrcMAC, /* source MAC addr */
(u_char *)&SrcIP, /* src proto addr */
DstMAC, /* dst MAC addr */
(u_char *)&DstIP, /* dst IP addr */
NULL, /* no payload */
0, /* payload length */
plibnet_app, /* libnet tag */
0); /* ptag see man */
/*出错处理*/
if (-1==ptag) /* 把-1写在前面是怕我们粗心的写成 ptag=-1 */
{
perror("libnet_build_arp");
exit(1);
}
/*出错处理*/
以上代码基本上只注意其中的几个参数就可以了:
ARPOP_REPLY 这个参数是个宏也可以是 ARP_REQUEST;表明是ARP查询还是应达。
SrcMAC 指向源MAC数组的指针
DesMAC 指向目地MAC数组的指针
SrcIP 指向源IP地址的指针
DstIP 指向目地IP地直的指针
plibnet_app 刚才我们初始化libnet返回的指针
接下来。我们构造这个ARP包的底层,也就是物理层的数据。一般是ethernet层的ethernet 头数据包。用函数libnet_build_ethernet( );
这个函数很简单同上。也返回一个 libnet_ptag_t的值。如果是-1,说明失败。
libnet_ptag_t eth_tag;
eth_tag = libnet_build_ethernet(
DstMAC, /* dst MAC addr */
SrcMAC, /* src MAC addr */
0x0806, /* ether packet type */
NULL, /* ptr to payload */
0, /* payload size */
plibnet_app,
0); /* ptr to packet memory */
/*出错处理*/
if (-1 == eth_tag)
{
perror("libnet_build_ethernet");
exit(1);
}
/*出错处理*/
同样只注意 DstMAC ,SrcMAC , plibnet_app三个数据就可以了。
6、发送数据包。一般用一个无限的循环 如:
int n;/*n==-1时没有发送成功*/
for(;;)
{
n= libnet_write(plibnet_app);
/*出错处理*/
if(-1==n)printf("lost packet\n");
/*出错处理*/
};
7、释放内存。
libnet_destroy(plibnet_app);
三、编译
gcc 源文件.c -o 目标文件 -lnet
四、回顾一下上面的知识。写一个小程序。(注意,这里没有错误检查,为的是让代码更短小)
#include <libnet.h>
int main()
{
char device[ ]="eth1";
u_int32_t srcip, desip;
u_char srcmac[6]={0x11,0x11,0x11,0x11,0x11,0x11};
u_char desmac[6]={0x22,0x22,0x22,0x22,0x22,0x22};
libnet_t *plibnet_app;
char errbuf[100];
plibnet_app=libnet_init(LIBNET_LINK_ADV, device, errbuf);
/********************************************************************************
下面填充要构造的数据包的内容
要源IP地址:192.168.18.10 MAC地址:11:11:11:11:11:11
目标IP地址:192.168.18.1 MAC地址:22:22:22:22:22:22
源IP向目地IP发送应答包。应答192.168.18.10的MAC地址为11:11:11:11:11:11
**********************************************************************************/
srcip=inet_addr("192.168.18.10");
desip=inet_addr("192.168.18.1");
/*************************** 以下开始构造ARP包 及ETHERNET包头 **************************************/
libnet_build_arp( ARPHRD_ETHER,//hardware addr
ETHERTYPE_IP,//protocol addr
6,//hardware addr size
4,//protocol addr size
ARPOP_REPLY,//operation type
(u_int8_t*)&srcmac,//sender hardware addr (u_int8_t point)
(u_int8_t *)&srcip,//sender protocol addr(u_int8_t point)
(u_int8_t*)&desmac,//target hardware addr(u_int8_t point)
(u_int8_t *)&desip,//target protocol addr(u_int8_t point)
NULL,//payload
0,//payload size
plibnet_app,//libnet handle
0/*libnet id*/);
libnet_build_ethernet( desmac,//des HW addr*
srcmac,//src HW addr*
0x0806,//ether packet type
NULL,//prt to payload
0,//payload size
plibnet_app,//libnet handle
0);//ptr toi packet memory
/********************************** 构造完成。开始发包 **************************************/
for(;;)
{
//libnet_adv_cull_packet(plibnet_app, &packet, &packet_size);
libnet_write(plibnet_app);
printf("Send ARP Packet\n");
sleep(1);
};
/***********************************结束********************************************/
libnet_destroy(plibnet_app);
return 0;
}
/***********************************UBUNTU7.10, libnet1.13RC01下调试通过*********************************************
gcc test.c -o test -lnet
./test
产生的数据,用Wireshark抓包得到如下结果
0000 22 22 22 22 22 22 11 11 11 11 11 11 08 06 00 01 """""".. ........
0010 08 00 06 04 00 02 11 11 11 11 11 11 c0 a8 12 0a ........ ........
0020 22 22 22 22 22 22 c0 a8 12 01 """""".. ..
************************************注意你的网卡一般是eht0。我的网卡名是eth1********************************************/
linux下libnet编程 亲自测试可用的更多相关文章
- linux 下 poll 编程
poll 与 select 很类似,都是对描述符进行遍历,查看是否有描述符就绪.如果有就返回就绪文件描述符的个数将.poll 函数如下: #include <poll.h> int pol ...
- kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 【转】
转自:http://blog.chinaunix.net/uid-26349264-id-4455634.html 目录 kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 ...
- Linux下socket编程基本知识
本文档主要讲解了Linux下socket编程的一些基本知识,主要包括套接字和字节序的概念,以及一些常用的结构体和函数. 本文是在网易云课堂学习过程中的记录,这个老师讲得很不错,推荐大家围观. Linu ...
- 推荐一个linux下的web压力测试工具神器webbench
推荐一个linux下的web压力测试工具神器webbench2014-04-30 09:35:29 来源: 评论:0 点击:880 用多了apache的ab工具之后你就会发现ab存在很多问题, ...
- Linux下Socket编程的端口问题( Bind error: Address already in use )
Linux下Socket编程的端口问题( Bind error: Address already in use ) 在进行linux网络编程时,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误 ...
- Linux 下IOport编程訪问
曾经写的一篇笔记.偶尔翻出来了,放在这里做个纪念 Linux 下IOport编程訪问 这里记录的方法是在用户态訪问IOport,不涉及驱动程序的编写. 首先要包括头文件 /usr/include/as ...
- linux下socket编程实例
linux下socket编程实例一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.s ...
- Linux 下shell 编程学习脚手架
linux body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-t ...
- 基于linux下的NIST数字测试包安装过程
基于linux下的NIST数字测试包安装过程 1. 首先解决windows文件不能粘贴到Ubuntu的问题 选择利用VMware Tools进行解决 打开虚拟机VMware Workstation,启 ...
随机推荐
- 搭建Windows IIS(Internet Information Server)服务器
1.找到 控制面板\程序 点击 “打开或关闭Windows功能” ,全部选上“Internet信息服务”,这里可能要等几分钟. 2.完成之后你打开C盘,在他的根目录下多出一个inetpub文件夹里面有 ...
- SpringMVC之DispatcherServlet类
一.DispatcherServlet是什么 DispatcherServlet是前置控制器,配置在web.xml文件中的.拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据 ...
- 常用CMD指令
快捷方式: dcomcnfg.exe 打开windows的组件服务. regedit 打开windows的注册表的界面,进行管理. services.msc 打开service面板 calc ...
- Cookie认证
Cookie认证 由于HTTP协议是无状态的,但对于认证来说,必然要通过一种机制来保存用户状态,而最常用,也最简单的就是Cookie了,它由浏览器自动保存并在发送请求时自动附加到请求头中.尽管在现代W ...
- 从I/O事件到阻塞、非阻塞、poll到epoll的理解过程
I/O事件 I/O事件 非阻塞I/O.在了解非阻塞I/O之前,需要先了解I/O事件 我们知道,内核有缓冲区.假设有两个进程A,B,进程B想读进程A写入的东西(即进程A做写操作,B做读操作).进程A ...
- SSIS控件使用
1.转换控件: 2.执行SQL任务,返回一个值后,判断全量,还是增量?
- Java函数的传参机制
一 最近的一个项目,里面各种返回void,参数用引用类型,那叫一个熟和多,但是也把我绕糊涂了. 我就打算好好理一理java的传参机制,整理一番 二 很多人一听Java的传参,那一定会脱口而出,java ...
- ruby 正则表达式 匹配所有符合规则的信息
假设一个字符串当中有很多符合规则的信息,下面的例子可以把所有匹配到的结果打印出来: message="afhadhffkdf414j9tr3j43i3433094jwoert223jwew1 ...
- JavaScirpt 的垃圾(garbage collection)回收机制
一.垃圾回收机制—GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存. 原理:垃圾收集器会定期(周期性 ...
- nginx只允许域名访问网址,禁止ip访问
修改nginx配置 文件 在server段里插入如下正则: if ( $host != 'www.baidu.com') { return 403; } 说明:如果访问讨还不是www.baidu.co ...