⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arpd.c

📁 linux下arp查询的源代码
💻 C
字号:
/* *	File:	arpd.c *	 *	Author:	zhubo@legendsec.com *	 *	Date:	2008-08-18 * *	Brief:	arpd deamon that query the arp information *  */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <errno.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include <linux/sockios.h>#include <net/if.h>#include <net/if_arp.h>#include <arpa/inet.h>#include <netinet/in.h>#include <netinet/if_ether.h>#define BUFSIZE			186#define MAX_ROW			10#define GATEWAY_ROW		1#define GATEWAY_NUM		10#define SIOCGARPMSG		0x1003typedef struct _ether_pkg_ {    unsigned char ether_dhost[6];    unsigned char ether_shost[6];       unsigned short int ether_type;   				        unsigned short int ar_hrd;        unsigned short int ar_pro;        unsigned char ar_hln;        unsigned char ar_pln;        unsigned short int ar_op;       unsigned char arp_sha[6];        unsigned char arp_spa[4];        unsigned char arp_tha[6];        unsigned char arp_tpa[4];  }ether_pkg;	unsigned int gateway_num = 0;unsigned int time_lag = 0;char *device = {0};static void usage(){	printf("\nUsage: arpd\n"		   "        -t  <time>          the time interval to detect IP conflict\n"		   "        -d  <interface>     specify the net interface name\n"		   "        -h                  help\n");	exit(-1);}static void parse_args(int argc, char *argv[]){	int ch = 0;	while ((ch = getopt(argc, argv, "t:d:h")) != -1) {		switch(ch) {		case 't':			time_lag = atoi(optarg);			break;		case 'd':			device = optarg;			break;		case 'h':		default:			usage(argv[0]);			break;		}	}	if (argc <= 1)		usage();	if (optind < argc) {         printf ("non-option ARGV-elements: ");        while (optind < argc)             printf ("%s ", argv[optind++]);        printf ("\n");         exit (-1);    }}/* initialize the deamon */static void deamon_init(void){	pid_t pid;		umask(0);	pid = fork();		if (pid)		exit(0);	else if (pid < 0)		exit(1);	if (chdir("/") < 0) {		perror("chdir()");		exit(1);	}		setsid();	pid = fork();		if (pid)		exit(0);	else if (pid < 0)		exit(1);	signal(SIGCHLD, SIG_IGN);}/* get the IP address of the gateway by reading the route table /proc/net/route */static int get_gateway(struct sockaddr_in *gateway_addr){	if (gateway_addr == NULL)		return -1;		FILE *fp = NULL;	unsigned char buf[BUFSIZE] = {0};	unsigned long route[MAX_ROW] = {0};	unsigned char *ip = NULL;	char iface[8] = {0};	int lines = 0;	int nitems = 0;	int num = 0;	struct in_addr gate_addr;	buf[BUFSIZE-1] = 0;	fp = fopen("/proc/net/route", "rb");	if (!fp) {		fprintf(stderr, "Unable to open route table\n");		return -1;	}	lines = 0;	while (1) {		if (!fgets(buf, BUFSIZE-1, fp)) {			fclose(fp); 			break;		}		lines++;		nitems = sscanf(buf, "%s %lx %lx", iface, route, route+1);		if (nitems == 3 && lines > 1) {			if (route[GATEWAY_ROW]) {				gate_addr.s_addr = route[GATEWAY_ROW]; 				(gateway_addr + num)->sin_addr = gate_addr;				num++;				ip = inet_ntoa(gate_addr);				fprintf(stderr, "The gateway IP on interface %s is:%s\n", iface, ip);			}			continue;		}	}	gateway_num = num;		fprintf(stderr, "There are %d lines in route table and %d gateway\n", lines, gateway_num);		return 0;}/* get local mac and ip address*/int get_local_mac_ip(unsigned char *local_mac, unsigned char *local_ip)   {   	if ( NULL == local_mac) {		fprintf(stderr, "%s %d:invalid argument", __func__, __LINE__);		return -1;	}	int sockfd;   	struct ifreq req;   	struct sockaddr_in *sin;    	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)   	{   		fprintf(stderr, "Sock Error:%s\n\a", strerror(errno));   		return -1;   	}       	memset(local_mac, 0, sizeof(local_mac));	memset(local_ip, 0, sizeof(local_ip));	memset(&req, 0, sizeof(req));   	strcpy(req.ifr_name, device);	if(ioctl(sockfd, SIOCGIFHWADDR, (char *)&req) == -1)   	{   		fprintf(stderr, "ioctl SIOCGIFHWADDR:%s\n\a", strerror(errno));   		close(sockfd);   		return -1;   	}	memcpy(local_mac, req.ifr_hwaddr.sa_data, 6);		req.ifr_addr.sa_family = AF_INET;   	if(ioctl(sockfd, SIOCGIFADDR, (char *)&req) == -1)   	{   		fprintf(stderr, "ioctl SIOCGIFADDR:%s\n\a", strerror(errno));   		close(sockfd);   		return -1;   	}			sin = (struct sockaddr_in *)&req.ifr_addr;	memcpy(local_ip, (char *)&(sin->sin_addr), 4);	fprintf(stderr, "The local IP is:%s\n", inet_ntoa(sin->sin_addr));	fprintf(stderr, "The local MAC is:%02x:%02x:%02x:%02x:%02x:%02x\n", 			local_mac[0], local_mac[1], local_mac[2], 			local_mac[3], local_mac[4], local_mac[5]);    	return 0;   }/* build arp packet and execute arp query */static inline int arp_query(unsigned char *dst_ip, unsigned char *dst_mac){	if ((NULL == dst_ip) || (NULL == dst_mac) || strlen(dst_ip) == 0)		return -1;		ether_pkg pkg;	ether_pkg *parse = NULL;   	unsigned char buffer[255] = {0};   	unsigned char mac[7] = {0};   	unsigned char ip[5] ={0};  	struct sockaddr_in local_ip;	int sockfd = 0;	int len = 0;	struct sockaddr sa;   	unsigned char broad_mac[7] = {0xff,0xff,0xff,0xff,0xff,0xff,0x00};       	memset(mac, 0, sizeof(mac));   	memset(ip, 0, sizeof(ip));   	memset(&local_ip, 0, sizeof(struct sockaddr_in));   	if(get_local_mac_ip(mac, ip) == -1)		return -1;	/* build the arp packet */	  	memset((char *)&pkg, '\0', sizeof(pkg));       	memcpy((char *)pkg.ether_shost, (char *)mac, 6);   	memcpy((char *)pkg.ether_dhost, (char *)broad_mac, 6);   	pkg.ether_type = htons(ETHERTYPE_ARP);    	pkg.ar_hrd = htons(ARPHRD_ETHER);	pkg.ar_pro = htons(ETHERTYPE_IP);	pkg.ar_hln = 6;	pkg.ar_pln = 4;	pkg.ar_op = htons(ARPOP_REQUEST);	memcpy((char *)pkg.arp_sha, (char *)mac, 6);	memcpy((char *)pkg.arp_spa, (char *)ip, 4);	memcpy((char *)pkg.arp_tha, (char *)broad_mac, 6);	memcpy((char *)pkg.arp_tpa, (char *)dst_ip, 4);	if((sockfd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL)))==-1) {   		fprintf(stderr,"Socket Error:%s\n\a", strerror(errno));   		return -1;   	}       	memset(&sa, 0,sizeof(struct sockaddr));   	strcpy(sa.sa_data, device);	len = sendto(sockfd, &pkg, sizeof(pkg), 0, &sa, sizeof(sa));	if(len != sizeof(pkg)) {   		fprintf(stderr,"Sendto Error:%s\n\a", strerror(errno));   		return -1;   	}       	int i = 0;	parse = (ether_pkg *)buffer;   	while(1) {   		memset(buffer, 0, sizeof(buffer));   		recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, &len);				if((ntohs(parse->ether_type) == ETHERTYPE_ARP) && (ntohs(parse->ar_op) == ARPOP_REPLY)) {			memcpy(dst_mac, &parse->arp_tha, 6);			fprintf(stderr, "The mac of the host %d.%d.%d.%d is %02x:%02x:%02x:%02x:%02x:%02x\n", 					dst_ip[0], dst_ip[1], dst_ip[2], dst_ip[3],					dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4],dst_mac[5]);			break;   		}		i++;		if(i > 255) break;	}   	return 0;   }/* communication with the kernel in order to send the arp message to kernel */static inline int send_arp_msg(unsigned char *ip_addr, unsigned char *mac_addr){		if ((NULL == ip_addr) || (NULL == mac_addr) || (strlen (ip_addr) ==0) || (strlen(mac_addr) == 0))		return -1;		    int fd = 0;	char ip[16] = {0};	struct arpreq arpreq;	struct sockaddr_in *sin;	struct sockaddr *sa;	struct in_addr pa;		memset(&arpreq, 0, sizeof(struct arpreq));	fd = socket(AF_INET, SOCK_DGRAM, 0);	if (fd < 0)	{        perror("socket failed\n");		return -1;	}		sprintf(ip, "%d.%d.%d.%d", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);	sin = (struct sockaddr_in *)&arpreq.arp_pa;	memset(sin, 0, sizeof(struct sockaddr_in));	sin->sin_family = AF_INET;	pa.s_addr = inet_addr(ip);	memcpy(&sin->sin_addr, &pa, sizeof(struct in_addr));	sa = &arpreq.arp_ha;	memset(sa, 0, sizeof(struct sockaddr));	memcpy(sa->sa_data, mac_addr, 6);	strcpy(arpreq.arp_dev, device);	/* specify the net device name */	arpreq.arp_flags = ATF_COM;		if (ioctl(fd, SIOCSARP, &arpreq) == -1) {	    perror("ioctl failed");        close(fd);				return -1;	}		return 0;}static inline int recieve_arp_msg(char *ip_addr){    if (ip_addr == NULL)		return -1;			int fd = 0;	unsigned int cmd = 0;	struct sockaddr_in arp_arg;		cmd = SIOCGARPMSG;	//the command defined by ourselves	fd = socket(AF_INET, SOCK_STREAM, 0);	if ( fd < 0 )	{        perror( "socket failed" );		return -1;	}    	if ( ioctl(fd, SIOCGARPMSG, &arp_arg) == -1 )	{	    perror( "ioctl filed" );        close( fd );		return -1;	}	memcpy(ip_addr, (char *)(&arp_arg.sin_addr), 6);		return 0;}static void check_ip(){	unsigned char ip[5] = {0};	unsigned char mac[7] = {0};	unsigned char dst_mac[7] = {0};	if(get_local_mac_ip(mac, ip) == -1)		return;		if(arp_query(ip, dst_mac) == -1)		return;		if (strncmp(mac, dst_mac, 6))		fprintf(stderr, "The IP:%s conflict!", ip);		alarm(time_lag);}/* the main function */int main(int argc, char *argv[]){	int i = 0;	unsigned char ip_addr[5] = {0}; 	unsigned char mac_addr[7] = {0};	struct sockaddr_in gateway_addr[GATEWAY_NUM];		deamon_init();	parse_args(argc,argv);	if(get_gateway(gateway_addr) == -1) {		fprintf(stderr, "Can't get gateway address\n");	}		if (gateway_num > 0) {		for (i = 0; i < gateway_num; i++) {			memcpy(ip_addr, (char *)(&gateway_addr[i].sin_addr), 4);			arp_query(ip_addr, mac_addr);			send_arp_msg(ip_addr, mac_addr);		}	}	signal(SIGALRM, check_ip);	alarm(1);		while(1) {		memset(ip_addr, 0, 4);		memset(mac_addr, 0, 6);		recieve_arp_msg(ip_addr);		arp_query(ip_addr, mac_addr);		send_arp_msg(ip_addr, mac_addr);	}		return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -