网上代码敲下来后这两个函数模块的类似地方错误一直改不好,可以发完整源码,帮我运行看看错误吗
#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 *)∈
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;
}
可以把代码块放在问题里吗?
问题如下,你从哪⬇️的代码呢pacp_next_ex
这个函数名称可能拼写错误,应该是pcap_next_ex
,需要修改为正确的函数名。
在SendArpPacket
函数中,memcpy(ah.dst_mac_add,0xff,6);
这行代码可能存在问题,因为第二个参数应该是一个指向对应数据的指针,而0xff
是整数类型,需要修改为memcpy(ah.dst_mac_add, "\xff\xff\xff\xff\xff\xff", 6);
。
在GetLivePC
函数中,结构体类型struct arp_packet
没有定义,可能需要修改为struct arp_head
。
在最后返回的函数中,gparam
的类型和变量名都和之前定义的结构体类型和变量名重复,这也可能导致编译错误。
#include<stdio.h>
#include<stdlib.h> //头文件
#define MaxSize 60 //线性表存储空间的大小
typedef char ElemType; //自定义类型语句
typedef struct{ //线性表的顺序存储表示
ElemType data[MaxSize]; //存储线性中的元素
int length; //存放线性表的长度
}SqList; //线性表顺序存储结构类型名
void CreatList_Sq(SqList *&L,ElemType a[],int n)
{
int i;
L=(SqList *)malloc(sizeof(SqList)); //分配存放线性的空间
for(i=0;i<n;i++)
L->data[i]=a[i];
L->length=n; //令线性表L的长度为n
}
/*bool ListEmpty(SqList *L) //判断是否为空表
{
return(L->length==0);
}*/
void DispList(SqList *L) //输出线性表
{ int i;
/*if (ListEmpty(L))
return;*/
for (i=0;i<L->length;i++)
printf("%d",L->data[i]);
printf("\n");
}
int main()
{
SqList *L;
ElemType a[]={1,2,3,4,5,6,7,8};
CreatList_Sq(L,a,8);
printf("L:");
DispList(L);
return 0;
}