• 2006-04-26

    libnet介绍与分析(上)

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://wolfkiller.blogbus.com/logs/2360106.html

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

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

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

    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"

    #endif

    #i nclude "libnet_test.h"

    #ifdef __WIN32__

    #i nclude "../include/win32/getopt.h"

    #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(

    "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\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 <winsock2.h>

    #i nclude <ws2tcpip.h>

    #endif  /* __WIN32__ */

    /* EOF */

     


    收藏到:Del.icio.us




    引用地址: