2019-05-28 15:15:37 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2019-06-03 12:32:52 +00:00
|
|
|
#include "cap_utils.h"
|
2019-05-28 15:15:37 +00:00
|
|
|
#include "packet.h"
|
|
|
|
|
2019-06-03 15:09:40 +00:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-05-28 15:15:37 +00:00
|
|
|
int main(int argc, char** argv) {
|
2019-06-03 12:32:52 +00:00
|
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
|
|
|
printf("~ capdiff ~\n");
|
|
|
|
|
2019-05-28 15:15:37 +00:00
|
|
|
if (argc != 3) {
|
2019-06-03 15:09:40 +00:00
|
|
|
fprintf(stderr, "Usage %s FILE.IN FILE.OUT\n", argv[0]);
|
2019-05-28 15:15:37 +00:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
uint8_t verbose = 0;
|
|
|
|
|
2019-06-03 12:32:52 +00:00
|
|
|
struct cap_file cf[2];
|
|
|
|
for (int i = 0; i < 2; i++) cap_load(&cf[i], argv[i+1]);
|
2019-05-28 15:15:37 +00:00
|
|
|
|
2019-06-03 12:32:52 +00:00
|
|
|
if (cf[0].sz != cf[1].sz) {
|
2019-05-28 15:15:37 +00:00
|
|
|
printf("[!!] %s has %ld entries, %s has %ld entries\n",
|
|
|
|
argv[1],
|
2019-06-03 12:32:52 +00:00
|
|
|
cf[0].sz/sizeof(struct buffer_packet),
|
2019-05-28 15:15:37 +00:00
|
|
|
argv[2],
|
2019-06-03 12:32:52 +00:00
|
|
|
cf[1].sz/sizeof(struct buffer_packet));
|
2019-05-28 15:15:37 +00:00
|
|
|
} else if (verbose) {
|
|
|
|
printf("[OK] %s and %s have %ld entries\n",
|
|
|
|
argv[1],
|
|
|
|
argv[2],
|
2019-06-03 12:32:52 +00:00
|
|
|
cf[0].sz/sizeof(struct buffer_packet));
|
2019-05-28 15:15:37 +00:00
|
|
|
}
|
|
|
|
|
2019-06-03 15:09:40 +00:00
|
|
|
struct pkt_reconstruct pr;
|
2019-05-28 15:15:37 +00:00
|
|
|
struct buffer_packet bpread[2];
|
2019-06-03 15:09:40 +00:00
|
|
|
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;
|
2019-05-28 15:15:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:09:40 +00:00
|
|
|
printf("parsed (%d,%d) packets\n", c0, c1);
|
2019-05-28 15:15:37 +00:00
|
|
|
|
2019-06-03 15:09:40 +00:00
|
|
|
for (int i = 0; i < 2; i++) cap_unload (&cf[i]);
|
2019-05-28 15:15:37 +00:00
|
|
|
return 0;
|
|
|
|
}
|