Linux下用GCC编绎简单的sniffier工具
用lipcap工具包来写代码。就一个文件:eth_txt.c文件,然后在Linux环境下用GCC编绎通过,即可用在FC上面来侦测与分析网络包。
还有一个TEMP文件来保存捕获的内容。
//eth_txt.c
//when detect ethenet frame,deplay the text
//methods of use
//eth_txt <the name of interface>
//the example
//eth_txt le0
//the method of end
//input the control key C
//read the head file
#include<stdio.h>
#include<sys/types.h>
#include<sys/time.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netinet/in_systm.h>
#include<netinet/ip.h>
#include<netinet/if_ether.h>
#include<pcap.h>//pcap programe library
#include<netdb.h>//the use of DNS searching
#define DEFAULT_SNAPLEN 68
#define MAXSTRINGSIZE 256 //the length of the string
#define MAXENTRY 1024 //the max number of the fastcache in the table of the host
//print the mac address of the packet
void print_hwadd(u_char *hwadd){
int i;
for(i=0;i<5;i++)
printf("%2x:",hwadd[i]);
printf("%2x",hwadd[i]);
}
//print the ip address of the packet
void print_ipadd(u_char *ipadd){
int i;
for(i=0;i<3;++i)
printf("%d.",ipadd[i]);
printf("%d\n",ipadd[i]);
}
//mean the data of the packet
void packet_print(u_char *user,const struct pcap_pkthdr *h,const u_char *p)
{
struct ether_header *eth;//the pointer of the structe of the head of the ethernetpacket
static long int counter=0;
struct ether_arp *arppkt;
struct ip *iph;
struct icmphdr *icmp;
printf("%d\n",(h->ts).tv_sec);
printf("xiaobinker find data\n");
printf("%d\n",++counter);
printf("%d\n",h->len);
int i;
eth=(struct ether_header *)p;
print_hwadd(eth->ether_shost);
printf("----");
print_hwadd(eth->ether_dhost);
printf("\n");
printf("%x\n",ntohs(eth->ether_type));
if(ntohs(eth->ether_type)){
iph=(struct ip *)(p+sizeof(struct ether_header));
printf("Find IP ");
if(iph->ip_p==0){
icmp=(struct icmphdr *)(p+sizeof(struct ether_header)+sizeof(struct ip));
printf("ICMP packet");
//printf("%d\n",icmp->type);
}
print_hostname((u_char *)&(iph->ip_src));
//print_ipadd((u_char *)&(iph->ip_src));
printf("======");
//print_ipadd((u_char *)&(iph->ip_dst));
print_hostname((u_char *)&(iph->ip_dst));
printf("\t%d",iph->ip_ttl);
printf("\t%d",iph->ip_p);
}
unsigned int typeno;
typeno=ntohs(eth->ether_type);
if((typeno==ETHERTYPE_ARP)||(typeno==ETHERTYPE_REVARP)){
arppkt=(struct ether_arp *)(p+sizeof(struct ether_header));
if(typeno==ETHERTYPE_ARP)
printf("arp");
else printf("rarp");
print_hwadd((u_char *)&(arppkt->arp_sha));
printf(",");
print_ipadd((u_char *)&(arppkt->arp_spa));
printf("========");
print_hwadd((u_char *)&(arppkt->arp_tha));
printf(",");
print_ipadd((u_char *)&(arppkt->arp_tpa));
}
printf("\n");
fflush(stdout);
}
//the struct of the table (the use of host)
struct {
unsigned long int ipaddr; //the ip address
char hostname[MAXSTRINGSIZE]; //the name of the host
}nametable[MAXENTRY];
int tbllength=0;
//converge the hostname
void intohost(unsigned long int iadd,char *hn){
int i;
extern int tbllength;
for(i=0;i<tbllength;++i)
if(nametable[i].ipaddr==iadd)break;
if(i<tbllength){
strcpy(hn,nametable[i].hostname);
}
else{
fprintf(stderr,"Internal Error on void intohost()\n");
exit(1);
}
}
//log the hostname
void reghost(unsigned long int iadd){
int i;
struct hostent *shostname;
extern int tbllength;
for(i=0;i<tbllength;++i){
if(nametable[i].ipaddr==iadd)break;
}
if(i==tbllength){
nametable[i].ipaddr=iadd;
shostname=gethostbyaddr((char *)&iadd,sizeof(iadd),AF_INET);
if(shostname!=NULL){
strcpy(nametable[i].hostname,shostname->h_name);
}
else{
strcpy(nametable[i].hostname,"");
}
tbllength++;
}
}
//output the hostname
void print_hostname(u_char *ipadd){
int i;
unsigned long int iadd;
struct hostent *hostname;
char hn[MAXSTRINGSIZE];
iadd=*((unsigned long int *)(ipadd));
reghost(iadd);
intohost(iadd,hn);
if(strlen(hn)>0)
printf("%s",hn);
else{
for(i=0;i<3;++i)
printf("%d:",ipadd[i]);
printf("%d:",ipadd[i]);
}
}
//main
//the start and configure of getting packet
int main(int argc,char **argv)
{
char ebuf[PCAP_ERRBUF_SIZE];
pcap_t *pd;
if(argc<=1){
printf("usage:%s <network interface>\n",argv[0]);
exit(0);
}
/*configure using pcap*/
if((pd=pcap_open_live(argv[1],DEFAULT_SNAPLEN,1,1000,ebuf))==NULL)
{
(void)fprintf(stderr,"%s",ebuf);
exit(1);
}
/*get the packet by the pcap_loop*/
if(pcap_loop(pd,-1,packet_print,NULL)<0){
(void)fprintf(stderr,"pcap_loop:%s\n",pcap_geterr(pd));
exit(1);
}
pcap_close(pd);
exit(0);
}