QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1954|回复: 8

请问怎样编写网络抓包程序?

[复制链接]
发表于 2004-2-28 14:25:55 | 显示全部楼层 |阅读模式
最近用libpcap编写抓包程序时出现很多问题,哪为高手有完整的抓包程序给我借鉴一下,谢谢!
发表于 2004-2-28 21:46:59 | 显示全部楼层
嘿嘿~~居然也有人用libpcap~
[code:1]
#include <pcap.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/if_ether.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

char errbuf[PCAP_ERRBUF_SIZE];
char *dev;

typedef struct __eth_hdr
{
        u_int8_t  ether_dhost[ETH_ALEN];      /* destination eth addr */
        u_int8_t  ether_shost[ETH_ALEN];      /* source ether addr    */
        u_int16_t ether_type;  /*packet type ID field*/
}eth_hdr;

void err_exit(char *str,int i)
{
        fprintf(stderr,"%s%s\n",str,errbuf);
        exit(i);
}

void print_ether(u_int8_t *addr)
{
        int i;
        for(i=0;i<ETH_ALEN-1;i++)
                printf("%d:",addr[i]);
       
        printf("%d",addr[ETH_ALEN]);
        return ;
}

void fprint_raw_data(FILE *fp,u_char *packet,unsigned len)
{
        unsigned i;
        for(i=0;i<len;i++)
        {
//                if(NULL==fp)
                        printf("%c",packet++);
//                else
//                        fprintf(fp,"%c",packet++);
        }
//        if(NULL==fp)
                printf("\n\n");
//        else
//                fprintf(fp,"\n\n");
        return;
}

void my_call_back(u_char *usr,const struct pcap_pkthdr *pkthdr,
                const u_char *packet)
{
        struct in_addr addr;
        eth_hdr *e_hdr;
        struct iphdr *ip_hdr;
        struct tcphdr *tcp_hdr;
       
        e_hdr=(eth_hdr *)packet;
        printf("%s:%d ",dev,e_hdr->ether_type);
        print_ether(e_hdr->ether_shost);
        printf("->");
        print_ether(e_hdr->ether_dhost);
        printf("\n");
        if(e_hdr->ether_type==8)
        {
                printf("\t");
                ip_hdr=(struct iphdr *)(packet+sizeof(eth_hdr));
                addr.s_addr=ip_hdr->saddr;
                printf("%s->",inet_ntoa(addr));
                addr.s_addr=ip_hdr->daddr;
                printf("%s",inet_ntoa(addr));
                printf("\n\t");
                printf("\t%d\n",ntohs(ip_hdr->tot_len));
                if(ip_hdr->protocol==6)
                {
                        printf("\tProtocal:TCP\n");
                        tcp_hdr=(struct tcphdr *)(ip_hdr+sizeof(struct iphdr));
                        printf("\tPort:+%d->%d",
                                ntohs(tcp_hdr->source),
                                ntohs(tcp_hdr->dest));
                        printf("\n");
                }
                fprint_raw_data(fopen("./out","w+"),
                (u_char *)ip_hdr+sizeof(struct iphdr),
                ntohs(ip_hdr->tot_len)-sizeof(eth_hdr)-sizeof(struct iphdr));
       
        }
        return;
}

int main(int argc,char *argv[])
{
        pcap_t *hdl;
        bpf_u_int32 netp;
        bpf_u_int32 maskp;
        struct in_addr addr;
       
        dev=pcap_lookupdev(errbuf);
        if(NULL==dev)
                err_exit("pcap_loopupdev():",-1);
       
        if(pcap_lookupnet(dev,&netp,&maskp,errbuf)<0)
                err_exit("pcap_lookupnet():",-1);
        addr.s_addr=netp;
        printf("NET:%s\n",inet_ntoa(addr));
        addr.s_addr=maskp;
        printf("MASK:%s\n",inet_ntoa(addr));
       
        hdl=pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
        if(NULL==hdl)
                err_exit("pcap_open_live():",-1);
       
        if((argc!=2)||(!isdigit(*argv[1])))
                pcap_loop(hdl,-1,my_call_back,NULL);
        else
                pcap_loop(hdl,atoi(argv[1]),my_call_back,NULL);
        printf("END....");
        return 0;
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-3-1 09:39:54 | 显示全部楼层
默难, 感激不尽!
回复

使用道具 举报

发表于 2004-3-4 01:31:37 | 显示全部楼层
不客气不客气~那个是我前几天写的,有问题的话尽管来问啦~
回复

使用道具 举报

 楼主| 发表于 2004-3-9 17:44:40 | 显示全部楼层
可是为什么我抓出来的结果都是乱码呢?请指教!
回复

使用道具 举报

发表于 2004-3-9 19:30:50 | 显示全部楼层

没错~我那个程序抓下来之后没进行什么处理,所以就是乱码啦~
回复

使用道具 举报

 楼主| 发表于 2004-3-9 20:03:53 | 显示全部楼层
那你能教我怎样计算补捉到的数据包的数量吗?最好是能显示包头信息的!谢谢!
回复

使用道具 举报

发表于 2004-3-9 20:07:45 | 显示全部楼层
其实那些乱码就是包头信息啦~
你看看netinet里面的头文件,有ip头 tcp头的定义,看了就明白了,不明白QQ找我,或者E-mail我
回复

使用道具 举报

发表于 2004-3-9 21:39:56 | 显示全部楼层
将fprint_raw_data中的printf("%c",packet++)中的格式"%c"改为"%x"便可显示十六进制的包信息。若你取消那些注释,下一个fprintf也要一样改。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 20:50 , Processed in 0.040090 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表