📄 catch.c
字号:
//catch.c
//使用方法:catch〈网络接口名〉 > 〈输出文件名〉
//例如:catch etho > temp.txt
//结束方法:ctrl+c
//程序开始,读入头文件
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netinet/in_systm.h>
#include<netinet/ip.h>
#include<netinet/tcp.h>
#include<netinet/udp.h>
#include<netinet/if_ether.h>
#include<pcap.h> //pcap程序库
#include<netdb.h> //DNS检索使用
#define MAXSTRINGSIZE 256 //字符串长度
#define MAXSIZE 1024 //主机高速缓存中的最大记录条数
#define DEFAULT_SNAPLEN 68 //数据包数据的长度
int packet_num;
typedef struct
{
unsigned long int ipaddr; //IP地址
char hostname[MAXSTRINGSIZE]; //主机名
}dnstable; //高速缓存数据结构
typedef struct
{
dnstable table[MAXSIZE];
int front;
int rear;
}sequeue;
sequeue * sq; //定义缓存队列
//选择网络设备
pcap_if_t * select_netdrv()
{
pcap_if_t * alldevs;
pcap_if_t * d;
int inum;
int i=0;
pcap_t * adhandle;
char errbuf[PCAP_ERRBUF_SIZE]; //错误信息缓冲区
//取得网络设备列表
if(pcap_findalldevs(&alldevs,errbuf)==-1)
{
fprintf(stderr,"Error in pcap_findalldevs:%s\n",errbuf);
exit(1);
}
//显示网络设备列表
for(d=alldevs;d;d=d->next)
{
printf("%d. %s",++i,d->name);
if(d->description)
printf("(%s)\n",d->description);
else
printf("(No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure MinPcap is installed.\n");
exit(1);
}
//选择网络设备
printf("Enter the interface number(1-%d):",i);
scanf("%d",&inum);
if(inum<1||inum>i)
{
printf("\nInterface number out of range.\n");
//释放设备列表
pcap_freealldevs(alldevs);
exit(1);
}
//跳转到已选择的网络适配器
for(d=alldevs,i=0;i<inum-1;d=d->next,i++);
return (d);
}
//输出MAC地址函数
void print_hwadd(u_char * hwadd)
{
int i;
for(i=0;i<5;++i)
printf("%2x:",hwadd[i]);
printf("%2x",hwadd[i]);
}
//输出IP地址的函数
void print_ipadd(u_char *ipadd)
{
int i;
for(i=0;i<3;++i)
printf("%d.",ipadd[i]);
printf("%d",ipadd[i]);
}
//查询端口函数
void getportname(int portno,char portna[],char* proto)
{
if(getservbyport(htons(portno),proto)!=NULL)
{
strcpy(portna,getservbyport(htons(portno),proto)->s_name);
}
else
sprintf(portna,"%d",portno);
}
/*
//将IP转化为DNS名
void iptohost(unsigned long int ipad,char* hostn)
{
struct hostent * shostname;
int m,n,i;
m=sq->rear;
n=sq->front;
for(i=n%MAXSIZE;i=m%MAXSIZE;i=(++n)%MAXSIZE)
{
//检查IP是否第一次出现
if(sq->table[i].ipaddr==ipad)
{
strcpy(hostn,sq->table[i].hostname);
break;
}
}
if(i=m%MAXSIZE)
{//不存在则从域名服务器查询并把结果放入高速缓存
if((sq->rear+1)%MAXSIZE==sq->front) //判队满
sq->front=(sq->front+1)%MAXSIZE; //出队列
sq->table[i].ipaddr=ipad;
shostname=gethostbyaddr((char*)&ipad,sizeof(ipad),AF_INET);
if(shostname!=NULL)
strcpy(sq->table[i].hostname,shostname->h_name);
else
strcpy(sq->table[i].hostname,"");
sq->rear=(sq->rear+1)%MAXSIZE;
}
}
*/
void print_hostname(u_char* ipadd)
{
unsigned long int ipad;
char hostn[MAXSTRINGSIZE];
ipad=*((unsigned long int *)ipadd);
/*
iptohost(ipad,hostn);
if(strlen(hostn)>0)
printf("%s",hostn);
else
*/
print_ipadd(ipadd);
}
//处理数据包的函数
void packet_proce(u_char* packets,const struct pcap_pkthdr * header,const u_char *pp)
{
struct ether_header * eth; //以太网帧报头指针
struct ether_arp * arph; //ARP报头
struct ip * iph; //IP报头
struct tcphdr * tcph;//TCP报头
struct udphdr * udph;//UDP报头
u_short srcport,dstport; //端口号
char protocol[MAXSTRINGSIZE]; //协议类型名
char srcp[MAXSTRINGSIZE],dstp[MAXSTRINGSIZE]; //端口名
unsigned int ptype; //协议类型变量
u_char * data; //数据包数据指针
u_char tcpudpdata[MAXSTRINGSIZE]; //数据包数据
int i;
time_t timep;
time(&timep);//取得当前时间
packet_num++;
eth=(struct ether_header *)pp;
ptype=ntohs(((struct ether_header *)pp)->ether_type);
if((ptype==ETHERTYPE_ARP)||(ptype==ETHERTYPE_REVARP))//ARP或RARP数据包
{
arph=(struct ether_arp *)(pp+sizeof(struct ether_header));
if(ptype==ETHERTYPE_ARP)
printf("arp ");
else
printf("rarp "); //输出协议类型
print_hwadd((u_char *)&(arph->arp_sha));
printf("(");
print_hostname((u_char *)&(arph->arp_spa));
printf(")\n->");
print_hwadd((u_char *)&(arph->arp_tha));
printf("(");
print_hostname((u_char *)&(arph->arp_tpa));
printf(")\n\tpacketlen:%d",header->len);
}
else if(ptype==ETHERTYPE_IP) //IP数据报
{
iph=(struct ip *)(pp+sizeof(struct ether_header));
if(iph->ip_p==1) //ICMP报文
{
strcpy(protocol,"icmp");
srcport=dstport=0;
}
else if(iph->ip_p==6) //TCP报文
{
strcpy(protocol,"tcp");
tcph=(struct tcphdr *)(pp+sizeof(struct ether_header)+4*iph->ip_hl);
srcport=ntohs(tcph->source);
dstport=ntohs(tcph->dest);
data=(u_char *)(pp+sizeof(struct ether_header)+4*iph->ip_hl+4*tcph->doff);
for(i=0;i<MAXSTRINGSIZE-1;++i)
{
if(i>=header->len-sizeof(struct ether_header)-4*iph->ip_hl-4*tcph->doff)
break;
//else
tcpudpdata[i]=data[i];
}
} //TCP数据处理完毕
else if(iph->ip_p=17) //UDP报文
{
strcpy(protocol,"udp");
udph=(struct udphdr *)(pp+sizeof(struct ether_header)+4*iph->ip_hl);
srcport=ntohs(udph->source);
dstport=ntohs(udph->dest);
data=(u_char *)(pp+sizeof(struct ether_header)+4*iph->ip_hl+8);
for(i=0;i<MAXSTRINGSIZE-1;++i)
{
if(i>=header->len-sizeof(struct ether_header)-4*iph->ip_hl-8)
break;
else
tcpudpdata[i]=data[i];
}
}
tcpudpdata[i]='\0';
getportname(srcport,srcp,protocol);
getportname(dstport,dstp,protocol);
//-------输出部分-----
//printf("ip ");
printf("\n\n--------------------Packet %d --------------------------\n",packet_num);
printf("captured at %s ",ctime(&timep));
print_hwadd(eth->ether_shost);
printf("(");
print_hostname((u_char *)&(iph->ip_src));
printf(")[%s:%s]->\n",protocol,srcp);
print_hwadd(eth->ether_dhost);
printf("(");
print_hostname((u_char *)&(iph->ip_dst));
printf(")[%s:%s]\n",protocol,dstp);
printf("ttl:%d packetlen:%d",iph->ip_ttl,header->len);
printf("\n%s\n",tcpudpdata);
printf("--------------------endpacket--------------------------");
}
printf("\n");
}
//Main函数取数据包并初始化程序环境
int main(int argc,char ** argv)
{
//sq->rear=-1;
//sq->front=-1; //初始化队列
pcap_if_t * net_drv;
char ebuf[PCAP_ERRBUF_SIZE];
struct pcap * pd;
//设置PCAP程序库
net_drv=select_netdrv();
if((pd=pcap_open_live(net_drv->name,DEFAULT_SNAPLEN,1,1000,ebuf))==NULL)
{
(void)fprintf(stderr,"%s",ebuf);
exit(1);
}
//循环取数据包
//改变参数-1为其它值,可确定取数据包的个数,这里为无限个
if(pcap_loop(pd,-1,packet_proce,NULL)<0)
{
(void)fprintf(stderr,"pcap_loop:%s\n",pcap_geterr(pd));
exit(1);
}
pcap_close(pd);
exit(0);
}
//程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -