免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4510 | 回复: 14
打印 上一主题 下一主题

[C] libpcap捕包问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-23 00:22 |只看该作者 |正序浏览
int main(int argc,char **argv)
{
    char * dev; //设备名
    pcap_t * pt; //网卡设备描述符
    struct in_addr ipv4addr;//ipv4地址
    bpf_u_int32 netp;
    bpf_u_int32 maskp;
    u_char *packet;
    struct pcap_pkthdr pdr; //包结构体,其中包括了包长度、指向包数据的指针
    char errbuf[PCAP_ERRBUF_SIZE];//存放错误信息
    struct ether_header *ethhd;//指向以太网头部的指针
    struct bpf_program *fp;//用于HOLD滤包程序

    struct  pcap_dumper_t * fileInfo;//存放信息的文件的描述
   
    //查找网卡
    if( (dev = pcap_lookupdev(errbuf)) == NULL ){
        printf("lookupdev:%s ",errbuf);
        exit(1);
    }
    //打开设备,得到描述符
    if( (pt = pcap_open_live(dev, 1000, 0, 100, errbuf)) == NULL){
        printf("pcap_open_live:%s ",errbuf);
        exit(1);
    }
    //得到网络IP及掩码
    if( pcap_lookupnet(dev, &netp, &maskp, errbuf) == -1 ){
        printf("pcap_lookupnet:%s ",errbuf);
        exit(1);
    }

    //打印网络环境信息
    ipv4addr.s_addr = netp;
    printf("================================ ");
    printf("device name:%s ",dev);
    printf("net:%s ",inet_ntoa(ipv4addr));
    ipv4addr.s_addr = maskp;
    printf("mask:%s ",inet_ntoa(ipv4addr));   
    printf("================================ ");

    /////////////////////////////////////
    //开始包的相关处理

    //打开存放抓捕信息的文件,此文件名为pcapinfo;
    if((fileInfo=pcap_dump_open(pt, "pcapinfo"))==NULL)
       {perror("pcap_dump_open");
        exit(1);
       }

   
    if( (pcap_loop(pt, -1, pcap_dump,NULL)) == -1 ){
        perror("pcap_loop");
        exit(1);
    }   

    //关闭文件
    pcap_dump_close(fileInfo);

    pcap_close(pt);
    printf("end of program ");
}
想将抓的包数据存入名为"pcapinfo"的文件中,
执行后出现段错误的提示,
问题出在红色字的部分,请教高手指点,多谢了!

论坛徽章:
0
15 [报告]
发表于 2010-01-25 13:12 |只看该作者
退出前调用pcap_dump_close,缓冲的数据就会全保存下来。

论坛徽章:
0
14 [报告]
发表于 2010-01-25 12:37 |只看该作者

回复 #13 rain_fish 的帖子

终于弄明白了,确实是都存进去了。这个问题折腾我好几天了,多谢了!向你致敬!
要ping 一段时间之后才能发生变化。
可能是程序要把存储缓冲区装满才能让输出,所以要等一段时间。
那如果是这样的话,岂不是总有一些数据会留在缓冲区中。我下去后再研究研究。

论坛徽章:
0
13 [报告]
发表于 2010-01-25 11:41 |只看该作者
应该都存进去了,你使用tcpdump看看包内容。

论坛徽章:
0
12 [报告]
发表于 2010-01-25 11:33 |只看该作者
谢谢!
我发现了一个问题,我以前都是用ping  命令测试的,文件大小都没变化,用ftp传输文件时它能存取抓获的信息。
它不存相关的头信息,只存payload里面的信息吗?
那能否把链路层之上的所有信息用这个几个函数存入文件,包括头信息?

论坛徽章:
0
11 [报告]
发表于 2010-01-25 10:59 |只看该作者

回复 #10 wxpz 的帖子

就是你写的代码啊

#include <stdlib.h>
#include <stdio.h>
#include <pcap.h>
int main(int argc, char *argv[])
{
        pcap_t *handle;                        /* Session handle */
        char *dev;                        /* The device to sniff on */
        char errbuf[PCAP_ERRBUF_SIZE];        /* Error string */
        struct bpf_program fp;                /* The compiled filter */
        //char filter_exp[] = "port 23";        /* The filter expression */
        char filter_exp[] = "";
        bpf_u_int32 mask;                /* Our netmask */
        bpf_u_int32 net;                /* Our IP */
        struct pcap_pkthdr *header;        /* The header that pcap gives us */
        const u_char *packet;                /* The actual packet */

        pcap_dumper_t *fileInfo;//file handle
        u_char *pkt_data;

        /* Define the device */
        dev = pcap_lookupdev(errbuf);
        if (dev == NULL)
        {
                fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
                return(2);
        }
        
        /* Find the properties for the device */
        if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1)
        {
                fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
                net = 0;
                mask = 0;
        }
               
        /* Open the session in promiscuous mode */
        handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
        if (handle == NULL)
        {
                fprintf(stderr, "Couldn't open device: %s\n",  errbuf);
                return(2);
        }
        
        /* Compile and apply the filter */
        if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1)
        {
                fprintf(stderr, "Couldn't parse filter %s: %s\n",filter_exp, pcap_geterr(handle));
                return(2);
        }
        if (pcap_setfilter(handle, &fp) == -1)
        {
                fprintf(stderr, "Couldn't install filter %s: %s\n",filter_exp, pcap_geterr(handle));
                return(2);
        }

        /* Grab a packet */
//        packet = pcap_next(handle, &header);

        if((fileInfo=pcap_dump_open(handle, "pcapinfom"))==NULL)
               {perror("pcap_dump_open");
                exit(1);
               }

         while(1)
         {
                 if ( pcap_next_ex(handle ,&header, (const u_char**)&pkt_data) < 0 )
                         break;
               //  packet = pcap_next(handle,&header);
                 pcap_dump((u_char*)(fileInfo), header, pkt_data);
        //        pcap_dump((u_char*)(fileInfo),&header,packet);
         }/*
        if( (pcap_loop(handle, -1, pkt_callback,NULL)) == -1 )
        {
                perror("pcap_loop");
                return(2);
            }   
*/

        //close file
            pcap_dump_close(fileInfo);

        /* And close the session */
        pcap_close(handle);
        return(0);
}

论坛徽章:
0
10 [报告]
发表于 2010-01-25 10:32 |只看该作者
我的电脑上只有一个网卡,但还是不能将数据存入文件,用pcap_dispatch()只能抓出一个包,放在循环语句里也用不了。
会不会是操作系统的版本的问题呢?
我的系统内核是:2.4.20-8.
能把你的源代码贴出来吗?多谢了!

论坛徽章:
0
9 [报告]
发表于 2010-01-25 10:00 |只看该作者
先把捕获的包打印出来看看

论坛徽章:
0
8 [报告]
发表于 2010-01-25 09:13 |只看该作者

回复 #6 wxpz 的帖子

刚才我测试了一下,有数据啊,如果你的没有,确认一下你电脑上有几块网卡

-rw-r--r-- 1 root root  40960 Jan 25 09:11 pcapinfom

论坛徽章:
0
7 [报告]
发表于 2010-01-23 20:03 |只看该作者
感谢zhainx,按你的方法修改以后也可通过,但也是没有将抓到的信息存入文件中。

其实我用其它的方法也达到了目标,就是重新写了一个函数pkt_callback,用于回调,但就是觉得太复杂,想用libpcap提供的函数完成任务,还请各位高手指教。
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP