diff --git a/CMakeLists.txt b/CMakeLists.txt index 1182bb3..d9c9490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,8 @@ list(APPEND CSOURCES src/timer.c src/capture_traffic.h src/capture_traffic.c + src/cap_utils.h + src/cap_utils.c ) add_executable(donar ${CSOURCES} src/donar.c) @@ -42,6 +44,7 @@ add_executable(measlat ${CSOURCES} src/meas_lat.c) add_executable(udpecho ${CSOURCES} src/udp_echo.c) add_executable(torecho ${CSOURCES} src/tor_echo.c) add_executable(capdiff ${CSOURCES} src/capdiff.c) +add_executable(capreplay ${CSOURCES} src/capreplay.c) find_package(PkgConfig REQUIRED) pkg_search_module(GLIB REQUIRED glib-2.0) @@ -61,6 +64,9 @@ target_link_libraries(torecho ${GLIB_LDFLAGS}) target_include_directories(capdiff PRIVATE ${GLIB_INCLUDE_DIRS}) target_link_libraries(capdiff ${GLIB_LDFLAGS}) -install(TARGETS donar measlat udpecho torecho capdiff +target_include_directories(capreplay PRIVATE ${GLIB_INCLUDE_DIRS}) +target_link_libraries(capreplay ${GLIB_LDFLAGS}) + +install(TARGETS donar measlat udpecho torecho capdiff capreplay RUNTIME DESTINATION bin LIBRARY DESTINATION lib) diff --git a/src/cap_utils.c b/src/cap_utils.c new file mode 100644 index 0000000..765808a --- /dev/null +++ b/src/cap_utils.c @@ -0,0 +1,29 @@ +#include "cap_utils.h" + +void cap_load(struct cap_file *cf, char* filename) { + if ((cf->fd = fopen(filename, "r")) == NULL) { + perror("Unable to open file"); + exit(EXIT_FAILURE); + } + + fseek(cf->fd, 0, SEEK_END); + cf->sz = ftell(cf->fd); + fseek(cf->fd, 0, SEEK_SET); +} + +void cap_next_bp(struct cap_file *cf, struct buffer_packet* bp) { + fread(bp, sizeof(struct buffer_packet), 1, cf->fd); +} + +void cap_peek_bp(struct cap_file *cf, struct buffer_packet* bp) { + size_t n = fread(bp, sizeof(struct buffer_packet), 1, cf->fd); + fseek(cf->fd, -n, SEEK_CUR); +} + +size_t cap_count_bp(struct cap_file *cf) { + return cf->sz / sizeof(struct buffer_packet); +} + +void cap_unload(struct cap_file *cf) { + fclose(cf->fd); +} diff --git a/src/cap_utils.h b/src/cap_utils.h new file mode 100644 index 0000000..5f0f4ba --- /dev/null +++ b/src/cap_utils.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include "packet.h" + +struct cap_file { + FILE *fd; + size_t sz; +}; + +void cap_load(struct cap_file *cf, char* filename); +void cap_next_bp(struct cap_file *cf, struct buffer_packet* bp); +void cap_peek_bp(struct cap_file *cf, struct buffer_packet* bp); +size_t cap_count_bp(struct cap_file *cf); +void cap_unload(struct cap_file *cf); diff --git a/src/capdiff.c b/src/capdiff.c index 5ab055c..0cb3e49 100644 --- a/src/capdiff.c +++ b/src/capdiff.c @@ -1,45 +1,40 @@ #include #include +#include "cap_utils.h" #include "packet.h" int main(int argc, char** argv) { + setvbuf(stdout, NULL, _IONBF, 0); + printf("~ capdiff ~\n"); + if (argc != 3) { - fprintf(stderr, "Usage %s ./cap.0 ./cap.1\n", argv[0]); + fprintf(stderr, "Usage %s FILE1 FILE2\n", argv[0]); exit(EXIT_FAILURE); } uint8_t verbose = 0; - FILE *fd[2]; size_t sz[2]; - for (int i = 0; i < 2; i++) { - if ((fd[i] = fopen(argv[i+1], "r")) == NULL) { - perror("Unable to open file"); - exit(EXIT_FAILURE); - } + struct cap_file cf[2]; + for (int i = 0; i < 2; i++) cap_load(&cf[i], argv[i+1]); - fseek(fd[i], 0, SEEK_END); - sz[i] = ftell(fd[i]); - fseek(fd[i], 0, SEEK_SET); - } - - if (sz[0] != sz[1]) { + if (cf[0].sz != cf[1].sz) { printf("[!!] %s has %ld entries, %s has %ld entries\n", argv[1], - sz[0]/sizeof(struct buffer_packet), + cf[0].sz/sizeof(struct buffer_packet), argv[2], - sz[1]/sizeof(struct buffer_packet)); + cf[1].sz/sizeof(struct buffer_packet)); } else if (verbose) { printf("[OK] %s and %s have %ld entries\n", argv[1], argv[2], - sz[0]/sizeof(struct buffer_packet)); + cf[0].sz/sizeof(struct buffer_packet)); } - size_t to_read = sz[0] < sz[1] ? sz[0] : sz[1]; + size_t to_read = cf[0].sz < cf[1].sz ? cf[0].sz : cf[1].sz; size_t to_read_obj = to_read / sizeof(struct buffer_packet); uint16_t expected_id = 0; struct buffer_packet bpread[2]; for (size_t c = 0; c < to_read_obj; c++) { - for (int i = 0; i < 2; i++) fread(&bpread[i], sizeof(struct buffer_packet), 1, fd[i]); + for (int i = 0; i < 2; i++) cap_next_bp(&cf[i], &bpread[i]); /*if (expected_id != bpread[0].ip.ap.fmt.content.clear.id || expected_id != bpread[1].ip.ap.fmt.content.clear.id) { printf("[!!] expected id is %d, %s has id %d, %s has id %d\n", expected_id, @@ -78,10 +73,7 @@ int main(int argc, char** argv) { expected_id++; } - - for (int i = 0; i < 2; i++) { - fclose(fd[i]); - } + for (int i = 0; i < 2; i++) cap_unload (&cf[i]); printf("parsed %d packets\n", expected_id); return 0; diff --git a/src/capreplay.c b/src/capreplay.c new file mode 100644 index 0000000..fdec439 --- /dev/null +++ b/src/capreplay.c @@ -0,0 +1,60 @@ +#include +#include +#include "cap_utils.h" +#include "net_tools.h" + +int main(int argc, char** argv) { + setvbuf(stdout, NULL, _IONBF, 0); + printf("~ capreplay ~\n"); + + int opt, verbose = 0, is_active = 0; + char *outf, *inf; + while ((opt = getopt(argc, argv, "r:s:m:v")) != -1) { + switch(opt) { + case 'v': + verbose++; + break; + case 'r': + inf = optarg; + break; + case 's': + outf = optarg; + break; + case 'm': + is_active = strcmp(optarg, "active") == 0; + break; + default: + goto usage; + } + } + + struct cap_file cf; + cap_load(&cf, inf); + + size_t nbp = cap_count_bp (&cf); + if (nbp < 1) { + fprintf(stderr, "No buffer packet to read\n"); + exit(EXIT_FAILURE); + } + + struct timespec started; + struct buffer_packet bp; + cap_peek_bp (&cf, &bp); + started = bp.seen; + + int fd = create_udp_client ("127.0.0.1", "5000"); + + for (int c = 0; c < nbp; c++) { + cap_next_bp (&cf, &bp); + //sleep(bp.seen); + // send on UDP to 127.13.3.7 + // sleep for given time + //sendto(fd, bp.ip.ap.fmt.content.clear.payload); + } + + return 0; + +usage: + fprintf(stderr, "Usage: %s -r FILE.0 -s FILE.1 -m [active|passive] [-v]\n", argv[0]); + return 1; +}