Working capdiff
This commit is contained in:
parent
1ee6727a98
commit
2408f6ba75
3 changed files with 91 additions and 46 deletions
|
@ -5,19 +5,30 @@ void cap_load(struct cap_file *cf, char* filename) {
|
|||
perror("Unable to open file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
cf->filename = filename;
|
||||
fseek(cf->fd, 0, SEEK_END);
|
||||
cf->sz = ftell(cf->fd);
|
||||
fseek(cf->fd, 0, SEEK_SET);
|
||||
|
||||
cf->sz_obj = cf->sz / sizeof(struct buffer_packet);
|
||||
}
|
||||
|
||||
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) {
|
||||
void cap_npeek_bp(struct cap_file *cf, int c, struct buffer_packet* bp) {
|
||||
//fprintf(stdout, "c: %d, current pos: %ld, ", c, ftell(cf->fd));
|
||||
|
||||
ssize_t cbytes = c*sizeof(struct buffer_packet);
|
||||
fseek(cf->fd, cbytes, SEEK_CUR);
|
||||
size_t n = fread(bp, sizeof(struct buffer_packet), 1, cf->fd);
|
||||
fseek(cf->fd, -n, SEEK_CUR);
|
||||
fseek(cf->fd, -(n*sizeof(struct buffer_packet) + cbytes), SEEK_CUR);
|
||||
//fprintf(stdout, "cbytes: %ld, n: %ld, final pos: %ld\n", cbytes, n, ftell(cf->fd));
|
||||
}
|
||||
|
||||
void cap_peek_bp(struct cap_file *cf, struct buffer_packet* bp) {
|
||||
cap_npeek_bp(cf, 0, bp);
|
||||
}
|
||||
|
||||
size_t cap_count_bp(struct cap_file *cf) {
|
||||
|
|
|
@ -6,11 +6,14 @@
|
|||
|
||||
struct cap_file {
|
||||
FILE *fd;
|
||||
char* filename;
|
||||
size_t sz;
|
||||
size_t sz_obj;
|
||||
};
|
||||
|
||||
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);
|
||||
void cap_npeek_bp(struct cap_file *cf, int c, struct buffer_packet* bp);
|
||||
size_t cap_count_bp(struct cap_file *cf);
|
||||
void cap_unload(struct cap_file *cf);
|
||||
|
|
117
src/capdiff.c
117
src/capdiff.c
|
@ -3,12 +3,63 @@
|
|||
#include "cap_utils.h"
|
||||
#include "packet.h"
|
||||
|
||||
#define MAX_PKTS_TO_CHECK_FOR_DROP 10
|
||||
|
||||
uint8_t are_packets_equal(struct buffer_packet bpread[]) {
|
||||
size_t s1 = bpread[0].ip.ap.fmt.headers.size, s2 = bpread[1].ip.ap.fmt.headers.size;
|
||||
if (s1 != s2) return 0;
|
||||
|
||||
for (size_t idx = sizeof(bpread[0].ip.ap.fmt.headers) + sizeof(bpread[0].ip.ap.fmt.content.clear) - sizeof(char); idx < s1; idx++) {
|
||||
char e1 = (&bpread[0].ip.ap.raw)[idx], e2 = (&bpread[1].ip.ap.raw)[idx];
|
||||
if (e1 != e2) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum pkt_reconstruct_res { PREC_SAME, PREC_DROP, PREC_FAIL };
|
||||
struct pkt_reconstruct {
|
||||
enum pkt_reconstruct_res r;
|
||||
int diff_0;
|
||||
int diff_1;
|
||||
};
|
||||
|
||||
void reconstruct_action(struct cap_file cf[], struct pkt_reconstruct* pr) {
|
||||
struct buffer_packet bpread[2];
|
||||
pr->r = PREC_FAIL;
|
||||
for (int m1 = 0; m1 < MAX_PKTS_TO_CHECK_FOR_DROP; m1++) {
|
||||
for (int m2 = 0; m2 <= m1; m2++) {
|
||||
cap_npeek_bp(&cf[0], m1, &bpread[0]);
|
||||
cap_npeek_bp(&cf[1], m2, &bpread[1]);
|
||||
if(are_packets_equal(bpread)) {
|
||||
pr->r = m1 == 0 && m2 == 0 ? PREC_SAME : PREC_DROP;
|
||||
pr->diff_0 = m1;
|
||||
pr->diff_1 = m2;
|
||||
while (m1-- >= 0) cap_next_bp (&cf[0], &bpread[0]);
|
||||
while (m2-- >= 0) cap_next_bp (&cf[1], &bpread[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
cap_npeek_bp(&cf[0], m2, &bpread[0]);
|
||||
cap_npeek_bp(&cf[1], m1, &bpread[1]);
|
||||
if(are_packets_equal(bpread)) {
|
||||
pr->r = PREC_DROP;
|
||||
pr->diff_0 = m2;
|
||||
pr->diff_1 = m1;
|
||||
while (m2-- >= 0) cap_next_bp (&cf[0], &bpread[0]);
|
||||
while (m1-- >= 0) cap_next_bp (&cf[1], &bpread[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
printf("~ capdiff ~\n");
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage %s FILE1 FILE2\n", argv[0]);
|
||||
fprintf(stderr, "Usage %s FILE.IN FILE.OUT\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
uint8_t verbose = 0;
|
||||
|
@ -29,52 +80,32 @@ int main(int argc, char** argv) {
|
|||
cf[0].sz/sizeof(struct buffer_packet));
|
||||
}
|
||||
|
||||
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 pkt_reconstruct pr;
|
||||
struct buffer_packet bpread[2];
|
||||
for (size_t c = 0; c < to_read_obj; c++) {
|
||||
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,
|
||||
argv[1],
|
||||
bpread[0].ip.ap.fmt.content.clear.id,
|
||||
argv[2],
|
||||
bpread[1].ip.ap.fmt.content.clear.id);
|
||||
}*/
|
||||
|
||||
size_t s1 = bpread[0].ip.ap.fmt.headers.size, s2 = bpread[1].ip.ap.fmt.headers.size;
|
||||
uint8_t is_same_size = s1 == s2;
|
||||
if (!is_same_size) {
|
||||
printf("[!!] %s packet has size %d, %s packet has size %d for expected id %d\n",
|
||||
argv[1],
|
||||
bpread[0].ip.ap.fmt.headers.size,
|
||||
argv[2],
|
||||
bpread[1].ip.ap.fmt.headers.size,
|
||||
expected_id);
|
||||
} else if (verbose) {
|
||||
printf("[OK] %s and %s packets for expected id %d have size %d\n",
|
||||
argv[1],
|
||||
argv[2],
|
||||
expected_id,
|
||||
bpread[0].ip.ap.fmt.headers.size);
|
||||
int c0 = 0, c1 = 0, stop = 0;
|
||||
while (c0 < cf[0].sz_obj && c1 < cf[1].sz_obj && !stop) {
|
||||
reconstruct_action(cf, &pr);
|
||||
c0 += pr.diff_0 + 1;
|
||||
c1 += pr.diff_1 + 1;
|
||||
switch (pr.r) {
|
||||
case PREC_SAME:
|
||||
// Nothing
|
||||
break;
|
||||
case PREC_DROP:
|
||||
fprintf(stderr, "[!!] packets (%d,%d) ", c0, c1);
|
||||
if (c0 > 0) fprintf(stderr, "%s dropped %d pkts ", cf[0].filename, pr.diff_0);
|
||||
if (c1 > 0) fprintf(stderr, "%s has dropped %d pkts ", cf[1].filename, pr.diff_1);
|
||||
fprintf(stderr, "\n");
|
||||
break;
|
||||
case PREC_FAIL:
|
||||
fprintf(stderr, "[!!] Unable to remap packets (%d, %d). We should stop\n", c0, c1);
|
||||
stop = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
size_t max_size = s1 > s2 ? s1 : s2;
|
||||
for (size_t idx = sizeof(bpread[0].ip.ap.fmt.headers) + sizeof(bpread[0].ip.ap.fmt.content.clear) - sizeof(char); idx < max_size; idx++) {
|
||||
char e1 = (&bpread[0].ip.ap.raw)[idx], e2 = (&bpread[1].ip.ap.raw)[idx];
|
||||
if (e1 != e2) {
|
||||
printf("[!!] for expected id %d, byte 0x%04x is different: 0x%02x vs 0x%02x\n", expected_id, (uint16_t)idx, (uint8_t)e1, (uint8_t)e2);
|
||||
}
|
||||
}
|
||||
|
||||
expected_id++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) cap_unload (&cf[i]);
|
||||
printf("parsed (%d,%d) packets\n", c0, c1);
|
||||
|
||||
printf("parsed %d packets\n", expected_id);
|
||||
for (int i = 0; i < 2; i++) cap_unload (&cf[i]);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue