上传
This commit is contained in:
174
ARP编程/代码/test.c
Normal file
174
ARP编程/代码/test.c
Normal file
@@ -0,0 +1,174 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
struct arppacket
|
||||
{
|
||||
struct arphdr ar_head;/*硬件类型、协议、地址长度、操作码*/
|
||||
unsigned char ar_sha[ETH_ALEN];/*发送方MAC*/
|
||||
struct in_addr ar_sip;/*发送方IP*/
|
||||
unsigned char ar_tha[ETH_ALEN];;/*目的MAC*/
|
||||
struct in_addr ar_tip;/*目的IP*/
|
||||
}__attribute__((packed));
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//初始化及参数检查
|
||||
struct in_addr pingaddr;
|
||||
struct in_addr netaddr;
|
||||
struct in_addr netmask;
|
||||
struct sockaddr_ll hwaddr;
|
||||
memset(&netaddr, 0, sizeof(netaddr));
|
||||
memset(&netmask, 0, sizeof(netmask));
|
||||
memset(&hwaddr, 0, sizeof(hwaddr));
|
||||
|
||||
//输入错误,显示正确输入格式
|
||||
if(argc != 2)
|
||||
{
|
||||
perror("Usage: ./test xxx.xxx.xxx.xxx\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//参数错误,输入的不是ip地址
|
||||
if(inet_aton(argv[1], &pingaddr) < 0)
|
||||
{
|
||||
perror("not a correct ip address\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
// 注册原始套接字
|
||||
int fd = socket(PF_PACKET, SOCK_RAW, htonl(0x0003));
|
||||
|
||||
// 获得网卡信息
|
||||
char buf[1024];
|
||||
struct ifconf ifc;
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if(ioctl(fd, SIOCGIFCONF, &ifc) == -1)
|
||||
{
|
||||
perror("get net interface error\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
// get correct net interface
|
||||
int flag = 0;
|
||||
int i;
|
||||
struct ifreq *ifrPtr;
|
||||
int networkNum = ifc.ifc_len / sizeof(struct ifreq);
|
||||
for(i = 0; i < networkNum; i++)
|
||||
{
|
||||
ifrPtr = ((struct ifreq*)buf) + i;
|
||||
if(ioctl(fd, SIOCGIFADDR, ifrPtr) == -1)
|
||||
{
|
||||
perror("get ip address error\n");
|
||||
exit(-1);
|
||||
}
|
||||
netaddr = ((struct sockaddr_in*)&(ifrPtr->ifr_addr))->sin_addr;
|
||||
|
||||
if(ioctl(fd, SIOCGIFNETMASK, ifrPtr) == -1)
|
||||
{
|
||||
perror("get netmask error\n");
|
||||
exit(-1);
|
||||
}
|
||||
netmask = ((struct sockaddr_in*)&(ifrPtr->ifr_netmask))->sin_addr;
|
||||
// 设置sockaddr_ll地址
|
||||
if((pingaddr.s_addr & netmask.s_addr) == (netaddr.s_addr & netmask.s_addr))
|
||||
{
|
||||
hwaddr.sll_family = PF_PACKET;
|
||||
hwaddr.sll_protocol = htons(ETH_P_ARP);
|
||||
hwaddr.sll_hatype = ARPHRD_ETHER;
|
||||
hwaddr.sll_pkttype = PACKET_OTHERHOST;
|
||||
hwaddr.sll_halen = ETH_ALEN;
|
||||
|
||||
if(ioctl(fd, SIOCGIFINDEX, ifrPtr) == -1)
|
||||
{
|
||||
perror("get net interface index error\n");
|
||||
exit(-1);
|
||||
}
|
||||
hwaddr.sll_ifindex = ifrPtr->ifr_ifindex;
|
||||
|
||||
if(ioctl(fd, SIOCGIFHWADDR, ifrPtr) == -1)
|
||||
{
|
||||
perror("get net interface hwaddr error\n");
|
||||
exit(-1);
|
||||
}
|
||||
memcpy(hwaddr.sll_addr, ifrPtr->ifr_hwaddr.sa_data, ETH_ALEN);
|
||||
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(flag != 1)
|
||||
{
|
||||
perror("can not find correct net interface\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
// 构建ARP请求包
|
||||
char ef[ETH_FRAME_LEN];
|
||||
//使p_eth指向以太网帧的帧头
|
||||
struct ethhdr *p_eth = (struct ethhdr*)ef;
|
||||
//目的以太网地址
|
||||
memset(p_eth->h_dest, 0xff, ETH_ALEN);
|
||||
//源以太网地址
|
||||
memcpy(p_eth->h_source, hwaddr.sll_addr, ETH_ALEN);
|
||||
//设置协议类型
|
||||
p_eth->h_proto = htons(ETH_P_ARP);
|
||||
|
||||
//定位ARP包地址
|
||||
struct arppacket *p_arp = (struct arppacket*)(ef + ETH_HLEN);
|
||||
//硬件类型
|
||||
p_arp->ar_head.ar_hrd = htons(ARPHRD_ETHER);/*arp硬件类型*/
|
||||
p_arp->ar_head.ar_pro = htons(ETH_P_IP); /*协议类型*/
|
||||
p_arp->ar_head.ar_hln = ETH_ALEN; /*硬件地址长度*/
|
||||
p_arp->ar_head.ar_pln = 4; /*IP地址长度*/
|
||||
p_arp->ar_head.ar_op = htons(ARPOP_REQUEST);
|
||||
|
||||
/*复制源以太网地址*/
|
||||
memcpy(p_arp->ar_sha, hwaddr.sll_addr, ETH_ALEN);
|
||||
/*源IP地址*/
|
||||
p_arp->ar_sip = netaddr;
|
||||
/*复制目的以太网地址*/
|
||||
memset(p_arp->ar_tha, 0, ETH_ALEN);
|
||||
//目的IP地址
|
||||
p_arp->ar_tip = pingaddr;
|
||||
//绑定网卡
|
||||
if(bind(fd, (struct sockaddr*)&hwaddr, sizeof(struct sockaddr_ll)) == -1)
|
||||
{
|
||||
perror("bind network error\n");
|
||||
exit(-1);
|
||||
}
|
||||
//发送以太网帧
|
||||
write(fd, ef, 60);
|
||||
//读取并打印目的MAC
|
||||
while(1)
|
||||
{
|
||||
read(fd, ef, sizeof(ef));
|
||||
struct arppacket *recv_arp = (struct arppacket*)(ef+ETH_HLEN);
|
||||
if(recv_arp->ar_tip.s_addr == netaddr.s_addr)
|
||||
{
|
||||
printf("Find %s 's mac:",argv[1]);
|
||||
for (i = 0; i < ETH_ALEN - 1; i++)
|
||||
printf("%02x-", recv_arp->ar_sha[i]);
|
||||
printf("%02x\n", recv_arp->ar_sha[ETH_ALEN - 1]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BIN
ARP编程/说明.pdf
Normal file
BIN
ARP编程/说明.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user