本文来源http://blog.csdn.net/gt945/article/details/40836871
/*
* arp_hack.c
*
* Created on: 2014年11月4日
* Author: tao
*/
#include
#include
#include
#include
#include
#undef __USE_MISC
#include
#include
#include
#include
typedef struct __attribute__ ((__packed__)) {
uint8_t dst_mac[6];
uint8_t src_mac[6];
uint16_t etype;
uint16_t htype;
uint16_t ptype;
uint8_t hlen;
uint8_t plen;
uint16_t opcode;
uint8_t sender_mac[6];
struct in_addr sender_ip;
uint8_t target_mac[6];
struct in_addr target_ip;
} arp_pkt;
int arp_create_fd()
{
int fd = -1;
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (fd < 0) {
perror("socket():");
goto exit;
}
exit:
return fd;
}
int arp_read(int fd, arp_pkt *our)
{
char buff[4096];
fd_set rset;
int length;
int ret = -1;
int i;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(fd, &rset);
tv.tv_sec = 0;
tv.tv_usec = 0;
while (select(fd + 1, &rset, NULL, NULL, &tv) > 0) {
length = recvfrom(fd, buff, sizeof(buff), 0, NULL, NULL);
if (length == -1) {
perror("recvfrom():");
goto exit;
}
{
arp_pkt *pkt;
pkt = (arp_pkt *)buff;
if (ntohs(pkt->etype) == ETH_P_ARP
&& ntohs(pkt->opcode) == ARPOP_REPLY
&& our->sender_ip.s_addr == pkt->target_ip.s_addr) {
for (i = 0; i < 3; i++) {
printf("%d.", *((char *)&pkt->sender_ip + i) & 0xFF);
}
printf("%d\n", *((char *)&pkt->sender_ip + i) & 0xFF);
}
}
}
ret = 0;
exit:
return ret;
}
int arp_build_packet(arp_pkt *pkt, char *interface)
{
int ret = -1;
int tmp_fd = 0;
memset(pkt, 0, sizeof(arp_pkt));
{
struct ifreq ifr;
if ((tmp_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("socket() failed to get socket descriptor for using ioctl() ");
goto exit;
}
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", interface);
if (ioctl(tmp_fd, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl() failed to get source MAC address ");
goto exit;
}
memcpy(pkt->sender_mac, ifr.ifr_hwaddr.sa_data, 6 * sizeof(uint8_t));
memcpy(pkt->src_mac, ifr.ifr_hwaddr.sa_data, 6 * sizeof(uint8_t));
if (ioctl(tmp_fd, SIOCGIFADDR, &ifr) < 0) {
perror("ioctl() failed to get interface ip address ");
goto exit;
}
pkt->sender_ip = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr;
}
pkt->htype = htons(1);
pkt->ptype = htons(ETH_P_IP);
pkt->hlen = 6;
pkt->plen = 4;
pkt->opcode = htons(ARPOP_REQUEST);
memset(pkt->target_mac, 0, 6 * sizeof(uint8_t));
memset(pkt->dst_mac, 0xFF, 6);
pkt->etype = htons(ETH_P_ARP);
ret = 0;
exit:
if (tmp_fd > 0) {
close(tmp_fd);
}
return ret;
}
int arp_send(arp_pkt *pkt, char *interface)
{
int ret = -1;
int sd;
int bytes;
struct sockaddr_ll device;
memset(&device, 0, sizeof(device));
device.sll_ifindex = if_nametoindex (interface);
device.sll_family = AF_PACKET;
device.sll_halen = htons(6);
memcpy(device.sll_addr, pkt->sender_mac, 6 * sizeof(uint8_t));
if ((sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
perror("socket() failed ");
goto exit;
}
if ((bytes = sendto(sd, pkt, sizeof(arp_pkt), 0, (struct sockaddr *) &device, sizeof(device))) <= 0) {
perror("sendto() failed");
goto exit;
}
ret = 0;
exit:
if (sd > 0) {
close(sd);
}
return ret;
}
int main()
{
arp_pkt arppkt;
char *interface = "wlp7s0";
char *address = "192.168.1.1";
{
struct if_nameindex *ifs;
int i;
ifs = if_nameindex();
for (i = 0; ifs[i].if_name; ++i) {
if (0 == strcmp(ifs[i].if_name, interface)) {
break;
}
}
if (!ifs[i].if_name) {
printf("No such device\n");
exit(1);
}
}
arp_build_packet(&arppkt, interface);
{
struct in_addr addr;
uint32_t temp;
int arp_fd;
int i, n;
fd_set rset;
struct timeval tv;
arp_fd = arp_create_fd();
inet_aton(address, &addr);
temp = ntohl(addr.s_addr);
temp = temp & 0xFFFFFF00;
i = 0;
tv.tv_sec = 0;
tv.tv_usec = 10000;
while (1) {
FD_ZERO(&rset);
FD_SET(arp_fd, &rset);
if ((n = select(arp_fd + 1, &rset, NULL, NULL, &tv)) < 0) {
if (errno == EINTR)
continue;
else
perror("select error");
}
if (FD_ISSET(arp_fd, &rset)) {
arp_read(arp_fd, &arppkt);
}
if (i++ < 255) {
arppkt.target_ip.s_addr = htonl(temp + i);
arp_send(&arppkt, interface);
usleep(2000);
} else {
break;
}
}
sleep(1);
arp_read(arp_fd, &arppkt);
close(arp_fd);
}
}