mardi 21 juillet 2020

Using libtins to recreate IP packet change its header

I have a uint8_t* buffer which I get by doing buf.data(). It's a buffer of an IP packet.

I want to change the source address and recalculate the checksum, so I recreated the packet in libtins by doing what you see below:

//prints original packet  
for (size_t i = 0; i < buf.size(); i++)
{
    printf("%x ", buf.data()[i]);
}
printf("\n");

Tins::IP pa = Tins::IP(buf.data(), buf.size());
pa.src_addr(newIpv4address);
uint8_t *packetData = pa.serialize().data();

//prints libtins packet created from original packet
for (size_t i = 0; i < buf.size(); i++)
{
    printf("%x ", packetData[i]);
}
printf("\n");

The problem is that the packet printed from libtins appears with a different header:

45 0 0 34 0 0 40 0 40 6 6b 53 c0 a8 45 1 ac d9 1c ee 0 20 0 50 0 0 0 0 0 0 0 0 80 2 fd e8 a5 4d 0 0 2 4 5 b4 3 3 0 4 2 0 0 0 

60 b 0 34 62 76 0 0 d0 8 0 28 62 76 0 0 ac d9 1c ee 0 20 0 50 0 0 0 0 0 0 0 0 80 2 fd e8 eb 47 0 0 2 4 5 b4 3 3 0 4 2 0 0 0

I then tried to change the buf with the new packet even though it looks different:

uint8_t* b = buf.data();
uint8_t* o = pa.serialize().data();

for (int i = 0; i < buf.size(); i++)
{
    b[i] = o[i];
}

auto p = Tins::IP(buf.data(), buf.size());

but on the line auto p = Tins::IP(buf.data(), buf.size()); I get:

terminate called after throwing an instance of 'Tins::malformed_packet'
  what():  Malformed packet

which is strange since it's literally a packet generated from libtins.

What am I doing wrong? According to libtins documentation I can create a libtins packet from a buffer and a size.

UPDATE:

#include <iostream>
#include <memory>
#include <tins/ip.h>

int main()
{
    const int packet_size = 52;
    uint8_t ip_packet[] = {
        69, 0, 0, 52, 0, 0, 64, 0, 64, 6, 107,
        83, 192, 168, 69, 1, 172, 217, 28, 238,
        0, 112, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 128,
        2, 253, 232, 164, 253, 0, 0, 2, 4, 5, 180,
        3, 3, 0, 4, 2, 0, 0, 0};

    std::cout << "packet BEFORE " << std::endl;
    for (size_t i = 0; i < packet_size; i++)
    {
        printf("%x ", ip_packet[i]);
    }

    uint8_t b[52];
    for (int i = 0; i < packet_size; i++)
    {
        b[i] = ip_packet[i];
    }
    printf("\n");

    Tins::IP pa = Tins::IP(b, packet_size);
    pa.src_addr("172.78.123.76");
    uint8_t *packetData = pa.serialize().data();
    std::cout << "TINS packet: " << std::endl;
    for (size_t i = 0; i < packet_size; i++)
    {
        printf("%x ", packetData[i]);
    }
    printf("\n");

    return 0;
}

OUTPUT:

packet BEFORE 
45 0 0 34 0 0 40 0 40 6 6b 53 c0 a8 45 1 ac d9 1c ee 0 70 0 50 0 0 0 0 0 0 0 0 80 2 fd e8 a4 fd 0 0 2 4 5 b4 3 3 0 4 2 0 0 0 
TINS packet: 
0 0 0 0 0 0 0 0 10 90 68 1 0 0 0 0 ac d9 1c ee 0 70 0 50 0 0 0 0 0 0 0 0 80 2 fd e8 83 c 0 0 2 4 5 b4 3 3 0 4 2 0 0 0 

Aucun commentaire:

Enregistrer un commentaire