北斋143 2023-06-22 16:50 采纳率: 61.5%
浏览 48
已结题

网上代码敲下来后这两个函数模块的类似地方错误一直改不好

网上代码敲下来后这两个函数模块的类似地方错误一直改不好,可以发完整源码,帮我运行看看错误吗

img

img

img

img

img

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"Ws2_32.lib")
#include "pcap.h"
#include "Packet32.h"
#pragma pack(1)
#define IPTOSBUFFERS  12
#define ETH_ARP   0x0806
#define ARP_HARDWARE 1
#define ETH_IP    0x0800
#define ARP_REQUEST  1
#define ARP_REPLY    2
#define HOSTNUM      255


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 char *ip_addr,unsigned char *ip_mac);
DWORD WINAPI SendArpPacket(LPVOID lpParameter);
DWORD WINAPI GetLivePC(LPVOID lpParameter);

//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 src_mac_add[6];  //源mac地址
 unsigned long src_ip_add;      //源ip
 unsigned char dst_mac_add[6];  //目的mac地址
 unsigned long dst_ip_add;      //目的ip地址
};

//14字节以太网帧结构
struct ethernet_head
{
 unsigned char dst_mac_add[6];
 unsigned char src_mac_add[6];
 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
{
 pcap_t *adhandle;
};
int flag;
struct sparam sp;
struct gparam gp;
int main()
{
    pcap_if_t *alldevs;
    pcap_if_t *d;
    int inum;
    int i=0;
    pcap_t *adhandle;
    char errbuf[PCAP_ERRBUF_SIZE];
    char *ip_addr;
    char *ip_netmask;
    unsigned char *ip_mac;
    HANDLE sendthread;
    HANDLE recvthread;

    ip_addr=(char *)malloc(sizeof(char)*16);  //申请内存存放IP地址
    if(ip_addr==NULL){
        printf("申请内存存放IP地址失败1\n");
        return -1;
    }
    ip_netmask=(char *)malloc(sizeof(char)*16);
    if(ip_netmask==NULL){
        printf("申请内存存放NETMASK地址失败!\n");
        return -1;
    }
    ip_mac=(unsigned char *)malloc(sizeof(unsigned char)*6);//申请内存存放MAC地址
    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);
          return -1;
       }
       //跳转到选中得适配器
       for(d=alldevs,i=0;i<inum-1;d=d->next,i++)
        //打开设备
        if((adhandle=pcap_open(d->name,65536, PCAP_OPENFLAG_PROMISCUOUS,1000, NULL, errbuf))==NULL)  //PCAP_OPENFLAG_PROMINSICUOUS 混杂模式
       {
           fprintf(stderr,"\n无法读取该适配器,适配器%s 不被WinPcap支持\n",d->name);
           pcap_freealldevs(alldevs);
           return -1;
       }
       void ifget(d,ip_addr,ip_netmask);
       GetSelfMac(adhandle,ip_addr,ip_mac);
       sp.adhandle=adhandle;
       sp.ip=ip_addr;
       sp.mac=ip_mac;
       sp.netmask=ip_netmask;
       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("\nlisting 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];

    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);
          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 char *ip_addr,unsigned char *ip_mac)
{
    unsigned char sendbuf[42];
    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.dst_mac_add,0xff,6);//目的地址全为广播地址
    memset(eh.src_mac_add,0x0f,6);
    memset(ah.src_mac_add,0x0f,6);
    memset(ah.dst_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.hardware_add_len=4;
    ah.src_ip_add=inet_addr("100.100.100.100");//随便设一个请求方ip
    ah.operation_field=htons(ARP_REQUEST);
    ah.dst_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",(int)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){
  struct 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];
  struct ethernet_head eh;
  struct arp_head ah;
  memset(eh.dst_mac_add,0xff,6);
  memcpy(eh.src_mac_add,mac,6);
  memcpy(ah.src_mac_add,mac,6);
  memcpy(ah.dst_mac_add,0xff,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.src_ip_add=inet_addr(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.dst_ip_add=htonl(hisip+i);
    memset(sendbuf,0,sizeof(sendbuf));
    memcpy(sendbuf,&eh,sizeof(sendbuf));
    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",(int)GetLastError());
    }
    Sleep(50);
  }
  Sleep(1000);
  flag=1;
  return 0;

}

//分析截留的数据包获取活动的主机IP地址
DWORD WINAPI GetLivePC(LPVOID lpParameter)
{
    struct gparam *gparam=(gparam*)lpParameter;
    pcap_t *adhandle=gparam->adhandle;
    int res;
    unsigned char Mac[6];
    struct pcap_pkthdr *pkt_header;
    const char *pkt_data;
    while(1){
        if(flag){
            printf("扫描完毕,按任意键退出!\n");
            break;
        }
        if((res=pacp_next_ex(adhandle,&pkt_header,&pkt_data))>=0){
            if(*(unsigned short*)(pkt_data+12)==htons(ETH_ARP)){
                    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.src_ip_add&255,recv->ah.src_ip_add>>8&255,recv->ah.src_ip_add>>16&255,recv->ah.src_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;
}


  • 写回答

3条回答 默认 最新

  • P2441M 2023-06-22 16:59
    关注

    可以把代码块放在问题里吗?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月30日
  • 已采纳回答 6月22日
  • 修改了问题 6月22日
  • 修改了问题 6月22日
  • 展开全部

悬赏问题

  • ¥15 Matlab安装yalmip和cplex功能安装失败
  • ¥15 加装宝马安卓中控改变开机画面
  • ¥15 STK安装问题问问大家,这种情况应该怎么办
  • ¥15 更换了一个新的win10系统,再下载VS时碰到的问题,是C++组件的?
  • ¥15 关于罗技鼠标宏lua文件的问题
  • ¥15 halcon ocr mlp 识别问题
  • ¥15 已知曲线满足正余弦函数,根据其峰值,还原出整条曲线
  • ¥20 无法创建新的堆栈防护界面
  • ¥15 sessionStorage在vue中的用法
  • ¥15 wordpress更换域名后用户图片头像不显示