TCP/IP RAW ARP扫描

本文来源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);
		}

	}


你可能感兴趣的:(linux,ARP,raw,tcpip)