免费ARP简单介绍和程序编写
来源:互联网 发布:2018域名行情预测 编辑:程序博客网 时间:2024/04/27 20:54
免费ARP,在网络上有很多的介绍。在《tcp/ip协议卷》中的第四章也有介绍,下面再啰嗦一下介绍其作用和操作:
免费ARP,主要用于检测网络中IP地址是否冲突,它是一种功能而非协议。当设备重启或代理ARP功能开启时就会向本地网络主动发免费ARP以检测IP地址是否冲突。免费ARP是以源、目的IP都是自己,源MAC也是自己,目标MAC是广播,即向自己所在网络请求自己的MAC地址,当网络中如果有其他主机使用了与自己相同的IP地址,他就会给主机一个ARP回复,此时如果发免费ARP的主机收到了回复就证明自己所用的IP地址有冲突,如果没有收到回复则说明没有IP地址冲突。
(若上面的文字有雷同,则以别人的文章为主;若有版权请告知我,本人会在24小时撤掉,谢谢~~~)
下面是免费ARP的代码,作为一个参考吧:
/////////////////////////////////////////////////////////////////////////////////// 文件名: arp_func.c// 作者: cfjtaishan// 版本: 1.0// 日期: 2013-05-14// 描述: 免费ARP--用于检测IP地址是否冲突.// 历史记录://///////////////////////////////////////////////////////////////////////////////#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <linux/if_packet.h>#include <netdb.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <net/ethernet.h>#include <netinet/ether.h>#include <net/if.h>#include <netinet/ip.h>#define FAILURE -1#define SUCCESS 0unsigned char src_ip[4] = { 192, 168, 9, 118 }; //要检测的主机IP地址unsigned char src_mac[6] = {0x00, 0x0c, 0x29, 0x4b, 0x6c, 0x13}; //要检测的主机的MAC地址unsigned char dst_ip[4] = { 192, 168, 9, 118 }; //目标IP地址unsigned char dst_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; //ARP广播地址int send_arp(int sockfd, struct sockaddr_ll *peer_addr);int recv_arp(int sockfd, struct sockaddr_ll *peer_addr);//ARP封装包typedef struct _tagARP_PACKET{ struct ether_header eh; struct ether_arp arp; }ARP_PACKET_OBJ, *ARP_PACKET_HANDLE; int main(int argc, char *argv[]){int sockfd;int rtval = -1;struct sockaddr_ll peer_addr;//创建socketsockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));if (sockfd < 0){fprintf(stderr, "socket error: %s\n", strerror(errno));exit(EXIT_FAILURE);}memset(&peer_addr, 0, sizeof(peer_addr)); peer_addr.sll_family = AF_PACKET; struct ifreq req;bzero(&req, sizeof(struct ifreq)); strcpy(req.ifr_name, "eth0"); if(ioctl(sockfd, SIOCGIFINDEX, &req) != 0)perror("ioctl()"); peer_addr.sll_ifindex = req.ifr_ifindex; peer_addr.sll_protocol = htons(ETH_P_ARP);//peer_addr.sll_family = AF_PACKET;while (1){rtval = send_arp(sockfd, &peer_addr);if (FAILURE == rtval){fprintf(stderr, "Send arp socket failed: %s\n", strerror(errno));}rtval = recv_arp(sockfd, &peer_addr);if (rtval == SUCCESS){printf ("Get packet from peer and IP conflicts!\n");}else if (rtval == FAILURE){fprintf(stderr, "Recv arp IP not conflicts: %s\n", strerror(errno));}else{fprintf(stderr, "Recv arp socket failed: %s\n", strerror(errno));}//sleep(1);}return 0;}//////////////////////////////////////////////////////////////////////////// 函数名: send_arp // 描述 : 填充ARP数据包报文并发送出去。// 参数: // [in] sockfd -- 创建的socket描述符;// [in] peer_addr -- 对端的IP信息// 返回值: // 成功: SUCCESS, 失败: FAILURE;// 说明: //////////////////////////////////////////////////////////////////////////int send_arp(int sockfd, struct sockaddr_ll *peer_addr){int rtval;ARP_PACKET_OBJ frame;memset(&frame, 0x00, sizeof(ARP_PACKET_OBJ));//填充以太网头部 memcpy(frame.eh.ether_dhost, dst_mac, 6); //目的MAC地址 memcpy(frame.eh.ether_shost, src_mac, 6); //源MAC地址 frame.eh.ether_type = htons(ETH_P_ARP); //协议 //填充ARP报文头部 frame.arp.ea_hdr.ar_hrd = htons(ARPHRD_ETHER); //硬件类型 frame.arp.ea_hdr.ar_pro = htons(ETHERTYPE_IP); //协议类型 ETHERTYPE_IP | ETH_P_IP frame.arp.ea_hdr.ar_hln = 6; //硬件地址长度 frame.arp.ea_hdr.ar_pln = 4; //协议地址长度 frame.arp.ea_hdr.ar_op = htons(ARPOP_REQUEST); //ARP请求操作 memcpy(frame.arp.arp_sha, src_mac, 6); //源MAC地址 memcpy(frame.arp.arp_spa, src_ip, 4); //源IP地址 memcpy(frame.arp.arp_tha, dst_mac, 6); //目的MAC地址 memcpy(frame.arp.arp_tpa, dst_ip, 4); //目的IP地址 rtval = sendto(sockfd, &frame, sizeof(ARP_PACKET_OBJ), 0, (struct sockaddr*)peer_addr, sizeof(struct sockaddr_ll)); if (rtval < 0){return FAILURE;}return SUCCESS;}
//////////////////////////////////////////////////////////////////////////// 函数名: recv_arp // 描述 : 接收ARP回复数据报文并判断是不是对免费ARP的回复。// 参数: // [in] sockfd -- 创建的socket描述符;// [in] peer_addr -- 对端的IP信息// 返回值: // 成功: SUCCESS, 失败: FAILURE;// 说明: // 若是对免费arp请求的回复则返回:SUCCESS.//////////////////////////////////////////////////////////////////////////int recv_arp(int sockfd, struct sockaddr_ll *peer_addr){int rtval;ARP_PACKET_OBJ frame;memset(&frame, 0, sizeof(ARP_PACKET_OBJ));rtval = recvfrom(sockfd, &frame, sizeof(frame), 0, NULL, NULL);//判断是否接收到数据并且是否为回应包if (htons(ARPOP_REPLY) == frame.arp.ea_hdr.ar_op && rtval > 0){//判断源地址是否为冲突的IP地址if (memcmp(frame.arp.arp_spa, src_ip, 4) == 0){fprintf(stdout, "IP address is common~\n");return SUCCESS;}}if (rtval < 0){return FAILURE;}return FAILURE;}
该程序可以测试局域网中的某个IP地址是否有冲突的,以便于确定该地址是否可以作为本机的IP地址。下面是通过wireshark抓到了免费的ARP数据包,以及回应包,如下:
- 免费ARP简单介绍和程序编写
- 免费ARP简单介绍和程序编写
- 普通ARP和免费ARP
- 免费ARP(Gratuitous ARP)的介绍
- Gratuitous ARP(免费arp)简单说明
- ARP简单介绍
- 免费ARP和ARP欺骗攻击
- 免费ARP
- 免费ARP
- 免费ARP
- 免费ARP
- 免费arp
- 免费 arp
- 免费ARP
- 免费ARP
- 免费ARP
- gratuitous ARP(免费Arp)
- 编写和运行简单的Applet程序
- hibernate 和jpa
- ueditor文本超过编辑器宽度不换行问题(使pre标签内容自动换行)
- CentOS6安装总结
- 完全删除oracle11g的的步骤
- asp.net 操作excel 拒绝访问
- 免费ARP简单介绍和程序编写
- iOS 新浪微博客户端Demo实践之(二) 授权页面
- 有关于android mat分析中 系统默认加载的sPreloadedDrawables
- 64位c/c++应用程序开发教程(以vc为例)(一)
- 程序性能分析之time
- 技术政治之完美的奴隶
- [转]string, char*, int类型转换
- 内核中的gcc扩展
- POJ 3259