解析 IP 标头时出错

发布于 2024-08-22 13:13:50 字数 1154 浏览 1 评论 0原文

我有一个小函数尝试打印 IP 标头的片段偏移量。

ParseIpHeader(unsigned char *packet, int len)
{
    struct ethhdr *ethernet_header;
    struct iphdr *ip_header;

    /* First Check if the packet contains an IP header using
       the Ethernet header                                */

    ethernet_header = (struct ethhdr *)packet;

    if(ntohs(ethernet_header->h_proto) == ETH_P_IP)
    {
            /* The IP header is after the Ethernet header  */

            if(len >= (sizeof(struct ethhdr) + sizeof(struct iphdr)))
            {
                    ip_header = (struct iphdr*)(packet + sizeof(struct ethhdr));

                    /* print the Source and Destination IP address */

                    //printf("Dest IP address: %s\n", inet_ntoa(ip_header->daddr));
                    //printf("Source IP address: %s\n", inet_ntoa(ip_header->saddr));
                    printf("protocol %d\n", ip_header->protocol);
                    printf("Fragment off is %d\n", ntohs(ip_header->frag_off));

            }

}

我的数据包是 TCP(ip_header->协议始终为 6。问题是 frag_off 始终是16384。我发送了很多数据,为什么frag_off总是恒定的?

谢谢。

I have a small function that tries to print the fragment offset of an IP header.

ParseIpHeader(unsigned char *packet, int len)
{
    struct ethhdr *ethernet_header;
    struct iphdr *ip_header;

    /* First Check if the packet contains an IP header using
       the Ethernet header                                */

    ethernet_header = (struct ethhdr *)packet;

    if(ntohs(ethernet_header->h_proto) == ETH_P_IP)
    {
            /* The IP header is after the Ethernet header  */

            if(len >= (sizeof(struct ethhdr) + sizeof(struct iphdr)))
            {
                    ip_header = (struct iphdr*)(packet + sizeof(struct ethhdr));

                    /* print the Source and Destination IP address */

                    //printf("Dest IP address: %s\n", inet_ntoa(ip_header->daddr));
                    //printf("Source IP address: %s\n", inet_ntoa(ip_header->saddr));
                    printf("protocol %d\n", ip_header->protocol);
                    printf("Fragment off is %d\n", ntohs(ip_header->frag_off));

            }

}

My packets are TCP (the ip_header->protocol is always 6. the problem is that the frag_off
is always 16384. I am sending a lot of data, why the frag_off is always constant?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

救星 2024-08-29 13:13:50

片段偏移量与标志共享。您已设置“DF”(不分段)位。

假设片段偏移量为 0,则整个 16 位字段的值为 16384。

看一下 http://www.ietf.org/rfc/rfc791.txt,从第 10 页开始。

编辑

您正在接收的 TCP 段中的 DF 位由远程端,执行 路径 MTU 发现 - 简而言之,尝试避免碎片化。
在这种情况下,发送方了解整个路径可以处理的最大 MTU,并切割 TCP 段,以便在封装为 IP 后它们不会超过该 MTU。

EDIT2

关于recvfrom()和TCP的使用:TCP是面向连接的协议,所有分段/分段细节都已经由它处理(分段显然是由下层处理的, IP) - 所以你不需要处理它。您在发送端 write() 的任何内容最终都会在另一端 read() - 但可能在相同的块中 - 即两次 4K 写入有时可能会导致一次 8K 读取,有时会导致一次 8K 读取在两次 4K 读取中 - 取决于媒体在重新排序/丢失方面的行为。

IP 分段和重组由操作系统透明处理,因此您无需担心它,就像数据包乱序等一样(您只会看到性能下降对应用程序的影响)。

我可以推荐的一本好书是:UNIX 网络编程。鉴于 Steven 参与了 TCP,无论您使用哪种操作系统,这都是一本好书。

编辑3:

如果你正在做一些事情来成为“中间人”(假设你有这样做的充分且合法的理由:-) - 那么你可以通过查看以下内容来评估即将进行的工作现有技术:chaosreader(适用于 pcap 文件的单脚本方法,但适用于其他内容),或LibNIDS - 模拟 IP 碎片整理和 TCP 流重组;也许只是为了您的目的而重复使用它们。

Fragment offset is shared with flags. You have the "DF" (don't fragment) bit set.

Which gives you 16384 for the entire 16-bit field, given the fragment offset of 0.

Take a look at the http://www.ietf.org/rfc/rfc791.txt, starting from page 10.

EDIT:

The DF bit in the TCP segments that you are receiving is set by the remote side, to perform the Path MTU discovery - in a nutshell, to try to avoid the fragmentation.
In this case the sending side learns the biggest MTU that the overall path can handle, and chops the TCP segments such that they did not exceed it after the encapsulation into IP.

EDIT2:

regarding the use of recvfrom() and TCP: TCP is a connection-oriented protocol, and all of the segmentation/fragmentation details are already handled by it (fragmentation is obviously handled by the lower layer, IP) - so you do not need to deal with it. Anything you write() on the sending side will be eventually read() on the other side - possibly not in the same chunks though - i.e. two 4K writes may result in a single 8K read sometimes, and sometimes in two 4K reads - depending on the behaviour of the media inbetween concerning reordering/losses.

IP Fragmentation and reassembly is handled transparently by the operating system, so you do not need to worry about it, same as about packets out of order, etc. (you will just see the decreased performance as the effect on the application).

One good read I could recommend is this one: UNIX network programming. Given Steven's involvement with the TCP, it's a good book no matter which OS you use.

EDIT3:

And if you are doing something to be a "man in the middle" (assuming you have good and legitimate reasons for doing so :-) - then you can assess the upcoming work by looking at the prior art: chaosreader (one-script approach that works on pcap files, but adaptable to something else), or LibNIDS - that does emulate the IP defragmentation and the TCP stream reassembly; and maybe just reuse them for your purposes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文