forked from osmocom/wireshark
- 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:
parent
e18d6c34c9
commit
281e892939
64
follow.c
64
follow.c
|
@ -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];
|
||||
|
|
9
follow.h
9
follow.h
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue