`
simohayha
  • 浏览: 1400070 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

linux下检测ip冲突

阅读更多
原理其实很简单,那就是广播一个arp包,然后recv,如果没有数据(这里要设置延时),那么说明这个ip是可用的,否则就检测这个数据是否为回复我们发出的arp的应答包.如果是则证明ip已被使用,否则继续等待.

这里可以看下busybox的dhcp中的检测程序。
networking/udhcp/arpping.c

/* vi: set sw=4 ts=4: */
/*
 * arpping.c
 *
 * Mostly stolen from: dhcpcd - DHCP client daemon
 * by Yoichi Hariguchi <yoichi@fore.com>
 */

#include <netinet/if_ether.h>
#include <net/if_arp.h>

#include "common.h"
#include "dhcpd.h"

//这里是arp包的格式,其中的数据格式都是宏了,比如uint_8_t为无符char.
struct arpMsg {
	/* Ethernet header */
	uint8_t  h_dest[6];     /* 00 destination ether addr */
	uint8_t  h_source[6];   /* 06 source ether addr */
	uint16_t h_proto;       /* 0c packet type ID field */

	/* ARP packet */
	uint16_t htype;         /* 0e hardware type (must be ARPHRD_ETHER) */
	uint16_t ptype;         /* 10 protocol type (must be ETH_P_IP) */
	uint8_t  hlen;          /* 12 hardware address length (must be 6) */
	uint8_t  plen;          /* 13 protocol address length (must be 4) */
	uint16_t operation;     /* 14 ARP opcode */
	uint8_t  sHaddr[6];     /* 16 sender's hardware address */
	uint8_t  sInaddr[4];    /* 1c sender's IP address */
	uint8_t  tHaddr[6];     /* 20 target's hardware address */
	uint8_t  tInaddr[4];    /* 26 target's IP address */
	uint8_t  pad[18];       /* 2a pad for min. ethernet payload (60 bytes) */
} PACKED;

enum {
	ARP_MSG_SIZE = 0x2a
};


/* Returns 1 if no reply received */

//主程序,如果返回1说明此ip可用
int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *interface)
{

	int timeout_ms;
//这里使用poll来检测句柄。
	struct pollfd pfd[1];
#define s (pfd[0].fd)           /* socket */
	int rv = 1;             /* "no reply received" yet */
	struct sockaddr addr;   /* for interface name */
	struct arpMsg arp;

//建立scoket.由于我们是要直接访问访问链路层并自己组arp包.因此我们使用PF_PACKET协议簇.socket类型为SOCK_PACKET.

	s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
	if (s == -1) {
		bb_perror_msg(bb_msg_can_not_create_raw_socket);
		return -1;
	}

	if (setsockopt_broadcast(s) == -1) {
		bb_perror_msg("cannot enable bcast on raw socket");
		goto ret;
	}
//进行组包,由于是要广播,因此目的mac地址为全0.
	/* send arp request */
	memset(&arp, 0, sizeof(arp));
	memset(arp.h_dest, 0xff, 6);                    /* MAC DA */
	memcpy(arp.h_source, from_mac, 6);              /* MAC SA */
	arp.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 */
	memcpy(arp.sHaddr, from_mac, 6);                /* source hardware address */
	memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */
	/* tHaddr is zero-fiiled */                     /* target hardware address */
	memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */

	memset(&addr, 0, sizeof(addr));
	safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
//广播arp包.
	if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) {
		// TODO: error message? caller didn't expect us to fail,
		// just returning 1 "no reply received" misleads it.
		goto ret;
	}

	/* wait for arp reply, and check it */
//等待时间,超时则认为此ip地址可用
	timeout_ms = 2000;
	do {
		int r;
		unsigned prevTime = monotonic_us();

		pfd[0].events = POLLIN;
//这边他是害怕poll被信号打断,因此加了层循环,其实这边我们还可以使用ppoll的,就可以了。
		r = safe_poll(pfd, 1, timeout_ms);
		if (r < 0)
			break;
		if (r) {
//读取返回数据.
			r = read(s, &arp, sizeof(arp));
			if (r < 0)
				break;
//检测是否为应打包,发送ip是否为我们所请求的ip,这里是为了防止其他的数据包干扰我们检测。
			if (r >= ARP_MSG_SIZE
			 && arp.operation == htons(ARPOP_REPLY)
			 /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */
			 /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */
			 && *((uint32_t *) arp.sInaddr) == test_ip
			) {
//说明ip地址已被使用
				rv = 0;
				break;
			}
		}
		timeout_ms -= ((unsigned)monotonic_us() - prevTime) / 1000;
	} while (timeout_ms > 0);

 ret:
	close(s);
	DEBUG("%srp reply received for this address", rv ? "No a" : "A");
	return rv;
}

3
0
分享到:
评论
1 楼 xiangjie88 2014-03-25  
能否给出setsockopt_broadcast的头文件或函数

相关推荐

    Linux ip冲突检测程序

    在Linux中,我们可以使用命令行工具来检测IP冲突。例如,`ifconfig`命令可以显示当前网络接口的IP地址和其他网络信息,而`arp`命令则可以查看当前的ARP(地址解析协议)表,这有助于识别在同一网络段内的其他设备。...

    一个IP冲突检测的项目代码linux

    本文将深入探讨一个基于Linux系统的IP冲突检测项目代码,帮助你理解如何通过编程手段来预防和解决这类问题。 首先,让我们理解IP冲突的基本原理。在TCP/IP协议栈中,IP地址由网络ID和主机ID两部分组成,网络ID标识...

    检测ip是否冲突

    检测IP冲突的一种方法是通过发送ARP请求。ARP协议是一种在IPv4网络中将IP地址映射为物理(MAC)地址的协议。当一个设备需要向另一个IP地址发送数据时,它会先发送一个ARP请求,询问哪个MAC地址对应目标IP。如果网络...

    IPwatchD:Linux的IP冲突检测工具

    Linux的IP冲突检测工具 IPwatchD是一个简单的守护程序,它分析所有传入的ARP数据包以检测Linux上的IP冲突。 可以将其配置为在主动或被动模式下侦听一个或多个网络接口。 在活动模式下,它通过回答从冲突系统收到的...

    linux环境检查IP冲突脚本

    IP冲突检测看起来是一个很复杂的问题,其实在TCP/IP协议中,IP冲突检测是ARP协议的一个额外功能,原理很简单,使用ARP协议向网络中广播自己的IP地址,如果收到响应&gt;则存在IP冲突,这个功能在TCP/IP协议第一卷ARP协议...

    局域网内静态IP地址冲突避免软件设计(Linux-QT版)

    虽然DHCP被广泛应用于动态IP地址分配,但在一些校园或企业的办公室,仍然使用静态IP进行地址分派,因此经常出现IP地址冲突问题。本课题的目的就是开发一个基于Linux操作系统的静态IP地址配置工具,来解决IP地址分配...

    linux TCP IP协议栈源码解析资料大全

    《网络子系统在链路层的收发过程剖析.pdf》可能详细分析了数据在链路层的处理,包括以太网帧的封装、MAC地址解析和冲突检测等。 《Linux_协议栈.rar》可能是一个包含更多源代码、文档或实用工具的压缩包,供读者...

    LINUX平台下IP动态分配安全管理.pdf

    它解决了IP地址资源紧张和IP冲突的问题。Linux系统中,可以通过安装和配置DHCP服务器来提供DHCP服务。 3. **DHCP服务器的配置**: 在Linux系统中,通常使用isc-dhcp-server软件包来搭建DHCP服务器。安装后,需要...

    远程登录linux主机更换IP地址.docx

    "远程登录Linux主机更换IP地址" 远程登录Linux主机更换IP地址是指在远程...远程登录Linux主机更换IP地址是一个复杂的过程,需要正确地理解和执行每一步骤,以避免IP地址冲突和混乱,确保新实例的IP地址正确地配置。

    基于Linux下的IP包捕获及解析.pdf

    在Linux环境下,IP包捕获程序可以利用Libpcap库以及Linux的套接字功能来实现。IP包捕获程序的实现依赖于一系列的技术组件,包括操作系统、编译器、CPU和内存资源,以及专门的库函数。文档中特别提及了使用的Libpcap...

    史上最牛的ip检测器

    标题中的“史上最牛的ip检测器”暗示了这是一个功能强大、高效的IP地址检测软件,而描述则明确了它的主要用途——在局域网环境中检测和管理IP及MAC地址,以确保网络登记信息的准确性和完整性。从标签“ip”我们可以...

    网络游戏-检测计算机网络中的硬件地址冲突.zip

    4. 检测冲突:可以通过运行网络诊断工具,如Windows的"ipconfig /all"命令或Linux的"ifconfig"命令来查看当前设备的MAC地址。同时,使用网络扫描工具,如Nmap或Angry IP Scanner,可以检测网络上所有活动设备及其MAC...

    Linux 下一个ARP解析程序

    3. **ARP响应处理**:接收到的ARP响应可能会更新本地的ARP缓存,也可能触发异常处理,比如检测到冲突的IP或MAC地址。 4. **守护进程化**:为了确保`arpd`始终运行,程序需要设计成守护进程模式。这包括初始化、信号...

    Linux系统下ARP数据包截取和分析.pdf

    ARP协议主要用于解决IP地址到物理地址(MAC地址)的映射问题,但同时也可能成为网络攻击的工具,如IP冲突、ARP欺骗和ARP溢出等。了解ARP数据包的工作原理及如何高效截取和分析这些数据包,对于监控网络流量、检测...

    局域网抢IP的方法 原创内容

    在局域网环境中,IP地址是网络设备身份的标识,每个设备都需要一...建议优先通过规范网络环境、合理规划IP地址分配以及及时更新网络设备的固件,避免IP冲突的发生。同时,尊重网络社区的规则,避免对他人网络造成干扰。

    Atang群集软件+ORACLE Linux下应用配置

    - **IP冲突检查**:网络中不可存在与计划使用的虚拟IP地址(例如192.168.0.244)相同的地址,以避免网络冲突。 #### 三、Oracle安装与配置流程 ##### 3.1 安装前的系统与目录规划 - **目录分配策略**:Oracle系统...

    修改路由ip

    1. 避免IP冲突:在同一网络中,两个设备不能拥有相同的IP地址。 2. 安全考虑:定期更改IP可以提高网络安全,减少被攻击的风险。 3. 网络管理:在多网络环境中,切换不同的IP便于接入不同的网络。 执行这一操作通常...

    nacos2.3.1 linux版本

    本压缩包文件"nacos-server-2.2.3.tar.gz"提供了Nacos在Linux环境下的部署版本,版本号为2.3.1。 1. **Nacos服务发现**: Nacos作为服务注册与发现的平台,允许服务提供者将自身服务注册到Nacos,同时服务消费者...

    Linux下Bond做法.pdf

    - `mode=1`(主备模式):在这种模式下,eth1作为备份网卡,通常设置为`noarp`以防止网络冲突。当主网卡eth0出现问题时,系统会立即切换到eth1。 - `mode=0`(负载均衡模式):所有接口均参与数据传输,理论上可以...

    在linux系统下安装两个nginx的简单方法

    ### 在Linux系统下安装两个Nginx的详细步骤与注意事项 #### 一、前言 在实际工作中,有时我们需要在同一台Linux服务器上安装并运行多个Nginx实例,以满足不同项目的需求或进行A/B测试等操作。本文将详细介绍如何在...

Global site tag (gtag.js) - Google Analytics