首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >修改捕获数据包的报头

修改捕获数据包的报头
EN

Stack Overflow用户
提问于 2014-03-08 09:23:51
回答 1查看 2.3K关注 0票数 5

我试图通过使用libnetfiletr_queue修改IP报头,以包括更多的IP选项。到目前为止,我已经成功地获得了包,如下所示。

代码语言:javascript
复制
if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
    fprintf(stderr, "Unable to set nfq_set_mode\n");
    exit(1);
}

然后我设法走得很远如下所示

代码语言:javascript
复制
static int my_callBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,struct nfq_data *tb)
{   
    int id = 0;
    int packet_len;
    unsigned char *data;
    struct nfqnl_msg_packet_hdr *packet_hdr;
    unsigned char *data;

    packet_hdr = nfq_get_msg_packet_hdr(tb);

    if (packet_hdr) {
        id = ntohl(packet_hdr->packet_id);          
    }

    packet_len = nfq_get_payload(tb, &data);

    if (packet_len >= 0) {
        //print payload length
        printf("payload_length = %d ", packet_len);
        //modify packet ip header  
    }

    return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
}

但是从现在开始,我对如何在//modify packet ip header comment.Example修改IP报头(例如流量类(IPV6)/ IP选项/版本/标志/目标地址)时如何修改捕获的数据包感到有点困惑,因为我只需要了解修改是如何工作的:)。

我尝试了许多资源,但无法再继续下去了。非常感谢您对此查询的专家建议和帮助。:)

(非常感谢:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-10 23:50:43

若要修改IP报头的值,请从定义表示报头的结构开始。通过读取您要访问的协议的RFC规范,您可以找到应该使用的结构。

以下是IPv6:https://www.rfc-editor.org/rfc/rfc2460#section-3的RFC链接

IPv6头的第一行有点棘手,因为它们没有使用对字节对齐的字段。版本字段为4位宽,流量类为8位宽,流标签为20位宽.整个报头是320位(40字节),其中256是src和dest地址。其他字段只使用64位,因此可能最容易像这样定义您的结构:

代码语言:javascript
复制
struct ipv6_hdr {
    uint32_t row1;
    uint16_t payload_length;
    uint8_t next_header;
    uint8_t hop_limit;
    uint16_t src[8];
    uint16_t dest[8];
};

要提取第一行值,可以使用一些掩蔽:

代码语言:javascript
复制
#define VERSION_MASK 0xF0000000
#define TRAFFIC_CLASS_MASK 0x0FF00000
#define FLOW_LABEL_MASK 0x000FFFFF

struct ipv6_hdr foo;

...

nfq_get_payload(tb, &foo); // Just an example; don't overflow your buffer!

// bit-wise AND gets masked field from row1
uint8_t version = (uint8_t) ((foo->row1 & VERSION_MASK) >> 28);  // shift (32-4) bits

一旦将结构指向数据有效负载,假设字节数组与此格式匹配,则修改标头值将成为简单的赋值:

代码语言:javascript
复制
version = 6;

// bit-wise OR puts our value in the right place in row1
foo->row1 &= ~(VERSION_MASK) // clear out the old value first
foo->row1 = ((uint32_t) version << 28) | foo->row1;  

我选择将结构中的src和dest地址设置为16位值的数组,因为IPv6地址是由8,16位值组成的系列。这将使隔离任何给定的字节都变得容易。

在应用适当的结构之前,您必须确定数据有效负载的格式。

有关如何创建IPv4头的信息,请查看其RFC:https://www.rfc-editor.org/rfc/rfc791#section-3.1

希望这会有所帮助(您可能需要修改我的代码示例才能得到正确的语法,已经有几个月了)。

按照注释中的要求使用有关校验和的信息进行编辑

按照这个RFC在修改头后生成校验和:https://www.rfc-editor.org/rfc/rfc1071

在生成新校验和之前,键取掉标题中的校验和字段为零。

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

https://stackoverflow.com/questions/22267497

复制
相关文章

相似问题

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