⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getfreeip.c

📁 基于ARP协议的两个程序: 1:局域网攻击器 2:空闲IP查询
💻 C
字号:
/********************************************/
/**创建者:杨希          日期:2005/04/14  **/
/**文件名:getFreeIP.c   版本:1.0.2       **/
/**描  述:得到指定IP段的空闲IP            **/
/**其  它:其运行时不需要本机已经有IP,其  **/
/**        基本原理为依次广播指定IP段内的  **/
/**        每个IP的ARP请求,如果收到ARO应  **/
/**        答,则其为一个已经占用的IP      **/
/********************************************/

#include<stdio.h>
#include<string.h>   
#include<unistd.h>
#include<sys/types.h>
#include<signal.h> 
#include<sys/socket.h>    
#include<arpa/inet.h>     
#include<netdb.h> 
#include<netinet/if_ether.h>  
#include<unistd.h>  
#include<sys/stat.h>
#include <net/if_arp.h>
#include<time.h>

struct etharp { 
	struct arphdr hdr; 
	unsigned char sender_mac[6]; 
	unsigned char sender_ip[4]; 
	unsigned char rcver_mac[6]; 
	unsigned char rcver_ip[4]; 
}; 

struct etharp_frame { 
	unsigned char dst[6]; 
	unsigned char src[6]; 
	unsigned short type; 
	struct etharp arp; 
};

/* 本机的MAC地址 */
unsigned char localMAC[6] = {0x00, 0x0c, 0x29, 0x12, 0x10, 0xac}; 

/* 用于收包的结束标志 */
int FLAG = 1;

/* 返回-1,没有回应包,0有正确的回应包 */
int getARPReply(struct etharp_frame* recvBuf, int sockfd, long currIP);

/* 改变记号 */
void changeFlag()
{
	FLAG = 0;
	return ;
}

/********************************************/
int main(int argc, char* argv[])
{
	struct sockaddr addr;
	struct etharp_frame sndBuffer, rcvBuffer;    
	int sockfd, ret, len;
	long i, temp, startIP, endIP;
	
	/* 检查输入是否合法 */
	if(argc != 3){
		fprintf(stderr, "usage : ./programName startIP endIP\n");
		exit(1);
	}
	
	/* 得到其止IP */
	startIP = ntohl(inet_addr(argv[1]));
	endIP   = ntohl(inet_addr(argv[2]));
	
	if((sockfd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1){
		fprintf(stderr, "creat sockek error!\n");
		exit(1);
	}
	
	if((sockfd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1){
		fprintf(stderr, "creat sockek error!\n");
		exit(1);
	}
	
	/* 初始化addr */
	memset(&addr, 0, sizeof(addr));
	addr.sa_family = PF_PACKET;
	strcpy(addr.sa_data, "eth0");
	if(bind(sockfd, &addr, sizeof(addr)) < 0){
		fprintf(stderr, "bind sockek error!\n");
		exit(1);
	}
	
	/* 初始化一个ARP请求包,采用的方法是从网络上截获一个ARP请求包来
	   初始化 */
	while(1){
		len = sizeof(struct sockaddr);  
     		ret = recvfrom(sockfd, &rcvBuffer, sizeof(struct etharp_frame), 0, 
     		            &addr, &len);	
     		if(ret == -1)
     			continue;
     			
     		if(ntohs(rcvBuffer.arp.hdr.ar_op) != ARPOP_REQUEST)
     			continue;
     			
     		/* 具体制作ARP请求包包*/
		memcpy(&sndBuffer, &rcvBuffer, sizeof(struct etharp_frame));
		/* 将ARP请求包的源MAC地址置为本机的MAC地址,注意要复制两次 */
		memcpy(sndBuffer.src, localMAC, 6);
		memcpy(sndBuffer.arp.sender_mac, localMAC, 6);
		break;
	}
	
	/* 开始扫描存在的空闲IP */
	for(i = startIP; i <= endIP; i++){
		/* 待查询的IP地址的MAC地址 */
		temp = htonl(i);
		memcpy(sndBuffer.arp.rcver_ip, &temp, 4);
		/* 发送ARP请求包 */
		sendto(sockfd, &sndBuffer, sizeof(struct etharp_frame), 0, 
		      &addr, len);    	      
		/* 等待ARP回应包 */
		if(getARPReply(&rcvBuffer, sockfd, i) != -1)
			continue;
		printf("%s is free ip!\n", inet_ntoa(*(struct in_addr*)sndBuffer.arp.rcver_ip));
	}
}

/* 返回-1,没有回应包,0有正确的回应包 */
int getARPReply(struct etharp_frame* recvBuf, int fd, long currIP)
{  
	int ret = -1;
	
	FLAG = 1;
	/* 安装超时处理器 */
	signal(SIGALRM, changeFlag);
	
	alarm(1);
	/* 开始检查收到的包 */
	while(FLAG){	
		if(recvfrom(fd, recvBuf, sizeof(struct etharp_frame), 0, NULL, NULL) < 0){
			perror("recvfrom");
			exit(1);
		}
		if(ntohs(recvBuf->arp.hdr.ar_op) != ARPOP_REPLY)
     			continue;
     		/* 检查ARP相应包是否为当前IP的相应包 */
     		if(!memcmp(recvBuf->arp.sender_ip, &currIP, 4))
     			continue;
     		ret = 0;
     		break;
	}
	return ret;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -