"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "hosts_db.c" between
darkstat-3.0.719.tar.gz and darkstat-3.0.721.tar.gz

About: darkstat is a network traffic analyzer (reports over HTTP).

hosts_db.c  (darkstat-3.0.719):hosts_db.c  (darkstat-3.0.721)
skipping to change at line 43 skipping to change at line 43
/* FIXME: specify somewhere more sane/tunable */ /* FIXME: specify somewhere more sane/tunable */
#define MAX_ENTRIES 30 /* in an HTML table rendered from a hashtable */ #define MAX_ENTRIES 30 /* in an HTML table rendered from a hashtable */
typedef uint32_t (hash_func_t)(const struct hashtable *, const void *); typedef uint32_t (hash_func_t)(const struct hashtable *, const void *);
typedef void (free_func_t)(struct bucket *); typedef void (free_func_t)(struct bucket *);
typedef const void * (key_func_t)(const struct bucket *); typedef const void * (key_func_t)(const struct bucket *);
typedef int (find_func_t)(const struct bucket *, const void *); typedef int (find_func_t)(const struct bucket *, const void *);
typedef struct bucket * (make_func_t)(const void *); typedef struct bucket * (make_func_t)(const void *);
typedef void (format_cols_func_t)(struct str *); typedef void (format_cols_func_t)(struct str *);
typedef void (format_row_func_t)(struct str *, const struct bucket *, typedef void (format_row_func_t)(struct str *, const struct bucket *);
const char *);
struct hashtable { struct hashtable {
uint8_t bits; /* size of hashtable in bits */ uint8_t bits; /* size of hashtable in bits */
uint32_t size, mask; uint32_t size, mask;
uint32_t count, count_max, count_keep; /* items in table */ uint32_t count, count_max, count_keep; /* items in table */
uint32_t coeff; /* coefficient for Fibonacci hashing */ uint32_t coeff; /* coefficient for Fibonacci hashing */
struct bucket **table; struct bucket **table;
struct { struct {
uint64_t inserts, searches, deletions, rehashes; uint64_t inserts, searches, deletions, rehashes;
skipping to change at line 316 skipping to change at line 315
" <th><a href=\"?sort=in\">In</a></th>\n" " <th><a href=\"?sort=in\">In</a></th>\n"
" <th><a href=\"?sort=out\">Out</a></th>\n" " <th><a href=\"?sort=out\">Out</a></th>\n"
" <th><a href=\"?sort=total\">Total</a></th>\n"); " <th><a href=\"?sort=total\">Total</a></th>\n");
if (opt_want_lastseen) str_append(buf, if (opt_want_lastseen) str_append(buf,
" <th><a href=\"?sort=lastseen\">Last seen</a></th>\n"); " <th><a href=\"?sort=lastseen\">Last seen</a></th>\n");
str_append(buf, str_append(buf,
"</tr>\n"); "</tr>\n");
} }
static void static void
format_row_host(struct str *buf, const struct bucket *b, format_row_host(struct str *buf, const struct bucket *b)
const char *css_class)
{ {
const char *ip = addr_to_str(&(b->u.host.addr)); const char *ip = addr_to_str(&(b->u.host.addr));
str_appendf(buf, str_appendf(buf,
"<tr class=\"%s\">\n" "<tr>\n"
" <td><a href=\"./%s/\">%s</a></td>\n" " <td><a href=\"./%s/\">%s</a></td>\n"
" <td>%s</td>\n", " <td>%s</td>\n",
css_class,
ip, ip, ip, ip,
(b->u.host.dns == NULL) ? "" : b->u.host.dns); (b->u.host.dns == NULL) ? "" : b->u.host.dns);
if (hosts_db_show_macs) if (hosts_db_show_macs)
str_appendf(buf, str_appendf(buf,
" <td><tt>%x:%x:%x:%x:%x:%x</tt></td>\n", " <td><tt>%x:%x:%x:%x:%x:%x</tt></td>\n",
b->u.host.mac_addr[0], b->u.host.mac_addr[0],
b->u.host.mac_addr[1], b->u.host.mac_addr[1],
b->u.host.mac_addr[2], b->u.host.mac_addr[2],
b->u.host.mac_addr[3], b->u.host.mac_addr[3],
skipping to change at line 394 skipping to change at line 391
" <th>Service</td>\n" " <th>Service</td>\n"
" <th>In</td>\n" " <th>In</td>\n"
" <th>Out</td>\n" " <th>Out</td>\n"
" <th>Total</td>\n" " <th>Total</td>\n"
" <th>SYNs</td>\n" " <th>SYNs</td>\n"
"</tr>\n" "</tr>\n"
); );
} }
static void static void
format_row_port_tcp(struct str *buf, const struct bucket *b, format_row_port_tcp(struct str *buf, const struct bucket *b)
const char *css_class)
{ {
const struct port_tcp *p = &(b->u.port_tcp); const struct port_tcp *p = &(b->u.port_tcp);
str_appendf(buf, str_appendf(buf,
"<tr class=\"%s\">\n" "<tr>\n"
" <td class=\"num\">%u</td>\n" " <td class=\"num\">%u</td>\n"
" <td>%s</td>\n" " <td>%s</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
"</tr>\n", "</tr>\n",
css_class,
p->port, p->port,
getservtcp(p->port), getservtcp(p->port),
(qu)b->in, (qu)b->in,
(qu)b->out, (qu)b->out,
(qu)b->total, (qu)b->total,
(qu)p->syn (qu)p->syn
); );
} }
static void static void
skipping to change at line 434 skipping to change at line 429
" <th>Port</td>\n" " <th>Port</td>\n"
" <th>Service</td>\n" " <th>Service</td>\n"
" <th>In</td>\n" " <th>In</td>\n"
" <th>Out</td>\n" " <th>Out</td>\n"
" <th>Total</td>\n" " <th>Total</td>\n"
"</tr>\n" "</tr>\n"
); );
} }
static void static void
format_row_port_udp(struct str *buf, const struct bucket *b, format_row_port_udp(struct str *buf, const struct bucket *b)
const char *css_class)
{ {
const struct port_udp *p = &(b->u.port_udp); const struct port_udp *p = &(b->u.port_udp);
str_appendf(buf, str_appendf(buf,
"<tr class=\"%s\">\n" "<tr>\n"
" <td class=\"num\">%u</td>\n" " <td class=\"num\">%u</td>\n"
" <td>%s</td>\n" " <td>%s</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
"</tr>\n", "</tr>\n",
css_class,
p->port, p->port,
getservudp(p->port), getservudp(p->port),
(qu)b->in, (qu)b->in,
(qu)b->out, (qu)b->out,
(qu)b->total (qu)b->total
); );
} }
static void static void
format_cols_ip_proto(struct str *buf) format_cols_ip_proto(struct str *buf)
skipping to change at line 472 skipping to change at line 465
" <th>#</td>\n" " <th>#</td>\n"
" <th>Protocol</td>\n" " <th>Protocol</td>\n"
" <th>In</td>\n" " <th>In</td>\n"
" <th>Out</td>\n" " <th>Out</td>\n"
" <th>Total</td>\n" " <th>Total</td>\n"
"</tr>\n" "</tr>\n"
); );
} }
static void static void
format_row_ip_proto(struct str *buf, const struct bucket *b, format_row_ip_proto(struct str *buf, const struct bucket *b)
const char *css_class)
{ {
const struct ip_proto *p = &(b->u.ip_proto); const struct ip_proto *p = &(b->u.ip_proto);
str_appendf(buf, str_appendf(buf,
"<tr class=\"%s\">\n" "<tr>\n"
" <td class=\"num\">%u</td>\n" " <td class=\"num\">%u</td>\n"
" <td>%s</td>\n" " <td>%s</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
" <td class=\"num\">%'qu</td>\n" " <td class=\"num\">%'qu</td>\n"
"</tr>\n", "</tr>\n",
css_class,
p->proto, p->proto,
getproto(p->proto), getproto(p->proto),
(qu)b->in, (qu)b->in,
(qu)b->out, (qu)b->out,
(qu)b->total (qu)b->total
); );
} }
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* Initialise a hashtable. * Initialise a hashtable.
skipping to change at line 923 skipping to change at line 914
buf = html_hosts_detail(elem[1]); buf = html_hosts_detail(elem[1]);
for (i=0; i<num_elems; i++) for (i=0; i<num_elems; i++)
free(elem[i]); free(elem[i]);
free(elem); free(elem);
return (buf); /* FIXME: a NULL here becomes 404 Not Found, we might want return (buf); /* FIXME: a NULL here becomes 404 Not Found, we might want
other codes to be possible */ other codes to be possible */
} }
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* Format hashtable into HTML. * Get an array of pointers to all the buckets in the hashtable,
* or NULL if the hashtable is NULL or empty.
* The returned pointer should be free'd by the caller.
*/ */
static void const struct bucket **
format_table(struct str *buf, struct hashtable *ht, unsigned int start, hashtable_list_buckets(struct hashtable *ht)
const enum sort_dir sort, const int full)
{ {
const struct bucket **table; const struct bucket **table;
unsigned int i, pos, end; unsigned int i, pos;
int alt = 0;
if ((ht == NULL) || (ht->count == 0)) { if ((ht == NULL) || (ht->count == 0)) {
str_append(buf, "<p>The table is empty.</p>\n"); return NULL;
return;
} }
/* Fill table with pointers to buckets in hashtable. */ /* Fill table with pointers to buckets in hashtable. */
table = xcalloc(ht->count, sizeof(*table)); table = xcalloc(ht->count, sizeof(*table));
for (pos=0, i=0; i<ht->size; i++) { for (pos=0, i=0; i<ht->size; i++) {
struct bucket *b = ht->table[i]; struct bucket *b = ht->table[i];
while (b != NULL) { while (b != NULL) {
table[pos++] = b; table[pos++] = b;
b = b->next; b = b->next;
} }
} }
assert(pos == ht->count); assert(pos == ht->count);
return table;
}
typedef void (hashtable_foreach_func_t)(const struct bucket *, const void *);
/* ---------------------------------------------------------------------------
* Loop over all buckets in the given hashtable, calling the supplied function
* with each bucket and the supplied user_data.
*/
static void
hashtable_foreach(struct hashtable *ht,
hashtable_foreach_func_t *hashtable_foreach_func,
const void *user_data)
{
const struct bucket **table;
unsigned int i;
table = hashtable_list_buckets(ht);
if (table == NULL)
return;
for (i = 0; i<ht->count; i++) {
const struct bucket *b = table[i];
(*hashtable_foreach_func)(b, user_data);
}
free(table);
}
/* ---------------------------------------------------------------------------
* Format hashtable into HTML.
*/
static void
format_table(struct str *buf, struct hashtable *ht, unsigned int start,
const enum sort_dir sort, const int full)
{
const struct bucket **table;
unsigned int i, end;
int alt = 0;
table = hashtable_list_buckets(ht);
if (table == NULL) {
str_append(buf, "<p>The table is empty.</p>\n");
return;
}
if (full) { if (full) {
/* full report overrides start and end */ /* full report overrides start and end */
start = 0; start = 0;
end = ht->count; end = ht->count;
} else } else
end = MIN(ht->count, (uint32_t)start+MAX_ENTRIES); end = MIN(ht->count, (uint32_t)start+MAX_ENTRIES);
str_appendf(buf, "(%u-%u of %u)<br>\n", start+1, end, ht->count); str_appendf(buf, "(%u-%u of %u)<br>\n", start+1, end, ht->count);
qsort_buckets(table, ht->count, start, end, sort); qsort_buckets(table, ht->count, start, end, sort);
ht->format_cols_func(buf); ht->format_cols_func(buf);
for (i=start; i<end; i++) { for (i=start; i<end; i++) {
ht->format_row_func(buf, table[i], alt ? "alt1" : "alt2"); ht->format_row_func(buf, table[i]);
alt = !alt; /* alternate class for table rows */ alt = !alt; /* alternate class for table rows */
} }
free(table); free(table);
str_append(buf, "</table>\n"); str_append(buf, "</table>\n");
} }
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* Web interface: sorted table of hosts. * Web interface: sorted table of hosts.
*/ */
static struct str * static struct str *
skipping to change at line 1183 skipping to change at line 1218
export_proto_tcp_remote = 't', export_proto_tcp_remote = 't',
export_proto_udp = 'U', export_proto_udp = 'U',
export_proto_udp_remote = 'u'; export_proto_udp_remote = 'u';
static const unsigned char static const unsigned char
export_tag_host_ver1[] = {'H', 'S', 'T', 0x01}, export_tag_host_ver1[] = {'H', 'S', 'T', 0x01},
export_tag_host_ver2[] = {'H', 'S', 'T', 0x02}, export_tag_host_ver2[] = {'H', 'S', 'T', 0x02},
export_tag_host_ver3[] = {'H', 'S', 'T', 0x03}, export_tag_host_ver3[] = {'H', 'S', 'T', 0x03},
export_tag_host_ver4[] = {'H', 'S', 'T', 0x04}; export_tag_host_ver4[] = {'H', 'S', 'T', 0x04};
static void text_metrics_counter(struct str *buf, const char *metric, const char
*type, const char *help);
static void text_metrics_format_host(const struct bucket *b, const void *user_da
ta);
/* ---------------------------------------------------------------------------
* Web interface: export stats in Prometheus text format on /metrics
*/
struct str *
text_metrics()
{
struct str *buf = str_make();
text_metrics_counter(buf,
"host_bytes_total",
"counter",
"Total number of network bytes by host and direction.");
hashtable_foreach(hosts_db, &text_metrics_format_host, (void *)buf);
return buf;
}
static void
text_metrics_counter(struct str *buf,
const char *metric,
const char *type,
const char *help)
{
str_appendf(buf, "# HELP %s %s\n", metric, help);
str_appendf(buf, "# TYPE %s %s\n", metric, type);
}
static void
text_metrics_format_host_key(struct str *buf, const struct bucket *b) {
const char *ip = addr_to_str(&(b->u.host.addr));
str_appendf(buf,
"host_bytes_total{interface=\"%s\",ip=\"%s\"",
title_interfaces, ip);
if (hosts_db_show_macs)
str_appendf(buf, ",mac=\"%x:%x:%x:%x:%x:%x\"",
b->u.host.mac_addr[0],
b->u.host.mac_addr[1],
b->u.host.mac_addr[2],
b->u.host.mac_addr[3],
b->u.host.mac_addr[4],
b->u.host.mac_addr[5]);
}
static void
text_metrics_format_host(const struct bucket *b,
const void *user_data)
{
struct str *buf = (struct str *)user_data;
text_metrics_format_host_key(buf, b);
str_appendf(buf, ",dir=\"in\"} %qu\n", (qu)b->in);
text_metrics_format_host_key(buf, b);
str_appendf(buf, ",dir=\"out\"} %qu\n", (qu)b->out);
}
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* Load a host's ip_proto table from a file. * Load a host's ip_proto table from a file.
* Returns 0 on failure, 1 on success. * Returns 0 on failure, 1 on success.
*/ */
static int static int
hosts_db_import_ip(const int fd, struct bucket *host) hosts_db_import_ip(const int fd, struct bucket *host)
{ {
uint8_t count, i; uint8_t count, i;
if (!expect8(fd, export_proto_ip)) return 0; if (!expect8(fd, export_proto_ip)) return 0;
 End of changes. 20 change blocks. 
27 lines changed or deleted 125 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)