Skip to content

Commit

Permalink
add some programs for playing with DoS attacks on TCP
Browse files Browse the repository at this point in the history
  • Loading branch information
ambrop7 committed Sep 3, 2012
1 parent 93bc612 commit 47431d7
Show file tree
Hide file tree
Showing 11 changed files with 1,327 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ else ()
build_switch(NCD "build badvpn-ncd" OFF)
build_switch(TUNCTL "build badvpn-tunctl" OFF)
endif ()
build_switch(DOSTEST "build dostest-server and dostest-attacker" OFF)

if (BUILD_NCD AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
message(FATAL_ERROR "NCD is only available on Linux")
Expand Down Expand Up @@ -296,6 +297,11 @@ if (BUILD_NCD)
add_subdirectory(ncd-request)
endif ()

# dostest
if (BUILD_DOSTEST)
add_subdirectory(dostest)
endif ()

message(STATUS "Building components:")

# print what we're building and what not
Expand Down
2 changes: 2 additions & 0 deletions blog_channels.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,5 @@ ncd_net_ipv6_addr 4
ncd_net_ipv6_route 4
ncd_net_ipv4_addr_in_network 4
ncd_net_ipv6_addr_in_network 4
dostest_server 4
dostest_attacker 4
10 changes: 10 additions & 0 deletions dostest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_executable(dostest-server
dostest-server.c
StreamBuffer.c
)
target_link_libraries(dostest-server base system)

add_executable(dostest-attacker
dostest-attacker.c
)
target_link_libraries(dostest-attacker base system)
147 changes: 147 additions & 0 deletions dostest/StreamBuffer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/**
* @file StreamBuffer.c
* @author Ambroz Bizjak <[email protected]>
*
* @section LICENSE
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <misc/balloc.h>
#include <misc/minmax.h>

#include "StreamBuffer.h"

// called when receive operation is complete
static void input_handler_done (void *vo, int data_len)
{
StreamBuffer *o = (StreamBuffer *)vo;
ASSERT(data_len > 0)
ASSERT(data_len <= o->buf_size - (o->buf_start + o->buf_used))

// remember if buffer was empty
int was_empty = (o->buf_used == 0);

// increment buf_used by the amount that was received
o->buf_used += data_len;

// start another receive operation unless buffer is full
if (o->buf_used < o->buf_size - o->buf_start) {
int end = o->buf_start + o->buf_used;
StreamRecvInterface_Receiver_Recv(o->input, o->buf + end, o->buf_size - end);
}
else if (o->buf_used < o->buf_size) {
// wrap around
StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_start);
}

// if buffer was empty before, start send operation
if (was_empty) {
StreamPassInterface_Sender_Send(o->output, o->buf + o->buf_start, o->buf_used);
}
}

// called when send operation is complete
static void output_handler_done (void *vo, int data_len)
{
StreamBuffer *o = (StreamBuffer *)vo;
ASSERT(data_len > 0)
ASSERT(data_len <= o->buf_used)
ASSERT(data_len <= o->buf_size - o->buf_start)

// remember if buffer was full
int was_full = (o->buf_used == o->buf_size);

// increment buf_start and decrement buf_used by the
// amount that was sent
o->buf_start += data_len;
o->buf_used -= data_len;

// wrap around buf_start
if (o->buf_start == o->buf_size) {
o->buf_start = 0;
}

// start receive operation if buffer was full
if (was_full) {
int end;
int avail;
if (o->buf_used >= o->buf_size - o->buf_start) {
end = o->buf_used - (o->buf_size - o->buf_start);
avail = o->buf_start - end;
} else {
end = o->buf_start + o->buf_used;
avail = o->buf_size - end;
}
StreamRecvInterface_Receiver_Recv(o->input, o->buf + end, avail);
}

// start another receive send unless buffer is empty
if (o->buf_used > 0) {
int to_send = bmin_int(o->buf_used, o->buf_size - o->buf_start);
StreamPassInterface_Sender_Send(o->output, o->buf + o->buf_start, to_send);
}
}

int StreamBuffer_Init (StreamBuffer *o, int buf_size, StreamRecvInterface *input, StreamPassInterface *output)
{
ASSERT(buf_size > 0)
ASSERT(input)
ASSERT(output)

// remember arguments
o->buf_size = buf_size;
o->input = input;
o->output = output;

// allocate buffer memory
o->buf = (uint8_t *)BAllocSize(bsize_fromint(o->buf_size));
if (!o->buf) {
goto fail0;
}

// set initial buffer state
o->buf_start = 0;
o->buf_used = 0;

// set receive and send done callbacks
StreamRecvInterface_Receiver_Init(o->input, input_handler_done, o);
StreamPassInterface_Sender_Init(o->output, output_handler_done, o);

// start receive operation
StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_size);

DebugObject_Init(&o->d_obj);
return 1;

fail0:
return 0;
}

void StreamBuffer_Free (StreamBuffer *o)
{
DebugObject_Free(&o->d_obj);

// free buffer memory
BFree(o->buf);
}
70 changes: 70 additions & 0 deletions dostest/StreamBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* @file StreamBuffer.h
* @author Ambroz Bizjak <[email protected]>
*
* @section LICENSE
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef BADVPN_STREAMBUFFER_H
#define BADVPN_STREAMBUFFER_H

#include <misc/debug.h>
#include <base/DebugObject.h>
#include <flow/StreamRecvInterface.h>
#include <flow/StreamPassInterface.h>

/**
* Buffer object which reads data from a \link StreamRecvInterface and writes
* it to a \link StreamPassInterface.
*/
typedef struct {
int buf_size;
StreamRecvInterface *input;
StreamPassInterface *output;
uint8_t *buf;
int buf_start;
int buf_used;
DebugObject d_obj;
} StreamBuffer;

/**
* Initializes the buffer object.
*
* @param o object to initialize
* @param buf_size size of the buffer. Must be >0.
* @param input input interface
* @param outout output interface
* @return 1 on success, 0 on failure
*/
int StreamBuffer_Init (StreamBuffer *o, int buf_size, StreamRecvInterface *input, StreamPassInterface *output) WARN_UNUSED;

/**
* Frees the buffer object.
*
* @param o object to free
*/
void StreamBuffer_Free (StreamBuffer *o);

#endif
Loading

0 comments on commit 47431d7

Please sign in to comment.