/*
 * $Id: arprelease.c,v 1.2 2003/05/19 10:32:33 chris_schneider Exp $
 * based on arpoison v0.5 -- Steve Buer
 *
 * $Log: arprelease.c,v $
 * Revision 1.2  2003/05/19 10:32:33  chris_schneider
 * Ported to Libnet 1.1.0 (see also http://www.packetfactory.net/libnet/ )
 *
 * Revision 1.1.1.1  2001/07/19 11:57:02  chris_schneider
 * Initial checkin
 *
 */

#include <libnet.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>

void get_ip_addr(struct in_addr *, char *);

int main(int argc, char *argv[])
{
	/* various variables */
	libnet_t *l;
	struct libnet_ether_addr *e;	/* structure to hold returned MAC */
	int c;
        u_long IP;
        u_char *packet;
	u_long packet_size = 0;
        u_char *device;
	char err_buf[LIBNET_ERRBUF_SIZE];
	libnet_ptag_t n;
	u_char BROADCASTMAC[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 

	/* parse args etc */
	if (argc != 3)
	{
		printf("$Id: arprelease.c,v 1.2 2003/05/19 10:32:33 chris_schneider Exp $\nUsage: %s <device> <dest IP>\n", argv[0]);
		exit(1);
	}

	device = argv[1];

	IP = inet_addr(argv[2]); 

	if (IP == -1)
	{
		perror("inet_addr()");
		exit(1);
	}

	l = libnet_init(
		LIBNET_LINK_ADV,	/* injection type */
		device,			/* or device if you using LIBNET_LINK */
		err_buf);

	if (l == NULL)
	{
		fprintf(stderr, "libnet_init() failed: %s\n", err_buf);
		exit(1);
	}

	e = libnet_get_hwaddr(l);

        /* ARP header */
        n = libnet_build_arp(ARPHRD_ETHER,		/* hardware type */
			     ETHERTYPE_IP,		/* proto type */
			     6,				/* hw addr size */
			     4,				/* proto addr size */ 
			     ARPOP_REQUEST,		/* ARP REQUEST */
			     e->ether_addr_octet,	/* source HW addr */
			     (u_char *)&IP,		/* src proto addr */
			     BROADCASTMAC,		/* dst HW addr */
			     (u_char *)&IP,		/* dst IP addr */
			     NULL,			/* no payload */
			     0,				/* payload length */
			     l,				/* libnet handle */
			     0);			/* libnet id */

	if (n == -1)
	{
		perror("libnet_build_arp");
		exit(1);
	}

	n = libnet_autobuild_ethernet(
		BROADCASTMAC,			/* ethernet destination */
		ETHERTYPE_ARP,			/* protocol type */
		l);				/* libnet handle */


	/* Write it to the wire */
	c = libnet_adv_cull_packet(l, &packet, &packet_size);

	if (c == -1)
	{
		printf("libnet_adv_cull_packet: %s\n", libnet_geterror(l));
		exit(1);
	}

	c = libnet_write(l);

	if (c == -1)
	{
		fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
		exit(1);
	}

	libnet_destroy(l);

	return 0;
}
