| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2029 人关注过本帖
标题:winpacp和c++
只看楼主 加入收藏
sumoer
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2017-1-12
结帖率:0
收藏
已结贴  问题点数:20 回复次数:4 
winpacp和c++
#include<stdio.h>
#include<string.h>
#include"pcap.h"
#include"Packet64.h"
#pragma pack(1)  //按一个字节内存对齐
#define IPTOSBUFFERS  12
#define ETH_ARP       0x0806 //以太网帧类型表示后面数据的类型,对于ARP请求或应答来说,该字段的值为0x0806
#define ARP_HARDWARE  1      //硬件类型字段值表示以太网地址
#define ETH_IP        0x0800 //协议类型字段表示要映射的协议地址,类型值为0x0800表示IP地址
#define ARP_REQUEST   1
#define ARP_REPLY     2
#define HOSTNUM       255
/*packet handler 函数原型*/
void packet_handler(u_char *param,const struct pcap_pkthdr *header,const u_char *pkt_data);
//函数原型
void ifget(pcap_if_t*d,char *ip_addr,char ip_netmask);
char *iptos(u_long in);
char *ip6tos(struct sockaddr *sockaddr,char *address,int addrlen);
int SendArp(pcap_t *adhandle,char *ip,unsigned char *mac);
int GetSelfMac(pcap_t *adhandle,const *ip_addr,unsigned char *ip_mac);
DWORD WINAPI SendArpPacket(LPVOID lpParameter);
DWORD wINAPI GetLivePC(lPVOID IpParameter);
//28字节ARP帧结构
struct arp_head
{
    unsigned short hardware_type;    //硬件类型
    unsigned short protocol_type;    //协议类型
    unsigned char hardware_add_len;  //硬件地址长度
    unsigned char protocol_add_len;  //协议地址长度
    unsigned short operation_field;  //操作字段
    unsigned char source_mac_add[6]; //源MAC地址
    unsigned long source_ip_add;     //源IP地址
    unsigned char dest_mac_add[6];   //目的MAC地址
    unsigned long dest_ip_add;       //目的IP地址
};
//14字节以太网帧结构
struct ethernet_head
{
    unsigned char dest_mac_add[6];//目的MAC地址
    unsigned char source_mac_add[6];//源MAC地址
    unsigned short type;//帧类型
};
//ARP最终包结构
struct arp_packet
{
    struct ethernet_head ed;
    struct arp_head ah;
};
struct sparam
{
    pcap_t *adhandle;
    char *ip;
    unsigned char *mac;
    char *netmask;
};
struct gparam
{
    pacp_t *adhandle;
};
bool flag;
struct sparam sp;
struct gparam gp;

int main()
{
    pacp_if_t *alldevs;
    pacp_if_t *d;
    int inum;
    int i=0;
    pacp_t *adhandle;
    char errbuf[PCAP_ERRBUF_SIZE];
    char *ip_addr;
    char *ip_netmask;
    unsigned char *ip_mac;
    HANDLE sendthread;
    HANDLE recnthread;

    ip_addr=(char *)malloc(sizeof(char)*16);
    if(ip_addr==NULL)
    {
        printf("申请内存存放IP地址失败!\n");       //申请内存存放IP地址
        return -1;
    }
    ip_netmask=(char *)malloc(sizeof(char)*16);
    if(ip_netmask=NULL)
    {
        printf("申请内存存放NETMASK地址失败\n");     //申请内存存放NETMASK地址
        return -1;
    }
    ip_mac=(unsigned char *)malloc(sizeof(unsigned char)*6);
    if(ip_mac==NULL)
    {
        printf("申请内存存放MAC地址失败!\n");
        return -1;
    }
    /*获取本机设备列表*/
    if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1)
    {
        fprintf(stderr,"Error in pcap_findalldevs:%s\n",errbuf);
        exit(1);
    }
    /*打印列表*/
    printf("[本机网卡列表:]\n");
    for(d=alldevs;d;d=d->next)
    {
        printf("%d)%s\n",++i,d->name);
        if(d->description)
            printf("(%s)\n",d->description);
        else
            printf("(No description available)\n");
    }
    if(i==0)
    {
        printf("\n找不到网卡!请确认是否已安装WinPcap.\n");
        return -1;
    }
    printf("\n");
    printf("请选择要打开的网卡号(1-%d):",i);
    scanf("%d",&inum);
    if(inum<1||inum>i)
    {
        printf("\n 该网卡号超过现有网卡数!请按任意键退出...\n");
        getchar();
        getchar();
        /*释放设备列表*/
        pcap_freealldevs(alldevs);
        retrun -1;
    }
    /*跳转到选中的适配器*/
    for(d=alldevs,i=0;i<inum-1;d=d->next,i++);
    /*打开设备*/
    if((adhandle=pcap_open(d->name,//设备名
        65536,                     //65535保证能捕获到不同数据链路层上的每个数据包的全部内容
        PCAP_OPENFLAG_PROMISCUOUS, //混杂模式
        1000,                      //读取超时时间
        NULL,                       //远程机器验证
        errbuf                     //错误缓冲池
        ))==NULL)
        {
            fprintf(stderr,"\n无法读取该适配器,适配器%s,不被WinPcap支持\n",d->name);
            /*释放设备列表*/
            pcap_freealldevs(alldevs);
            retrurn -1;
        }
        ifget(d,ip_addr,ip_netmask);//获取所选网卡的基本信息-掩码-地址
        GetSelfMac(adhandle,ip_addr,ip_mac);//输入网卡设备句柄网卡设IP地址获取该设备的MAC地址
        sp.adhandle=adhandle;
        sp.ip=ip_addr;
        sp.mac=ip_mac;
        
        gp.adhandle=adhandle;
        sendthread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)SendArpPacket,&sp,0,NULL);
        recvthread=CreateThread(NULL,0,(lpTHREAD_START_ROUTINE)GetLivePC,&gp,0,NULL);
        printf("\nlistening on 网卡%d...\n",inum);
        /*释放设备列表*/
        pcap_freealldevs(alldevs);
        getchar();
        getchar();
        return 0;
}
/*获取可用信息*/
void ifget(pcap_if_t *d,char *ip_addr,char *ip_netmask)
{
    pcap_addr_t *a;
    char ip6str[128];
    /*IP addresses*/
    for(a=d->addresses,a;a=a->next)
    {
        switch(a->addr->sa_family)
        {
            case AF_INET;
            if(a->addr)
            {
                char *ipstr;
                ipstr=iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr);//*ip_addr
                memcpy(ip_addr,ipstr,16);
            }
            if(a->netmask)
            {
                char *netmaskstr;
                netmaskstr=iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr);
                memcpy(ip_netmask,netmaskstr,16);
            }
            case AF_INET6;
            break;
        }
    }
}
/*将数字类型的IP地址转换成字符串类型*/
char *iptos(u_long in)
{
    static char output[IPTOSBUFFERS][3*4+3+1];
    static short which;
    u_char *p;
    p=(u_char *)&in;
    which=(which+1==IPTOSBUFFERS?0:which+1);
    sprintf(output[which],"%d.%d.%d.%d",p[0],p[1],p[2],p[3]);
    return output[which];
}
char *ip6tos(struct sockaddr *sockaddr,char *address,int addrlen)
{
    socklen_t sockaddrlen;
    #ifdef WIN32
    sockaddrlen=sizeof(struct sockaddr_in6);
    #else
    sockaddrlen=sizeof(struct sockaddr_storage);
    #endif

    if(getnameinfo(sockaddr,sockaddrlen,address,addrlen,NULL,0,NI_NUMERICHOST)!=0)
        address=NULL;
    return address;
}
/*获取自己主机的MAC地址*/
int GetSelfMac(pcap_t *adhandle,const *ip_addr,unsigned char *ip_mac)
{
    unsigned char sendbuf[42];//ARP包结构大小
    int i=-1;
    int res;
    struct ethernet_head eh;
    struct arp_head ah;
    struct pcap_pkthdr *pkt_header;
    const u_char *pkt_data;
    memset(eh.dest_mac_add,0xff,6);//目的地址全为广播地址
    memset(eh.source_mac_add,0x0f,6);
    memset(ah.source_mac_add,0x0f,6);
    memset(ah.dest_mac_add,0x00,6);
    th.type=htons(ETH_ARP);
    ah.hardware_type=htons(ARP_HARDWARE);
    ah.protocol_type=htons(ETH_IP);
    ah.hardware_add_len=6;
    ah.protocol_add_len=4;
    ah.source_ip_add=inet_addr("100.100.100.100");//随便设的请求方IP
    ah.operation_field=htons(ARP_REQUEST);
    ah.dest_ip_add=inet_addr(ip_addr);
    memset(sendbuf,0,sizeof(sendbuf));
    memcpy(sendbuf,&eh,sizeof(eh));
    memcpy(sendbuf+sizeof(eh),&ah,sizeof(ah));
    if(pcap_sendpacket(adhandle,sendbuf,42)==0)
    {
        printf("\nPacketSend succeed\n");
    }
    else
    {
        printf("PacketSendPacket in getmine Error:%d\n",GetLastError());
        return 0;
    }
    while((res=pcap_next_ex(adhandle,&pkt_header,&pkt_data))>=0)
    {
        if(*(unsigned short *)(pkt_data+12)==htons(ETH_ARP)&&*(unsigned short *)(pkt_data+20)==htons(ARP_REPLY)&&*(unsigned long *)(pkt_data+38)==inet_addr("100,100,100,100"))
        {
            for(i=0;i<6;i++)
            {
                ip_mac[i]=*(unsigned char *)(pkt_data+22+i);
            }
            printf("获取自己主机的MAC地址成功!\n");
            break;
        }
    }
    if(i==6)
    {
        return 1;
    }
    else
    {
        return 0;
    }

}
/*向局域网内所有可能的IP地址发送ARP请求包线程*/
DWORD WINAPI SendArpPacket(LPVOID lpParameter)//(pcap_t *adhandle,char *ip,unsigned char *mac,char *netmask)
{
    sparam *spara=(sparam *)lpParameter;
    pcap_t *adhandle=spara->adhandle;
    char *ip=spara->ip;
    unsigned char *mac=spara->mac;
    char *netmask=spara->netmask;
    printf("ip_mac:%02x-%02x-%02x-%02x-%02x-%02x\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
    printf("自身的IP地址为:%s\n",ip);
    printf("地址掩码NETMASK为:%s\n",netmask);
    printf("\n");
    unsigned char sendbuf[42];//arp包结构大小
    struct ethernet_head eh;
    struct arp_head ah;
    memset(eh.dest_mac_add,0xff,6);//目的地址全为广播地址
    memcpy(eh.source_mac_add,mac,6);
    memcpy(ah.source_mac_add,mac,6);
    memset(ah.dest_mac_add,0x00,6);
    eh.type=htons(ETH_ARP);
    ah.hardware_type=htons(ARP_HARDWARE);
    ah.protocol_type=htons(ETH_IP);
    ah.hardware_add_len=6;
    ah.protocol_add_len=4;
    ah.source_ip_add=inet_addr(ip);//请求方的IP地址为自身的IP地址
    ah.operation_field=htons(ARP_REQUEST);
    //向局域网内广播发送ARP包
    unsigned long myip=inet_addr(ip);
    unsigned long mynetmask=inet_addr(netmask);
    unsigned long hisip=htonl((myip&mynetmask));
    for(int i=0;i<HOSTNUM;i++)
    {
        ah.dest_ip_add=hton(hisip+i);
        memset(sendbuf,0,sizeof(sendbuf));
        memcpy(sendbuf,&eh,sizefo(eh));
        memcpy(sendbuf+sizeof(eh),&ah,sizeof(ah));
        if(pcap_sendpacket(adhandle,sendbuf,42)==0)
        {
            //printf("\nPacketSend succed\n");
        }
        else
        {
            printf("PacketSendPacket in getmine Error:%d\n",GetLastError());
        }
        Sleep(50);
    }
    Sleep(1000);
    flag=TRUE;
    return 0;
}
/*分析截留的数据包获取活动的主机IP地址*/
DWORD WINAPI GetLivePc(LPVOID lpParameter)//(pcap_t *adhandle)
{
    gparam *gpara=(gparam *)lpParameter;
    pcap_t *adhandle=gpara->adhandle;
    const u_char *pkt_data;
    while(true)
    {
        if(flag)
        {
            printf("扫描完毕,按任意键退出!\n");
            break;
        }
        if((res=pcap_next_ex(adhandle,&pkt_header,&pkt_data))>=0)
        {
            if(*(unsigned short *)(pkt_data+20)==htons(ARP_REPLY))
            {
                struct arp_packet *recv=(arp_packet *)pkt_data;
                if(*(unsigned short *)(pkt_data+20)==htons(ARP_REPLY))
                {
                    printf("--------------------------------------\n");
                    printf("IP地址:%d.%d.%d.%d       MAC地址:",recv->ah.source_ip_add&255,recv->ah.source_ip_add>>8&255,recv->ah.source_ip_add>>24&255);
                    for(int i=0;i<6;i++)
                    {
                        Mac[i]=*(unsigned char *)(pkt_data+22+i);
                        printf("%02x",Mac[i]);
                    }
                    printf("\n");
                }
            }        
        }
        Sleep(10);
    }
    return 0;
}
搜索更多相关主题的帖子: 硬件 以太网 IP地址 include 
2017-01-12 12:13
sumoer
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2017-1-12
收藏
得分:0 
WinPcap_4_1_3
WpdPack_4_1_2
,用的这两个文件
2017-01-12 12:15
sumoer
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2017-1-12
收藏
得分:0 
求大神帮助
2017-01-12 12:15
sumoer
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2017-1-12
收藏
得分:0 
warning C4091: 'typedef ' : ignored on left of 'int' when no variable is declared
2017-01-12 12:24
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10538
专家分:42927
注 册:2014-5-20
收藏
得分:20 
做什么用的?
2017-01-12 15:49
快速回复:winpacp和c++
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020822 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved