菜鸟求助 linux下ARP请求发送和接收的问题
各位大牛,在下最近研究LINUX SOCKET方面的东西,遇到一个问题实在不解,向大家请教
虚拟机下,以bridged adapter方式连接网络
自己写了个ARP请求发送的程序,功能很简单,只是向目的IP发送一个ARP广播包,运行时发现了一些问题,操作步骤如下:
1.发送前查看了本机的MAC映射表
2.运行程序发送后再次查看却没有发现请求的主机的IP和MAC映射
3.通过sniffer观察,发现确实发出了ARP请求包,也确实收到了回应
4.通过自己写的syn_flood对目标主机发送数据包后再次查看映射表,这时出现了目标主机的IP和MAC映射
5.用arp -d删除该映射条目
6.再次运行程序发送ARP请求包,发现这次居然出现了映射条目
7.反复重复第5步和第6步,发现每次均能获得映射条目
8.重启虚拟机,发现第2步中表现出的问题仍然存在
在下表示非常费解,希望能有大牛指导
在线等
源码如下: #include <stdio.h>
#include <error.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if_arp.h>
#include <net/ethernet.h>
#include <linux/if.h>
#include <arpa/inet.h>
#include <linux/if_packet.h>
#define bzero(a, b) memset(a, 0, b)
typedef struct arp_hdr
{
unsigned short ar_hrd; /* format of hardware address */
unsigned short ar_pro; /* format of protocol address */
unsigned char ar_hln; /* length of hardware address */
unsigned char ar_pln; /* length of protocol address */
unsigned short ar_op; /* ARP opcode (command) */
unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
unsigned char ar_sip[4]; /* sender IP address */
unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
unsigned char ar_tip[4]; /* target IP address */
} arpheader;
static const char *dev_name = "eth4";
const unsigned char brod_mac[ETHER_ADDR_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
const unsigned char SMAC[ETHER_ADDR_LEN] = {0x08, 0x00, 0x27, 0x53, 0x86, 0x1A};
char *sip = "192.168.0.13";
char dip[INET_ADDRSTRLEN];
char sendbuf[64];
int sock;
struct sockaddr_ll sdev, ddev;
struct ether_header eth;
arpheader arph;
void bind_dev(void);
void fill_arphdr(void);
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("usage :mf <dest IP>\n");
exit(1);
}
//创建套接字
if((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) < 0)
{
perror("socket");
exit(1);
}
bzero(dip, INET_ADDRSTRLEN);
memcpy(dip, argv[1], INET_ADDRSTRLEN);
//绑定设备接口
bind_dev();
//填充ARP报文
fill_arphdr();
//发送ARP请求
if(sendto(sock, sendbuf, 64, 0, (struct sockaddr *)&ddev, sizeof(ddev)) == -1)
{
perror("send to");
exit(1);
}
return 0;
}
void bind_dev(void)
{
struct ifreq dev_itf;
strncpy(dev_itf.ifr_name, dev_name, IFNAMSIZ);
if(ioctl(sock, SIOCGIFINDEX, &dev_itf) == -1)
{
perror("ioctl - get device index");
exit(1);
}
sdev.sll_family = AF_PACKET;
sdev.sll_protocol = htons(ETH_P_ARP);
sdev.sll_ifindex = dev_itf.ifr_ifindex;
sdev.sll_hatype = ARPHRD_ETHER;
sdev.sll_pkttype = PACKET_HOST;
sdev.sll_halen = ETH_ALEN;
memcpy(sdev.sll_addr, SMAC, ETH_ALEN);
ddev.sll_family = AF_PACKET;
ddev.sll_protocol = htons(ETH_P_ARP);
ddev.sll_ifindex = dev_itf.ifr_ifindex;
ddev.sll_hatype = ARPHRD_ETHER;
ddev.sll_pkttype = PACKET_BROADCAST;
ddev.sll_halen = ETH_ALEN;
memcpy(ddev.sll_addr, brod_mac, ETH_ALEN);
if(bind(sock,(struct sockaddr *)&sdev, sizeof(sdev)) < 0)
{
perror("bind");
close(sock);
exit(1);
}
}
void fill_arphdr(void)
{
memcpy(eth.ether_shost, SMAC, ETHER_ADDR_LEN);
memcpy(eth.ether_dhost, brod_mac, ETHER_ADDR_LEN);
eth.ether_type = htons(ETHERTYPE_ARP);
arph.ar_hrd = htons(ARPHRD_ETHER);
arph.ar_pro = htons(ETHERTYPE_IP);
arph.ar_hln = 6;
arph.ar_pln = 4;
arph.ar_op = htons(ARPOP_REQUEST);
memcpy(arph.ar_sha, SMAC, ETH_ALEN);
*((unsigned int *)arph.ar_sip) = inet_addr(sip);
*((unsigned int *)arph.ar_tip) = inet_addr(dip);
bzero(sendbuf, 64);
memcpy(sendbuf, ð, sizeof(struct ether_header));
memcpy(sendbuf + sizeof(struct ether_header), &arph, sizeof(arpheader));
}