简体   繁体   English

关于使用libpcap的以太网/ IP标头主机/地址的问题?

[英]Problems about ethernet/IP header host/addr using libpcap?

I'm using libpcap to decode some ip packets. 我正在使用libpcap解码一些IP数据包。

But I find both the ethernet ether_shost/ether_dhost and ip saddr/daddr I decode are the same. 但是我发现我解码的以太网ether_shost / ether_dhost和ip saddr / daddr是相同的。

Where do I mess up? 我在哪里弄糟?

Thanks in advance. 提前致谢。

Here's part of the callback function: 这是回调函数的一部分:

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
    ...
}

inet_ntoa does the following: inet_ntoa执行以下操作:

  • Puts the string form of the address into a buffer 将地址的字符串形式放入缓冲区
  • Returns the address of the buffer 返回缓冲区的地址

The key thing is that it uses the same buffer each time you call it! 关键是每次调用它都使用相同的缓冲区!

So when this line runs: 因此,当此行运行时:

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

first it will put one address in the buffer, then it will put the other address in the buffer, then it will print the contents of the buffer twice. 首先它将一个地址放入缓冲区,然后将另一个地址放入缓冲区,然后将缓冲区内容打印两次。

You could fix this by storing the strings in your own separate buffers: 您可以通过将字符串存储在自己的单独缓冲区中来解决此问题:

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);

or by calling printf twice: 或两次调用printf

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

ether_ntoa has the same problem. ether_ntoa也有同样的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM