libpcap抓包疑问

21 views
Skip to first unread message

Bamboo Hui

unread,
Jun 22, 2013, 10:21:25 PM6/22/13
to sh...@googlegroups.com
试着用libpcap的API抓包玩,代码如下,在打印IP header中的源地址和目标地址时(加粗语句),
不同的输出方式打印出来不同的结果,十分不解,求指教。
为什么用两个printf分别打印源地址和目标地址时,源和目标是不同的(期望值)?而在一个printf中打印输出的源和目标却是相同的?
(CentOS 6.4 x64, gcc 4.4.7)


输出结果为:
SRC: 192.168.122.13
DST: 192.168.122.1
src: 192.168.122.13
dst: 192.168.122.13

SRC: 192.168.122.13
DST: 192.168.122.1
src: 192.168.122.13
dst: 192.168.122.13

SRC: 192.168.122.1
DST: 192.168.122.13
src: 192.168.122.1
dst: 192.168.122.1




源码:
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <pcap-bpf.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SNAP_LEN    1518

void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
    const struct ether_header *ethernet;
    const struct ip *ip;

    ethernet = (struct ether_header *)packet;
    ip = (struct ip*)(packet + ETHER_HDR_LEN);
    if ( ip->ip_hl * 4 < 20) {
        fprintf(stderr, "Invalid IP header length\n");
        return;
    }
    printf("SRC: %s\n", inet_ntoa(ip->ip_src));
    printf("DST: %s\n", inet_ntoa(ip->ip_dst));
    printf("src: %s\ndst: %s\n\n",
        inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst)
        );

}


int main(int argc, char **argv)
{
    char *dev, err_buff[PCAP_ERRBUF_SIZE];

    // 1. find the active interface for capturing data
    if ((dev = pcap_lookupdev(err_buff)) == NULL) {
        fprintf(stderr, "Couldn't find default device: %s\n", err_buff);
        return 1;
    }

    printf("%s\n", dev);

    // 2. open the interface
    pcap_t *handle = NULL;
    bpf_u_int32 net, mask;

    if ((handle = pcap_open_live(dev, SNAP_LEN, 0, 1000, err_buff)) == NULL) {
        fprintf(stderr, "Failed to open the device %s\n", dev);
        return 2;
    }

    if (pcap_lookupnet(dev, &net, &mask, err_buff) == -1) {
        fprintf(stderr, "Failed to get net.\n");
        return 3;
    }

    // 3. complie and set filter
    char filter[] = "ip";
    struct bpf_program fp;
    if (pcap_compile(handle, &fp, filter, 0, net) == -1) {
        fprintf(stderr, "failed to compile the filter %s: %s\n",
                                                filter, pcap_geterr(handle));
        return 4;
    }

    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "failed to set filter %s: %s\n", filter,
                                                        pcap_geterr(handle));
        return 4;
    }

    // 4. capture the packet
    int num_packets = 10;

    pcap_loop(handle, num_packets, got_packet, NULL);
   
    // 5. stop capturing packets and free memory.
    pcap_freecode(&fp);
    pcap_close(handle);

    return 0;
}

Shell Xu

unread,
Jun 23, 2013, 12:45:00 AM6/23/13
to shlug
       The  inet_ntoa()  function converts the Internet host address in, given
       in network byte order, to a string  in  IPv4  dotted-decimal  notation.
       The  string  is returned in a statically allocated buffer, which subse‐
       quent calls will overwrite.



2013/6/23 Bamboo Hui <bamboo...@gmail.com>

--
-- You received this message because you are subscribed to the Google Groups Shanghai Linux User Group group. To post to this group, send email to sh...@googlegroups.com. To unsubscribe from this group, send email to shlug+un...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/shlug?hl=zh-CN
---
您收到此邮件是因为您订阅了 Google 网上论坛的“Shanghai Linux User Group”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 shlug+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 



--
无能者无所求,饱食而遨游,泛若不系之舟
blog: http://shell909090.com/blog/
twitter: http://twitter.com/shell909090

Richard Ma

unread,
Jun 23, 2013, 12:49:53 AM6/23/13
to shlug
根据楼上的说法,应该是缓存问题了。。。
Best Regards.

Richard Ma

My Blog: www.richardma.org

none_nobody

unread,
Jun 23, 2013, 12:53:24 AM6/23/13
to sh...@googlegroups.com

应该说是 glibc 里 intoa 具有不可重入性,

需要按以下的方法自己写一个。

/*
 * given a packet, print a decode of via tcpdump
 */

char * xintoa (struct in_addr addr, char *buf, u_short bufLen) {

  char *cp, *retStr;
  u_int byte;
  int n;

  cp = &buf[bufLen];
  *--cp = '\0';

  n = 4;
  do {
    byte = addr.s_addr & (0xff << 24);
    byte >>= 24;
    *--cp = byte % 10 + '0';
    byte /= 10;
    if (byte > 0) {
      *--cp = byte % 10 + '0';
      byte /= 10;
      if (byte > 0)
    *--cp = byte + '0';
    }  
    *--cp = '.';
    addr.s_addr <<= 8;
  } while (--n > 0);

  retStr = (char *) (cp + 1);

  return (retStr);
}

none_nobody

unread,
Jun 23, 2013, 1:39:00 AM6/23/13
to sh...@googlegroups.com
或者不可重入是错的(不是多线程的可重入),应该说是,intoa利用本地栈,具有破坏性。

Chaos Eternal

unread,
Jun 23, 2013, 2:30:41 AM6/23/13
to sh...@googlegroups.com
为啥用本地栈就有破坏性?

难道不是用全局栈才有破坏性的么

2013/6/23 none_nobody <lyx...@gmail.com>:
> 或者不可重入是错的(不是多线程的可重入),应该说是,intoa利用本地栈,具有破坏性。
>
>
> On Sunday, June 23, 2013 12:53:24 PM UTC+8, none_nobody wrote:
>>
>>
>> 应该说是 glibc 里 intoa 具有不可重入性,
>>
>>

Bamboo Hui

unread,
Jun 23, 2013, 3:11:52 AM6/23/13
to sh...@googlegroups.com
谢谢,还有一点没理解……请指点

The  string  is returned in a statically allocated buffer, which subsequent calls will overwrite.
应该是说后面的调用会覆盖返回的静态缓存中的数据


    printf("SRC: %s\n", inet_ntoa(ip->ip_src));
    printf("DST: %s\n", inet_ntoa(ip->ip_dst));
    printf("src: %s\ndst: %s\n\n",
        inet_ntoa(ip->ip_src),
        inet_ntoa(ip->ip_dst)
        );


输出为:

SRC: 192.168.122.13
DST: 192.168.122.1
src: 192.168.122.13
dst: 192.168.122.13

应该是inet_ntoa(ip->ip_dst)覆盖inet_ntoa(ip->ip_src)呀,上面的输出为什么是src覆盖了dst呢


2013/6/23 Shell Xu <shell...@gmail.com>

Liu Cheng

unread,
Jun 23, 2013, 3:56:47 AM6/23/13
to sh...@googlegroups.com
函数调用里面参数的计算顺序是不确定的,也就是
inet_ntoa(ip->ip_src)
inet_ntoa(ip->ip_dst)
这两句谁先谁后执行是不确定的

Yongwei Wu

unread,
Jun 23, 2013, 4:01:47 AM6/23/13
to sh...@googlegroups.com
首先函数里多个参数的估值顺序应该是由编译器决定的。C/C++标准都不对此规
定。

在x86平台上,使用栈传递参数,从右到左压栈(除非使用一些其他的调用规
范;可参见:http://en.wikipedia.org/wiki/X86_calling_conventions)。所
以,一般参数的估值顺序也是从右到左,但程序员不应该依赖这样的顺序。
Wu Yongwei
URL: http://wyw.dcweb.cn/

none_nobody

unread,
Jun 23, 2013, 10:25:36 AM6/23/13
to sh...@googlegroups.com
就那么个意思,我解释不清楚。羞愧地低头不语。

On Sunday, June 23, 2013 2:30:41 PM UTC+8, Soahc Lanrete wrote:
为啥用本地栈就有破坏性?

难道不是用全局栈才有破坏性的么

Chaos Eternal

unread,
Jun 23, 2013, 10:47:37 AM6/23/13
to sh...@googlegroups.com
珍惜生命,远离C吧

2013/6/23 none_nobody <lyx...@gmail.com>:

none_nobody

unread,
Jun 23, 2013, 1:11:27 PM6/23/13
to sh...@googlegroups.com
C 木绳么不好。算了,我只会这一样。你和老头较什么真呢?

要么来把Torch7 ?  lua 样式的。要么玛塔拉宝?是他色体擦了啊


On Sunday, June 23, 2013 10:47:37 PM UTC+8, Soahc Lanrete wrote:
珍惜生命,远离C吧


SuperCat

unread,
Jun 23, 2013, 1:23:10 PM6/23/13
to sh...@googlegroups.com
珍惜生命,远离Linux吧


2013/6/23 Chaos Eternal <chaose...@shlug.org>

Wizard

unread,
Jun 25, 2013, 4:54:55 AM6/25/13
to shlug
有意思的,试了试,确实是这样的。

下次注意了。


2013/6/23 Bamboo Hui <bamboo...@gmail.com>

--
-- You received this message because you are subscribed to the Google Groups Shanghai Linux User Group group. To post to this group, send email to sh...@googlegroups.com. To unsubscribe from this group, send email to shlug+un...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/shlug?hl=zh-CN
---
您收到此邮件是因为您订阅了 Google 网上论坛的“Shanghai Linux User Group”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 shlug+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 



--
Wizard
Reply all
Reply to author
Forward
0 new messages