Skip to content

Commit

Permalink
Add AS lookup to geolookup and add new -s srcasn, dstasn and asn for …
Browse files Browse the repository at this point in the history
…AS organistation name. Needs maxmind DB to work.
  • Loading branch information
phaag committed Jul 20, 2024
1 parent 3a9908e commit 1811ea3
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 48 deletions.
6 changes: 6 additions & 0 deletions man/nfdump.1
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,18 @@ flow directions ingress/egress
source AS numbers
.It Cm dstas
destination AS numbers
.It Cm srcasn
source AS organisations and numbers
.It Cm dstasn
destination AS organisations and numbers
.It Cm srcgeo
2 letter geo source country code
.It Cm dstgeo
2 letter geo destination country code
.It Cm as
any (source or destination) AS numbers
.It Cm asn
any (source or destination) AS org and numbers
.It Cm inif
input interface
.It Cm outif
Expand Down
35 changes: 35 additions & 0 deletions src/libnfdump/maxmind/maxmind.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,35 @@ static void StoreASV6tree(nffile_t *nffile) {

} // End of StoreASV6tree

static void StoreASorgtree(nffile_t *nffile) {
// get new empty data block
dataBlock_t *dataBlock = WriteBlock(nffile, NULL);
void *outBuff = GetCursor(dataBlock);

// put array header on block
PushArrayHeader(dataBlock, ASOrgtreeElementID, sizeof(asOrgNode_t));
outBuff = GetCurrentCursor(dataBlock);

for (asOrgNode_t *asOrgNode = NextasOrgNode(FIRSTNODE); asOrgNode != NULL; asOrgNode = NextasOrgNode(NEXTNODE)) {
if (!IsAvailable(dataBlock, sizeof(asOrgNode_t))) {
// flush block - get an empty one
dataBlock = WriteBlock(nffile, dataBlock);

// put array header on block
PushArrayHeader(dataBlock, ASOrgtreeElementID, sizeof(asOrgNode_t));
outBuff = GetCurrentCursor(dataBlock);
}

memcpy(outBuff, asOrgNode, sizeof(asOrgNode_t));
outBuff += sizeof(asOrgNode_t);
dataBlock->size += sizeof(asOrgNode_t);
dataBlock->NumRecords++;
}
// flush current datablock
FlushBlock(nffile, dataBlock);

} // End of StoreASorgtree

int SaveMaxMind(char *fileName) {
nffile_t *nffile = OpenNewFile(fileName, NULL, CREATOR_LOOKUP, LZ4_COMPRESSED, NOT_ENCRYPTED);
if (!nffile) {
Expand All @@ -226,6 +255,7 @@ int SaveMaxMind(char *fileName) {
StoreIPV6tree(nffile);
StoreASV4tree(nffile);
StoreASV6tree(nffile);
StoreASorgtree(nffile);
return CloseUpdateFile(nffile);

} // End of SaveMaxMind
Expand Down Expand Up @@ -289,6 +319,11 @@ int LoadMaxMind(char *fileName) {
arrayElementSizeCheck(asV6Node);
LoadASV6Tree(asV6Node, dataBlock->NumRecords);
} break;
case ASOrgtreeElementID: {
asOrgNode_t *asOrgNode = (asOrgNode_t *)arrayElement;
arrayElementSizeCheck(asOrgNode);
LoadASorgTree(asOrgNode, dataBlock->NumRecords);
} break;
default:
LogError("Skip unknown array element: %u", arrayHeader->type);
}
Expand Down
4 changes: 4 additions & 0 deletions src/libnfdump/maxmind/maxmind.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const char *LookupV4ASorg(uint32_t ip);

const char *LookupV6ASorg(uint64_t ip[2]);

const char *LookupASorg(uint32_t as);

void LookupWhois(char *ip);

void LookupAS(char *asString);

#endif
74 changes: 72 additions & 2 deletions src/libnfdump/maxmind/mmhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,24 @@ static inline int asV6Node_cmp(asV6Node_t a, asV6Node_t b) {
}
}

static inline int asOrgNode_cmp(asOrgNode_t a, asOrgNode_t b) {
if (a.as == b.as) return 0;
return a.as > b.as ? 1 : -1;
} // End of asOrgNode_cmp

KBTREE_INIT(asV4Tree, asV4Node_t, asV4Node_cmp);

KBTREE_INIT(asV6Tree, asV6Node_t, asV6Node_cmp);

KBTREE_INIT(asOrgTree, asOrgNode_t, asOrgNode_cmp);

typedef struct mmHandle_s {
khash_t(localMap) * localMap;
kbtree_t(ipV4Tree) * ipV4Tree;
kbtree_t(ipV6Tree) * ipV6Tree;
kbtree_t(asV4Tree) * asV4Tree;
kbtree_t(asV6Tree) * asV6Tree;
kbtree_t(asOrgTree) * asOrgTree;
} mmHandle_t;

static mmHandle_t *mmHandle = NULL;
Expand All @@ -140,8 +148,9 @@ int Init_MaxMind(void) {
mmHandle->ipV6Tree = kb_init(ipV6Tree, 10 * KB_DEFAULT_SIZE);
mmHandle->asV4Tree = kb_init(asV4Tree, 10 * KB_DEFAULT_SIZE);
mmHandle->asV6Tree = kb_init(asV6Tree, 10 * KB_DEFAULT_SIZE);
mmHandle->asOrgTree = kb_init(asOrgTree, 10 * KB_DEFAULT_SIZE);

if (!mmHandle->ipV4Tree || !mmHandle->ipV6Tree || !mmHandle->localMap || !mmHandle->asV4Tree || !mmHandle->asV6Tree) {
if (!mmHandle->ipV4Tree || !mmHandle->ipV6Tree || !mmHandle->localMap || !mmHandle->asV4Tree || !mmHandle->asV6Tree || !mmHandle->asOrgTree) {
LogError("Initialization of MaxMind failed");
return 0;
}
Expand Down Expand Up @@ -221,6 +230,19 @@ void LoadASV6Tree(asV6Node_t *asV6Node, uint32_t NumRecords) {

} // End of LoadASV6Tree

void LoadASorgTree(asOrgNode_t *asOrgNode, uint32_t NumRecords) {
kbtree_t(asOrgTree) *asOrgTree = mmHandle->asOrgTree;
for (int i = 0; i < NumRecords; i++) {
asOrgNode_t *node = kb_getp(asOrgTree, asOrgTree, asOrgNode);
if (node) {
LogError("Insert: %d Duplicate ASorg node: as: %d", i, asOrgNode->as);
} else {
kb_putp(asOrgTree, asOrgTree, asOrgNode);
}
asOrgNode++;
}
} // End of LoadASorgTree

void PutLocation(locationInfo_t *locationInfo) {
khash_t(localMap) *localMap = mmHandle->localMap;

Expand Down Expand Up @@ -283,6 +305,15 @@ void PutasV6Node(asV6Node_t *asV6Node) {
}
} // End of PutasV6Node

void PutASorgNode(asOrgNode_t *asOrgNode) {
kbtree_t(asOrgTree) *asOrgTree = mmHandle->asOrgTree;

asOrgNode_t *node = kb_getp(asOrgTree, asOrgTree, asOrgNode);
if (node == NULL) {
kb_putp(asOrgTree, asOrgTree, asOrgNode);
}
} // End of PutASorgNode

void LookupV4Country(uint32_t ip, char *country) {
if (!mmHandle) {
country[0] = '.';
Expand Down Expand Up @@ -432,6 +463,28 @@ uint32_t LookupV6AS(uint64_t ip[2]) {

} // End of LookupV6AS

const char *LookupASorg(uint32_t as) {
if (!mmHandle) {
return 0;
}

asOrgNode_t asSearch = {.as = as};
asOrgNode_t *asOrgNode = kb_getp(asOrgTree, mmHandle->asOrgTree, &asSearch);
return asOrgNode == NULL ? 0 : asOrgNode->orgName;

} // End of LookupASorg

void LookupAS(char *asString) {
long as = strtol(asString, (char **)NULL, 10);

if (as == 0 || as > 0xFFFFFFFFUL || as < 0) {
printf("Invalid AS number: %s: %s\n", asString, strerror(errno));
} else {
printf("%-7lu | %s\n", as, LookupASorg(as));
}

} // End of LookupAS

const char *LookupV4ASorg(uint32_t ip) {
if (!mmHandle) {
return "";
Expand Down Expand Up @@ -611,4 +664,21 @@ asV6Node_t *NextasV6Node(int start) {
} else {
return NULL;
}
} // End of NextasV6Node
} // End of NextasV6Node

asOrgNode_t *NextasOrgNode(int start) {
static kbitr_t itr = {0};
static asOrgNode_t *asOrgNode = NULL;

kbtree_t(asOrgTree) *asOrgTree = mmHandle->asOrgTree;
if (start == FIRSTNODE) kb_itr_first(asOrgTree, asOrgTree, &itr); // get an iterator pointing to the first

if (kb_itr_valid(&itr)) {
asOrgNode = &kb_itr_key(asOrgNode_t, &itr);
kb_itr_next(asOrgTree, asOrgTree, &itr); // move on
return asOrgNode;
} else {
return NULL;
}

} // End of NextasOrgNode
14 changes: 14 additions & 0 deletions src/libnfdump/maxmind/mmhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ typedef struct asV6Node_s {
char orgName[orgNameLength];
} asV6Node_t;

typedef struct asOrgNode_s {
// key
uint32_t as;

// value
char orgName[orgNameLength];
} asOrgNode_t;

int Init_MaxMind(void);

void LoadLocalInfo(locationInfo_t *locationInfo, uint32_t NumRecords);
Expand All @@ -111,6 +119,8 @@ void LoadASV4Tree(asV4Node_t *asV4Node, uint32_t NumRecords);

void LoadASV6Tree(asV6Node_t *asV6Node, uint32_t NumRecords);

void LoadASorgTree(asOrgNode_t *asOrgNode, uint32_t NumRecords);

void PutLocation(locationInfo_t *locationInfo);

void PutIPv4Node(ipV4Node_t *ipV4Node);
Expand All @@ -121,6 +131,8 @@ void PutasV4Node(asV4Node_t *asV4Node);

void PutasV6Node(asV6Node_t *asV6Node);

void PutASorgNode(asOrgNode_t *asOrgNode);

#define FIRSTNODE 1
#define NEXTNODE 0
locationInfo_t *NextLocation(int start);
Expand All @@ -133,6 +145,8 @@ asV4Node_t *NextasV4Node(int start);

asV6Node_t *NextasV6Node(int start);

asOrgNode_t *NextasOrgNode(int start);

int SaveMaxMind(char *fileName);

#endif
1 change: 1 addition & 0 deletions src/libnffile/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#define IPV6treeElementID 3
#define ASV4treeElementID 4
#define ASV6treeElementID 5
#define ASOrgtreeElementID 7
// tor
#define TorTreeElementID 6

Expand Down
20 changes: 12 additions & 8 deletions src/maxmind/geolookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ static char *string_trim(char *s) {
if (*s) {
char *p = s;
while (*p) p++;
while (isspace((unsigned char)*(--p)))
;
while (isspace((unsigned char)*(--p)));
p[1] = '\0';
}

Expand Down Expand Up @@ -192,11 +191,16 @@ int main(int argc, char **argv) {
if (argc - optind > 0) {
while (argc - optind > 0) {
char *arg = argv[optind++];
if (strlen(arg) > 2 && (valid_ipv4(arg) || valid_ipv6(arg))) {
LookupWhois(arg);
} else {
LogError("Not a valid IPv4 or IPv6: ", arg);
exit(EXIT_FAILURE);
if (strlen(arg) > 2) {
if (arg[0] == 'a' && arg[1] == 's') {
// do as Lookup
LookupAS(arg + 2);
} else if ((valid_ipv4(arg) || valid_ipv6(arg))) {
LookupWhois(arg);
} else {
LogError("Not a valid IPv4 or IPv6: ", arg);
exit(EXIT_FAILURE);
}
}
}
} else {
Expand All @@ -213,7 +217,7 @@ int main(int argc, char **argv) {
*eol = '\0';

// split ' ' separated words and check, if it's an IPv4/v6
char *sep = " ";
char *sep = " (";
char *word, *brkt;
word = strtok_r(line, sep, &brkt);
while (word) {
Expand Down
Loading

0 comments on commit 1811ea3

Please sign in to comment.