- add ipv6.addr for the source and destination addresses (like ipv4)

- implement the TCP follow feature for TCP over IPv6

svn path=/trunk/; revision=2258
This commit is contained in:
Laurent Deniel 2000-08-11 22:18:22 +00:00
parent e18d6c34c9
commit 281e892939
4 changed files with 91 additions and 33 deletions

View File

@ -1,6 +1,6 @@
/* follow.c
*
* $Id: follow.c,v 1.24 2000/08/09 05:18:37 gram Exp $
* $Id: follow.c,v 1.25 2000/08/11 22:18:12 deniel Exp $
*
* Copyright 1998 Mike Hall <mlh@io.com>
*
@ -48,9 +48,10 @@ FILE* data_out_file;
gboolean incomplete_tcp_stream = FALSE;
static guint32 ip_address[2];
static guint8 ip_address[2][MAX_IPADDR_LEN];
static u_int tcp_port[2];
static u_int bytes_written[2];
static gboolean is_ipv6 = FALSE;
static int check_fragments( int, tcp_stream_chunk * );
static void write_packet_data( int, tcp_stream_chunk *, const char * );
@ -61,9 +62,10 @@ follow_tcp_stats(follow_tcp_stats_t* stats)
int i;
for (i = 0; i < 2 ; i++) {
stats->ip_address[i] = ip_address[i];
memcpy(stats->ip_address[i], ip_address[i], MAX_IPADDR_LEN);
stats->tcp_port[i] = tcp_port[i];
stats->bytes_written[i] = bytes_written[i];
stats->is_ipv6 = is_ipv6;
}
}
@ -74,6 +76,7 @@ follow_tcp_stats(follow_tcp_stats_t* stats)
char*
build_follow_filter( packet_info *pi ) {
char* buf = g_malloc(1024);
int len;
if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4
&& pi->ipproto == 6 ) {
/* TCP over IPv4 */
@ -82,13 +85,26 @@ build_follow_filter( packet_info *pi ) {
ip_to_str( pi->net_src.data),
ip_to_str( pi->net_dst.data),
pi->srcport, pi->destport );
len = 4;
is_ipv6 = FALSE;
}
else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6
&& pi->ipproto == 6 ) {
/* TCP over IPv6 */
sprintf( buf,
"(ipv6.addr eq %s and ipv6.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)",
ip6_to_str((struct e_in6_addr *)pi->net_src.data),
ip6_to_str((struct e_in6_addr *)pi->net_dst.data),
pi->srcport, pi->destport );
len = 16;
is_ipv6 = TRUE;
}
else {
g_free( buf );
return NULL;
}
memcpy(&ip_address[0], pi->net_src.data, sizeof ip_address[0]);
memcpy(&ip_address[1], pi->net_dst.data, sizeof ip_address[1]);
memcpy(ip_address[0], pi->net_src.data, len);
memcpy(ip_address[1], pi->net_dst.data, len);
tcp_port[0] = pi->srcport;
tcp_port[1] = pi->destport;
return buf;
@ -100,15 +116,15 @@ build_follow_filter( packet_info *pi ) {
static tcp_frag *frags[2] = { 0, 0 };
static u_long seq[2];
static guint32 src_addr[2] = { 0, 0 };
static guint8 src_addr[2][MAX_IPADDR_LEN];
static u_int src_port[2] = { 0, 0 };
void
reassemble_tcp( u_long sequence, u_long length, const char* data,
u_long data_length, int synflag, address *net_src,
address *net_dst, u_int srcport, u_int dstport) {
guint32 srcx, dstx;
int src_index, j, first = 0;
guint8 srcx[MAX_IPADDR_LEN], dstx[MAX_IPADDR_LEN];
int src_index, j, first = 0, len;
u_long newseq;
tcp_frag *tmp_frag;
tcp_stream_chunk sc;
@ -117,22 +133,28 @@ reassemble_tcp( u_long sequence, u_long length, const char* data,
/* First, check if this packet should be processed. */
/* We only process IPv4 packets.
XXX - need to make this handle IPv6 as well. */
if (net_src->type != AT_IPv4 || net_dst->type != AT_IPv4)
if ((net_src->type != AT_IPv4 && net_src->type != AT_IPv6) ||
(net_dst->type != AT_IPv4 && net_dst->type != AT_IPv6))
return;
if (net_src->type == AT_IPv4)
len = 4;
else
len = 16;
/* Now check if the packet is for this connection. */
memcpy(&srcx, net_src->data, sizeof srcx);
memcpy(&dstx, net_dst->data, sizeof dstx);
if ((srcx != ip_address[0] && srcx != ip_address[1]) ||
(dstx != ip_address[0] && dstx != ip_address[1]) ||
memcpy(srcx, net_src->data, len);
memcpy(dstx, net_dst->data, len);
if ((memcmp(srcx, ip_address[0], len) != 0 &&
memcmp(srcx, ip_address[1], len) != 0) ||
(memcmp(dstx, ip_address[0], len) != 0 &&
memcmp(dstx, ip_address[1], len) != 0) ||
(srcport != tcp_port[0] && srcport != tcp_port[1]) ||
(dstport != tcp_port[0] && dstport != tcp_port[1]))
return;
/* Initialize our stream chunk. This data gets written to disk. */
sc.src_addr = srcx;
memcpy(sc.src_addr, srcx, len);
sc.src_port = srcport;
sc.dlen = data_length;
@ -140,7 +162,7 @@ reassemble_tcp( u_long sequence, u_long length, const char* data,
(Yes, we have to check both source IP and port; the connection
might be between two different ports on the same machine.) */
for( j=0; j<2; j++ ) {
if( src_addr[j] == srcx && src_port[j] == srcport ) {
if (memcmp(src_addr[j], srcx, len) == 0 && src_port[j] == srcport ) {
src_index = j;
}
}
@ -148,8 +170,8 @@ reassemble_tcp( u_long sequence, u_long length, const char* data,
if( src_index < 0 ) {
/* assign it to a src_index and get going */
for( j=0; j<2; j++ ) {
if( src_addr[j] == 0 ) {
src_addr[j] = srcx;
if( src_port[j] == 0 ) {
memcpy(src_addr[j], srcx, len);
src_port[j] = srcport;
src_index = j;
first = 1;
@ -275,9 +297,9 @@ reset_tcp_reassembly() {
incomplete_tcp_stream = FALSE;
for( i=0; i<2; i++ ) {
seq[i] = 0;
src_addr[i] = 0;
memset(src_addr[i], '\0', MAX_IPADDR_LEN);
src_port[i] = 0;
ip_address[i] = 0;
memset(ip_address[i], '\0', MAX_IPADDR_LEN);
tcp_port[i] = 0;
bytes_written[i] = 0;
current = frags[i];

View File

@ -1,6 +1,6 @@
/* follow.h
*
* $Id: follow.h,v 1.9 2000/08/09 05:18:38 gram Exp $
* $Id: follow.h,v 1.10 2000/08/11 22:18:13 deniel Exp $
*
* Copyright 1998 Mike Hall <mlh@io.com>
*
@ -30,6 +30,8 @@
#include "packet.h"
#define MAX_IPADDR_LEN 16
extern gboolean incomplete_tcp_stream;
typedef struct _tcp_frag {
@ -41,7 +43,7 @@ typedef struct _tcp_frag {
} tcp_frag;
typedef struct _tcp_stream_chunk {
guint32 src_addr;
guint8 src_addr[MAX_IPADDR_LEN];
guint16 src_port;
guint32 dlen;
} tcp_stream_chunk;
@ -52,9 +54,10 @@ void reassemble_tcp( u_long, u_long, const char*, u_long, int,
void reset_tcp_reassembly( void );
typedef struct {
guint32 ip_address[2];
guint8 ip_address[2][MAX_IPADDR_LEN];
guint32 tcp_port[2];
unsigned int bytes_written[2];
gboolean is_ipv6;
} follow_tcp_stats_t;
void follow_tcp_stats(follow_tcp_stats_t* stats);

View File

@ -1,6 +1,6 @@
/* follow_dlg.c
*
* $Id: follow_dlg.c,v 1.4 2000/08/11 13:33:12 deniel Exp $
* $Id: follow_dlg.c,v 1.5 2000/08/11 22:18:22 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -59,6 +59,7 @@
#include "gtkglobals.h"
#include "main.h"
#include "simple_dialog.h"
#include "packet-ipv6.h"
#include "prefs.h"
#include "resolv.h"
#include "util.h"
@ -87,6 +88,7 @@ typedef struct {
GtkWidget *ebcdic_bt;
GtkWidget *hexdump_bt;
GtkWidget *follow_save_as_w;
gboolean is_ipv6;
} follow_info_t;
static void follow_destroy_cb(GtkWidget * win, gpointer data);
@ -224,11 +226,25 @@ follow_stream_cb(GtkWidget * w, gpointer data)
/* Stream to show */
follow_tcp_stats(&stats);
hostname0 = get_hostname(stats.ip_address[0]);
hostname1 = get_hostname(stats.ip_address[1]);
if (stats.is_ipv6) {
struct e_in6_addr ipaddr;
memcpy(&ipaddr, stats.ip_address[0], 16);
hostname0 = get_hostname6(&ipaddr);
memcpy(&ipaddr, stats.ip_address[0], 16);
hostname1 = get_hostname6(&ipaddr);
} else {
guint32 ipaddr;
memcpy(&ipaddr, stats.ip_address[0], 4);
hostname0 = get_hostname(ipaddr);
memcpy(&ipaddr, stats.ip_address[1], 4);
hostname1 = get_hostname(ipaddr);
}
port0 = get_tcp_port(stats.tcp_port[0]);
port1 = get_tcp_port(stats.tcp_port[1]);
follow_info->is_ipv6 = stats.is_ipv6;
stream_om = gtk_option_menu_new();
stream_menu = gtk_menu_new();
@ -406,25 +422,28 @@ follow_read_stream(follow_info_t *follow_info,
void *arg)
{
tcp_stream_chunk sc;
int bcount;
guint32 client_addr = 0;
int bcount, iplen;
guint8 client_addr[MAX_IPADDR_LEN];
guint16 client_port = 0;
gboolean is_server;
guint16 current_pos, global_client_pos = 0, global_server_pos = 0;
guint16 *global_pos;
gboolean skip;
iplen = (follow_info->is_ipv6) ? 16 : 4;
data_out_file = fopen(follow_info->data_out_filename, "rb");
if (data_out_file) {
char buffer[FLT_BUF_SIZE];
int nchars;
while (fread(&sc, 1, sizeof(sc), data_out_file)) {
if (client_addr == 0) {
client_addr = sc.src_addr;
if (client_port == 0) {
memcpy(client_addr, sc.src_addr, iplen);
client_port = sc.src_port;
}
skip = FALSE;
if (client_addr == sc.src_addr && client_port == sc.src_port) {
if (memcmp(client_addr, sc.src_addr, iplen) == 0 &&
client_port == sc.src_port) {
is_server = FALSE;
global_pos = &global_client_pos;
if (follow_info->show_stream == FROM_SERVER) {

View File

@ -1,7 +1,7 @@
/* packet-ipv6.c
* Routines for IPv6 packet disassembly
*
* $Id: packet-ipv6.c,v 1.41 2000/08/08 21:49:13 gram Exp $
* $Id: packet-ipv6.c,v 1.42 2000/08/11 22:18:13 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -67,6 +67,7 @@ static int hf_ipv6_nxt = -1;
static int hf_ipv6_hlim = -1;
static int hf_ipv6_src = -1;
static int hf_ipv6_dst = -1;
static int hf_ipv6_addr = -1;
#ifdef TEST_FINALHDR
static int hf_ipv6_final = -1;
#endif
@ -296,6 +297,8 @@ dissect_ipv6(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
memcpy(&ipv6, (void *) &pd[offset], sizeof(ipv6));
pi.ipproto = ipv6.ip6_nxt; /* XXX make work TCP follow (ipproto = 6) */
SET_ADDRESS(&pi.net_src, AT_IPv6, 16, &pd[offset + IP6H_SRC]);
SET_ADDRESS(&pi.src, AT_IPv6, 16, &pd[offset + IP6H_SRC]);
SET_ADDRESS(&pi.net_dst, AT_IPv6, 16, &pd[offset + IP6H_DST]);
@ -340,6 +343,13 @@ dissect_ipv6(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
offset + offsetof(struct ip6_hdr, ip6_hlim), 1,
ipv6.ip6_hlim);
proto_tree_add_ipv6_hidden(ipv6_tree, hf_ipv6_addr, NullTVB,
offset + offsetof(struct ip6_hdr, ip6_src), 16,
ipv6.ip6_src.s6_addr8);
proto_tree_add_ipv6_hidden(ipv6_tree, hf_ipv6_addr, NullTVB,
offset + offsetof(struct ip6_hdr, ip6_dst), 16,
ipv6.ip6_dst.s6_addr8);
proto_tree_add_ipv6_format(ipv6_tree, hf_ipv6_src, NullTVB,
offset + offsetof(struct ip6_hdr, ip6_src), 16,
(guint8 *)&ipv6.ip6_src,
@ -457,6 +467,10 @@ proto_register_ipv6(void)
{ "Destination", "ipv6.dst",
FT_IPv6, BASE_NONE, NULL, 0x0,
"Destination IPv6 Address" }},
{ &hf_ipv6_addr,
{ "Address", "ipv6.addr",
FT_IPv6, BASE_NONE, NULL, 0x0,
"Source or Destination IPv6 Address" }},
#ifdef TEST_FINALHDR
{ &hf_ipv6_final,
{ "Final next header", "ipv6.final",