/*
 * $Id: arprelease.c,v 1.1.1.1 2001/07/19 11:57:02 chris_schneider Exp $
 * based on arpoison v0.5 -- Steve Buer
 *
 * $Log: arprelease.c,v $
 * 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 */
	int n;
	int packet_size = LIBNET_ETH_H + LIBNET_ARP_H;  
        u_long IP;
        u_char *packet;
        u_char *device;
	char err_buf[LIBNET_ERRBUF_SIZE];
        struct libnet_link_int *network; 
	struct ether_addr *MAC;
	u_char BROADCASTMAC[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 

	/* parse args etc */
	if (argc != 3)
	{
		printf("$Id: arprelease.c,v 1.1.1.1 2001/07/19 11:57:02 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);
	}

	/* open the link-layer interface */
	network = libnet_open_link_interface(device, err_buf);

	if (network == NULL)
	{
		perror("libnet_open_link_interface");
		exit(1);
	}

	if ((MAC = libnet_get_hwaddr(network, device, err_buf)) == NULL)
	{
		perror("libnet_get_hwaddr()");
		exit(1);
	}

        /* allocate memory for packet */
	n = libnet_init_packet(packet_size, &packet);  

	if (n != 1)
	{
		printf("libnet_init_packet: error\n");
		exit(1);
	}

        /* ethernet header */
        n = libnet_build_ethernet(BROADCASTMAC,		/* dst HW addr */
				  (u_char *)MAC,	/* src HW addr */
				  0x0806,		/* ether packet type */
				  NULL,			/* ptr to payload */
				  0,			/* payload size */
				  packet);		/* ptr to packet */ 

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

        /* ARP header */
        n = libnet_build_arp(1,				/* hardware type */
			     0x0800,			/* proto type */
			     6,				/* hw addr size */
			     4,				/* proto addr size */ 
			     1,				/* ARP REQUEST */
			     (u_char *)MAC,		/* 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 */
			     packet + LIBNET_ETH_H);	/* packet buffer mem */

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

	/* inject the mofo !! */
	n = libnet_write_link_layer(network,
				    device, 
				    packet, 
				    packet_size);
	if (n < packet_size)
	{
		printf("libnet_write_link_layer only wrote %d of %d bytes\n", n, packet_size);
	}

        /* 
         * Shut down the interface 
         */
        n = libnet_close_link_interface(network);  
	if (n == -1)
	{
		perror("libnet_close_link_interface");
		exit(1);
	}
	
        /* 
         * free packet memory 
         */
	libnet_destroy_packet(&packet); 

	return 0;
}
