本文来源http://blog.csdn.net/gt945/article/details/40836871
/* * arp_hack.c * * Created on: 2014年11月4日 * Author: tao */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <netdb.h> #undef __USE_MISC #include <net/if.h> #include <linux/if_arp.h> #include <sys/ioctl.h> #include <errno.h> 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); } }