【问题标题】:Problems about ethernet/IP header host/addr using libpcap?关于使用 libpcap 的以太网/IP 标头主机/地址的问题?
【发布时间】:2017-04-27 12:24:18
【问题描述】:

我正在使用 libpcap 来解码一些 ip 数据包。

但我发现我解码的以太网 ether_shost/ether_dhost 和 ip saddr/daddr 都是一样的。

我在哪里搞砸了?

提前致谢。

这里是回调函数的一部分:

void
got_packet(u_char *args, const struct pcap_pkthdr *header,
    const u_char *packet)
{
    ...
    eth_h = (struct ether_header *) packet;
    struct ether_addr shost, dhost;
    memcpy(&shost, eth_h->ether_shost, sizeof(shost));
    memcpy(&dhost, eth_h->ether_dhost, sizeof(dhost));
    printf("L2 DLT_EN10MB: %s -> %s\n", ether_ntoa(&shost), ether_ntoa(&dhost)); // shost == dhost?

    if (ntohs(eth_h->ether_type) != ETHERTYPE_IP) {
        return;
    }

    // only work for L2 DLT_EN10MB
    ip_h = (struct iphdr *) (packet + sizeof(struct ether_header));
    if (ip_h->version != 4) {
        return;
    }

    struct in_addr saddr, daddr;
    saddr.s_addr = ip_h->saddr;
    daddr.s_addr = ip_h->daddr;

    printf("%s -> %s\n", inet_ntoa(saddr), inet_ntoa(daddr)); // saddr == daddr?
    printf("%" PRIu32 " -> %" PRIu32 "\n", ntohl(ip_h->saddr), ntohl(ip_h->daddr)); // actually not the same
    ...
}

【问题讨论】:

    标签: c ip libpcap


    【解决方案1】:

    inet_ntoa 执行以下操作:

    • 将地址的字符串形式放入缓冲区
    • 返回缓冲区的地址

    关键是每次调用时它都使用相同的缓冲区!

    所以当这条线运行时:

    printf("%s -> %s\n", inet_ntoa(saddr), inet_ntoa(daddr));
    

    首先它将一个地址放入缓冲区,然后将另一个地址放入缓冲区,然后将缓冲区的内容打印两次。

    您可以通过将字符串存储在自己的单独缓冲区中来解决此问题:

    char saddr_str[INET_ADDRSTRLEN];
    char daddr_str[INET_ADDRSTRLEN];
    strcpy(saddr_str, inet_ntoa(saddr));
    strcpy(daddr_str, inet_ntoa(daddr));
    printf("%s -> %s\n", saddr_str, daddr_str);
    

    或致电printf 两次:

    printf("%s -> ", inet_ntoa(saddr));
    printf("%s\n", inet_ntoa(daddr));
    

     

    ether_ntoa也有同样的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-12
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多