我正在尝试解析tcp数据包,然后将其分配给有效负载开始的指针。

我正在使用C,这是到目前为止的代码:

void dump(const unsigned char *data, int length) { //*data contains the raw packet data
    unsigned int i;
    static unsigned long pcount = 0;

    // Decode Packet Header
    struct ether_header *eth_header = (struct ether_header *) data;

    printf("\n\n === PACKET %ld HEADER ===\n", pcount);

    printf("\nSource MAC: ");
    for (i = 0; i < 6; ++i) {
        printf("%02x", eth_header->ether_shost[i]); //? Why don't i use nthos here?
        if (i < 5) printf(":");
    }

    unsigned short ethernet_type = ntohs(eth_header->ether_type);
    printf("\nType: %hu\n", ethernet_type);

    if (ethernet_type == ETHERTYPE_IP) { //IP Header
        printf("\n  == IP HEADER ==\n");
        struct ip *ip_hdr = (struct ip*) data + sizeof(struct ether_header);
        unsigned int size_ip = ip_hdr->ip_hl * 4;
        printf("\nIP Version: %u", ip_hdr->ip_v); //? Nthos or no nthos
        printf("\nHeader Length: %u", ip_hdr->ip_hl); //? Nthos or no nthos
        printf("\nTotal Length: %hu", ntohs(ip_hdr->ip_len)); //? Nthos or no nthos

        // TCP Header
        printf("\n== TCP HEADER ==\n");
        struct tcphdr *tcp_hdr = (struct tcphdr*) data + sizeof(struct ether_header) + size_ip;
        printf("\n Source Port: %" PRIu16, nthos(tcp_hdr->th_sport));
        printf("\n Destination Port: %" PRIu16, nthos(tcp_hdr->th_dport));
        printf("\n fin: %" PRIu16, tcp_hdr->fin);
        printf("\n urg: %" PRIu16, tcp_hdr->urg);
        printf("\n ack_seq: %" PRIu32, ntohl(tcp_hdr->ack_seq));

        //Transport payload! i.e. rest of the data
        const unsigned char *payload = data + ETH_HLEN + size_ip + sizeof(struct tcphdr) + tcp_hdr->doff;

    }

我确定此代码中有错误,因为端口号都很奇怪。没有一个分配给80。分配的Ip版本也可能真的很奇怪(例如版本11)。我究竟做错了什么?谢谢!

我也不确定何时使用nthos,何时不使用nthos。我知道nthos适用于16位无符号整数,我知道nthol适用于32位无符号整数,但是我知道您不打算将它们用于这些数据包中的所有内容(例如:tcp_hdr-> fin)。为什么是某些东西而不是它们?

非常感谢!

编辑:

感谢Art解决了大多数问题。我编辑了tcp_hdr和ip_hdr,因此方括号正确了!

我仍然有2个问题:
  • 有效载荷的前10个字节具有奇怪的符号(因此我认为我没有正确分配有效载荷)。
  • 我仍然不确定何时使用nthos/nthol。我知道u_int16_t是ntohs,而u_int32_t是ntohl。但是,那些以int签名或未被忽略的short int的东西呢?例如,我没有使用ntohs或nthol来使ip_v正常工作。为什么不?是“ip_hdr-> ip_hl”吗?等...

  • EDIT2

    我已经解决了为什么我的有效载荷不能正确输出的问题(这是因为我计算的TCP_header大小错误)。

    尽管我仍然对何时使用nthos感到困惑,但我还是将其作为一个单独的问题,因为我认为我在这篇文章中问了太多问题!

    When to use ntohs and ntohl in C?

    最佳答案

    您的问题很可能在这里:

    struct ip *ip_hdr = (struct ip*) data + sizeof(struct ether_header);
    struct tcphdr *tcp_hdr = (struct tcphdr*) data + sizeof(struct ether_header) + size_ip;
    

    进行(struct ip*) data + sizeof(struct ether_header)首先将数据转换为struct ip *,然后向其添加sizeof(struct ether_header),我们从指针算术中知道这不会像您期望的那样执行。

    如果问题仍然不清楚,可以使用以下简单程序将正确的方向指示给您:
    #include <stdio.h>
    
    struct foo {
        int a, b;
    };
    
    int
    main(int argc, char **argv)
    {
        char *x = NULL;
    
        printf("%p\n", x);
        printf("%p\n", (struct foo *)x + 4);
        printf("%p\n", (struct foo *)(x + 4));
    
        return 0;
    }
    

    09-25 18:28
    查看更多