diff --git a/iftop.c b/iftop.c index 224987b..88228fc 100644 --- a/iftop.c +++ b/iftop.c @@ -113,6 +113,7 @@ static void handle_packet(char* args, const struct pcap_pkthdr* pkthdr,const cha struct ip* iptr; history_type* ht; addr_pair ap; + int promisc = 0; iptr = (struct ip*)(packet + sizeof(struct ether_header)); /* alignment? */ @@ -125,13 +126,19 @@ static void handle_packet(char* args, const struct pcap_pkthdr* pkthdr,const cha ap.src = iptr->ip_dst; ap.dst = iptr->ip_src; } + /* + * This packet is not from or to this interface. Therefore assume + * it was picked up in promisc mode. + */ else if(iptr->ip_src.s_addr < iptr->ip_dst.s_addr) { ap.src = iptr->ip_src; ap.dst = iptr->ip_dst; + promisc = 1; } else { ap.src = iptr->ip_dst; ap.dst = iptr->ip_src; + promisc = 1; } @@ -140,12 +147,13 @@ static void handle_packet(char* args, const struct pcap_pkthdr* pkthdr,const cha if(hash_find(history, &ap, (void**)&ht) == HASH_STATUS_KEY_NOT_FOUND) { ht = history_create(); + ht->promisc = promisc; hash_insert(history, &ap, ht); } /* Update record */ ht->last_write = history_pos; - if(iptr->ip_src.s_addr < iptr->ip_dst.s_addr) { + if(iptr->ip_src.s_addr == ap.src.s_addr) { ht->sent[history_pos] += ntohs(iptr->ip_len); } else { diff --git a/iftop.h b/iftop.h index 3b25a84..bea11d1 100644 --- a/iftop.h +++ b/iftop.h @@ -14,6 +14,7 @@ typedef struct { long recv[HISTORY_LENGTH]; long sent[HISTORY_LENGTH]; int last_write; + int promisc; } history_type; void tick(); diff --git a/ui.c b/ui.c index 4fc718d..bc760d5 100644 --- a/ui.c +++ b/ui.c @@ -190,7 +190,15 @@ void ui_print() { tsent = trecv = 0; trecv += d->recv[ii]; - tsent += d->sent[ii]; + if(d->promisc == 1) { + /* If this was picked up by promiscuous mode, it must + * have been incoming + */ + trecv += d->recv[ii]; + } + else { + tsent += d->sent[ii]; + } for(j = 0; j < HISTORY_DIVISIONS; j++) { if(i < history_divs[j]) {