DHCP编程高手帮忙,在分配地址前加一段功能,检测非DHCP 客户机使用的IP

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DHCP编程高手帮忙,在分配地址前加一段功能,检测非DHCP 客户机使用的IP相关的知识,希望对你有一定的参考价值。

DHCP 服务器对预分配给DHCP 客户机的地址进行冲突检测, 服务器端在分配客户端地址之前, 通过向网络中发送包含预分配地址的ARP 请求报文,进行IP 地址冲突检测。即服务器端在封装DHCPACK 报文之前, 对从IP 地址池选择的分配给DHCP 客户端的IP 地址作图的处理。通过向网络中发送包含预分配地址的ARP 请求报文, 如果有主机回应, 则表示网络内存在地址冲突。
如能帮助解决,可现金酬谢

/*
checkip.h
*/

#ifndef __CHECKIP_H
#define __CHECKIP_H

struct arpMsg
struct ethhdr ethhdr; /* Ethernet header */
u_short htype; /* hardware type (must be ARPHRD_ETHER) */
u_short ptype; /* protocol type (must be ETH_P_IP) */
u_char hlen; /* hardware address length (must be 6) */
u_char plen; /* protocol address length (must be 4) */
u_short operation; /* ARP opcode */
u_char sHaddr[6]; /* sender's hardware address */
u_char sInaddr[4]; /* sender's IP address */
u_char tHaddr[6]; /* target's hardware address */
u_char tInaddr[4]; /* target's IP address */
u_char pad[18]; /* pad for min. Ethernet payload (60 bytes) */
;

struct server_config_t
u_int32_t server; /* Our IP, in network order */
u_int32_t start; /* Start address of leases, network order */
u_int32_t end; /* End of leases, network order */
struct option_set *options; /* List of DHCP options loaded from the config file */
char *interface; /* The name of the interface to use */
int ifindex; /* Index number of the interface to use */
unsigned char arp[6]; /* Our arp address */
unsigned long lease; /* lease time in seconds (host order) */
unsigned long max_leases; /* maximum number of leases (including reserved address) */
char remaining; /* should the lease file be interpreted as lease time remaining, or
* as the time the lease expires */
unsigned long auto_time; /* how long should udhcpd wait before writing a config file.
* if this is zero, it will only write one on SIGUSR1 */
unsigned long decline_time; /* how long an address is reserved if a client returns a
* decline message */
unsigned long conflict_time; /* how long an arp conflict offender is leased for */
unsigned long offer_time; /* how long an offered address is reserved */
unsigned long min_lease; /* minimum lease a client can request*/
char *lease_file;
char *pidfile;
char *notify_file; /* What to run whenever leases are written */
u_int32_t siaddr; /* next server bootp option */
char *sname; /* bootp server name */
char *boot_file; /* bootp boot file option */
;

#endif /* __CHECKIP_H */
/*
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*/

/*
checkip.c
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>

#include "checkip.h"

#define LOG_EMERG "EMERGENCY!"
#define LOG_ALERT "ALERT!"
#define LOG_CRIT "critical!"
#define LOG_WARNING "warning"
#define LOG_ERR "error"
#define LOG_INFO "info"
#define LOG_DEBUG "debug"
#define LOG(level, str, args...) do printf("%s, ", level); \
printf(str, ## args); \
printf("\n"); while(0)
#define DEBUG(level, str, args...) LOG(level, str, ## args)

/* miscellaneous defines */
#define MAC_BCAST_ADDR (unsigned char *) "\xff\xff\xff\xff\xff\xff"
#define ETH_INTERFACE "eth0"
/* globals */
struct server_config_t server_config;

int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp)

int fd;
struct ifreq ifr;
struct sockaddr_in *our_ip;

memset(&ifr, 0, sizeof(struct ifreq));
if((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0)
ifr.ifr_addr.sa_family = AF_INET;
strcpy(ifr.ifr_name, interface);

/*this is not execute*/
if (addr)
if (ioctl(fd, SIOCGIFADDR, &ifr) == 0)
our_ip = (struct sockaddr_in *) &ifr.ifr_addr;
*addr = our_ip->sin_addr.s_addr;
DEBUG(LOG_INFO, "%s (our ip) = %s", ifr.ifr_name, inet_ntoa(our_ip->sin_addr));
else
LOG(LOG_ERR, "SIOCGIFADDR failed, is the interface up and configured?: %s",
strerror(errno));
return -1;



if (ioctl(fd, SIOCGIFINDEX, &ifr) == 0)
DEBUG(LOG_INFO, "adapter index %d", ifr.ifr_ifindex);
*ifindex = ifr.ifr_ifindex;
else
LOG(LOG_ERR, "SIOCGIFINDEX failed!: %s", strerror(errno));
return -1;

if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0)
memcpy(arp, ifr.ifr_hwaddr.sa_data, 6);
DEBUG(LOG_INFO, "adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x",
arp[0], arp[1], arp[2], arp[3], arp[4], arp[5]);
else
LOG(LOG_ERR, "SIOCGIFHWADDR failed!: %s", strerror(errno));
return -1;


else
LOG(LOG_ERR, "socket failed!: %s", strerror(errno));
return -1;

close(fd);
return 0;


/* args: yiaddr - what IP to ping
* ip - our ip
* mac - our arp address
* interface - interface to use
* retn: 1 addr free
* 0 addr used
* -1 error
*/

/* FIXME: match response against chaddr */
int arpping(u_int32_t yiaddr, u_int32_t ip, unsigned char *mac, char *interface)


int timeout = 2;
int optval = 1;
int s; /* socket */
int rv = 1; /* return value */
struct sockaddr addr; /* for interface name */
struct arpMsg arp;
fd_set fdset;
struct timeval tm;
time_t prevTime;

if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1)
LOG(LOG_ERR, "Could not open raw socket");
return -1;


if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) == -1)
LOG(LOG_ERR, "Could not setsocketopt on raw socket");
close(s);
return -1;


/* send arp request */
memset(&arp, 0, sizeof(arp));
memcpy(arp.ethhdr.h_dest, MAC_BCAST_ADDR, 6); /* MAC DA */
memcpy(arp.ethhdr.h_source, mac, 6); /* MAC SA */
arp.ethhdr.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */
arp.htype = htons(ARPHRD_ETHER); /* hardware type */
arp.ptype = htons(ETH_P_IP); /* protocol type (ARP message) */
arp.hlen = 6; /* hardware address length */
arp.plen = 4; /* protocol address length */
arp.operation = htons(ARPOP_REQUEST); /* ARP op code */
*((u_int *) arp.sInaddr) = ip; /* source IP address */
memcpy(arp.sHaddr, mac, 6); /* source hardware address */
*((u_int *) arp.tInaddr) = yiaddr; /* target IP address */

memset(&addr, 0, sizeof(addr));
strcpy(addr.sa_data, interface);
if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0)
rv = 0;

/* wait arp reply, and check it */
tm.tv_usec = 0;
time(&prevTime);
while (timeout > 0)
FD_ZERO(&fdset);
FD_SET(s, &fdset);
tm.tv_sec = timeout;
if (select(s + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, &tm) < 0)
DEBUG(LOG_ERR, "Error on ARPING request: %s", strerror(errno));
if (errno != EINTR) rv = 0;
else if (FD_ISSET(s, &fdset))
if (recv(s, &arp, sizeof(arp), 0) < 0 ) rv = 0;
if (arp.operation == htons(ARPOP_REPLY) &&
bcmp(arp.tHaddr, mac, 6) == 0 &&
*((u_int *) arp.sInaddr) == yiaddr)
DEBUG(LOG_INFO, "Valid arp reply receved for this address");
rv = 0;
break;


timeout -= time(NULL) - prevTime;
time(&prevTime);

close(s);
DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V");
return rv;


/* check is an IP is taken, if it is, add it to the lease table */
int check_ip(u_int32_t addr)

struct in_addr temp;

if (arpping(addr, server_config.server, server_config.arp, ETH_INTERFACE) == 0)
temp.s_addr = addr;
LOG(LOG_INFO, "%s belongs to someone, reserving it for %ld seconds",
inet_ntoa(temp), server_config.conflict_time);
//add_lease(blank_chaddr, addr, server_config.conflict_time);
return 1;
else return 0;


int Checkipconflict()

char* rebuf="XXX";/*你要检测的ip,你也可以修改下,采取变量的形式,通过argv传入ip */
char p[255]=0;
strcpy(p,rebuf);
if (read_interface(ETH_INTERFACE, &server_config.ifindex,
&server_config.server, server_config.arp) < 0)

exit(0);


if(!check_ip(inet_addr(p)))

DEBUG(LOG_INFO, "IP:%s can use", p);
return 1;

else

DEBUG(LOG_INFO, "IP:%s conflict", p);
return 0;




int main(int argc, char *argv[])

Checkipconflict();

return 0;
追问

你好,基本意思就是这个,很感谢您,这是我毕业设计题目,我从官网下了源代码,想把您这段插入且重新编译,最终能实现,不知您能不能抽空帮帮我,女生动手能力弱了点,呵呵,留个QQ,我们详细聊,谢谢您了,
如能帮助解决,可现金酬谢

参考技术A DHCP服务器有这个功能。但是实际网络中基本没什么作用,主要是那些有地址的机器,不一定总是开着,当你分配的时候可能没有开机,之后一开机还是你没有用。如果真是工程上使用,可以利用交换机的功能防止用户自己分配IP

if(!check_ip(inet_addr(p)))

DEBUG(LOG_INFO, "IP:%s can use", p);
return 1;

else

DEBUG(LOG_INFO, "IP:%s conflict", p);
return 0;本回答被提问者采纳
参考技术B 客户IP租用更新报文
(1)在当前租期已过去50%时,DHCP客户机直接向为其提供IP地址的DHCP服务器发送DHCPREQUEST消息包。如果客户机接收到该服务器回应的DHCPACK消息包,客户机就根据包中所提供的新的租期以及其它已经更新的TCP/IP参数,更新自己的配置,IP租用更新完成。如果没收到该服务器的回复,则客户机继续使用现有的
IP地址,因为当前租期还有50%。
(2)如果在租期过去50%时未能成功更新,则客户机将在当前租期过去87.5%时再次向为其提供IP地址的DHCP联系。如果联系不成功,则重新开始IP租用过程。
(3)如果DHCP客户机重新启动时,它将尝试更新上次关机时拥有的IP租用。如果更新未能成功,客户机将尝试联系现有IP租用中列出的缺省网关。如果联系成功且租用尚未到期,客户机则认为自己仍然位于与它获得现有IP租用时相同的子网上(没有被移走)继续使用现有IP地址。 如果未能与缺省网关联系成功,客户机则认为自己已经被移到不同的子网上,将会开始新一轮的IP租用过程。

DHCP客户机在发出IP租用请求的DHCPDISCOVER广播包后,将花费1秒钟的时间等待DHCP服务器的回应,如果1秒钟没有服务器的回应,它会将这一广播包重新广播四次(以2,4,8和16秒为间隔,加上1~1000毫秒之间随机长度的时间)。四次之后,如果仍未能收到服务器的回应,则运行Windows 2000的DHCP客户机将从169.254.0.0/16这个自动保留的私有IP地址(APIPA)中选用一个IP地址,而运行其他操作系统的DHCP客户机将无法获得IP地址。DHCP客户机仍然每隔5分钟重新广播一次,如果收到某个服务器的回应,则继续IP租用过程。

参考:
参考技术C 不明白你要做什么,DHCP服务器有这个功能。但是实际网络中基本没什么作用,主要是那些有地址的机器,不一定总是开着,当你分配的时候可能没有开机,之后一开机还是你没有用。如果真是工程上使用,可以利用交换机的功能防止用户自己分配IP。 参考技术D 若南、寻真

晓亦、向珊

用Autoit编程软件,如何读取屏幕上的信息?Autoit高手进!

急需各位Autoit高手帮忙,
本人想学一个类似批处理文件,但比它更强悍的编程语言
于是就看上了Autoit,这个软件的控制功能真牛叉,调用鼠标和键盘的函数非常实用
但是,我对它的读取功能表示怀疑。难道Autoit只能读取文件内容么?
因为用Autoit写程序有时会遇到多种情况,就需要读取屏幕上的内容分情况处理(例如读取被打开网页中的文字)
有什么函数能用来做这个的么?
实在不行,但是读取网页信息就行了,
还是不行的话,谁帮忙给个当前网页的内存地址也行...

应该说Autoit提供的功能还是很强大的,并不单纯是简单的鼠标和键盘函数,Autoit有一个可以称之为庞大的函数库,这个函数库除了软件自带的函数库之外,还有由Autoit爱好者不断更新的用户自定义函数库。
例如,读取网页文字,就可以通过用户函数库中的IE函数库包来进行处理。如:
_IEDocReadHTML:返回整个文档的HTML源代码.
_IEBodyReadText:返回网页中标记中的文本.
_IEImgClick:模拟鼠标点击网页上某一个图像,可以通过文本、名称进行定位匹配.
等等。
参考技术A 打开帮助,User Defined Function 中的Ie Management里的函数可以与IE内核浏览器交互。
比如,你不要关闭这个页面,运行下面的代码看看:

#include <IE.au3>
$oIE = _IEAttach ("用Autoit编程软件,如何读取屏幕上的信息?")
$sText = _IEBodyReadText ($oIE)
MsgBox(0, _IEPropertyGet ($oIE, "locationurl"), $sText)

以上是关于DHCP编程高手帮忙,在分配地址前加一段功能,检测非DHCP 客户机使用的IP的主要内容,如果未能解决你的问题,请参考以下文章

在路由器中DHCP服务器里设置静态地址分配有啥作用

求高手帮忙翻译一段基于OPENCV的运动目标检测的程序,详细翻译,老师会提问

怎样查看linux下dhcp服务器分配出去的IP地址及剩余IP地址

Linux中dhcp分配地址

Windows 2008 WDS服务器不开启DHCP可以吗?

DHCP动态管理主机地址