Added alternative resolver.
Altered display of totals.
This commit is contained in:
16
Makefile
16
Makefile
@@ -5,6 +5,8 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
|
|
||||||
|
VERSION = 0.10pre1
|
||||||
|
|
||||||
# C compiler to use.
|
# C compiler to use.
|
||||||
#CC = gcc
|
#CC = gcc
|
||||||
|
|
||||||
@@ -17,7 +19,15 @@ CFLAGS += -I/usr/include/pcap
|
|||||||
# directories:
|
# directories:
|
||||||
# LDFLAGS += -L/usr/local/lib
|
# LDFLAGS += -L/usr/local/lib
|
||||||
# LDFLAGS += -pg -a
|
# 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 specifies the base directory for the installation.
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
@@ -31,11 +41,11 @@ MANDIR = man
|
|||||||
#MANDIR = share/man # FHS-ish
|
#MANDIR = share/man # FHS-ish
|
||||||
|
|
||||||
# You shouldn't need to change anything below this point.
|
# You shouldn't need to change anything below this point.
|
||||||
VERSION = 0.9
|
|
||||||
CFLAGS += -g -Wall "-DIFTOP_VERSION=\"$(VERSION)\""
|
CFLAGS += -g -Wall "-DIFTOP_VERSION=\"$(VERSION)\""
|
||||||
LDFLAGS += -g
|
LDFLAGS += -g -pthread
|
||||||
LDLIBS += -lpcap -lcurses -lm
|
LDLIBS += -lpcap -lcurses -lm
|
||||||
|
|
||||||
|
|
||||||
SRCS = iftop.c addr_hash.c hash.c ns_hash.c resolver.c ui.c util.c sorted_list.c\
|
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
|
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\
|
HDRS = addr_hash.h hash.h iftop.h ns_hash.h resolver.h sorted_list.h ui.h options.h sll.h\
|
||||||
|
|||||||
120
resolver.c
120
resolver.c
@@ -14,11 +14,18 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef USELIBRESOLV
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#include <resolv.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ns_hash.h"
|
#include "ns_hash.h"
|
||||||
#include "iftop.h"
|
#include "iftop.h"
|
||||||
|
|
||||||
#include "threadprof.h"
|
#include "threadprof.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define RESOLVE_QUEUE_LENGTH 20
|
#define RESOLVE_QUEUE_LENGTH 20
|
||||||
|
|
||||||
struct in_addr resolve_queue[RESOLVE_QUEUE_LENGTH];
|
struct in_addr resolve_queue[RESOLVE_QUEUE_LENGTH];
|
||||||
@@ -31,6 +38,83 @@ hash_type* ns_hash;
|
|||||||
int head;
|
int head;
|
||||||
int tail;
|
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) {
|
void resolver_worker(void* ptr) {
|
||||||
struct timespec delay;
|
struct timespec delay;
|
||||||
/* int thread_number = *(int*)ptr;*/
|
/* int thread_number = *(int*)ptr;*/
|
||||||
@@ -45,12 +129,8 @@ void resolver_worker(void* ptr) {
|
|||||||
|
|
||||||
/* Keep resolving until the queue is empty */
|
/* Keep resolving until the queue is empty */
|
||||||
while(head != tail) {
|
while(head != tail) {
|
||||||
|
char * hostname;
|
||||||
struct in_addr addr = resolve_queue[tail];
|
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 */
|
/* mutex always locked at this point */
|
||||||
|
|
||||||
@@ -58,40 +138,22 @@ void resolver_worker(void* ptr) {
|
|||||||
|
|
||||||
pthread_mutex_unlock(&resolver_queue_mutex);
|
pthread_mutex_unlock(&resolver_queue_mutex);
|
||||||
|
|
||||||
hstbuflen = 1024;
|
hostname = do_resolve(&addr);
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store the result in ns_hash
|
* Store the result in ns_hash
|
||||||
*/
|
*/
|
||||||
pthread_mutex_lock(&resolver_queue_mutex);
|
pthread_mutex_lock(&resolver_queue_mutex);
|
||||||
|
|
||||||
/* Check for errors. */
|
if(hostname != NULL) {
|
||||||
if (res || hp == NULL) {
|
char* old;
|
||||||
/* failed */
|
if(hash_find(ns_hash, &addr, (void**)&old) == HASH_STATUS_OK) {
|
||||||
/* Leave the unresolved IP in the hash */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* success */
|
|
||||||
char* hostname;
|
|
||||||
if(hash_find(ns_hash, &addr, (void**)&hostname) == HASH_STATUS_OK) {
|
|
||||||
hash_delete(ns_hash, &addr);
|
hash_delete(ns_hash, &addr);
|
||||||
xfree(hostname);
|
xfree(old);
|
||||||
}
|
}
|
||||||
hostname = strdup(hp->h_name);
|
|
||||||
hash_insert(ns_hash, &addr, (void*)hostname);
|
hash_insert(ns_hash, &addr, (void*)hostname);
|
||||||
|
|
||||||
}
|
}
|
||||||
xfree(tmphstbuf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
ui.c
54
ui.c
@@ -71,6 +71,8 @@ sorted_list_type screen_list;
|
|||||||
host_pair_line totals;
|
host_pair_line totals;
|
||||||
int peaksent, peakrecv, peaktotal;
|
int peaksent, peakrecv, peaktotal;
|
||||||
|
|
||||||
|
int showhelphint = 0;
|
||||||
|
|
||||||
int screen_line_compare(void* a, void* b) {
|
int screen_line_compare(void* a, void* b) {
|
||||||
int i;
|
int i;
|
||||||
host_pair_line* aa = (host_pair_line*)a;
|
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);
|
left = strlen(hostname);
|
||||||
|
|
||||||
//TODO: Replace this with in-memory hash for speed.
|
|
||||||
//sent = getservbyport(port, "tcp");
|
|
||||||
|
|
||||||
|
|
||||||
if(port != 0) {
|
if(port != 0) {
|
||||||
skey.port = port;
|
skey.port = port;
|
||||||
skey.protocol = protocol;
|
skey.protocol = protocol;
|
||||||
@@ -405,37 +403,11 @@ void ui_print() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
clear();
|
|
||||||
/*
|
/*
|
||||||
//erase();
|
* erase() is faster than clear(). Dunno why we switched to
|
||||||
move(0, 0);
|
* clear() -pdw 24/10/02
|
||||||
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();
|
||||||
|
|
||||||
draw_bar_scale(&y);
|
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);
|
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);
|
mvaddstr(y, x, line);
|
||||||
x += L;
|
x += L;
|
||||||
|
|
||||||
@@ -484,9 +455,6 @@ void ui_print() {
|
|||||||
|
|
||||||
y = LINES - 3;
|
y = LINES - 3;
|
||||||
|
|
||||||
//mvaddstr(y, 0, "total: ");
|
|
||||||
//mvaddstr(y+1, 0, " peak: ");
|
|
||||||
|
|
||||||
mvhline(y-1, 0, 0, COLS);
|
mvhline(y-1, 0, 0, COLS);
|
||||||
|
|
||||||
mvaddstr(y, 0, "TX: ");
|
mvaddstr(y, 0, "TX: ");
|
||||||
@@ -522,6 +490,12 @@ void ui_print() {
|
|||||||
draw_totals(&totals);
|
draw_totals(&totals);
|
||||||
|
|
||||||
|
|
||||||
|
if(showhelphint > 0) {
|
||||||
|
mvaddstr(0, 0, "Press h for help ");
|
||||||
|
clrtoeol();
|
||||||
|
showhelphint--;
|
||||||
|
}
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
/* Bar chart auto scale */
|
/* Bar chart auto scale */
|
||||||
@@ -627,6 +601,12 @@ void ui_loop() {
|
|||||||
case 'P':
|
case 'P':
|
||||||
options.paused = !options.paused;
|
options.paused = !options.paused;
|
||||||
break;
|
break;
|
||||||
|
case ERR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
showhelphint = 2;
|
||||||
|
tick(1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
tick(0);
|
tick(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user