X-Git-Url: https://unix4lyfe.org/gitweb/darkstat-debian/blobdiff_plain/a1e8056c92203d02860d719abb1d562453896da8..HEAD:/acct.c diff --git a/acct.c b/acct.c index 62ad076..540bf35 100644 --- a/acct.c +++ b/acct.c @@ -1,5 +1,5 @@ /* darkstat 3 - * copyright (c) 2001-2011 Emil Mikulic. + * copyright (c) 2001-2012 Emil Mikulic. * * acct.c: traffic accounting * @@ -133,36 +133,25 @@ acct_init_localnet(const char *spec) verbosef(" local network mask: %s", addr_to_str(&localmask)); } -static int -addr_is_local(const struct addr * const a) -{ - if (a->family == IPv4) { - if (using_localnet4) { - if (addr_inside(a, &localnet4, &localmask4)) - return 1; - } else { - if (addr_equal(a, &localip4)) - return 1; - } - } else { - assert(a->family == IPv6); - if (using_localnet6) { - if (addr_inside(a, &localnet6, &localmask6)) - return 1; - } else { - if (addr_equal(a, &localip6)) - return 1; - } +static int addr_is_local(const struct addr * const a, + const struct local_ips *local_ips) { + if (is_localip(a, local_ips)) + return 1; + if (a->family == IPv4 && using_localnet4) { + if (addr_inside(a, &localnet4, &localmask4)) + return 1; + } else if (a->family == IPv6 && using_localnet6) { + if (addr_inside(a, &localnet6, &localmask6)) + return 1; } return 0; } /* Account for the given packet summary. */ -void -acct_for(const struct pktsummary * const sm) -{ - struct bucket *hs = NULL, *hd = NULL; - struct bucket *ps, *pd; +void acct_for(const struct pktsummary * const sm, + const struct local_ips * const local_ips) { + struct bucket *hs = NULL; // Source host. + struct bucket *hd = NULL; // Dest host. int dir_in, dir_out; #if 0 /* WANT_CHATTY? */ @@ -189,18 +178,15 @@ acct_for(const struct pktsummary * const sm) acct_total_bytes += sm->len; /* Graphs. */ - dir_out = addr_is_local(&(sm->src)); - dir_in = addr_is_local(&(sm->dst)); + dir_out = addr_is_local(&sm->src, local_ips); + dir_in = addr_is_local(&sm->dst, local_ips); /* Traffic staying within the network isn't counted. */ - if (dir_in == 1 && dir_out == 1) - dir_in = dir_out = 0; - - if (dir_out) { + if (dir_out && !dir_in) { daylog_acct((uint64_t)sm->len, GRAPH_OUT); graph_acct((uint64_t)sm->len, GRAPH_OUT); } - if (dir_in) { + if (dir_in && !dir_out) { daylog_acct((uint64_t)sm->len, GRAPH_IN); graph_acct((uint64_t)sm->len, GRAPH_IN); } @@ -209,15 +195,15 @@ acct_for(const struct pktsummary * const sm) /* Hosts. */ hosts_db_reduce(); - if (!opt_want_local_only || addr_is_local(&sm->src)) { + if (!opt_want_local_only || dir_out) { 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; + hs->u.host.last_seen_mono = now_mono(); } - if (!opt_want_local_only || addr_is_local(&sm->dst)) { + if (!opt_want_local_only || dir_in) { hd = host_get(&(sm->dst)); hd->in += sm->len; hd->total += sm->len; @@ -231,12 +217,12 @@ acct_for(const struct pktsummary * const sm) /* Protocols. */ if (sm->proto != IPPROTO_INVALID) { if (hs) { - ps = host_get_ip_proto(hs, sm->proto); + struct bucket *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); + struct bucket *pd = host_get_ip_proto(hd, sm->proto); pd->in += sm->len; pd->total += sm->len; } @@ -247,43 +233,64 @@ acct_for(const struct pktsummary * const sm) /* Ports. */ switch (sm->proto) { case IPPROTO_TCP: + // Local ports on host. if ((sm->src_port <= opt_highest_port) && hs) { - ps = host_get_port_tcp(hs, sm->src_port); + struct bucket *ps = host_get_port_tcp(hs, sm->src_port); ps->out += sm->len; ps->total += sm->len; } if ((sm->dst_port <= opt_highest_port) && hd) { - pd = host_get_port_tcp(hd, sm->dst_port); + struct bucket *pd = host_get_port_tcp(hd, sm->dst_port); pd->in += sm->len; pd->total += sm->len; if (sm->tcp_flags == TH_SYN) pd->u.port_tcp.syn++; } + + // Remote ports. + if ((sm->src_port <= opt_highest_port) && hd) { + struct bucket *pdr = host_get_port_tcp_remote(hd, sm->src_port); + pdr->out += sm->len; + pdr->total += sm->len; + } + if ((sm->dst_port <= opt_highest_port) && hs) { + struct bucket *psr = host_get_port_tcp_remote(hs, sm->dst_port); + psr->in += sm->len; + psr->total += sm->len; + if (sm->tcp_flags == TH_SYN) + psr->u.port_tcp.syn++; + } break; case IPPROTO_UDP: + // Local ports on host. if ((sm->src_port <= opt_highest_port) && hs) { - ps = host_get_port_udp(hs, sm->src_port); + struct bucket *ps = host_get_port_udp(hs, sm->src_port); ps->out += sm->len; ps->total += sm->len; } if ((sm->dst_port <= opt_highest_port) && hd) { - pd = host_get_port_udp(hd, sm->dst_port); + struct bucket *pd = host_get_port_udp(hd, sm->dst_port); pd->in += sm->len; pd->total += sm->len; } - break; - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - case IPPROTO_AH: - case IPPROTO_ESP: - case IPPROTO_OSPF: - /* known protocol, don't complain about it */ + // Remote ports. + if ((sm->src_port <= opt_highest_port) && hd) { + struct bucket *pdr = host_get_port_udp_remote(hd, sm->src_port); + pdr->out += sm->len; + pdr->total += sm->len; + } + if ((sm->dst_port <= opt_highest_port) && hs) { + struct bucket *psr = host_get_port_udp_remote(hs, sm->dst_port); + psr->in += sm->len; + psr->total += sm->len; + } break; - default: - verbosef("unknown IP proto (%04x)", sm->proto); + case IPPROTO_INVALID: + /* proto decoding failed, don't complain in accounting */ + break; } }