Reputation: 19
I have written a C-program that creates a TCP/IPv4-packet from the link-layer upwards. 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:
#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. So I turned on tcpdump, to see if the packets are even send at all and this came out:
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. Why does this happen when I clearly used the libnet_build_ipv4() function. And is there still a way to either properly receive these single packets or just get them to become normal ipv4?
Upvotes: 0
Views: 252
Reputation: 18410
It looks, like you do not use the correct order of parameters with 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);
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.
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
Upvotes: 0