libnet网络编程资料 - 图文(3)

2019-08-31 22:19

端口列表链初始化:

int libnet_plist_chain_new(struct libnet_plist_chain **plist, char *token_list);

获取端口列表链的下一项(端口范围):

int libnet_plist_chain_next_pair(struct libnet_plist_chain *plist, u_short *bport, u_short *eport); 端口列表链输出显示:

int libnet_plist_chain_dump(struct libnet_plist_chain *plist); 获取端口列表链:

u_char *libnet_plist_chain_dump_string(struct libnet_plist_chain *plist);

端口列表链内存释放:

void libnet_plist_chain_free(struct libnet_plist_chain *plist);

libnet介绍与分析(上)

libnet

介绍与分析

作者:菩提

当前,基于socket的网络编程已成为当今不可替代的编程方法,它将网络通讯当作文件描述符进行处理,把对这个“网络文件”(即socket套接字)的操作抽象成一种类似于文件操作的方式进行。从实现细节上,这种工作方式根据TCP/IP的网络通讯模型,封装了一系列的实现,使得我们只需要使用一个指定的参数,就可以实现在基于所需协议的数据的发送和接收。

但是,如果我们对那些系统自动给我们做的工作感兴趣,希望与发送的数据作“面对面”的接触,libnet则会是一个不错的选择。

libnet是UNIX系统同台上网络安全工具开发的重要的库,它和libpcap、libnids一起,给网络安全工具的开发人员提供了一组丰富而且完全的武器,使之得以很方便地编写出结构化强、健壮性好、可移植性高等特点的程序。

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

libnet当前的版本是1.1.2,相对于1.0.*版本有比较大的变化。

全部源代码包括18,000 行代码,109个导出函数,其中包括67个建包函数。这使得它支持现有的TCP/IP族的所有协议。此外,它支持多平台,Windows,OS X,BSD,Linux, Solaris,HPUX都能使用。

下图是它支持的协议:

libnet库可以被划分为4个功能部分:内存管理、地址解析、包处理、以及其他一些支持函数。

★ 内存管理函数

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

libnet_t *libnet_init(int injection_type, char *device, char *err_buf);

资源释放:

void libnet_destroy(libnet_t *l);

★ 地址解析函数 地址解析:

char *libnet_addr2name4(u_int32_t in, u_int8_t use_name);

libnet_name2addr4(libnet_t *l, char *host_name, u_int8_t use_name); struct libnet_in6_addr libnet_name2addr6(libnet_t *l, char *host_name,

u_int8_t use_name);

void libnet_addr2name6_r(struct libnet_in6_addr addr, u_int8_t use_name,

char *host_name, int host_name_len);

获取接口设备IP地址:

u_int32_t libnet_get_ipaddr4(libnet_t *l);

struct libnet_in6_addr libnet_get_ipaddr6(libnet_t *l);

获取接口设备硬件地址:

struct libnet_ether_addr *libnet_get_hwaddr(libnet_t *l);

★ 数据包构造函数

(这一部分函数较多,都以libnet_build_*()的形式出现,在此略过) ★ 数据包发送函数

int libnet_write(libnet_t *l); ★ 相关的支持函数

随机数种子生成器:

int libnet_seed_prand(libnet_t *l); 获取随机数:

u_int32_t libnet_get_prand(int mod);

端口列表链初始化:

int libnet_plist_chain_new(libnet_t *l, libnet_plist_t **plist, char *token_list);

获取端口列表链的下一项(端口范围):

int libnet_plist_chain_next_pair(libnet_plist_t *plist, u_int16_t *bport,

u_int16_t *eport);

端口列表链输出显示:

int libnet_plist_chain_dump(libnet_plist_t *plist);

获取端口列表链:

char *libnet_plist_chain_dump_string(libnet_plist_t *plist);

端口列表链内存释放:

int libnet_plist_chain_free(libnet_plist_t *plist);

对它的使用也非常简单,只要你了解自己要做什么事情、应该把哪些参数放在什么位置。利用libnet函数库开发应用程序的基本步骤非常简单:

1、数据包内存初始化; 2、构造数据包; 3、发送数据; 4、释放资源;

例: libnet的发行包里提供了很多示例程序,其中/libnet/sample/tcp1.c如果省略掉一些参数的设置和错误处理,则程序简化为: #if (H***E_CONFIG_H)

#i nclude \ #endif

#i nclude \ #ifdef __WIN32__

#i nclude \ #endif int

main(int argc, char *argv[]) {

//…….

l = libnet_init(

LIBNET_LINK, /* injection type */ NULL, /* network interface */ errbuf); /* error buffer */ //……

t = libnet_build_tcp_options(

\\\000\ 20, l, 0);

//……

t = libnet_build_tcp(src_prt, dst_prt, 0x01010101, 0x02020202, TH_SYN, 32767, 0, 10,

LIBNET_TCP_H + 20 + payload_s, payload, payload_s, l, 0);

t = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H + 20 + payload_s, 0, 242, 0, 64,

IPPROTO_TCP, 0, src_ip, dst_ip, NULL, 0, l, 0);

t = libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, l, 0);

c = libnet_write(l); libnet_destroy(l);

return (EXIT_SUCCESS); bad:

libnet_destroy(l);

return (EXIT_FAILURE); }

#if defined(__WIN32__)

#i nclude <../include/win32/getopt.h> #i nclude #i nclude #endif /* __WIN32__ */ /* EOF */

libnet介绍与分析(下)

对libnet源码的分析 ★ 整体设计思想

对每个要发送的包,libnet维护一个libnet_t结构,这个结构是理解整个libnet的关键,也是libnet得以实现它强大功能的关键。让我们先从它入手,从整体到细节地揭开libnet的面纱。下面左图是libnet_t这个结构的示例。

其中的fd就是发送数据包将要用到的socket套接字,injection_type将会被设置成libnet_init()中的第一个参数,即你选择发送的方式,是基于link_layer的链路层数据包?还是基于IP层的raw数据包?后一种情况又分为IP4和IP6两种。protocol_blocks 和protocol_end都是指针,指向一个libnet自定义的

libnet_pblock_t结构,由此管理一个libnet_pblock_t的链表。而libnet_pblock_t则表述各个协议,维护各个协议给发送的数据包添加的数据块,它的具体选项下面再说。link_type表示链路层的类型,link_offset则指向链路层也就是最底层协议包头的偏移地址。aligner是为了维护最后的数据包的字对齐而设置的,字符串指针device则指向通讯所用的设备,比如eth0.state是一个结构,与ptag_state一起,记录包在建立过程中的一些信息。label是一个字符数组。每当有错误发生的时候,errbuf数组就被用来记录错误信息。全部的数据包长度和保存于total_size中。

从libnet_t已经大概可以看出libnet的设计思想了:程序员决定一些参数,并且通过函数调用中的参数把相关的数据交给libnet.libnet则在程序员每要求购建一个协议包头的时候,为其创建一个libnet_pblock_t的结构保存这些数据,并将该结构入链表。当所有的准备工作完成,程序员一声令下,libnet就将协议块链(由protocol_blocks开始,终于pblock_end)中的协议包头以及数据组合成一个合乎规格的包,通过硬件发送出去。如果任何一个步骤出了差错,程序员都可以从errbuf中获取出错信息。最后,libnet从程序员手中接过一个指令,进行所有的善后工作。

每种协议的包头将在前期被实现为一个libnet_pblock_t的结构。libnet为它所支持的协议都定义了相应的数据结构,例如TCP包头的定义:

struct libnet_tcp_hdr {

u_int16_t th_sport; /* source port */ u_int16_t th_dport; /* destination port */ u_int32_t th_seq; /* sequence number */


libnet网络编程资料 - 图文(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:亨格瑞管理会计英文第15版练习答案04

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: