Skip to content

Commit

Permalink
use digest of networks as multinet identifier instead of random
Browse files Browse the repository at this point in the history
  • Loading branch information
pmikkila committed Apr 12, 2020
1 parent a1c4129 commit fed65d1
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 8 deletions.
38 changes: 38 additions & 0 deletions src/spindump_main_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,44 @@ spindump_main_processargs(int argc,
overlaps++;
}
}

//
// Create an identifier for each multinet aggregate by creating a digest of the networks
// belonging to that aggregate, in sort order. Place the identifier in the side 2 address
// of the aggregate.
//

for (unsigned int i = 0; i < config->nAggregates; i++) {
struct spindump_main_aggregate* a = &config->aggregates[i];
if (config->aggregates[i].side2type != multinet)
continue;
uint32_t digest = spindump_crc32c_init();
spindump_address_frombytes(&a->side2address, AF_INET, (void *)&digest);
}
for (unsigned int i = 0; i < config->nAggrnetws; i++) {
struct spindump_main_aggrnetw* anw = &config->aggrnetws[i];
unsigned char addrbytes[16], lenbyte;
sa_family_t af;
uint32_t digest;
spindump_assert(anw->aggregate->side2type == multinet);
spindump_address_tobytes(&anw->aggregate->side2address, &af, (void *)&digest);
spindump_assert(af == AF_INET);
spindump_address_tobytes(&anw->network.address, &af, addrbytes);
lenbyte = (unsigned char)anw->network.length;
digest = spindump_crc32c_update(digest, addrbytes, af == AF_INET ? 4 : 16);
digest = spindump_crc32c_update(digest, &lenbyte, 1);
spindump_address_frombytes(&anw->aggregate->side2address, AF_INET, (void *)&digest);
}
for (unsigned int i = 0; i < config->nAggregates; i++) {
struct spindump_main_aggregate* a = &config->aggregates[i];
if (config->aggregates[i].side2type != multinet)
continue;
uint32_t digest;
sa_family_t af;
spindump_address_tobytes(&a->side2address, &af, (void *)&digest);
digest = htonl(spindump_crc32c_finish(digest));
spindump_address_frombytes(&a->side2address, AF_INET, (void *)&digest);
}
}

//
Expand Down
10 changes: 2 additions & 8 deletions src/spindump_main_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,11 +605,8 @@ spindump_main_loop_initialize_aggregates(struct spindump_main_configuration* con
1,
analyzer->table);
} else if (aggregate->side1ishost && aggregate->side2type == multinet) {
uint32_t bytes = rand();
spindump_address identifier;
spindump_address_frombytes(&identifier, AF_INET, (void *)&bytes);
aggregateConnection = spindump_connections_newconnection_aggregate_hostmultinet(&aggregate->side1address,
&identifier,
&aggregate->side2address,
&startTime,
1,
analyzer->table);
Expand All @@ -628,11 +625,8 @@ spindump_main_loop_initialize_aggregates(struct spindump_main_configuration* con
1,
analyzer->table);
} else if (!aggregate->side1ishost && aggregate->side2type == multinet) {
uint32_t bytes = rand();
spindump_address identifier;
spindump_address_frombytes(&identifier, AF_INET, (void *)&bytes);
aggregateConnection = spindump_connections_newconnection_aggregate_networkmultinet(&aggregate->side1network,
&identifier,
&aggregate->side2address,
&startTime,
1,
analyzer->table);
Expand Down
104 changes: 104 additions & 0 deletions src/spindump_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,31 @@ spindump_address_frombytes(spindump_address* address,
}
}

//
// Write address to buffer
//

void
spindump_address_tobytes(const spindump_address* address,
sa_family_t *af,
unsigned char* string) {
spindump_assert(address != 0);
spindump_assert(af != 0);
spindump_assert(address->ss_family == AF_INET || address->ss_family == AF_INET6);
*af = address->ss_family;
if (address->ss_family == AF_INET) {
struct sockaddr_in* actual = (struct sockaddr_in*)address;
memcpy(string,
(unsigned char*)&actual->sin_addr.s_addr,
4);
} else {
struct sockaddr_in6* actual = (struct sockaddr_in6*)address;
memcpy(string,
(unsigned char*)&actual->sin6_addr.s6_addr,
16);
}
}

//
// Convert an address to a string. Returned string need not be freed,
// but will not survive the next call to this same function.
Expand Down Expand Up @@ -975,3 +1000,82 @@ spindump_strlcat(char * restrict dst, const char * restrict src, size_t size) {
return(strlen(src));
}

//
// CRC-32c calculation.
//

// 32 lowest bits of CRC-32c (Castagnoli93) generator polynomial.
static const uint32_t spindump_crc32c_poly = 0x1edc6f41UL;

static uint32_t spindump_crc32c_table[256];
static int spindump_crc32c_setup_done;

static inline unsigned char
spindump_crc32c_bitrev8(unsigned char byte)
{
unsigned char rev;

rev = (byte >> 4 & 0x0f) | (byte << 4 & 0xf0);
rev = (rev >> 2 & 0x33) | (rev << 2 & 0xcc);
rev = (rev >> 1 & 0x55) | (rev << 1 & 0xaa);
return rev;
}

static inline uint32_t
spindump_crc32c_bitrev32(uint32_t quad)
{
uint32_t rev;

rev = (quad >> 4 & 0x0f0f0f0f) | (quad << 4 & 0xf0f0f0f0);
rev = (rev >> 2 & 0x33333333) | (rev << 2 & 0xcccccccc);
rev = (rev >> 1 & 0x55555555) | (rev << 1 & 0xaaaaaaaa);
return rev;
}

static void
spindump_crc32c_setup(void)
{
uint32_t rem;
unsigned i, j;

for (i = 0; i < 256; i++) {
rem = (uint32_t)i << 24;
for (j = 0; j < 8; j++) {
if ((rem & 0x80000000))
rem = (rem << 1) ^ spindump_crc32c_poly;
else
rem = (rem << 1);
}
spindump_crc32c_table[spindump_crc32c_bitrev8(i)] = spindump_crc32c_bitrev32(rem);
}
}

uint32_t
spindump_crc32c_init(void)
{
if (!spindump_crc32c_setup_done) {
spindump_crc32c_setup_done = 1;
spindump_crc32c_setup();
}
return 0xffffffff;
}

uint32_t
spindump_crc32c_update(uint32_t digest, unsigned char* buf, size_t len)
{
unsigned int i;
uint32_t newdig = digest;
unsigned char byte;

for (i = 0; i < len; i++) {
byte = (newdig >> 24) ^ buf[i];
newdig = (newdig << 8) ^ spindump_crc32c_table[byte];
}
return newdig;
}

uint32_t
spindump_crc32c_finish(uint32_t digest)
{
return ~digest;
}
11 changes: 11 additions & 0 deletions src/spindump_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ void
spindump_address_frombytes(spindump_address* address,
sa_family_t af,
const unsigned char* string);
void
spindump_address_tobytes(const spindump_address* address,
sa_family_t* af,
unsigned char* string);
const char*
spindump_address_tostring(const spindump_address* address);
const char*
Expand Down Expand Up @@ -189,4 +193,11 @@ spindump_strlcpy(char * restrict dst, const char * restrict src, size_t size);
size_t
spindump_strlcat(char * restrict dst, const char * restrict src, size_t size);

uint32_t
spindump_crc32c_init(void);
uint32_t
spindump_crc32c_update(uint32_t digest, unsigned char* buf, size_t len);
uint32_t
spindump_crc32c_finish(uint32_t digest);

#endif // SPIDUMP_UTIL_H

0 comments on commit fed65d1

Please sign in to comment.