/* simple packet flooder written for madwifi debugging
 *
 * (C) 2007-07-31 Georg Lukas <georg@boerde.de>
 *
 * You can distribute / modify this program under the terms of the
 * GNU General Public Licence v2.
 */
#define _BSD_SOURCE 1
#include <sys/time.h> /* timersub */
#include <netpacket/packet.h> /* sockaddr_ll */
#include <iwlib.h> /* WE functions */
#include <string.h> /* strncpy */

char broadcast[ETHER_ADDR_LEN+1] = "\xff\xff\xff\xff\xff\xff";
char mac[ETHER_ADDR_LEN];

int size = 1500;
char *dev = "ath0";

struct packet {
	struct ether_header hdr;
	char data[1500];
}__attribute((packed));

int bind_raw(char *devname) {
	int s;
	struct ifreq req;
	struct sockaddr_ll addr;

	s = socket(PF_PACKET, SOCK_RAW, htons(0x5508));
	if (s < 0)
		perror("socket(SOCK_RAW)");

	strncpy(req.ifr_name, devname, IFNAMSIZ);
	if (ioctl(s, SIOCGIFINDEX, &req) != 0)
	    perror("ioctl(SIOCGIFINDEX)");

	/* bind the socket to the right device */
	addr.sll_family = AF_PACKET;
	addr.sll_protocol = htons(0x5508);
	addr.sll_ifindex = req.ifr_ifindex;
	if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
		perror("bind(raw)");
	
	strncpy(req.ifr_name, devname, IFNAMSIZ);
	ioctl(s, SIOCGIFHWADDR, &req);
	memcpy(mac, req.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);

	/* ifconfig up the device */
	strncpy(req.ifr_name, devname, IFNAMSIZ);
	if (ioctl(s, SIOCGIFFLAGS, &req) != 0)
		perror("ioctl(SIOCGIFFLAGS)");
	req.ifr_flags |= IFF_UP | IFF_RUNNING;
	if (ioctl(s, SIOCSIFFLAGS, &req) != 0)
		perror("ioctl(SIOCSIFFLAGS)");
	if (ioctl(s, SIOCGIFFLAGS, &req) != 0)
		perror("ioctl(SIOCGIFFLAGS)");

	return s;
}


int main(int argc, char **argv) {
	int raws;
	struct packet p;
	int sent;
	int rawsize;

	if (argc > 1) {
		dev = argv[1];
	}
	
	if (argc > 2) {
		size = atoi(argv[2]);
	}
	
	raws = bind_raw(dev);

	memset(&p, 0x5A, sizeof(p));
	memcpy(&p.hdr.ether_dhost, broadcast, ETHER_ADDR_LEN);
	memcpy(&p.hdr.ether_shost, mac, ETHER_ADDR_LEN);
	p.hdr.ether_type = htons(0x5508);

	rawsize = size + sizeof(struct ether_header);
	while (1) {
		printf("Sending %i bytes packet on %s...\n", size, dev);
		sent = send(raws, (char*)&p, rawsize, 0);
		if (sent < 0) {
			perror("send()");
			exit(1);
		} else if (sent < rawsize) {
			printf("truncated!\n");
		}
		//sleep(1);
	}
}
