mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-20 09:03:24 +00:00
214 lines
5.6 KiB
C++
214 lines
5.6 KiB
C++
/*
|
|
*
|
|
* (C) 2013-17 - ntop.org
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
#include "ntop_includes.h"
|
|
|
|
#include "../third-party/patricia/patricia.c"
|
|
|
|
/* **************************************** */
|
|
|
|
AddressTree::AddressTree() { init(); }
|
|
|
|
/* **************************************** */
|
|
|
|
static void free_ptree_data(void *data) { ; }
|
|
|
|
/* **************************************** */
|
|
|
|
void AddressTree::init() {
|
|
numAddresses = 0;
|
|
ptree_v4 = New_Patricia(32), ptree_v6 = New_Patricia(128), macs = NULL;
|
|
}
|
|
|
|
/* **************************************** */
|
|
|
|
AddressTree::~AddressTree() {
|
|
cleanup();
|
|
}
|
|
|
|
/* ******************************************* */
|
|
|
|
bool AddressTree::addAddress(char *_what, const int16_t user_data) {
|
|
u_int32_t _mac[6];
|
|
int16_t id = (user_data == -1) ? numAddresses : user_data;
|
|
|
|
if(sscanf(_what, "%02X:%02X:%02X:%02X:%02X:%02X",
|
|
&_mac[0], &_mac[1], &_mac[2],
|
|
&_mac[3], &_mac[4], &_mac[5]) == 6) {
|
|
int16_t v;
|
|
u_int8_t mac[6];
|
|
|
|
for(int i=0; i<6; i++) mac[i] = (u_int8_t)_mac[i];
|
|
|
|
if((v = findMac(mac)) == -1) {
|
|
/* Not found: let's add it */
|
|
MacKey_t *s;
|
|
|
|
if((s = (MacKey_t*)malloc(sizeof(MacKey_t))) != NULL) {
|
|
memcpy(s->mac, mac, 6), s->value = id;
|
|
HASH_ADD(hh, macs, mac, 6, s);
|
|
} else
|
|
return(false);
|
|
}
|
|
} else {
|
|
patricia_node_t *node = Utils::ptree_add_rule(strchr(_what, '.') ? ptree_v4 : ptree_v6, _what);
|
|
|
|
if(node)
|
|
node->user_data = id;
|
|
}
|
|
|
|
numAddresses++;
|
|
|
|
return(true);
|
|
}
|
|
|
|
/* ******************************************* */
|
|
|
|
/* Format: 131.114.21.0/24,10.0.0.0/255.0.0.0 */
|
|
bool AddressTree::addAddresses(char *rule, const int16_t user_data) {
|
|
char *tmp, *net = strtok_r(rule, ",", &tmp);
|
|
|
|
while(net != NULL) {
|
|
if(!addAddress(net, user_data))
|
|
return false;
|
|
|
|
net = strtok_r(NULL, ",", &tmp);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* ******************************************* */
|
|
|
|
int16_t AddressTree::findAddress(int family, void *addr) {
|
|
patricia_tree_t *p;
|
|
int bits;
|
|
patricia_node_t *node;
|
|
|
|
if(family == AF_INET)
|
|
p = ptree_v4, bits = 32;
|
|
else if(family == AF_INET6)
|
|
p = ptree_v6, bits = 128;
|
|
else
|
|
return(-1);
|
|
|
|
node = Utils::ptree_match(p, family, addr, bits);
|
|
|
|
if(node == NULL)
|
|
return(-1);
|
|
else
|
|
return(node->user_data);
|
|
}
|
|
|
|
/* ******************************************* */
|
|
|
|
int16_t AddressTree::findMac(u_int8_t addr[]) {
|
|
MacKey_t *s = NULL;
|
|
|
|
HASH_FIND(hh, macs, addr, 6, s);
|
|
|
|
return(s ? s->value : -1);
|
|
}
|
|
|
|
/* **************************************************** */
|
|
|
|
static void address_tree_dump_funct(prefix_t *prefix, void *data, void *user_data) {
|
|
char address[64], ret[64], *a;
|
|
|
|
if(!prefix) return;
|
|
|
|
switch(prefix->family) {
|
|
case AF_INET:
|
|
a = Utils::intoaV4(ntohl(prefix->add.sin.s_addr), address, sizeof(address));
|
|
snprintf(ret, sizeof(ret), "%s/%d", a, prefix->bitlen);
|
|
break;
|
|
|
|
case AF_INET6:
|
|
a = Utils::intoaV6(*((struct ndpi_in6_addr*)&prefix->add.sin6), prefix->bitlen, address, sizeof(address));
|
|
snprintf(ret, sizeof(ret), "%s/%d", a, prefix->bitlen);
|
|
break;
|
|
}
|
|
|
|
if(user_data)
|
|
lua_push_str_table_entry((lua_State*)user_data, ret, (char*)"");
|
|
else
|
|
ntop->getTrace()->traceEvent(TRACE_NORMAL, "[AddressTree] %s", ret);
|
|
}
|
|
|
|
/* **************************************************** */
|
|
|
|
void AddressTree::getAddresses(lua_State* vm) {
|
|
if(ptree_v4->head) patricia_walk_inorder(ptree_v4->head, address_tree_dump_funct, vm);
|
|
if(ptree_v6->head) patricia_walk_inorder(ptree_v6->head, address_tree_dump_funct, vm);
|
|
|
|
if(macs) {
|
|
MacKey_t *current, *tmp;
|
|
|
|
HASH_ITER(hh, macs, current, tmp) {
|
|
char key[32], val[8];
|
|
|
|
snprintf(key, sizeof(key), "%02X:%02X:%02X:%02X:%02X:%02X",
|
|
current->mac[0], current->mac[1], current->mac[2],
|
|
current->mac[3], current->mac[4], current->mac[5]);
|
|
|
|
snprintf(val, sizeof(val), "%u", current->value);
|
|
|
|
lua_push_str_table_entry(vm, key, val);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* **************************************************** */
|
|
|
|
void AddressTree::dump() {
|
|
if(ptree_v4->head) patricia_walk_inorder(ptree_v4->head, address_tree_dump_funct, NULL);
|
|
if(ptree_v6->head) patricia_walk_inorder(ptree_v6->head, address_tree_dump_funct, NULL);
|
|
|
|
if(macs) {
|
|
MacKey_t *current, *tmp;
|
|
|
|
HASH_ITER(hh, macs, current, tmp) {
|
|
char key[32];
|
|
|
|
snprintf(key, sizeof(key), "%02X:%02X:%02X:%02X:%02X:%02X",
|
|
current->mac[0], current->mac[1], current->mac[2],
|
|
current->mac[3], current->mac[4], current->mac[5]);
|
|
|
|
ntop->getTrace()->traceEvent(TRACE_NORMAL, "[AddressTree] %s", key);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* **************************************************** */
|
|
|
|
void AddressTree::cleanup() {
|
|
if(ptree_v4) Destroy_Patricia(ptree_v4, free_ptree_data);
|
|
if(ptree_v6) Destroy_Patricia(ptree_v6, free_ptree_data);
|
|
|
|
if(macs) {
|
|
MacKey_t *current, *tmp;
|
|
|
|
HASH_ITER(hh, macs, current, tmp) {
|
|
HASH_DEL(macs, current); /* delete it */
|
|
free(current); /* free it */
|
|
}
|
|
}
|
|
}
|