读书人

不到100行的libpcap程序获取源IP与目

发布时间: 2012-02-16 21:30:36 作者: rapoo

不到100行的libpcap程序,获取源IP与目的IP完全相同,不知道为什么,请高手给看看,谢谢
我编写的libpcap程序,分析网络数据包,发现分析出来的源IP与目的IP完全相同,而实际上不是这样的。请高手指点,谢谢。
直接编译:gcc test.c -o test -lpcap
test.c源代码如下(也可以直接下载附件):

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>
#include <string.h>
#include <time.h>
#include <error.h>

struct ether_header
{
unsigned char source[6];
unsigned char dest[6];
unsigned int type;
};

struct ip_header
{
#ifdef WORDS_BIGENDIAN
u_int8_t ip_version:4,
ip_header_length:4;
#else
u_int8_t ip_header_length:4,
ip_version:4;
#endif
u_int8_t ip_tos; /*type of service */
u_int16_t ip_length; /*length */
u_int16_t ip_id; /*identity */
u_int16_t ip_off; /* offset */
u_int8_t ip_ttl; /*time to live*/
u_int8_t ip_protocol; /* type of protocol*/
u_int16_t ip_chechsum; /* chechsum */
struct in_addr source;
struct in_addr dest;
};

void packet_callback(unsigned char* argument,const struct pcap_pkthdr* packet_header, const unsigned char* packet_content)
{
struct ether_header* eptr;
struct ip_header* iptr;

eptr=(struct ether_header*) packet_content;
switch(ntohs(eptr-> type))
{
case 0x0800 :/*IP*/
iptr=(struct ip_header*)(packet_content+14);
switch(iptr-> ip_protocol)
{
case 6: /* TCP */
printf( "%s %s \n ", inet_ntoa(iptr-> source),inet_ntoa(iptr-> dest));
break;
}


break;
}
return ;
};

int main(int argc ,char* argv[])
{
char errbuf[PCAP_ERRBUF_SIZE]; //store the information for error
char* net_interface; //store the chars of net interface
bpf_u_int32 ipaddr;
bpf_u_int32 ipmask;
pcap_t* pcap_handle; //the handle of pcap
struct bpf_program bpf_filter;
char bpf_filter_string[]= "tcp "; //the filter string

net_interface=pcap_lookupdev(errbuf);
pcap_lookupnet(net_interface,&(ipaddr),&(ipmask),errbuf);
pcap_handle=pcap_open_live(net_interface,BUFSIZ,1,0,errbuf);
if(pcap_handle==NULL)
{
printf( "Error in function pcap_open_live. Exiting ...\n ");
exit(1);
}
if(pcap_compile(pcap_handle,&bpf_filter,bpf_filter_string,0,ipaddr)==-1)
{
printf( "Error in function pcap_compile. Exiting ...\n ");
exit(1);
}
if(pcap_setfilter(pcap_handle,&bpf_filter)==-1)
{
printf( "Error in function pcap_setfilter. Exiting ...\n ");
exit(1);
}
pcap_loop(pcap_handle,-1,packet_callback,NULL);
pcap_close(pcap_handle);
return 0;
}


[解决办法]
一个Libpcap的源码分析

http://www.parsesoft.net/DocumentFiles/d9d17f9f-9c2b-4328-bfdc-e5ce602382e5/index.html
[解决办法]
发现这里有个错误
if(pcap_compile(pcap_handle,&bpf_filter,bpf_filter_string,0,ipaddr)==-1)

参数中的ipaddr 应该改为 ipmask,为什么,暂时还没有去了解

sizeof(struct ether_header)是14吗?如果不是,比如是16的话,iptr-> source则刚好偏移两个字节,指向了 2.1,和你反映的源和目标ip相同得目标ip192.168.2.1得前两个字节结合,变为
2.1.192.168

^_^纯乱猜
[解决办法]
不好意思,搞错。是用ipaddr(应该是net) 不是mask
/* 10Mb/s ethernet header */
struct ether_header
{
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*/
} __attribute__ ((__packed__));
这是应是14

你上面的问题爱莫能助

读书人网 >UNIXLINUX

热点推荐