2012-11-02 86 views
1

我想使用Libnet11功能:Libnet11建立IPv6数据包手动

int libnet_write_raw_ipv6 (libnet_t *l, u_int8_t *packet, u_int32_t size) 

对网络层注入IPv6数据包。 我用Wireshark创建了IPv6数据包并将其捕获到 。 Wireshark的报道: 畸形报文(Wireshark的说,在IPv6的未来 头值是错误的,有效载荷 大小在我看来是太大了)

我希望有人可以帮助我最少的代码示例, 表现如何使用libnet11(libnet_write_raw_ipv6())手动构建IPv6数据包(使用ICMPv6 扩展标头)。

我假设最少的代码可能是这样的:

packet_len = 40 + 16; // 40B ~ IPv6 packet, 16B ~ ICMPv6 header 
u_char *buf = NULL; 

struct ip6_hdr *ip6 = NULL; 
struct icmp6_hdr *icmp6 = NULL; 

l = libnet_init(); 
if ((buf = malloc(packet_len)) == NULL) { 
    // error 
} 

// create IPv6 header 
ip6 = (struct ip6_hdr *) buf; 
ip6->ip6_flow = 0; 
ip6->ip6_vfc = 6 << 4; 
ip6->ip6_plen = 16;    // ICMPv6 packet size 
ip6->ip6_nxt = IPPROTO_ICMPV6; // 0x3a 
ip6->ip6_hlim = 64; 
memcpy(&(ip6->ip6_src), &src_addr, sizeof(struct in6_addr)); 
memcpy(&(ip6->ip6_dst), &dst_addr, sizeof(struct in6_addr)); 

// create ICMPv6 header 
icmp6 = (struct icmp6_hdr *) (buf + 40); // 40B ~ IPv6 packet size 
icmp6->icmp6_type = ICMP6_ECHO_REQUEST; 
icmp6->icmp6_code = 0; 
icmp6->icmp6_cksum= 0; 
icmp6->icmp6_data32[0] = 0; 

libnet_do_checksum(l, (u_int8_t *)buf, IPPROTO_ICMPV6, packet_len); 

written = libnet_write_raw_ipv6(l, buf, packet_len); 
if (written != packet_len) 
    perror("Failed to send packet"); 

libnet_destroy(l); 
free(buf); 

我试图找到代码示例,但没有成功。 预先感谢您。

马丁

+0

什么Wireshark的显示下一个标题?您可能需要调用htnos()来翻转字节顺序,如果它以0x3A00而不是0x003A出现。 – PherricOxide

回答

0

如果您使用C++,那么我建议你libtins,数据包制作一个嗅探库。这个简短的代码片段正是你想要的:

#include <tins/tins.h> 

using namespace Tins; 

void test(const IPv6Address &dst, const IPv6Address &src) { 
    PacketSender sender; 
    IPv6 ipv6 = IPv6(dst, src)/ICMPv6(); 
    ipv6.hop_limit(64); 
    sender.send(ipv6); 
} 

int main() { 
    // now use it 
    test("f0ef:1234::1", "f000::1"); 
} 
0

虽然你可以用原始套接字创建它。我也必须做类似的事情,但找不到任何参考。

要使用原始套接字做到这一点,这link给你一个很好的解释