Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Paul Warren
iftop
Commits
803ee46d
Commit
803ee46d
authored
Oct 10, 2002
by
pdw
Browse files
Added support for displaying ports.
parent
fb66807a
Changes
8
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
803ee46d
Change log for iftop
$Id$
0.8
Added support for displaying port numbers
0.7 02/10/02
Fixed missing sll.h file.
...
...
TODO
View file @
803ee46d
Things to do for iftop
$Id$
* Interface types other than ethernet? Should at least detect these....
* Include ports in display
- implement service name hash
- add key press for src/dest port aggregation
* IP types other than v4?
* Include ports in display.
* Which average to use for the bar graph? Show several and peaks? Colours?
* Single keypress firewalling of troublesome connections, a la top(1)'s K
...
...
addr_hash.c
View file @
803ee46d
...
...
@@ -12,7 +12,9 @@ int compare(void* a, void* b) {
addr_pair
*
aa
=
(
addr_pair
*
)
a
;
addr_pair
*
bb
=
(
addr_pair
*
)
b
;
return
(
aa
->
src
.
s_addr
==
bb
->
src
.
s_addr
&&
aa
->
dst
.
s_addr
==
bb
->
dst
.
s_addr
);
&&
aa
->
src_port
==
bb
->
src_port
&&
aa
->
dst
.
s_addr
==
bb
->
dst
.
s_addr
&&
aa
->
dst_port
==
bb
->
dst_port
);
}
int
hash
(
void
*
key
)
{
...
...
@@ -25,13 +27,15 @@ int hash(void* key) {
hash
=
((
addr
&
0x000000FF
)
+
(
addr
&
0x0000FF00
>>
8
)
+
(
addr
&
0x00FF0000
>>
16
)
+
(
addr
&
0xFF000000
>>
24
))
%
0xFF
;
+
(
addr
&
0xFF000000
>>
24
)
+
ap
->
src_port
)
%
0xFF
;
addr
=
(
long
)
ap
->
dst
.
s_addr
;
hash
=
(
hash
+
(
addr
&
0x000000FF
)
+
(
addr
&
0x0000FF00
>>
8
)
+
(
addr
&
0x00FF0000
>>
16
)
+
(
addr
&
0xFF000000
>>
24
))
%
0xFF
;
+
(
addr
&
0xFF000000
>>
24
)
+
ap
->
dst_port
)
%
0xFF
;
return
hash
;
}
...
...
addr_hash.h
View file @
803ee46d
...
...
@@ -12,7 +12,9 @@
#include "hash.h"
typedef
struct
{
unsigned
short
int
src_port
;
struct
in_addr
src
;
unsigned
short
int
dst_port
;
struct
in_addr
dst
;
}
addr_pair
;
...
...
iftop.c
View file @
803ee46d
...
...
@@ -11,6 +11,8 @@
#include <net/if.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <pthread.h>
#include <curses.h>
#include <signal.h>
...
...
@@ -47,8 +49,8 @@ static void finish(int sig) {
/* Only need ethernet and IP headers
.
*/
#define CAPTURE_LENGTH
4
8
/* Only need ethernet and IP headers
(48) + first 2 bytes of tcp/udp header
*/
#define CAPTURE_LENGTH
6
8
void
init_history
()
{
history
=
addr_hash_create
();
...
...
@@ -118,6 +120,39 @@ int in_filter_net(struct in_addr addr) {
return
ret
;
}
/**
* Creates an addr_pair from an ip (and tcp/udp) header, swapping src and dst
* if required
*/
void
assign_addr_pair
(
addr_pair
*
ap
,
struct
ip
*
iptr
,
int
flip
)
{
unsigned
short
int
src_port
=
0
;
unsigned
short
int
dst_port
=
0
;
/* Does this protocol use ports? */
if
(
iptr
->
ip_p
==
SOL_TCP
||
iptr
->
ip_p
==
SOL_UDP
)
{
/* We take a slight liberty here by treating UDP the same as TCP */
/* Find the TCP/UDP header */
struct
tcphdr
*
thdr
=
((
void
*
)
iptr
)
+
iptr
->
ip_hl
*
4
;
src_port
=
ntohs
(
thdr
->
source
);
dst_port
=
ntohs
(
thdr
->
dest
);
}
if
(
flip
==
0
)
{
ap
->
src
=
iptr
->
ip_src
;
ap
->
src_port
=
src_port
;
ap
->
dst
=
iptr
->
ip_dst
;
ap
->
dst_port
=
dst_port
;
}
else
{
ap
->
src
=
iptr
->
ip_dst
;
ap
->
src_port
=
dst_port
;
ap
->
dst
=
iptr
->
ip_src
;
ap
->
dst_port
=
src_port
;
}
}
static
void
handle_ip_packet
(
struct
ip
*
iptr
,
int
hw_dir
)
{
int
direction
=
0
;
/* incoming */
...
...
@@ -131,28 +166,27 @@ static void handle_ip_packet(struct ip* iptr, int hw_dir)
*/
if
(
hw_dir
==
1
)
{
/* Packet leaving this interface. */
ap
.
src
=
iptr
->
ip_src
;
ap
.
dst
=
iptr
->
ip_dst
;
assign_addr_pair
(
&
ap
,
iptr
,
0
);
direction
=
1
;
}
else
if
(
hw_dir
==
0
)
{
/* Packet incoming */
a
p
.
src
=
iptr
->
ip_dst
;
ap
.
dst
=
iptr
->
ip_src
;
a
ssign_addr_pair
(
&
ap
,
iptr
,
1
)
;
direction
=
0
;
}
/*
* This packet is not from or to this interface, or the h/ware
* layer did not give the direction away. Therefore assume
* it was picked up in promisc mode, and account it as incoming.
*/
/*
* This packet is not from or to this interface, or the h/ware
* layer did not give the direction away. Therefore assume
* it was picked up in promisc mode, and account it as incoming.
*/
else
if
(
iptr
->
ip_src
.
s_addr
<
iptr
->
ip_dst
.
s_addr
)
{
a
p
.
src
=
iptr
->
ip_src
;
ap
.
dst
=
iptr
->
ip_dst
;
a
ssign_addr_pair
(
&
ap
,
iptr
,
0
)
;
direction
=
0
;
}
else
{
a
p
.
src
=
iptr
->
ip_dst
;
ap
.
dst
=
iptr
->
ip_src
;
a
ssign_addr_pair
(
&
ap
,
iptr
,
0
)
;
direction
=
0
;
}
}
else
{
...
...
@@ -161,14 +195,13 @@ static void handle_ip_packet(struct ip* iptr, int hw_dir)
*/
if
(
in_filter_net
(
iptr
->
ip_src
)
&
!
in_filter_net
(
iptr
->
ip_dst
))
{
/* out of network */
ap
.
src
=
iptr
->
ip_src
;
ap
.
dst
=
iptr
->
ip_dst
;
assign_addr_pair
(
&
ap
,
iptr
,
0
);
direction
=
1
;
}
else
if
(
in_filter_net
(
iptr
->
ip_dst
)
&
!
in_filter_net
(
iptr
->
ip_src
))
{
/* into network */
a
p
.
src
=
iptr
->
ip_dst
;
ap
.
dst
=
iptr
->
ip_src
;
a
ssign_addr_pair
(
&
ap
,
iptr
,
1
)
;
direction
=
0
;
}
else
{
/* drop packet */
...
...
options.c
View file @
803ee46d
...
...
@@ -18,7 +18,7 @@
options_t
options
;
char
optstr
[]
=
"+i:f:n:dhpb"
;
char
optstr
[]
=
"+i:f:n:dhpb
P
"
;
/* Global options. */
...
...
@@ -66,6 +66,7 @@ static void set_defaults() {
options
.
dnsresolution
=
1
;
options
.
promiscuous
=
0
;
options
.
showbars
=
1
;
options
.
showports
=
OPTION_PORTS_OFF
;
options
.
aggregate
=
OPTION_AGGREGATE_OFF
;
}
...
...
@@ -120,6 +121,7 @@ static void usage(FILE *fp) {
" -f filter code use filter code to select packets to count
\n
"
" (default: none, but only IP packets are counted)
\n
"
" -n net/mask show traffic flows in/out of network
\n
"
" -P show ports as well as hosts
\n
"
"
\n
"
"iftop, version "
IFTOP_VERSION
" copyright (c) 2002 Paul Warren <pdw@ex-parrot.com>
\n
"
);
...
...
@@ -153,6 +155,10 @@ void options_read(int argc, char **argv) {
options
.
promiscuous
=
1
;
break
;
case
'P'
:
options
.
showports
=
OPTION_PORTS_ON
;
break
;
case
'n'
:
set_net_filter
(
optarg
);
break
;
...
...
options.h
View file @
803ee46d
...
...
@@ -16,6 +16,13 @@ typedef enum {
OPTION_AGGREGATE_DEST
}
option_aggregate_t
;
typedef
enum
{
OPTION_PORTS_OFF
,
OPTION_PORTS_AGGSRC
,
OPTION_PORTS_AGGDEST
,
OPTION_PORTS_ON
}
option_port_t
;
typedef
struct
{
/* interface on which to listen */
char
*
interface
;
...
...
@@ -30,6 +37,7 @@ typedef struct {
int
dnsresolution
;
int
promiscuous
;
int
showbars
;
option_port_t
showports
;
option_aggregate_t
aggregate
;
}
options_t
;
...
...
ui.c
View file @
803ee46d
...
...
@@ -10,6 +10,7 @@
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <netdb.h>
#include "addr_hash.h"
#include "iftop.h"
...
...
@@ -199,15 +200,25 @@ void analyse_data() {
ap
=
*
(
addr_pair
*
)
n
->
key
;
/* Aggregate hosts, if required */
if
(
options
.
aggregate
==
OPTION_AGGREGATE_SRC
)
{
ap
.
dst
.
s_addr
=
0
;
}
else
if
(
options
.
aggregate
==
OPTION_AGGREGATE_DEST
)
{
ap
.
src
.
s_addr
=
0
;
}
/* Aggregate ports, if required */
if
(
options
.
showports
==
OPTION_PORTS_AGGSRC
||
options
.
showports
==
OPTION_PORTS_OFF
)
{
ap
.
src_port
=
0
;
}
if
(
options
.
showports
==
OPTION_PORTS_AGGDEST
||
options
.
showports
==
OPTION_PORTS_OFF
)
{
ap
.
dst_port
=
0
;
}
if
(
hash_find
(
screen_hash
,
&
ap
,
(
void
**
)
&
screen_line
)
==
HASH_STATUS_KEY_NOT_FOUND
)
{
screen_line
=
xcalloc
(
1
,
sizeof
*
screen_line
);
screen_line
=
xcalloc
(
1
,
sizeof
*
screen_line
);
hash_insert
(
screen_hash
,
&
ap
,
screen_line
);
screen_line
->
ap
=
ap
;
}
...
...
@@ -233,6 +244,9 @@ void analyse_data() {
}
hash_delete_all
(
screen_hash
);
/**
* Calculate peaks and totals
*/
for
(
i
=
0
;
i
<
HISTORY_LENGTH
;
i
++
)
{
int
j
;
int
ii
=
(
HISTORY_LENGTH
+
history_pos
-
i
)
%
HISTORY_LENGTH
;
...
...
@@ -257,6 +271,48 @@ void analyse_data() {
}
void
sprint_host
(
char
*
line
,
struct
in_addr
*
addr
,
unsigned
int
port
,
int
L
)
{
char
hostname
[
HOSTNAME_LENGTH
];
char
service
[
10
];
struct
servent
*
sent
;
int
left
;
if
(
addr
->
s_addr
==
0
)
{
sprintf
(
hostname
,
" * "
);
}
else
{
if
(
options
.
dnsresolution
)
resolve
(
addr
,
hostname
,
L
);
else
strcpy
(
hostname
,
inet_ntoa
(
*
addr
));
}
left
=
strlen
(
hostname
);
//TODO: Replace this with in-memory hash for speed.
//sent = getservbyport(port, "tcp");
if
(
port
!=
0
)
{
sent
=
NULL
;
if
(
sent
==
NULL
)
{
snprintf
(
service
,
10
,
":%d"
,
port
);
}
else
{
snprintf
(
service
,
10
,
":%s"
,
sent
->
s_name
);
}
}
else
{
service
[
0
]
=
'\0'
;
}
sprintf
(
line
,
"%-*s"
,
L
,
hostname
);
if
(
left
>
(
L
-
strlen
(
service
)))
{
left
=
L
-
strlen
(
service
);
if
(
left
<
0
)
{
left
=
0
;
}
}
sprintf
(
line
+
left
,
"%-*s"
,
L
-
left
,
service
);
}
void
ui_print
()
{
sorted_list_node
*
nn
=
NULL
;
char
hostname
[
HOSTNAME_LENGTH
];
...
...
@@ -313,22 +369,16 @@ void ui_print() {
host_pair_line
*
screen_line
=
(
host_pair_line
*
)
nn
->
data
;
if
(
y
<
LINES
-
4
)
{
fprintf
(
stderr
,
"Drawing at %d
\r\n
"
,
y
);
L
=
(
COLS
-
8
*
HISTORY_DIVISIONS
-
4
)
/
2
;
if
(
L
>
sizeof
hostname
)
{
L
=
sizeof
hostname
;
}
if
(
screen_line
->
ap
.
src
.
s_addr
==
0
)
{
sprintf
(
hostname
,
" * "
);
}
else
{
if
(
options
.
dnsresolution
)
resolve
(
&
(
screen_line
->
ap
.
src
),
hostname
,
L
);
else
strcpy
(
hostname
,
inet_ntoa
(
screen_line
->
ap
.
src
));
}
sprintf
(
line
,
"%-*s"
,
L
,
hostname
);
sprint_host
(
line
,
&
(
screen_line
->
ap
.
src
),
screen_line
->
ap
.
src_port
,
L
);
//sprintf(line, "%-*s", L, hostname);
mvaddstr
(
y
,
x
,
line
);
x
+=
L
;
...
...
@@ -336,16 +386,9 @@ void ui_print() {
mvaddstr
(
y
+
1
,
x
,
" <= "
);
x
+=
4
;
if
(
screen_line
->
ap
.
dst
.
s_addr
==
0
)
{
sprintf
(
hostname
,
" * "
);
}
else
{
if
(
options
.
dnsresolution
)
resolve
(
&
screen_line
->
ap
.
dst
,
hostname
,
L
);
else
strcpy
(
hostname
,
inet_ntoa
(
screen_line
->
ap
.
dst
));
}
sprintf
(
line
,
"%-*s"
,
L
,
hostname
);
sprint_host
(
line
,
&
(
screen_line
->
ap
.
dst
),
screen_line
->
ap
.
dst_port
,
L
);
mvaddstr
(
y
,
x
,
line
);
draw_line_totals
(
y
,
screen_line
);
...
...
@@ -413,6 +456,7 @@ void ui_init() {
screen_list_init
();
screen_hash
=
addr_hash_create
();
}
void
ui_loop
()
{
...
...
@@ -448,6 +492,13 @@ void ui_loop() {
?
OPTION_AGGREGATE_OFF
:
OPTION_AGGREGATE_DEST
;
break
;
case
'P'
:
options
.
showports
=
(
options
.
showports
==
OPTION_PORTS_OFF
)
?
OPTION_PORTS_ON
:
OPTION_PORTS_OFF
;
// Don't tick here, otherwise we get a bogus display
break
;
}
tick
(
0
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment