首页 > 其他分享 >libnet使用方法

libnet使用方法

时间:2023-05-04 22:55:13浏览次数:52  
标签:libnet int16 ptag ip 方法 使用 NULL 数据包

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,int16,ptag,ip,方法,使用,NULL,数据包
From: https://www.cnblogs.com/full-stack-linux-new/p/17372798.html

相关文章

  • 用户故事与敏捷方法 二
    对一个项目来说,客户团队里包括一个或多个真实用户是极其重要的。遗憾的是,我们很难与实际用户一起工作。我们期望与尽可能多的用户接触,这些用户代表了产品的不同角度,当我们无法接触到他们时,我们就需要求助各种用户代理,他们不是用户,但在项目中扮演用户角色。用户的经理:不要得罪用户......
  • Shell的基本使用方法
    Shell是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。KenThompson的sh是第一种UnixShell,WindowsExplorer是一个典型的图......
  • c:forEach简单使用
    个人认为这就相当于一个for循环语句<c:forEachitems="001"var="002"varStatus="003"begin="004"end="005"step="006"></c:forEach>001:接收遍历的集合eg.{a,b,c,d}002:放刚从001取出的每一条信息,var就表示a,b,c,d003:表示4种状......
  • win10家庭版没有Hyper-v的解决方法
    pushd"%~dp0"dir/b%SystemRoot%\servicing\Packages\*Hyper-V*.mum>hyper-v.txtfor/f%%iin('findstr/i.hyper-v.txt2^>nul')dodism/online/norestart/add-package:"%SystemRoot%\servicing\Packages\%%i"delh......
  • 再谈USB存储设备的使用痕迹
    近来有小伙伴在看了我先前的文章-<如何检视USB存储设备的使用记录>,如下所示:https://www.cnblogs.com/pieces0310/p/15943567.html 仍然想要进一步知道如何具体操作,因此,我就再次进行说明好了~ 首先,关于你提到的问题,其实操作系统的机制本就不在为操作行为留下记录,说穿了......
  • Stata与Python的交互使用
    官方参考文档https://www.stata.com/python/api17/index.html不论是从Stata里调用python,还是从python里调用stata,都无法实现stata和python的数据互通。为了实现stata和Python的数据互通,stata官方提供了名为sfi(StataFunctionInterface)的包,可以在python中获得stata的数据。先......
  • 使用apidoc生成接口文档
    一、首先安装node.js1.下载Node.js官方Windows版程序:  https://nodejs.org/download/  从0.6.1开始,Node.js在Windows平台上提供了两种安装方式,一是.MSI安装文件,另外还有一个.EXE可执行文件。  我选择了.EXE文件。因为.MSI安装文件除了将node.exe复制到C:\ProgramFi......
  • Swift下Data处理全流程:从网络下载,数模转换,本地缓存到页面使用
    Swift下将网络返回json数据转换成struct假如网络请求返回的数据结构是一个深层嵌套的Json首先要通过key-value取出这个json中的数据源//将返回的json字符串转Dictoryletjson="""{"name":"jack","age":20,"description":"Astudent."......
  • 对于Object中一些方法的疑惑与理解
    getClass这是生成字节码文件对象的三种方式之一,由任意对象调用getClass(Object中定义的方法)可以返回该类的字节码文件对象,一般一般用于反射getName该方法是,Class类中定义的一个方法,用于返回字节码文件对象所表示的实体(类或者接口)的全类名2023.5.4对于向上转型和任何类型都可以......
  • 肯天脱模剂|持续使用Ultra Purge™,避免PET瓶胚生产中出现黑斑
    我们都知道,热塑性塑料行业需要准确、效率和一致。在肯天,我们通过开发螺杆清洗料和模具维护产品为热塑性塑料行业提供服务,并支持不同热塑性塑料工艺(如注射成型、挤出和滚塑成型)的客户,为其制定解决方案以克服生产难题。我们的产品组合能提升质量和生产力,同时尽可能地减少对环境的负面......