简体   繁体   English

ip4数据包组装为ip6-libnet

[英]ip4 packet assembled as ip6 - libnet

I have written a C-program that creates a TCP/IPv4-packet from the link-layer upwards. 我编写了一个C程序,该程序从链路层开始创建一个TCP / IPv4数据包。 The goal of this program was to receive the single packet with an open socket, either raw or just a stream socket. 该程序的目标是使用开放套接字(原始端口或仅是流套接字)接收单个数据包。 The packet consists of an ethernet header, a tcp header and ipv4: 该数据包包括一个以太网头,一个tcp头和ipv4:

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

uint8_t *randmac();    //creates my random source-mac, shady I know but I got 
                       //tired of typing in the same input over and over
void gateway();        //gets my standart gateway i.e. the router (as far as 
                       //I understand the ethernet layer is for the router 
                       //and tcp and ip for the rest of the net.)



int main() {
uint32_t src, dst, seq, ack;
char payload[1024], destip[16];
uint16_t sp = 2001, dp = 2000;
libnet_ptag_t tcp;
libnet_ptag_t ip4;
libnet_ptag_t eth;
char errbuf[LIBNET_ERRBUF_SIZE];
int i, bytes;
uint8_t *dstmc;     //destination mac address (router)
uint8_t *smc;       //source mac address
int  len;
libnet_t * l;

l = libnet_init(LIBNET_LINK, NULL, errbuf);
if(l == NULL)

//getting the destination ip-address, works all right...

//payload is fine too

smc = malloc(6);
gatemac = malloc(6);

libnet_seed_prand(l);
src = libnet_get_prand(LIBNET_PRu32);
seq = 0;
ack = libnet_get_prand(LIBNET_PRu32);
dst = libnet_name2addr4(l, destip, LIBNET_DONT_RESOLVE);
smc = randmac();
gateway();

//getting the rest of the required addresses etc, works as well...




tcp = libnet_build_tcp(sp, dp, seq, ack, TH_SYN, 0, 0, 0, LIBNET_TCP_H + 
sizeof(payload),(uint8_t *) payload, sizeof(payload), l, 0);
if(tcp == -1)
printf("(1)unable because: %s\n", libnet_geterror(l));
perror("libnet_build_tcp()");

ip4 = libnet_build_ipv4(LIBNET_TCP_H + LIBNET_IPV4_H + sizeof(payload), 
IPPROTO_TCP, 1, 1024, 60, 0, 0, src, dst, NULL, 0, l, 0);   //or (uint8_t) 
if(ip4 == -1)
printf("(2)unable because: %s\n", libnet_geterror(l));
perror("libnet_build_ipv4()");

eth = libnet_build_ethernet(gatemac, smc, ETHERTYPE_IP, NULL, 0, l, 0);
if(eth == -1)
printf("(3) unable because: %s\n", libnet_geterror(l));
perror("libnet_build_ethernet()");


bytes = libnet_write(l);

//error handling

}

The program itself works all right, no errors, the packets are written and so on. 程序本身可以正常工作,没有错误,数据包被写入等等。 But the funny thing is: I can't receive them with any kind of raw or ipv4 socket. 但有趣的是:我无法通过任何原始或ipv4套接字接收它们。 So I turned on tcpdump, to see if the packets are even send at all and this came out: 因此,我打开了tcpdump,以查看数据包是否甚至都已发送,结果如下:

 13:43:24.003324 IP 74.253.145.81 > 192.168.88.130: hopopt
 13:43:27.007860 IP 74.253.145.81 > 192.168.88.130: hopopt

 //Random source address, I also sent multiple packets to eliminate the 
 //chances of missing them.
 //There is also no doubt that these are truly my programmed packets due to 
 //their number and random addresses.

I did some researching and found out, that "hopopt" stands for hop-by-hop extension-header used by ipv6. 我进行了一些研究,发现“ hopopt”代表ipv6使用的逐跳扩展头。 Why does this happen when I clearly used the libnet_build_ipv4() function. 为什么当我清楚地使用libnet_build_ipv4()函数时会发生这种情况。 And is there still a way to either properly receive these single packets or just get them to become normal ipv4? 仍然有一种方法可以正确接收这些单个数据包,或者只是使其变为普通的ipv4?

It looks, like you do not use the correct order of parameters with libnet_build_ipv4 : 看起来,好像您没有对libnet_build_ipv4使用正确的参数libnet_build_ipv4

ip4 = libnet_build_ipv4(LIBNET_TCP_H + LIBNET_IPV4_H + sizeof(payload), 

IPPROTO_TCP, 1, 1024, 60, 0, 0, src, dst, NULL, 0, l, 0); IPPROTO_TCP,1、1024、60、0、0,src,dst,NULL,0,l,0);

The correct order is: 正确的顺序是:

libnet_ptag_t libnet_build_ipv4 (u_int16_t len,
u_int8_t tos, u_int16_t id, u_int16_t frag,
u_int8_t ttl, u_int8_t prot, u_int16_t 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);

So, your sixth parameter (prot) is 0 , which exactly corresponds to the hop-by-hop-option (hopopt) you observe with tcpdump. 因此,您的第六个参数(prot)为0 ,与您在tcpdump中观察到的逐跳选项(hopopt)完全对应。

You probably want something like: 您可能想要类似的东西:

ip4 = libnet_build_ipv4(LIBNET_TCP_H + LIBNET_IPV4_H + sizeof(payload), //len
                        0,           // tos
                        1234,        // some id
                        0,           // No fragment
                        0x40,        // Standard TTL (64)
                        IPPROTO_TCP, // Next protocol goes here
                        0,           // Checksum, auto-filled?
                        src,         // IP source address
                        dst,         // IP destination address
                        NULL,        // payload
                        0,           // payload length
                        l,           // libnet handle
                        0            // ptag
);

If you fix the order of the parameters, it should work as expected! 如果您固定参数的顺序,它应该可以正常工作! See also a libnet Tutorial here 另请参见libnet 教程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM