Added service hash for resolving port/protocol numbers to names.
Minor fix to handling of netmasks end /32.
This commit is contained in:
5
Makefile
5
Makefile
@@ -33,8 +33,9 @@ LDFLAGS += -g
|
|||||||
LDLIBS += -lpcap -lpthread -lcurses -lm
|
LDLIBS += -lpcap -lpthread -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
|
options.c serv_hash.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\
|
||||||
|
serv_hash.h
|
||||||
TXTS = README CHANGES INSTALL TODO iftop.8 COPYING
|
TXTS = README CHANGES INSTALL TODO iftop.8 COPYING
|
||||||
SPECFILE = iftop.spec
|
SPECFILE = iftop.spec
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ int compare(void* a, void* b) {
|
|||||||
return (aa->src.s_addr == bb->src.s_addr
|
return (aa->src.s_addr == bb->src.s_addr
|
||||||
&& aa->src_port == bb->src_port
|
&& aa->src_port == bb->src_port
|
||||||
&& aa->dst.s_addr == bb->dst.s_addr
|
&& aa->dst.s_addr == bb->dst.s_addr
|
||||||
&& aa->dst_port == bb->dst_port);
|
&& aa->dst_port == bb->dst_port
|
||||||
|
&& aa->protocol == bb->protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hash(void* key) {
|
int hash(void* key) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
unsigned short int protocol;
|
||||||
unsigned short int src_port;
|
unsigned short int src_port;
|
||||||
struct in_addr src;
|
struct in_addr src;
|
||||||
unsigned short int dst_port;
|
unsigned short int dst_port;
|
||||||
|
|||||||
6
iftop.c
6
iftop.c
@@ -193,12 +193,12 @@ static void handle_ip_packet(struct ip* iptr, int hw_dir)
|
|||||||
/*
|
/*
|
||||||
* Net filter on, assign direction according to netmask
|
* Net filter on, assign direction according to netmask
|
||||||
*/
|
*/
|
||||||
if(in_filter_net(iptr->ip_src) & !in_filter_net(iptr->ip_dst)) {
|
if(in_filter_net(iptr->ip_src) && !in_filter_net(iptr->ip_dst)) {
|
||||||
/* out of network */
|
/* out of network */
|
||||||
assign_addr_pair(&ap, iptr, 0);
|
assign_addr_pair(&ap, iptr, 0);
|
||||||
direction = 1;
|
direction = 1;
|
||||||
}
|
}
|
||||||
else if(in_filter_net(iptr->ip_dst) & !in_filter_net(iptr->ip_src)) {
|
else if(in_filter_net(iptr->ip_dst) && !in_filter_net(iptr->ip_src)) {
|
||||||
/* into network */
|
/* into network */
|
||||||
assign_addr_pair(&ap, iptr, 1);
|
assign_addr_pair(&ap, iptr, 1);
|
||||||
direction = 0;
|
direction = 0;
|
||||||
@@ -209,6 +209,8 @@ static void handle_ip_packet(struct ip* iptr, int hw_dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ap.protocol = iptr->ip_p;
|
||||||
|
|
||||||
/* Add the addresses to be resolved */
|
/* Add the addresses to be resolved */
|
||||||
resolve(&iptr->ip_dst, NULL, 0);
|
resolve(&iptr->ip_dst, NULL, 0);
|
||||||
resolve(&iptr->ip_src, NULL, 0);
|
resolve(&iptr->ip_src, NULL, 0);
|
||||||
|
|||||||
27
options.c
27
options.c
@@ -87,18 +87,31 @@ static void set_net_filter(char* arg) {
|
|||||||
if (inet_aton(arg, &options.netfilternet) == 0)
|
if (inet_aton(arg, &options.netfilternet) == 0)
|
||||||
die("Invalid network address\n");
|
die("Invalid network address\n");
|
||||||
/* Accept a netmask like /24 or /255.255.255.0. */
|
/* Accept a netmask like /24 or /255.255.255.0. */
|
||||||
if (!mask[strspn(mask, "0123456789")]) {
|
if (mask[strspn(mask, "0123456789")] == '\0') {
|
||||||
|
/* Whole string is numeric */
|
||||||
int n;
|
int n;
|
||||||
n = atoi(mask);
|
n = atoi(mask);
|
||||||
if (n > 32)
|
if (n > 32) {
|
||||||
die("Invalid netmask");
|
die("Invalid netmask");
|
||||||
else {
|
|
||||||
uint32_t mm = 0xffffffffl;
|
|
||||||
mm >>= n;
|
|
||||||
options.netfiltermask.s_addr = htonl(~mm);
|
|
||||||
}
|
}
|
||||||
} else if (inet_aton(mask, &options.netfiltermask) == 0)
|
else {
|
||||||
|
if(n == 32) {
|
||||||
|
/* This needs to be special cased, although I don't fully
|
||||||
|
* understand why -pdw
|
||||||
|
*/
|
||||||
|
options.netfiltermask.s_addr = htonl(0xffffffffl);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint32_t mm = 0xffffffffl;
|
||||||
|
mm >>= n;
|
||||||
|
options.netfiltermask.s_addr = htonl(~mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (inet_aton(mask, &options.netfiltermask) == 0) {
|
||||||
die("Invalid netmask\n");
|
die("Invalid netmask\n");
|
||||||
|
}
|
||||||
|
options.netfilternet.s_addr = options.netfilternet.s_addr & options.netfiltermask.s_addr;
|
||||||
|
|
||||||
options.netfilter = 1;
|
options.netfilter = 1;
|
||||||
|
|
||||||
|
|||||||
66
serv_hash.c
Normal file
66
serv_hash.c
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* hash table */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include "serv_hash.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "iftop.h"
|
||||||
|
|
||||||
|
// Deliberately not a power of 2 or 10
|
||||||
|
#define hash_table_size 123
|
||||||
|
|
||||||
|
int serv_hash_compare(void* a, void* b) {
|
||||||
|
ip_service* aa = (ip_service*)a;
|
||||||
|
ip_service* bb = (ip_service*)b;
|
||||||
|
return (aa->port == bb->port &&
|
||||||
|
aa->protocol == bb->protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serv_hash_hash(void* key) {
|
||||||
|
ip_service* serv = (ip_service*)key;
|
||||||
|
return serv->protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* serv_hash_copy_key(void* orig) {
|
||||||
|
ip_service* copy;
|
||||||
|
copy = xmalloc(sizeof *copy);
|
||||||
|
*copy = *(ip_service*)orig;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serv_hash_delete_key(void* key) {
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and return a hash
|
||||||
|
*/
|
||||||
|
hash_type* serv_hash_create() {
|
||||||
|
hash_type* hash_table;
|
||||||
|
hash_table = xcalloc(hash_table_size, sizeof *hash_table);
|
||||||
|
hash_table->size = hash_table_size;
|
||||||
|
hash_table->compare = &serv_hash_compare;
|
||||||
|
hash_table->hash = &serv_hash_hash;
|
||||||
|
hash_table->delete_key = &serv_hash_delete_key;
|
||||||
|
hash_table->copy_key = &serv_hash_copy_key;
|
||||||
|
hash_initialise(hash_table);
|
||||||
|
return hash_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serv_hash_initialise(hash_type* sh) {
|
||||||
|
struct servent* ent;
|
||||||
|
struct protoent* pent;
|
||||||
|
ip_service* service;
|
||||||
|
setprotoent(1);
|
||||||
|
while((ent = getservent()) != NULL) {
|
||||||
|
pent = getprotobyname(ent->s_proto);
|
||||||
|
if(pent != NULL) {
|
||||||
|
service = xmalloc(sizeof(ip_service));
|
||||||
|
service->port = ntohs(ent->s_port);
|
||||||
|
service->protocol = pent->p_proto;
|
||||||
|
hash_insert(sh, service, xstrdup(ent->s_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endprotoent();
|
||||||
|
}
|
||||||
22
serv_hash.h
Normal file
22
serv_hash.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* addr_hash.h:
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SERV_HASH_H_ /* include guard */
|
||||||
|
#define __SERV_HASH_H_
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int port;
|
||||||
|
int protocol;
|
||||||
|
} ip_service;
|
||||||
|
|
||||||
|
hash_type* serv_hash_create();
|
||||||
|
void serv_hash_initialise(hash_type* sh);
|
||||||
|
|
||||||
|
#endif /* __SERV_HASH_H_ */
|
||||||
30
ui.c
30
ui.c
@@ -13,6 +13,7 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
#include "addr_hash.h"
|
#include "addr_hash.h"
|
||||||
|
#include "serv_hash.h"
|
||||||
#include "iftop.h"
|
#include "iftop.h"
|
||||||
#include "resolver.h"
|
#include "resolver.h"
|
||||||
#include "sorted_list.h"
|
#include "sorted_list.h"
|
||||||
@@ -43,6 +44,7 @@ extern options_t options ;
|
|||||||
void ui_finish();
|
void ui_finish();
|
||||||
|
|
||||||
hash_type* screen_hash;
|
hash_type* screen_hash;
|
||||||
|
hash_type* service_hash;
|
||||||
sorted_list_type screen_list;
|
sorted_list_type screen_list;
|
||||||
host_pair_line totals;
|
host_pair_line totals;
|
||||||
int peaksent, peakrecv, peaktotal;
|
int peaksent, peakrecv, peaktotal;
|
||||||
@@ -274,10 +276,11 @@ void analyse_data() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprint_host(char * line, struct in_addr* addr, unsigned int port, int L) {
|
void sprint_host(char * line, struct in_addr* addr, unsigned int port, unsigned int protocol, int L) {
|
||||||
char hostname[HOSTNAME_LENGTH];
|
char hostname[HOSTNAME_LENGTH];
|
||||||
char service[10];
|
char service[HOSTNAME_LENGTH];
|
||||||
struct servent* sent;
|
char* s_name;
|
||||||
|
ip_service skey;
|
||||||
int left;
|
int left;
|
||||||
if(addr->s_addr == 0) {
|
if(addr->s_addr == 0) {
|
||||||
sprintf(hostname, " * ");
|
sprintf(hostname, " * ");
|
||||||
@@ -292,13 +295,16 @@ void sprint_host(char * line, struct in_addr* addr, unsigned int port, int L) {
|
|||||||
|
|
||||||
//TODO: Replace this with in-memory hash for speed.
|
//TODO: Replace this with in-memory hash for speed.
|
||||||
//sent = getservbyport(port, "tcp");
|
//sent = getservbyport(port, "tcp");
|
||||||
|
|
||||||
|
|
||||||
if(port != 0) {
|
if(port != 0) {
|
||||||
sent = NULL;
|
skey.port = port;
|
||||||
if(sent == NULL) {
|
skey.protocol = protocol;
|
||||||
snprintf(service, 10, ":%d", port);
|
if(hash_find(service_hash, &skey, (void**)&s_name) == HASH_STATUS_OK) {
|
||||||
|
snprintf(service, HOSTNAME_LENGTH, ":%s", s_name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
snprintf(service, 10, ":%s", sent->s_name);
|
snprintf(service, HOSTNAME_LENGTH, ":%d", port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -372,14 +378,12 @@ void ui_print() {
|
|||||||
host_pair_line* screen_line = (host_pair_line*)nn->data;
|
host_pair_line* screen_line = (host_pair_line*)nn->data;
|
||||||
|
|
||||||
if(y < LINES - 4) {
|
if(y < LINES - 4) {
|
||||||
fprintf(stderr, "Drawing at %d \r\n", y);
|
|
||||||
|
|
||||||
L = (COLS - 8 * HISTORY_DIVISIONS - 4) / 2;
|
L = (COLS - 8 * HISTORY_DIVISIONS - 4) / 2;
|
||||||
if(L > sizeof hostname) {
|
if(L > sizeof hostname) {
|
||||||
L = sizeof hostname;
|
L = sizeof hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprint_host(line, &(screen_line->ap.src), screen_line->ap.src_port, L);
|
sprint_host(line, &(screen_line->ap.src), screen_line->ap.src_port, screen_line->ap.protocol, L);
|
||||||
|
|
||||||
//sprintf(line, "%-*s", L, hostname);
|
//sprintf(line, "%-*s", L, hostname);
|
||||||
mvaddstr(y, x, line);
|
mvaddstr(y, x, line);
|
||||||
@@ -390,7 +394,7 @@ void ui_print() {
|
|||||||
|
|
||||||
x += 4;
|
x += 4;
|
||||||
|
|
||||||
sprint_host(line, &(screen_line->ap.dst), screen_line->ap.dst_port, L);
|
sprint_host(line, &(screen_line->ap.dst), screen_line->ap.dst_port, screen_line->ap.protocol, L);
|
||||||
|
|
||||||
mvaddstr(y, x, line);
|
mvaddstr(y, x, line);
|
||||||
|
|
||||||
@@ -460,6 +464,10 @@ void ui_init() {
|
|||||||
screen_list_init();
|
screen_list_init();
|
||||||
screen_hash = addr_hash_create();
|
screen_hash = addr_hash_create();
|
||||||
|
|
||||||
|
service_hash = serv_hash_create();
|
||||||
|
serv_hash_initialise(service_hash);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_loop() {
|
void ui_loop() {
|
||||||
|
|||||||
Reference in New Issue
Block a user