最近搬砖需要对libnet进行介绍在这里对知识进行汇总。

1libnet简介

在libnet出现以前,如果要构造数据包并发送到网络中,程序员要通过一些复杂的接口来处理。libnet的出现,为程序员提供了一个简单而易于使用的编程接口,可以帮助程序员方便地构造网络数据包,编写网络应用程序。

libnet是一个与libpcap类似的数据包注入器,可以用来编写有关网络测试、网络故障诊断和网络安全等方面的应用程序和工具。

许多网络工具 (如snort,Nmap)都是利用它来实现其部分功能。

libnet提供一系列的接口函数,实现和封装了数据包的构造和发送过程。利用它可以亲自构造从应用层到链路层的各层协议的数据包头,并将这些包头与有效数据有序地组合在一起发送出去。当然,它也是基于TCP/IP协议网络模型的。

全部源代码包括18,000行代码,109个导出函数,其中包括67个建包函数。这使得它支持现有的TCP/IP族的所有协议。

2libnet的特点

libnet是一个小型的接口函数库,主要用C语言写成,提供了低层网络数据报的构造、处理和发送功能。libnet的开发目的是建立一个简单统一的网络编程接口以屏蔽不同操作系统低层网络编程的差别,使得程序员将精力集中在解决关键问题上。

它具有以下特点:

(1)高层接口:libnet被用于提取低 层数据报转移的专用体系结构细节。

(2)低层数据报构建:libnet的一个主要特点就是它完全控制每个数据报的头 域。

(3)可移植性的接口:与具体的操作系统平台无关。libnet目前可以在Windows、Linux、OS、FreeBSD、Solaris等操作系统上运行,并且提供了统一的接口。

(4)数据包构造:libnet提供了一系列的TCP/IP数据报文的构造函数以方便用户使用。

(5)数据包的处理:libnet提供了一系列处理底层网络编程的辅助函数,利用这些辅助函数,帮助用户简化那些烦琐的事务性的编程工作。

(6)数据包发送:libnet允许用户在两种不同的数据包发送方法中选择。

(7)libnet支持TCP/IP协议族中的所有协议。

libnet函数库提供的接口函数包含 15 种数据包生成器和两种数据包发送器(IP 层和数据链路层)。

提供的接口函数包括:

1)内存管理(分配和释放)函数

2)地址解析函数

3)各种协议类型的数据包构造函数

4)数据包发送函数(IP层和链路层)

5)一些辅助函数,如产生随机数、错误报告、端口列表管理等。

利用libnet函数库开发应用程序的基本步骤:

1)数据包内存初始化

2)构造数据包

3)发送数据

4)释放资源

以发送 UDP 数据包为例,流程图如图

常用函数介绍

以下函数的使用需要包含头文件libnet.h

1、libnet_t *libnet_init(int injection_type, char *device, char *err_buf)

功能:

数据包内存初始化及环境建立

参数:

injection_type:构造的类型

LIBNET_LINK,链路层

LIBNET_RAW4,网络接口层(网络层)

LIBNET_LINK_ADV,链路层高级版本

LIBNET_RAW4_ADV,网络层高级版本

device:网络接口,如 "eth0",或IP地址,亦可为NULL (自动查询搜索)

err_buf:存放出错的信息

返回值:

成功:一个libnet *类型的指针,后面的操作都得使用这个指针

失败:NULL

该函数初始化libnet函数库,返回一个libnet_t类型的描述符,以备随后的构造数据包和发送数据包的函数中使用。

injection_type指明了发送数据包使用的 接口类型,如数据链路层或者原始套接字等。Device是一个网络设备名称的字符串,在linux下“eth0”等。如果函数错误,返回NULL,er_buf字符串中将携带有错误的原因。

2、void libnet_destroy(libnet_t *l);

功能:

释放资源

参数:

l:libnet_init() 返回的libnet *指针

返回值:

3、char* libnet_addr2name4(u_int32_t in, u_int8_t use_name)

功能:

将网络字节序转换成点分十进制数串

参数:

in:网络字节序的ip地址

use_name:

LIBNET_RESOLVE,对应主机名

LIBNET_DONT_RESOLVE,对应点分十进制IPv4地址

返回值:

成功:点分十进制ip地址

失败:NULL

4、u_int32_t libnet_name2addr4(libnet_t *l, char *host_name, u_int8_t use_name)

功能:

将点分十进制数串转换为网络字节序ip地址

参数:

l:libnet_init()返回的libnet *指针

host_name:

LIBNET_RESOLVE,  对应主机名

LIBNET_DONT_RESOLVE,对应点分十进制 IPv4 地址

返回值:

成功:网络字节序 ip 地址

失败:-1

5、struct libnet_ether_addr* libnet_get_hwaddr(libnet_t *l)

功能:

获取接口设备硬件地址

参数:

l:libnet_init()返回的libnet *指针

返回值:

成功:指向MAC地址的指针

失败:NULL

6、libnet_ptag_t libnet_build_udp(u_int16_t sp, u_int16_t dp,u_int16_t len, u_int16_t sum,u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)

功能:

构造udp数据包

参数:

sp:源端口号

dp:目的端口号

len:udp包总长度

sum:校验和设为0,libnet自动填充

payload:负载为给应用程序发送的文本内容,没有内容时可设置为 NULL

payload_s:负载长度,给应用程序发送文本内容的长度,或为0

l:libnet_init()返回的libnet *指针

ptag:协议标记,第一次组新的发送包时,这里写0,同一个应用程序,下一次再组包时,这个位置的值写此函数的返回值。

返回值:

成功:协议标记

失败:-1

7、libnet_ptag_t libnet_build_tcp(u_int16_t sp, u_int16_t dp, u_int32_t seq, u_int32_t ack, u_int8_t control, u_int16_t winu_int16_t sum, u_int16_t urg, u_int16_t len, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag );

功能:

构造 tcp 数据包

参数:

sp:源端口号

dp:目的端口号

seq:序号

ack:ack 标记

control:控制标记

win:窗口大小

sum:校验和,设为 0,libnet 自动填充

urg:紧急指针

len:tcp包长度

payload:负载,为给应用程序发送的文本内容,可设置为 NULL

payload_s:负载长度,或为 0

l:libnet_init() 返回的 libnet * 指针

ptag:协议标记,第一次组新的发送包时,这里写 0,同一个应用程序,下一次再组包时,这个位置的值写此函数的返回值。

返回值:

成功:协议标记

失败:-1

8、libnet_ptag_t libnet_build_ipv4( u_int16_t ip_len, u_int8_t tos, u_int16_t id, u_int16_t flag, u_int8_t ttl, u_int8_t prot, u_int16 sum, u_int32_t src, u_int32_t dst, u_int8_t *payload,u_int32_t payload_s,libnet_t *l, libnet_ptag_t ptag )

功能:

构造一个 IPv4 数据包

参数:

ip_len:ip 包总长

tos:服务类型

id:ip 标识

flag:片偏移

ttl:生存时间

prot:上层协议

sum:校验和,设为 0,libnet 自动填充

src:源ip地址

dst:目的ip地址

payload:负载,可设置为 NULL(这里通常写 NULL)

payload_s:负载长度,或为 0(这里通常写 0 )

l:libnet 句柄,libnet_init()返回的libnet * 指针

ptag:协议标记,第一次组新的发送包时,这里写 0,同一个应用程序,下一次再组包时,这个位置的值写此函数的返回值。

返回值:

成功:协议标记

失败:-1

9、libnet_ptag_t libnet_build_ethernet(u_int8_t*dst, u_int8_t *src, u_int16_ttype, u_int8_t*payload, u_int32_tpayload_s, libnet_t*l, libnet_ptag_t ptag )

功能:

构造一个以太网数据包

参数:

dst:目的mac

src:源mac

type:上层协议类型

payload:负载,即附带的数据,可设置为 NULL(这里通常写 NULL)

payload_s:负载长度,或为 0(这里通常写 0 )

l:libnet 句柄,libnet_init() 返回的 libnet * 指针

ptag:协议标记,第一次组新的发送包时,这里写0,同一个应用程序,下一次再组包时,这个位置的值写此函数的返回值。

返回值:

成功:协议标记

失败:-1

10、int libnet_write(libnet_t * l)

功能:

发送数据包

参数:

l:libnet 句柄,libnet_init()返回的 libnet * 指针

返回值:

成功:发送数据包的长度

失败:返回 -1

libnet的使用案例

1、在Ubuntu上安装libnet

安装命令:sudo apt-get install libnet-dev,图23-2

图23-2 libnet在linux中安装

2、按照图23-1编写发送UDP数据包的代码

#include <stdio.h> 

#include <stdlib.h> 

#include <string.h> 

#include <unistd.h> 

#include <libnet.h> 

 

int main(int argc, charchar *argv[]) 

{ 

    char send_msg[1000] = ""; 

    char err_buf[100] = ""; 

    libnet_t *lib_net = NULL; 

    int lens = 0; 

    libnet_ptag_t lib_t = 0; 

    unsigned char src_mac[6] = {0x00,0x0c,0x29,0x97,0xc7,0xc1};

//发送者网卡地址00:0c:29:97:c7:c1 

    unsigned char dst_mac[6] = {0x74,0x27,0xea,0xb5,0xff,0xd8};

//接收者网卡地址74-27-EA-B5-FF-D8 

    char *src_ip_str = "192.168.31.163"; //源主机IP地址 

    char *dst_ip_str = "192.168.31.248"; //目的主机IP地址 

    unsigned long src_ip,dst_ip = 0; 

 

    lens = sprintf(send_msg, "%s", "this is for the udp test"); 

 

    lib_net = libnet_init(LIBNET_LINK_ADV, NULL, err_buf);    //初始化 

    if(NULL == lib_net) 

    { 

        perror("libnet_init"); 

        exit(-1); 

    } 

 

    src_ip = libnet_name2addr4(lib_net,src_ip_str,LIBNET_RESOLVE); 

//将字符串类型的ip转换为顺序网络字节流 

    dst_ip = libnet_name2addr4(lib_net,dst_ip_str,LIBNET_RESOLVE); 

 

    lib_t=libnet_build_udp(  //构造udp数据包

8080, 8080, 8+lens, 0, send_msg, lens, lib_net, 0); 

 

    lib_t = libnet_build_ipv4(  //构造ip数据包 

20+8+lens,0,500,0,10,17, 0, src_ip,dst_ip,NULL,0,lib_net, 0); 

 

    lib_t = libnet_build_ethernet(  //构造以太网数据包 

     (u_int8_t*)dst_mac,(u_int8_t *)src_mac,0x800,NULL,0,lib_net,0); 

    int res = 0; 

    res = libnet_write(lib_net);    //发送数据包 

    if(-1 == res) 

    { 

        perror("libnet_write"); 

        exit(-1); 

    } 

 

    libnet_destroy(lib_net);    //销毁资源 

     

    printf("----ok-----\n"); 

    return 0; 

 } 

编译代码时,注意需要加上 -lnet,输入命令编译源代码,生成demo可执行文件,运行可执行文件,如图23-3

图23-3 libnet在linux中安装

3、抓包分析

利用wireshark进行抓包如图23-4

23-4 libnet的抓包结果

可以看出成功的用libnet构造了一个UDP的数据包。

libnet的使用详解的更多相关文章

  1. 基于CentOS6.5或Ubuntu14.04下Suricata里搭配安装 ELK (elasticsearch, logstash, kibana)(图文详解)

    前期博客 基于CentOS6.5下Suricata(一款高性能的网络IDS.IPS和网络安全监控引擎)的搭建(图文详解)(博主推荐) 基于Ubuntu14.04下Suricata(一款高性能的网络ID ...

  2. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  3. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  4. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

  5. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  6. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  7. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  8. Git初探--笔记整理和Git命令详解

    几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...

  9. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

随机推荐

  1. DeFi热下的冷思考 NGK以更深层次的方式参与DeFi建设

    独具慧眼,深度挖掘DeFi潜力项目 作为早期DeFi的探索者和推动者,NGK在此轮热潮席卷市场前就已经开始构建自己的DeFi生态,独具慧眼的NGK上线了Baccarat流动性挖矿项目,完成了首个由平台 ...

  2. 大小厂必问Java后端面试题(含答案)

    你好,我是yes. 这个系列的文章不会是背诵版,不是那种贴上标准答案,到时候照着答就行的面试题汇总. 我会用大白话尽量用解释性.理解性的语言来回答,但是肯定没有比平时通过一篇文章来讲解清晰,不过我尽量 ...

  3. pytorch resnet实现

    官方github上已经有了pytorch基础模型的实现,链接 但是其中一些模型,尤其是resnet,都是用函数生成的各个层,自己看起来是真的难受! 所以自己按照caffe的样子,写一个pytorch的 ...

  4. MarkDown编辑器基础使用教程

    教程原创链接 MarkDown 段落和换行 一个 Markdown 段落是由一个或多个连续的文本行组成,它的前后要有一个以上的空行(空行的定义是显示上看起来像是空的,便会被视为空行.比方说,若某一行只 ...

  5. js实现复制粘贴

    项目中经常会遇到点击按钮复制订单号.订单id等内容到粘贴板中的需求.可是通常我们都是用Ctrl + c或右击复制的,别操心,js也是有复制命令的,那就是document.execCommand('co ...

  6. WPF 解决内置谷歌浏览器(Cef.ChromiumWebBrowser)在触摸屏无法进行滚动的问题

    1.问题描述: 最近在WPF的项目中,需要在控件中嵌套可以浏览特定网页的内容,所以使用了 Cef.ChromiumWebBrowser来解决问题.在执行项目的过程中,主要碰到的问题有: 1.1 当把项 ...

  7. mui调用本地相册调用相机上传照片

    调用mui的常用库和jquery html部分: <header class="mui-bar mui-bar-nav"> <a class="mui- ...

  8. Django模型层2

    目录 一.聚合查询 聚合函数 二.分组查询 利用group by进行分组查询 三.F与Q查询 1. F类 2. Q类 四.orm字段及参数 五.自定义char字段 六.orm中的事务操作 1. 什么是 ...

  9. java list集合遍历时删除元素

    转: java list集合遍历时删除元素 大家可能都遇到过,在vector或arraylist的迭代遍历过程中同时进行修改,会抛出异常java.util.ConcurrentModification ...

  10. [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)

    单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...