/************************************************************************
*									*
* ORODRUIN.c			Il Monte del Fato, la forgia entro cui	*
*				l' Uno e' stato creato, nella terra di	*
*				Mordor, dove l'ombra nera attende.	*
*									*
*				    Uno Spoof per regnarli,		*
*					Uno Spoof per trovarli, 	*
*				Uno Spoof per ghermirli, e nel buio	*
*				 incatenarli, nella terra di Redmond	*
*					dove il nero hacker attende ... *
*									*
* 				(C)1999 FuSyS TCP/IP Tools Unlimited	*
************************************************************************/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>

unsigned short ip_fast_csum(unsigned char *iph,unsigned long ihl) {
        unsigned long sum;

        __asm__ __volatile__("
            movl (%1), %0
            subl $4, %2
            jbe 2f
            addl 4(%1), %0
            adcl 8(%1), %0
            adcl 12(%1), %0
1:          adcl 16(%1), %0
            lea 4(%1), %1
            decl %2
            jne 1b
            adcl $0, %0
            movl %0, %2
            shrl $16, %0
            addw %w2, %w0
            adcl $0, %0
            notl %0
2:
 	    "
        : "=r" (sum), "=r" (iph), "=r" (ihl)
        : "1" (iph), "2" (ihl));
        return(sum);
}

struct pseudo {
	unsigned long saddr, daddr;
	unsigned char zero, proto;
	unsigned short len;
};

unsigned long in_aton(const char *str)
{
        unsigned long l;
        unsigned long val;
        int i;

        l = 0;
        for (i = 0; i < 4; i++)
        {
           l <<= 8;
           if (*str != '\0')
           {
               val = 0;
               while (*str != '\0' && *str != '.')
               {
                        val *= 10;
                        val += *str - '0';
                                str++;
                        }
                        l |= val;
                        if (*str != '\0')
                                str++;
                }
        }
        return(htonl(l));
}

void uff(void) {
	printf("\nUso: Orodruin sourceIP destIP ");
	printf("[-h -s -d -n -F -S -R -P -A -U]\n");
	printf("        -h       questa litania di Angmar ...\n");
	printf("	-s porta l' origine dell' Uno\n");
	printf("        -d porta la destinazione dell' Uno\n");
	printf("        -n x     il numero delle creazioni\n");
	printf("        -FSRPAU  le bandiere dell'Uno\n\n");
	exit(1);
}
int main(int argc, char **argv) {

	unsigned char pkt[1500], *x0F, b, flags=0;
	struct sockaddr_in sin;
	struct pseudo psp;
	int fd, fdo, ln, i, snt, opt, hz=1, os=0, od=0;
	unsigned long saddr, daddr;
	unsigned short src=0, dest=0;

	if(argc<3) {
		uff();
		exit(1);
	}

	saddr=in_aton(argv[1]);daddr=in_aton(argv[2]);

	while ((opt = getopt(argc, (char**)argv, "hs:d:n:FSRPAU")) != EOF )
        {
                switch(opt)
                {
			case 'h':
			uff();
			exit(0);
			break;

			case 's':
			src=(unsigned short)atoi(optarg);
			os++;
			break;

			case 'd':
			dest=(unsigned short)atoi(optarg);
			od++;
			break;
	
			case 'n':
                        hz=atoi(optarg);
                        break;
		
			case 'F':
			flags|=0x01;
			break;

			case 'S':
                        flags|=0x02;
                        break;

			case 'R':
                        flags|=0x04;
                        break;

			case 'P':
                        flags|=0x08;
                        break;

			case 'A':
                        flags|=0x10;
                        break;

			case 'U':
                        flags|=0x20;
                        break;

			default:
			break;
		}
	}
	if((fd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW))<0) {
		fprintf(stderr, "\nSOCK_RAW Died\n");
		exit(2);
	}
	fdo=1;
	if(setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &fdo, sizeof(fdo))<0) {
		fprintf(stderr, "\nHDRINCL Died\n");
		exit(3);
	}
	srand(time(NULL));
	printf("\n\033[1;34m----] \033[1;32mO R O D R U I N\033[0m");
        printf("\033[1;34m [----\033[0m");
        printf("\n\033[1;34m    TCP Forger by FuSyS\033[0m");
        printf("\n\033[1;34m   TCP/IP Tools Unlimited\033[0m");
        printf("\n\033[1;34m------------][-------------\033[0m\n\n");


     /* Magia Nera Del Re Stregone di Minas Morgul, Signore Dei Nazgul */

while(hz){if(!os)src=1024+(rand()%2000);if(!od)dest=rand()%2000;if(flags==0)
flags|=0x20|0x08;sin.sin_family=AF_INET;sin.sin_addr.s_addr=daddr;sin.sin_port=
dest;ln=sizeof(sin);x0F=pkt;memset((unsigned char*)x0F,0,1500);psp.saddr=saddr;
psp.daddr =daddr;psp.len=htons(20);psp.zero=0;psp.proto=6;b=0x45;memcpy(x0F,&b,
sizeof(unsigned char));x0F+=2;*((unsigned short*)x0F)=htons(40);x0F+=2;*((
unsigned short*)x0F)=0xFFFF;x0F+=2;*(( unsigned short*)x0F)=0x0000;x0F+=2;*((
unsigned char*)x0F)=0xFF;x0F+=1;b=6;memcpy(x0F,&b,sizeof(unsigned char));x0F+=3
;*((unsigned long*)x0F)=saddr;x0F+=4;*((unsigned long*)x0F)=daddr;x0F+=4;*((
unsigned short*)x0F)=htons(src);x0F+=2;*((unsigned short*)x0F)=htons(dest);x0F
+=2;*((unsigned long*)x0F)=htonl(rand());x0F+=4;*((unsigned long*)x0F)=htonl(
rand());x0F+=4;b=0x50;memcpy(x0F,&b,sizeof(unsigned char));x0F+=1;memcpy(x0F,
&flags,sizeof(unsigned short));x0F+=1;*((unsigned short*)x0F)=htons(1024);x0F+=
2;*((unsigned short*)x0F)=ip_fast_csum((unsigned char*)&psp,32);snt=sendto(fd,
pkt,40,0,(struct sockaddr*)&sin,ln);hz--;}

	exit(1);
}
