From 4ef789bed10a53c5aa69d1c069a97d6c3900a80c Mon Sep 17 00:00:00 2001 From: pdw <> Date: Thu, 24 Oct 2002 13:42:11 +0000 Subject: [PATCH] Added alternative resolver. Altered display of totals. --- Makefile | 20 ++++++--- resolver.c | 120 ++++++++++++++++++++++++++++++++++++++++------------- ui.c | 58 +++++++++----------------- 3 files changed, 125 insertions(+), 73 deletions(-) diff --git a/Makefile b/Makefile index 2507203..043b0e1 100644 --- a/Makefile +++ b/Makefile @@ -5,19 +5,29 @@ # $Id$ # +VERSION = 0.10pre1 + # C compiler to use. #CC = gcc # Give the location of pcap.h here: -CFLAGS += -I/usr/include/pcap +CFLAGS += -I/usr/include/pcap # CFLAGS += -I/usr/pkg/include # CFLAGS += -pg -a # Give the location of libpcap here if it's not in one of the standard # directories: -#LDFLAGS += -L/usr/local/lib +# LDFLAGS += -L/usr/local/lib # LDFLAGS += -pg -a -LDFLAGS += -pthread + +# +# Uncomment to use libresolv +# +#CFLAGS += -DUSELIBRESOLV + +# This may be needed to use libresolv on Linux. +#LDLIBS += /usr/lib/libresolv.a + # PREFIX specifies the base directory for the installation. PREFIX = /usr/local @@ -31,11 +41,11 @@ MANDIR = man #MANDIR = share/man # FHS-ish # You shouldn't need to change anything below this point. -VERSION = 0.9 CFLAGS += -g -Wall "-DIFTOP_VERSION=\"$(VERSION)\"" -LDFLAGS += -g +LDFLAGS += -g -pthread LDLIBS += -lpcap -lcurses -lm + SRCS = iftop.c addr_hash.c hash.c ns_hash.c resolver.c ui.c util.c sorted_list.c\ options.c serv_hash.c threadprof.c HDRS = addr_hash.h hash.h iftop.h ns_hash.h resolver.h sorted_list.h ui.h options.h sll.h\ diff --git a/resolver.c b/resolver.c index 8602421..aa30910 100644 --- a/resolver.c +++ b/resolver.c @@ -14,11 +14,18 @@ #include #include +#ifdef USELIBRESOLV +#include +#include +#endif + #include "ns_hash.h" #include "iftop.h" #include "threadprof.h" + + #define RESOLVE_QUEUE_LENGTH 20 struct in_addr resolve_queue[RESOLVE_QUEUE_LENGTH]; @@ -31,6 +38,83 @@ hash_type* ns_hash; int head; int tail; + +#ifndef USELIBRESOLV +/** + * Implementation of do_resolve for platforms with working gethostbyaddr_r + */ +char* do_resolve(struct in_addr * addr) { + struct hostent hostbuf, *hp; + size_t hstbuflen = 1024; + char *tmphstbuf; + int res; + int herr; + char * ret = NULL; + + /* Allocate buffer, remember to free it to avoid memory leakage. */ + tmphstbuf = xmalloc (hstbuflen); + + while ((res = gethostbyaddr_r ((char*)addr, sizeof(struct in_addr), AF_INET, + &hostbuf, tmphstbuf, hstbuflen, + &hp, &herr)) == ERANGE) { + /* Enlarge the buffer. */ + hstbuflen *= 2; + tmphstbuf = realloc (tmphstbuf, hstbuflen); + } + + /* Check for errors. */ + if (res || hp == NULL) { + /* failed */ + /* Leave the unresolved IP in the hash */ + } + else { + ret = xstrdup(hp->h_name); + + } + xfree(tmphstbuf); + return ret; +} + +#else + +/** + * libresolv implementation + */ +char* do_resolve(struct in_addr * addr) { + char msg[PACKETSZ]; + char s[35]; + int l; + unsigned char* a; + char * ret = NULL; + + a = (unsigned char*)addr; + + snprintf(s, 35, "%d.%d.%d.%d.in-addr.arpa.",a[3], a[2], a[1], a[0]); + + l = res_search(s, C_IN, T_PTR, msg, PACKETSZ); + if(l != -1) { + ns_msg nsmsg; + ns_rr rr; + if(ns_initparse(msg, l, &nsmsg) != -1) { + int c; + int i; + c = ns_msg_count(nsmsg, ns_s_an); + for(i = 0; i < c; i++) { + if(ns_parserr(&nsmsg, ns_s_an, i, &rr) == 0){ + if(ns_rr_type(rr) == T_PTR) { + char buf[256]; + ns_name_uncompress(msg, msg + l, ns_rr_rdata(rr), buf, 256); + ret = xstrdup(buf); + } + + } + } + } + } + return ret; +} +#endif + void resolver_worker(void* ptr) { struct timespec delay; /* int thread_number = *(int*)ptr;*/ @@ -45,12 +129,8 @@ void resolver_worker(void* ptr) { /* Keep resolving until the queue is empty */ while(head != tail) { + char * hostname; struct in_addr addr = resolve_queue[tail]; - struct hostent hostbuf, *hp; - size_t hstbuflen; - char *tmphstbuf; - int res; - int herr; /* mutex always locked at this point */ @@ -58,40 +138,22 @@ void resolver_worker(void* ptr) { pthread_mutex_unlock(&resolver_queue_mutex); - hstbuflen = 1024; - /* Allocate buffer, remember to free it to avoid memory leakage. */ - tmphstbuf = xmalloc (hstbuflen); - - while ((res = gethostbyaddr_r ((char*)&addr, sizeof(addr), AF_INET, - &hostbuf, tmphstbuf, hstbuflen, - &hp, &herr)) == ERANGE) { - /* Enlarge the buffer. */ - hstbuflen *= 2; - tmphstbuf = realloc (tmphstbuf, hstbuflen); - } + hostname = do_resolve(&addr); /* * Store the result in ns_hash */ pthread_mutex_lock(&resolver_queue_mutex); - /* Check for errors. */ - if (res || hp == NULL) { - /* failed */ - /* Leave the unresolved IP in the hash */ - } - else { - /* success */ - char* hostname; - if(hash_find(ns_hash, &addr, (void**)&hostname) == HASH_STATUS_OK) { + if(hostname != NULL) { + char* old; + if(hash_find(ns_hash, &addr, (void**)&old) == HASH_STATUS_OK) { hash_delete(ns_hash, &addr); - xfree(hostname); + xfree(old); } - hostname = strdup(hp->h_name); hash_insert(ns_hash, &addr, (void*)hostname); - } - xfree(tmphstbuf); + } } } diff --git a/ui.c b/ui.c index 3e96122..1d22230 100644 --- a/ui.c +++ b/ui.c @@ -71,6 +71,8 @@ sorted_list_type screen_list; host_pair_line totals; int peaksent, peakrecv, peaktotal; +int showhelphint = 0; + int screen_line_compare(void* a, void* b) { int i; host_pair_line* aa = (host_pair_line*)a; @@ -354,10 +356,6 @@ void sprint_host(char * line, struct in_addr* addr, unsigned int port, unsigned } left = strlen(hostname); - //TODO: Replace this with in-memory hash for speed. - //sent = getservbyport(port, "tcp"); - - if(port != 0) { skey.port = port; skey.protocol = protocol; @@ -405,37 +403,11 @@ void ui_print() { } - clear(); - /* - //erase(); - move(0, 0); - attron(A_REVERSE); - addstr(" q "); - attroff(A_REVERSE); - addstr(" quit "); - attron(A_REVERSE); - addstr(" r "); - attroff(A_REVERSE); - addstr(options.dnsresolution ? " resolver off " - : " resolver on "); - attron(A_REVERSE); - addstr(" b "); - attroff(A_REVERSE); - addstr(options.showbars ? " bars off " - : " bars on "); - - attron(A_REVERSE); - addstr(" s "); - attroff(A_REVERSE); - addstr(options.aggregate_src ? " show src " - : " hide src "); - - attron(A_REVERSE); - addstr(" d "); - attroff(A_REVERSE); - addstr(options.aggregate_dest ? " show dest " - : " hide dest "); - */ + /* + * erase() is faster than clear(). Dunno why we switched to + * clear() -pdw 24/10/02 + */ + erase(); draw_bar_scale(&y); @@ -461,7 +433,6 @@ void ui_print() { sprint_host(line, &(screen_line->ap.src), screen_line->ap.src_port, screen_line->ap.protocol, L); - //sprintf(line, "%-*s", L, hostname); mvaddstr(y, x, line); x += L; @@ -483,9 +454,6 @@ void ui_print() { y = LINES - 3; - - //mvaddstr(y, 0, "total: "); - //mvaddstr(y+1, 0, " peak: "); mvhline(y-1, 0, 0, COLS); @@ -521,6 +489,12 @@ void ui_print() { draw_totals(&totals); + + if(showhelphint > 0) { + mvaddstr(0, 0, "Press h for help "); + clrtoeol(); + showhelphint--; + } refresh(); @@ -627,6 +601,12 @@ void ui_loop() { case 'P': options.paused = !options.paused; break; + case ERR: + break; + default: + showhelphint = 2; + tick(1); + break; } tick(0); }