/* darkstat 3
- * copyright (c) 2001-2008 Emil Mikulic.
+ * copyright (c) 2001-2011 Emil Mikulic.
*
* acct.c: traffic accounting
*
#include "now.h"
#include "opt.h"
-#include <arpa/inet.h> /* for inet_aton() */
#define __FAVOR_BSD
#include <netinet/tcp.h>
#include <sys/socket.h>
errx(1, "family mismatch between net and mask");
} else {
uint8_t frac, *p;
+ char *endptr;
localmask.family = localnet.family;
/* Compute the prefix length. */
- pfxlen = (int)strtonum(tokens[1], 1,
- (localnet.family == IPv6) ? 128 : 32, NULL);
+ pfxlen = (unsigned int)strtol(tokens[1], &endptr, 10);
- if (pfxlen == 0)
+ if ((pfxlen < 0) ||
+ ((localnet.family == IPv6) && (pfxlen > 128)) ||
+ ((localnet.family == IPv4) && (pfxlen > 32)) ||
+ (tokens[1][0] == '\0') ||
+ (*endptr != '\0'))
errx(1, "invalid network prefix length \"%s\"", tokens[1]);
/* Construct the network mask. */
/* Hosts. */
hosts_db_reduce();
- hs = host_get(&(sm->src));
- hs->out += sm->len;
- hs->total += sm->len;
- memcpy(hs->u.host.mac_addr, sm->src_mac, sizeof(sm->src_mac));
- hs->u.host.last_seen = now;
-
- hd = host_get(&(sm->dst));
- hd->in += sm->len;
- hd->total += sm->len;
- memcpy(hd->u.host.mac_addr, sm->dst_mac, sizeof(sm->dst_mac));
- hd->u.host.last_seen = now;
+ if (!opt_want_local_only || addr_is_local(&sm->src)) {
+ hs = host_get(&(sm->src));
+ hs->out += sm->len;
+ hs->total += sm->len;
+ memcpy(hs->u.host.mac_addr, sm->src_mac, sizeof(sm->src_mac));
+ hs->u.host.lastseen = now;
+ }
+
+ if (!opt_want_local_only || addr_is_local(&sm->dst)) {
+ hd = host_get(&(sm->dst));
+ hd->in += sm->len;
+ hd->total += sm->len;
+ memcpy(hd->u.host.mac_addr, sm->dst_mac, sizeof(sm->dst_mac));
+ /*
+ * Don't update recipient's last seen time, we don't know that
+ * they received successfully.
+ */
+ }
/* Protocols. */
if (sm->proto != IPPROTO_INVALID) {
- ps = host_get_ip_proto(hs, sm->proto);
- ps->out += sm->len;
- ps->total += sm->len;
-
- pd = host_get_ip_proto(hd, sm->proto);
- pd->in += sm->len;
- pd->total += sm->len;
+ if (hs) {
+ ps = host_get_ip_proto(hs, sm->proto);
+ ps->out += sm->len;
+ ps->total += sm->len;
+ }
+ if (hd) {
+ pd = host_get_ip_proto(hd, sm->proto);
+ pd->in += sm->len;
+ pd->total += sm->len;
+ }
}
if (opt_ports_max == 0) return; /* skip ports accounting */
/* Ports. */
switch (sm->proto) {
case IPPROTO_TCP:
- if (sm->src_port <= opt_highest_port) {
+ if ((sm->src_port <= opt_highest_port) && hs) {
ps = host_get_port_tcp(hs, sm->src_port);
ps->out += sm->len;
ps->total += sm->len;
}
-
- if (sm->dst_port <= opt_highest_port) {
+ if ((sm->dst_port <= opt_highest_port) && hd) {
pd = host_get_port_tcp(hd, sm->dst_port);
pd->in += sm->len;
pd->total += sm->len;
break;
case IPPROTO_UDP:
- if (sm->src_port <= opt_highest_port) {
+ if ((sm->src_port <= opt_highest_port) && hs) {
ps = host_get_port_udp(hs, sm->src_port);
ps->out += sm->len;
ps->total += sm->len;
}
-
- if (sm->dst_port <= opt_highest_port) {
+ if ((sm->dst_port <= opt_highest_port) && hd) {
pd = host_get_port_udp(hd, sm->dst_port);
pd->in += sm->len;
pd->total += sm->len;