無料ARPの簡単な紹介とプログラムの作成
無料ARPは、ネットでいろいろ紹介されています.「tcp/ipプロトコルボリューム」の第4章でも紹介されていますが、その役割と操作について説明します.
無料ARPは、主にネットワーク内のIPアドレスが競合しているかどうかを検出するために使用され、プロトコルではなく機能です.デバイスが再起動したり、プロキシARP機能がオンになったりすると、IPアドレスが競合しているかどうかを検出するために、ローカルネットワークに無料ARPがアクティブに送信されます.無料ARPはソース、目的IPはすべて自分で、ソースMACも自分で、目標MACは放送で、つまり自分の所在するネットワークに自分のMACアドレスを要求して、ネットワークの中でもし他のホストが自分と同じIPアドレスを使ったならば、彼はホストに1つのARPに返事をして、この時もし無料ARPを送ったホストが返事を受け取ったならば自分の使ったIPアドレスが衝突していることを証明して、返信が受信されていない場合は、IPアドレスの競合がないことを示します.
(上の文字が似ていれば、他の人の文章を主とします.著作権があれば教えてください.私は24時間で撤去します.ありがとうございます~~~)
以下は無料ARPのコードで、参考にしましょう.
このプログラムは、ローカルエリアネットワーク内のIPアドレスが競合しているかどうかをテストし、そのアドレスがホストのIPアドレスとして使用できるかどうかを判断することができる.以下はwiresharkで無料のARPパケットを捕まえたものと、以下のような応答パケットです.
無料ARPは、主にネットワーク内のIPアドレスが競合しているかどうかを検出するために使用され、プロトコルではなく機能です.デバイスが再起動したり、プロキシARP機能がオンになったりすると、IPアドレスが競合しているかどうかを検出するために、ローカルネットワークに無料ARPがアクティブに送信されます.無料ARPはソース、目的IPはすべて自分で、ソースMACも自分で、目標MACは放送で、つまり自分の所在するネットワークに自分のMACアドレスを要求して、ネットワークの中でもし他のホストが自分と同じIPアドレスを使ったならば、彼はホストに1つの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 0
unsigned 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;
// socket
sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
if (sockfd < 0)
{
fprintf(stderr, "socket error: %s
", 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
", strerror(errno));
}
rtval = recv_arp(sockfd, &peer_addr);
if (rtval == SUCCESS)
{
printf ("Get packet from peer and IP conflicts!
");
}
else if (rtval == FAILURE)
{
fprintf(stderr, "Recv arp IP not conflicts: %s
", strerror(errno));
}
else
{
fprintf(stderr, "Recv arp socket failed: %s
", 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~
");
return SUCCESS;
}
}
if (rtval < 0)
{
return FAILURE;
}
return FAILURE;
}
このプログラムは、ローカルエリアネットワーク内のIPアドレスが競合しているかどうかをテストし、そのアドレスがホストのIPアドレスとして使用できるかどうかを判断することができる.以下はwiresharkで無料のARPパケットを捕まえたものと、以下のような応答パケットです.