WIP capture / replay tools

This commit is contained in:
Quentin 2019-06-03 14:32:52 +02:00
parent 01527ca88f
commit e93b237e79
5 changed files with 126 additions and 23 deletions

View file

@ -35,6 +35,8 @@ list(APPEND CSOURCES
src/timer.c src/timer.c
src/capture_traffic.h src/capture_traffic.h
src/capture_traffic.c src/capture_traffic.c
src/cap_utils.h
src/cap_utils.c
) )
add_executable(donar ${CSOURCES} src/donar.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(udpecho ${CSOURCES} src/udp_echo.c)
add_executable(torecho ${CSOURCES} src/tor_echo.c) add_executable(torecho ${CSOURCES} src/tor_echo.c)
add_executable(capdiff ${CSOURCES} src/capdiff.c) add_executable(capdiff ${CSOURCES} src/capdiff.c)
add_executable(capreplay ${CSOURCES} src/capreplay.c)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0) 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_include_directories(capdiff PRIVATE ${GLIB_INCLUDE_DIRS})
target_link_libraries(capdiff ${GLIB_LDFLAGS}) 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 RUNTIME DESTINATION bin
LIBRARY DESTINATION lib) LIBRARY DESTINATION lib)

29
src/cap_utils.c Normal file
View file

@ -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);
}

16
src/cap_utils.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include <stdlib.h>
#include <stdio.h>
#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);

View file

@ -1,45 +1,40 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "cap_utils.h"
#include "packet.h" #include "packet.h"
int main(int argc, char** argv) { int main(int argc, char** argv) {
setvbuf(stdout, NULL, _IONBF, 0);
printf("~ capdiff ~\n");
if (argc != 3) { 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); exit(EXIT_FAILURE);
} }
uint8_t verbose = 0; uint8_t verbose = 0;
FILE *fd[2]; size_t sz[2]; struct cap_file cf[2];
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) cap_load(&cf[i], argv[i+1]);
if ((fd[i] = fopen(argv[i+1], "r")) == NULL) {
perror("Unable to open file");
exit(EXIT_FAILURE);
}
fseek(fd[i], 0, SEEK_END); if (cf[0].sz != cf[1].sz) {
sz[i] = ftell(fd[i]);
fseek(fd[i], 0, SEEK_SET);
}
if (sz[0] != sz[1]) {
printf("[!!] %s has %ld entries, %s has %ld entries\n", printf("[!!] %s has %ld entries, %s has %ld entries\n",
argv[1], argv[1],
sz[0]/sizeof(struct buffer_packet), cf[0].sz/sizeof(struct buffer_packet),
argv[2], argv[2],
sz[1]/sizeof(struct buffer_packet)); cf[1].sz/sizeof(struct buffer_packet));
} else if (verbose) { } else if (verbose) {
printf("[OK] %s and %s have %ld entries\n", printf("[OK] %s and %s have %ld entries\n",
argv[1], argv[1],
argv[2], 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); size_t to_read_obj = to_read / sizeof(struct buffer_packet);
uint16_t expected_id = 0; uint16_t expected_id = 0;
struct buffer_packet bpread[2]; struct buffer_packet bpread[2];
for (size_t c = 0; c < to_read_obj; c++) { 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) { /*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", printf("[!!] expected id is %d, %s has id %d, %s has id %d\n",
expected_id, expected_id,
@ -78,10 +73,7 @@ int main(int argc, char** argv) {
expected_id++; expected_id++;
} }
for (int i = 0; i < 2; i++) cap_unload (&cf[i]);
for (int i = 0; i < 2; i++) {
fclose(fd[i]);
}
printf("parsed %d packets\n", expected_id); printf("parsed %d packets\n", expected_id);
return 0; return 0;

60
src/capreplay.c Normal file
View file

@ -0,0 +1,60 @@
#include <stdio.h>
#include <stdlib.h>
#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;
}