**************************************************
*** 作 者:cak ***
*** 完成时间:2009.5.01 ***
*** 项目名称:Linux静态IP地址冲突避免软件设计 ***
*** 软件类型:开源共享软件 ***
**************************************************
本软件源代码上传到“CSDN 下载频道", 如需下载源代码,请访问:http://download.csdn.net/source/1432278
(或者在csdn上搜索chuniyb的资源,即可看到源代码)
1.软件设计思路
向本局域网每个主机发送ARP请求,如果该主机在线,则会收到该主机的ARP应答,如果该主机不在线,则不收到该主机的ARP应答。这样就可以根据局域网IP地址的范围找出没有使用的IP地址,在空闲的IP池中找一个IP地址设为本机IP。然后把本软件加入linux开机启动的一个脚本中,让本软件开机自动运行。
2. 软件主框架图:
框架图流程:1.创建进程;2.子进程负责发送ARP请求报文;3.父进程负责接收ARP应答报文、之后找出空闲IP、设置IP网关DNS等信息、设置开机启动等信息。如图所示:
3.软件实现:
3.2.1 发送ARP和接收ARP
3.2.1.1 ARP头部数据链路层首部
ARP头部固定部分为28个字节,数据结构定义如下:
typedef struct ARP
{
unsigned short arp_hardware_type;
unsigned short arp_p;
unsigned char arp_hardware_len;
unsigned char arp_ip_len;
unsigned short arp_option;
unsigned char arp_src_hardware[6];
unsigned char arp_src_ip[4];
unsigned char arp_dst_hardware[6];
unsigned char arp_dst_ip[4];
}ArpHead;
各部分的含义:
arp_hardware_type : 硬件类型 ,值为0x1表示以太网。
arp_p : 上层协议类型 ,IP值为0X0800。
arp_hardware_len : 为硬件地址占的字节长度 ,IPv4值为6。
arp_ip_len : IP地址占的字节长度,值一般为4。
arp_option : ARP操作,当操作 0X1 为请求 ,0x2为应答。
arp_src_hardware[6] : 源MAC地址。
arp_src_ip[4] : 源IP地址。
arp_dst_hardware[6] : 目的MAC地址。
arp_dst_ip[4] : 目的IP地址。
数据链路层头部占14字节,数据结构定义如下:
typedef struct machead
{
unsigned char mac_dst[6];
unsigned char mac_src[6];
unsigned short mac_p;
}MacHead;
各部分的含义:
mac_dst[6] :目标MAC。
mac_src[6] :源MAC。
short mac_p :上层协议类型当值为0x0806时为ARP,当值为0X0800时为IP。
3.2.1.3 发送ARP
发送ARP主要流程:a.创建原始套接字;b.选择使用哪张网卡;c.获取网卡索引节点;d.封装数据链路层包头;e.封装ARP请求报文部分包头;f.循环封装ARP目标IP和循环发送数据。
函数实现如下:
/*********************************/
/* function send arp*/
/*******************************/
#include "include.h"
int sendto_arp(char *eth, unsigned char *ip, unsigned char *maxip, unsigned char *netnumber,unsigned char *mac)
{
unsigned char mac_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
unsigned char my_mac[6] = {0x0, 0x30, 0x18, 0xAF, 0x5F, 0x51};
unsigned char my_ip[4] = {210, 41, 239, 10};
//unsigned char broad_ip[4] = {210, 41, 239, 2};
int z;
struct sockaddr_ll socket_address;
struct ifreq ifstruct;
int sock;
//set pointer of eth.hdr