📄 getfreeip.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 + -