本文用于记录libnet 1.1核心功能及常用函数,主要内容来源于Libnet 1.1 tutorial(https://repolinux.wordpress.com/2011/09/18/libnet-1-1-tutorial/)和libnet_functions.h。
1、libnet如何工作:
(1)通过libnet_init()函数进行初始化,建立libnet context;
(2)从高层到低层建立报头。例如,建立UDP数据包时,调用函数的顺序如下:libnet_build_udp(), libnet_build_ipv4(),
libnet_build_ethernet();
(3)调用libnet_write()写入数据包,发送;
(4)准备发送新的数据包,一般而言,有以下两种方式:
(4.1)调用libnet_clear_packet()清除之前发送的数据包,回到第(2)步;
(4.2)接着上次发送的数据包继续发送:即回到第(2)步,并使用相同函数更新数据包,但是现在所使用的数据包tag是上次发送数据包后所返回的tag;
(5)完成所有数据包发送工作,调用libnet_destroy()清除libnet context,退出。
2、libnet中的主要函数:
(1)初始化及注销
// libnet context初始化,injection_type包括(LIBNET_LINK, LIBNET_LINK_ADV, LIBNET_RAW4, LIBNET_RAW4_ADV, LIBNET_RAW6, LIBNET_RAW6_ADV)
libnet_t *libnet_init(int injection_type, const char *device, char *err_buf);
// 注销libnet context
void libnet_destroy(libnet_t *l);
// 清除上次发送的封包
void libnet_clear_packet(libnet_t *l);
(2)生成随机数
// 通常用于为第一个封包生成随机的ID number
int libnet_seed_prand(libnet_t *l);
uint32_t libnet_get_prand(int mod);
(3)地址格式转换
// ip地址有两种表示格式,字符串或数字,以下函数用于对两种表示格式进行相互转换,其中use_name表示LIBNET_RESOLVE或LIBNET_DONT_RESOLVE
char * libnet_addr2name4(uint32_t in, uint8_t use_name);
uint32_t libnet_name2addr4(libnet_t *l, char *host_name, uint8_t use_name);
struct libnet_in6_addr libnet_name2addr6(libnet_t *l, const char *host_name, uint8_t use_name);
void libnet_addr2name6_r(struct libnet_in6_addr addr, uint8_t use_name, char *host_name, int host_name_len);
在ipv6的地址表示中,struct libnet_in6_addr的定义为:
/* * IPv6 address */ struct libnet_in6_addr { union { uint8_t __u6_addr8[16]; uint16_t __u6_addr16[8]; uint32_t __u6_addr32[4]; } __u6_addr; /* 128-bit IP6 address */ };
(4)创建、回收端口列表
// 创建、回收端口列表,plist表示创建或回收的端口列表,token_list表示端口列表原语。成功返回1,失败返回-1
int libnet_plist_chain_new(libnet_t *l, libnet_plist_t **plist, char *token_list);
int libnet_plist_chain_free(libnet_plist_t *plist);
(5)创建协议的报头
// 创建各层协议的报头,从链路层到传输层。参数:type-上一层协议;payload-有效载荷;payload_s-有效载荷的长度;ptag-发送上一个数据包后返回的tag,初始时是0
// 链路层协议
libnet_ptag_t libnet_build_ethernet(const uint8_t *dst, const uint8_t *src, uint16_t type, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_autobuild_ethernet(const uint8_t *dst, uint16_t type, libnet_t *l);
// ARP协议
libnet_ptag_t libnet_build_arp(uint16_t hrd, uint16_t pro, uint8_t hln, uint8_t pln, uint16_t op, const uint8_t *sha, const uint8_t *spa, const uint8_t *tha, const uint8_t *tpa,
const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_autobuild_arp(uint16_t op, const uint8_t *sha, const uint8_t *spa, const uint8_t *tha, uint8_t *tpa, libnet_t *l);
// 网络层(IP)
libnet_ptag_t libnet_build_ipv4(uint16_t ip_len, uint8_t tos, uint16_t id, uint16_t frag, uint8_t ttl, uint8_t prot, uint16_t sum, uint32_t src, uint32_t dst,
const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_build_ipv4_options(const uint8_t *options, uint32_t options_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_autobuild_ipv4(uint16_t len, uint8_t prot, uint32_t dst, libnet_t *l);
libnet_ptag_t libnet_build_ipv6(uint8_t tc, uint32_t fl, uint16_t len, uint8_t nh, uint8_t hl, struct libnet_in6_addr src, struct libnet_in6_addr dst, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_autobuild_ipv6(uint16_t len, uint8_t nh, struct libnet_in6_addr dst, libnet_t *l, libnet_ptag_t ptag);
等等
// 传输层
// TCP
libnet_ptag_t libnet_build_tcp(uint16_t sp, uint16_t dp, uint32_t seq, uint32_t ack, uint8_t control, uint16_t win, uint16_t sum, uint16_t urg, uint16_t len, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_build_tcp_options(const uint8_t *options, uint32_t options_s, libnet_t *l, libnet_ptag_t ptag);
// UDP
libnet_ptag_t libnet_build_udp(uint16_t sp, uint16_t dp, uint16_t len, uint16_t sum, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
// ICMP
libnet_ptag_t libnet_build_icmpv4_echo(uint8_t type, uint8_t code, uint16_t sum, uint16_t id, uint16_t seq, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_build_icmpv4_mask(uint8_t type, uint8_t code, uint16_t sum, uint16_t id, uint16_t seq, uint32_t mask, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_build_icmpv4_unreach(uint8_t type, uint8_t code, uint16_t sum, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_build_icmpv4_redirect(uint8_t type, uint8_t code, uint16_t sum, uint32_t gateway, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
libnet_ptag_t libnet_build_icmpv6_echo(uint8_t type, uint8_t code, uint16_t sum, uint16_t id, uint16_t seq, uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag);
等等
(6)获取本机的ip、ethernet地址
uint32_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);
uint8_t * libnet_hex_aton(const char *s, int *len);
(7)向网络中写入数据
// 成功返回写入的字节数,失败返回-1
int libnet_write(libnet_t *l);
(8)Advanced模式
// 截取数据包或报头
int libnet_adv_cull_packet(libnet_t *l, uint8_t **packet, uint32_t *packet_s);
int libnet_adv_cull_header(libnet_t *l, libnet_ptag_t ptag, uint8_t **header, uint32_t *header_s);
(9)错误处理函数
// 返回error string
char * libnet_geterror(libnet_t *l);

这篇博客详细介绍了libnet 1.1库的工作流程和主要函数,包括libnet_init()初始化、报头构建、libnet_write()发送数据包、libnet_clear_packet()清除数据包等。还列举了如libnet_seed_prand()生成随机数、libnet_addr2name4()地址转换、libnet_build_ethernet()创建以太网报头等关键函数的使用。
648

被折叠的 条评论
为什么被折叠?



