首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用libtins重新创建IP数据包更改其报头

使用libtins重新创建IP数据包更改其报头
EN

Stack Overflow用户
提问于 2020-07-21 04:39:52
回答 1查看 341关注 0票数 0

我有一个uint8_t*缓冲区,这是通过执行buf.data()获得的。它是IP数据包的缓冲区。

我希望更改源地址并重新计算校验和,因此我在libtins中通过执行以下操作重新创建了包:

代码语言:javascript
复制
//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");

问题是,从libtins打印出来的数据包具有不同的标题:

代码语言:javascript
复制
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

然后,我尝试用新包更改buf,尽管它看起来不一样:

代码语言:javascript
复制
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());

但在auto p = Tins::IP(buf.data(), buf.size());上我得到了:

代码语言:javascript
复制
terminate called after throwing an instance of 'Tins::malformed_packet'
  what():  Malformed packet

这很奇怪,因为它实际上是由libtins生成的包。

我做错了什么?根据libtins文档,我可以从缓冲区和大小创建libtins数据包。

更新:

代码语言:javascript
复制
#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;
}

输出:

代码语言:javascript
复制
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 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-21 07:19:29

使用您提供的示例IP数据包,我完成了以下操作:

代码语言:javascript
复制
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
};

Tins::IP ip(ip_packet, sizeof(ip_packet));
for (std::size_t i = 0; i < sizeof(ip_packet); i++)
    std::cout << +ip_packet[i] << " ";

std::cout << std::endl;

ip.src_addr("192.155.32.10");

auto data = ip.serialize();
for (std::size_t i = 0; i < data.size(); i++)
    std::cout << +data[i] << " ";

std::cout << std::endl;

我得到了以下输出:

代码语言:javascript
复制
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
69 0 0 52 0 0 64 0 64 6 144 87 192 155 32 10 172 217 28 238 0 112 0 80 0 0 0 0 0 0 0 0 128 2 253 232 202 1 0 0 2 4 5 180 3 3 0 4 2 0 0 0

所以它能像预期的那样工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63007505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档