美文网首页
Libnet发送UDP

Libnet发送UDP

作者: 二进制人类 | 来源:发表于2022-09-23 10:13 被阅读0次

流程

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

相关API

#include <libnet.h>
/**
 * [libnet_init 数据包内存初始化]
 * @param  injection_type [
 *      构造类型
        LIBNET_LINK,链路层
        LIBNET_RAW4,网络接口层(网络层)
        LIBNET_LINK_ADV,链路层高级版本
        LIBNET_RAW4_ADV, 网络层高级版本
        ]
 * @param  device         [发送设备接口名称]
 * @param  err_buf        [返回错误消息]
 * @return                [成功返回数据包句柄,识别返回NULL]
 */
libnet_t *libnet_init(int injection_type, char *device, char *err_buf);
#include <libnet.h>
/**
 * [libnet_build_ethernet 构建以太网数据包]
 * @param  dst       [目的MAC]
 * @param  src       [源MAC]
 * @param  type      [报文类型]
 * @param  payload   [负载,需要发送的数据包]
 * @param  payload_s [负载长度,或为 0]
 * @param  l         [数据包的句柄]
 * @param  ptag      [协议标记,使用0]
 * @return           [数据包结构体]
 */
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);
#include <libnet.h>
/**
 * [libnet_build_ipv4 构建IP数据包]
 * @param  ip_len    [IP数据包长度,设置为20+8+msg_len    20IP头部长度 + 8udp头部长度+msg_len数据长度]
 * @param  tos       [服务类型]
 * @param  id        [标识]
 * @param  flag      [片偏移]
 * @param  ttl       [生存时间]
 * @param  prot      [协议类型]
 * @param  sum       [头部校验和,用户使用0占位,由libnet自动填充校验和的值]
 * @param  src       [源IP]
 * @param  dst       [目的IP]
 * @param  payload   [负载,需要发送的数据包]
 * @param  payload_s [负载长度,或为 0]
 * @param  l         [数据包的句柄]
 * @param  ptag      [协议标记,使用0]
 * @return           [数据包结构体]
 */
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);
#include <libnet.h>
/**
 * [libnet_build_udp 构建UDP数据包]
 * @param  sp        [源端口号]
 * @param  dp        [目的端口]
 * @param  len       [udp数据包长度(udp头长度+数据长度)]
 * @param  sum       [udp数据包校验和(使用者填充0占位,有libnet自动校验填充)]
 * @param  payload   [负载(需要发送的udp数据),可设置为 NULL]
 * @param  payload_s [负载长度,或为 0]
 * @param  l         [表示数据包的句柄]
 * @param  ptag      [协议标记,使用0]
 * @return           [数据包结构体]
 */
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);
#include <libnet.h>
/*发送数据包*/
int libnet_write(libnet_t * l);
#include <libnet.h>
/*释放数据包内存*/
void libnet_destroy(libnet_t *l);

实例

#include <stdio.h>
#include <libnet.h>

int main()
{
    int ret;
    libnet_t *mylibnet;
    char err_buf[512];
    libnet_ptag_t ptag;
    char data[] = "hello libnet";
    char send_msg[1024];
    char msg_len;
    char *src_ip = "10.7.181.31";
    char *dest_ip = "10.7.181.123";
    unsigned char src_mac[] = {0x00, 0x0c, 0x29, 0x84, 0x0e, 0x96};
    unsigned char dest_mac[] = {0x00, 0xe0, 0x4c, 0x7b, 0x59, 0x17};
    
    /* 初始化libnet句柄 */
    mylibnet = libnet_init(LIBNET_LINK_ADV, "ens33", err_buf);
    if (mylibnet == NULL) {
        fprintf(stderr, "libnet_init fail\n");
        return -1;
    }
    
    printf("libnet_init success\n");    
    
    /* 封装UDP数据包 */
    msg_len = sprintf(send_msg, "%s", data);
    ptag = libnet_build_udp(8888, 8080, 8+msg_len, 0, send_msg, msg_len, mylibnet, 0);
    if (ptag == -1) {
        fprintf(stderr, "libnet_build_udp fail\n");
        return -1;
    }
    
    /* 封装IPV4数据包 */
    ptag = libnet_build_ipv4(
        20+8+msg_len,           /* 20IP头部长度 + 8udp头部长度+msg_len数据长度 */
        0,0,0,                  /* 服务类型,标识,片偏移 */
        128,                    /* 生存时间 */
        17,                     /* 协议类型:17 = UDP报文 */
        0,                      /* 头部校验和 */
        inet_addr(src_ip),      /* 源IP */
        inet_addr(dest_ip),     /* 目的IP */
        NULL, 0,                /* 在IPV4中负载不能 设置 */
        mylibnet,
        0
    );
    if (ptag == -1) {
        fprintf(stderr, "libnet_build_ipv4 fail\n");
        return -1;
    }
    
    /* 封装以太网数据包 */
    ptag = libnet_build_ethernet((u_int8_t *)dest_mac, (u_int8_t *)src_mac, 0x0800, NULL, 0, mylibnet, 0);
    if (ptag == -1) {
        fprintf(stderr, "libnet_build_ethernet fail\n");
        return -1;
    }
    
    /* 发送数据包 */
    ret = libnet_write(mylibnet);
    if (ret == -1) {
        fprintf(stderr, "libnet_write fail\n");
        return -1;
    }
    /* 释放libnet数据包内存 */
    libnet_destroy(mylibnet);
}

相关文章

网友评论

      本文标题:Libnet发送UDP

      本文链接:https://www.haomeiwen.com/subject/qsmoortx.html