libnet网络编程资料.doc_第1页
libnet网络编程资料.doc_第2页
libnet网络编程资料.doc_第3页
libnet网络编程资料.doc_第4页
libnet网络编程资料.doc_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于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)include ./include/config.h#endifinclude libnet_test.h#ifdef _WIN32_include ./include/win32/getopt.h#endifintmain(int argc, char *argv) /. l = libnet_init( LIBNET_LINK, /* injection type */ NULL, /* network interface */ errbuf); /* error buffer */ / t = libnet_build_tcp_options(003003012001002004001011010012077077077077000000000000000000, 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_)include include include #endif /* _WIN32_ */* EOF */libnetlibnet是一个小型的接口函数库,主要用C语言写成,提供了低层网络数据包的构造、处理和发送功能。libnet的开发目的是:建立一个简单统一的网络编程接口以屏蔽不同操作系统底层网络编程的差别,使得程序员将精力集中在解决关键问题上。目 录1libnet2接口函数及其功能1. 2.1 内存管理函数 2. 2.2 地址解析函数 3. 2.3 数据包构造函数 4. 2.4 数据包发送函数 5. 2.5 相关的支持函数1libnet它的主要特点是:高层接口:libnet主要用C语言写成可移植性:libnet目前可以在Linux、FreeBSD、Solaris、WindowsNT等操作系统上运行,并且提供了统一的接口数据包构造:libnet提供了一系列的TCP/IP数据报文的构造函数以方便用户使用数据包的处理:libnet提供了一系列的辅助函数,利用这些辅助函数,帮助用户简化那些烦琐的事务性的编程工作数据包发送:libnet允许用户在两种不同的数据包发送方法中选择。另外libnet允许程序获得对数据包的绝对的控制,其中一些是传统的网络程序接口所不提供的。这也是libnet的魅力之一。libnet支持TCP/IP协议族中的多种协议,比如其上一个版本libnet1.0支持了10种协议,一些新的协议,比如对IPV6的支持还在开发之中。libnet目前最新的版本是1.1.2.1版本,在该版本中,作者将这些函数做了进一步的封装,用户的使用步骤也得到了进一步的简化。内存的初始化、管理、释放等以及校验和的计算等函数,在默认情况下,都无须用户直接干预,使得libnet的使用更为方便。作者还提供了基于老版本的应用程序移植到新版本上的方法指导。-libnet库的1.0.0版本,共约7600行C源代码,33个源程序文件,12个C头文件,50余个自定义函数,提供的接口函数包含15种数据包生成器和两种数据包发送器(IP层和数据链路层)。目前只支持IPv4,不支持IPv6。已经过测试的系统平台包括:* OpenBSD 2.6snap, 2.5, 2.4, 2.3, 2.2 (i386)* FreeBSD 4.0-STABLE, 3.3-STABLE, 3.2-RELEASE, 3.1-CURRENT, 3.0, 2.2 (i386)* NetBSD 1.3.2 (i386)* BSD/OS 3.x (i386)* BSDi 3.0 (i386)* Linux 2.2.x, 2.0.3x, 2.1.124 (i386, alpha) (libc: 2.4.x, glibc: 2.0.x)* Solaris 7 (SPARC, gcc 2.7.213, 2.8.2), 2.6 (SPARC, gcc 2.8.2),2.5.x (SPARC, gcc 2.7.213)* IRIX 6.2* MacOS 5.3rhapsody (powerpc)libnet提供的接口函数按其作用可分为四类:* 内存管理(分配和释放)函数* 地址解析函数* 数据包构造函数* 数据包发送函数2接口函数及其功能以下分别列出这些接口函数及其功能(其参数含义简单易懂,不再解释):内存管理函数单数据包内存初始化:int libnet_init_packet(u_short packet_size, u_char *buf);单数据包内存释放:void libnet_destroy_packet(u_char *buf);多数据包内存初始化:int libnet_init_packet_arena(struct libnet_arena *arena,u_short packet_num, u_short packet_size);访问多数据包内存中的下一个数据包:u_char *libnet_next_packet_from_arena(struct libnet_arena *arena,u_short packet_size);多数据包内存释放:void libnet_destroy_packet_arena(struct libnet_arena *arena);地址解析函数解析主机名:u_char *libnet_host_lookup(u_long ip, u_short use_name);解析主机名(可重入函数):void libnet_host_lookup_r(u_long ip, u_short use_name, u_char *buf);域名解析:u_long libnet_name_resolve(u_char *ip, u_short use_name);获取接口设备IP地址:u_long libnet_get_ipaddr(struct libnet_link_int *l,const u_char *device, const u_char *ebuf);获取接口设备硬件地址:struct ether_addr *libnet_get_hwaddr(struct libnet_link_int *l,const u_char *device,const u_char *ebuf);数据包构造函数ARP协议数据包:int libnet_build_arp(u_short hrdw, u_short prot, u_short h_len,u_short p_len, u_short op, u_char *s_ha,u_char *s_pa, u_char *t_ha, u_char *t_pa,const u_char *payload, int payload_len,u_char *packet_buf);DNS协议数据包:int libnet_build_dns(u_short id, u_short flags, u_short num_q,u_short num_answ_rr, u_short num_auth_rr,u_short num_add_rr, const u_char * payload,int payload_len, u_char *packet_buf);以太网协议数据包:int libnet_build_ethernet(u_char *daddr, u_char *saddr, u_short id,const u_char *payload, int payload_len,u_char *packet_buf);ICMP协议数据包(ICMP_ECHO / ICMP_ECHOREPLY):int libnet_build_icmp_echo(u_char type, u_char code, u_short id,u_short seq, const u_char *payload,int payload_len, u_char *packet_buf);ICMP协议数据包(ICMP_MASKREQ / ICMP_MASKREPLY):int libnet_build_icmp_mask(u_char type, u_char code, u_short id,u_short seq, u_long mask,const u_char *payload, int payload_len,u_char *packet_buf);ICMP协议数据包(ICMP_UNREACH):int libnet_build_icmp_unreach(u_char type, u_char code,u_short orig_len, u_char orig_tos,u_short orig_id, u_short orig_frag,u_char orig_ttl, u_char orig_prot,u_long orig_saddr, u_long orig_daddr,const u_char *payload, int payload_len,u_char *packet_buf);ICMP协议数据包(ICMP_TIMEXCEED):int libnet_build_icmp_timeexceed(u_char type, u_char code,u_short orig_len, u_char orig_tos,u_short orig_id, u_short orig_frag,u_char orig_ttl, u_char orig_prot,u_long orig_saddr, u_long orig_daddr,const u_char *payload, int payload_len,u_char *packet_buf);ICMP协议数据包(ICMP_REDIRECT):int libnet_build_icmp_redirect(u_char type, u_char code, u_long gateway,u_short orig_len, u_char orig_tos,u_short orig_id, u_short orig_frag,u_char orig_ttl, u_char orig_prot,u_long orig_saddr, u_long orig_daddr,const u_char *payload, int payload_len,u_char *packet_buf);ICMP协议数据包(ICMP_TSTAMP / ICMP_TSTAMPREPLY):int libnet_build_icmp_timestamp(u_char type, u_char code, u_short id,u_short seq, n_time otime, n_time rtime,n_time ttime, const u_char *payload,int payload_len, u_char *packet_buf);IGMP协议数据包:int libnet_build_igmp(u_char type, u_char code, u_long ip,const u_char *payload, int payload_len,u_char *packet_buf);IP协议数据包:int libnet_build_ip(u_short len, u_char tos, u_short ip_id, u_short frag,u_char ttl, u_char protocol, u_long saddr,u_long daddr, const u_char *payload, int payload_len,u_char *packet_buf);OSPF路由协议数据包:int libnet_build_ospf(u_short len, u_char type, u_long router_id,u_long area_id, u_short auth_type,const char *payload, int payload_s, u_char *buf);OSPF路由协议数据包(Hello):int libnet_build_ospf_hello(u_long netmask, u_short interval,u_char options, u_char priority,u_int dead_interval, u_long des_router,u_long backup, u_long neighbor,const char *payload, int payload_s,u_char *buf);OSPF路由协议数据包(DataBase Description (DBD):int libnet_build_ospf_dbd(u_short len, u_char options, u_char type,u_int sequence_num, const char *payload,int payload_s, u_char *buf);OSPF路由协议数据包(Link State Request (LSR):int libnet_build_ospf_lsr(u_int type, u_int ls_id, u_long adv_router,const char *payload, int payload_s,u_char *buf);OSPF路由协议数据包(Link State Update (LSU):int libnet_build_ospf_lsu(u_int num, const char *payload,int payload_s, u_char *buf);OSPF路由协议数据包(Link State Acknowledgement (LSA):int libnet_build_ospf_lsa(u_short age, u_char options, u_char type,u_int ls_id, u_long adv_router,u_int sequence_num, u_short len,const char *payload, int payload_s,u_char *buf);OSPF路由协议数据包(OSPF Link Sate NetworkLink State Router):int libnet_build_ospf_lsa_net(u_long netmask, u_int router_id,const char *payload, int payload_s,u_char *buf);OSPF路由协议数据包(Link State Router):int libnet_build_ospf_lsa_rtr(u_short flags, u_short num, u_int id,u_int data, u_char type, u_char tos,u_short metric, const char *payload,int payload_s, u_char *buf);OSPF路由协议数据包(Link State Summary):int libnet_build_ospf_lsa_sum(u_long netmask, u_int metric, u_int tos,const char *payload, int payload_s,u_char *buf);OSPF路由协议数据包(Link State AS External):int libnet_build_ospf_lsa_as(u_long netmask, u_int metric,u_long fwd_addr, u_int tag,const char *payload, int payload_s,u_char *buf);RIP路由协议数据包:int libnet_build_rip(u_char cmd, u_char ver, u_short domain,u_short addr_fam, u_short route_tag, u_long ip,u_long mask, u_long next_hop, u_long metric,const u_char *payload, int payload_len,u_char *packet_buf);TCP协议数据包:int libnet_build_tcp(u_short th_sport, u_short th_dport, u_long th_seq,u_long th_ack, u_char th_flags, u_short th_win,u_short th_urg, const u_char *payload,int payload_len, u_char *packet_buf);UDP协议数据包:int libnet_build_udp(u_short sport, u_short dport, const u_char *payload,int payload_len, u_char *packet_buf);IP协议数据包选项:int libnet_insert_ipo(struct ipoption *opt, u_char opt_len,u_char *packet_buf);TCP协议数据包选项:int libnet_insert_tcpo(struct tcpoption *opt, u_char opt_len,u_char *packet_buf);数据包发送函数打开raw socket:int libnet_open_raw_sock(int protocol);关闭raw socket:int libnet_close_raw_sock(int socket);选择接口设备:int libnet_select_device(struct sockaddr_in *sin,u_char *device, u_char *ebuf);打开链路层接口设备:struct libnet_link_int *libnet_open_link_interface(char *device,char *ebuf);关闭链路层接口设备:int libnet_close_link_interface(struct libnet_link_int *l);发送IP数据包:int libnet_write_ip(int socket, u_char *packet, int packet_size);发送链路层数据包:int libnet_write_link_layer(struct libnet_link_int *l,const u_char *device, u_char *packet,int packet_size);检验和计算:int libnet_do_checksum(u_char *packet, int protocol, int packet_size);相关的支持函数随机数种子生成器:int libnet_seed_prand();获取随机数:u_long libnet_get_prand(int modulus);16进制数据输出:void libnet_hex_dump(u_char * buf, int len, int swap, FILE *stream);端口列表链初始化: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 ./include/config.h#endifi nclude libnet_test.h#ifdef _WIN32_i nclude ./include/win32/getopt.h#endifintmain(int argc, char *argv)/.l = libnet_init(LIBNET_LINK,/* injection type */NULL,/* network interface */errbuf);/* error buffer */t = libnet_build_tcp_options(003003012001002004001011010012077077077077000000000000000000,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 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两种

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论