Ethereal-dev: Re: [ethereal-dev] Keeping state for SMB decodes
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Sun, 17 Oct 1999 01:19:04 -0700
I've attached a patch, and the files "conversation.c" and "conversation.h", as per my previous message.
? errs
? file.c.SAVE
? conversation.c
? conversation.h
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/ethereal/Makefile.am,v
retrieving revision 1.88
diff -c -r1.88 Makefile.am
*** Makefile.am 1999/10/15 17:00:46 1.88
--- Makefile.am 1999/10/17 08:02:58
***************
*** 39,44 ****
--- 39,46 ----
colors.h \
column.c \
column.h \
+ conversation.c \
+ conversation.h \
dfilter-int.h \
dfilter-grammar.y \
dfilter-scanner.l \
Index: file.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/file.c,v
retrieving revision 1.108
diff -c -r1.108 file.c
*** file.c 1999/10/12 05:00:47 1.108
--- file.c 1999/10/17 08:03:02
***************
*** 83,89 ****
--- 83,96 ----
#include "gtk/proto_draw.h"
#include "dfilter.h"
#include "timestamp.h"
+ #include "conversation.h"
+ #ifndef __RESOLV_H__
+ #include "resolv.h"
+ #endif
+
+ #include "packet-ipv6.h"
+
#include "packet-ncp.h"
extern GtkWidget *packet_list, *prog_bar, *info_bar, *byte_view, *tree_view;
***************
*** 130,135 ****
--- 137,145 ----
and fill in the information for this file. */
close_cap_file(cf, info_bar, file_ctx);
+ /* Initialize the table of conversations. */
+ conversation_init();
+
/* Initialize protocol-specific variables */
ncp_init_protocol();
smb_init_protocol();
***************
*** 524,537 ****
/* To do: Add check_col checks to the col_add* routines */
static void
! col_add_abs_time(frame_data *fd, gint el)
{
struct tm *tmp;
time_t then;
then = fd->abs_secs;
tmp = localtime(&then);
! col_add_fstr(fd, el, "%02d:%02d:%02d.%04ld",
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
--- 534,547 ----
/* To do: Add check_col checks to the col_add* routines */
static void
! col_set_abs_time(frame_data *fd, int col)
{
struct tm *tmp;
time_t then;
then = fd->abs_secs;
tmp = localtime(&then);
! snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%02d:%02d:%02d.%04ld",
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
***************
*** 539,592 ****
}
static void
! col_add_rel_time(frame_data *fd, gint el)
{
! col_add_fstr(fd, el, "%d.%06d", fd->rel_secs, fd->rel_usecs);
}
static void
! col_add_delta_time(frame_data *fd, gint el)
{
! col_add_fstr(fd, el, "%d.%06d", fd->del_secs, fd->del_usecs);
}
/* Add "command-line-specified" time. */
static void
! col_add_cls_time(frame_data *fd)
{
switch (timestamp_type) {
case ABSOLUTE:
! col_add_abs_time(fd, COL_CLS_TIME);
break;
case RELATIVE:
! col_add_rel_time(fd, COL_CLS_TIME);
break;
case DELTA:
! col_add_delta_time(fd, COL_CLS_TIME);
break;
}
}
static void
fill_in_columns(frame_data *fd)
{
! if (check_col(fd, COL_NUMBER))
! col_add_fstr(fd, COL_NUMBER, "%u", fd->num);
! /* Set any time stamp columns. */
! if (check_col(fd, COL_CLS_TIME))
! col_add_cls_time(fd);
! if (check_col(fd, COL_ABS_TIME))
! col_add_abs_time(fd, COL_ABS_TIME);
! if (check_col(fd, COL_REL_TIME))
! col_add_rel_time(fd, COL_REL_TIME);
! if (check_col(fd, COL_DELTA_TIME))
! col_add_delta_time(fd, COL_DELTA_TIME);
! if (check_col(fd, COL_PACKET_LENGTH))
! col_add_fstr(fd, COL_PACKET_LENGTH, "%d", fd->pkt_len);
}
static void
--- 549,722 ----
}
static void
! col_set_rel_time(frame_data *fd, int col)
{
! snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->rel_secs,
! fd->rel_usecs);
}
static void
! col_set_delta_time(frame_data *fd, int col)
{
! snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->del_secs,
! fd->del_usecs);
}
/* Add "command-line-specified" time. */
static void
! col_set_cls_time(frame_data *fd, int col)
{
switch (timestamp_type) {
case ABSOLUTE:
! col_set_abs_time(fd, col);
break;
case RELATIVE:
! col_set_rel_time(fd, col);
break;
case DELTA:
! col_set_delta_time(fd, col);
break;
}
}
static void
+ col_set_addr(frame_data *fd, int col, address *addr, gboolean is_res)
+ {
+ u_int ipv4_addr;
+ struct e_in6_addr ipv6_addr;
+
+ switch (addr->type) {
+
+ case AT_ETHER:
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_ether_name(addr->data), COL_MAX_LEN);
+ else
+ strncpy(fd->cinfo->col_data[col], ether_to_str(addr->data), COL_MAX_LEN);
+ break;
+
+ case AT_IPv4:
+ memcpy(&ipv4_addr, addr->data, sizeof ipv4_addr);
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_hostname(ipv4_addr), COL_MAX_LEN);
+ else
+ strncpy(fd->cinfo->col_data[col], ip_to_str(addr->data), COL_MAX_LEN);
+ break;
+
+ case AT_IPv6:
+ memcpy(&ipv6_addr.s6_addr, addr->data, sizeof ipv6_addr.s6_addr);
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_hostname6(&ipv6_addr), COL_MAX_LEN);
+ else
+ strncpy(fd->cinfo->col_data[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
+ break;
+
+ case AT_IPX:
+ strncpy(fd->cinfo->col_data[col],
+ ipx_addr_to_str(pntohl(&addr->data[0]), &addr->data[4]), COL_MAX_LEN);
+ break;
+
+ default:
+ break;
+ }
+ fd->cinfo->col_data[col][COL_MAX_LEN - 1] = '\0';
+ }
+
+ static void
fill_in_columns(frame_data *fd)
{
! int i;
!
! for (i = 0; i < fd->cinfo->num_cols; i++) {
! switch (fd->cinfo->col_fmt[i]) {
!
! case COL_NUMBER:
! snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%u", fd->num);
! break;
!
! case COL_CLS_TIME:
! col_set_cls_time(fd, i);
! break;
!
! case COL_ABS_TIME:
! col_set_abs_time(fd, i);
! break;
!
! case COL_REL_TIME:
! col_set_rel_time(fd, i);
! break;
!
! case COL_DELTA_TIME:
! col_set_delta_time(fd, i);
! break;
!
! case COL_DEF_SRC:
! case COL_RES_SRC: /* COL_DEF_SRC is currently just like COL_RES_SRC */
! col_set_addr(fd, i, &pi.src, TRUE);
! break;
!
! case COL_UNRES_SRC:
! col_set_addr(fd, i, &pi.src, FALSE);
! break;
!
! case COL_DEF_DL_SRC:
! case COL_RES_DL_SRC:
! col_set_addr(fd, i, &pi.dl_src, TRUE);
! break;
!
! case COL_UNRES_DL_SRC:
! col_set_addr(fd, i, &pi.dl_src, FALSE);
! break;
!
! case COL_DEF_NET_SRC:
! case COL_RES_NET_SRC:
! col_set_addr(fd, i, &pi.net_src, TRUE);
! break;
!
! case COL_UNRES_NET_SRC:
! col_set_addr(fd, i, &pi.net_src, FALSE);
! break;
!
! case COL_DEF_DST:
! case COL_RES_DST: /* COL_DEF_DST is currently just like COL_RES_DST */
! col_set_addr(fd, i, &pi.dst, TRUE);
! break;
!
! case COL_UNRES_DST:
! col_set_addr(fd, i, &pi.dst, FALSE);
! break;
! case COL_DEF_DL_DST:
! case COL_RES_DL_DST:
! col_set_addr(fd, i, &pi.dl_dst, TRUE);
! break;
! case COL_UNRES_DL_DST:
! col_set_addr(fd, i, &pi.dl_dst, FALSE);
! break;
!
! case COL_DEF_NET_DST:
! case COL_RES_NET_DST:
! col_set_addr(fd, i, &pi.net_dst, TRUE);
! break;
!
! case COL_UNRES_NET_DST:
! col_set_addr(fd, i, &pi.net_dst, FALSE);
! break;
!
! case COL_PROTOCOL: /* currently done by dissectors */
! case COL_INFO: /* currently done by dissectors */
! break;
!
! case COL_PACKET_LENGTH:
! snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%d", fd->pkt_len);
! break;
!
! case NUM_COL_FMTS: /* keep compiler happy - shouldn't get here */
! break;
! }
! }
}
static void
***************
*** 1072,1084 ****
/* There are columns that show the time in the "command-line-specified"
format; update them. */
for (i = 0; i < cf->cinfo.num_cols; i++) {
- cf->cinfo.col_data[i][0] = '\0';
- }
- col_add_cls_time(fd);
- for (i = 0; i < cf->cinfo.num_cols; i++) {
if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) {
/* This is one of the columns that shows the time in
"command-line-specified" format; update it. */
gtk_clist_set_text(GTK_CLIST(packet_list), fd->row, i,
cf->cinfo.col_data[i]);
}
--- 1202,1212 ----
/* There are columns that show the time in the "command-line-specified"
format; update them. */
for (i = 0; i < cf->cinfo.num_cols; i++) {
if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) {
/* This is one of the columns that shows the time in
"command-line-specified" format; update it. */
+ cf->cinfo.col_data[i][0] = '\0';
+ col_set_cls_time(fd, i);
gtk_clist_set_text(GTK_CLIST(packet_list), fd->row, i,
cf->cinfo.col_data[i]);
}
Index: follow.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/follow.c,v
retrieving revision 1.15
diff -c -r1.15 follow.c
*** follow.c 1999/09/09 02:42:25 1.15
--- follow.c 1999/10/17 08:03:02
***************
*** 50,56 ****
gboolean incomplete_tcp_stream = FALSE;
! static u_long ip_address[2];
static u_int tcp_port[2];
static int check_fragments( int );
--- 50,56 ----
gboolean incomplete_tcp_stream = FALSE;
! static guint32 ip_address[2];
static u_int tcp_port[2];
static int check_fragments( int );
***************
*** 63,82 ****
char*
build_follow_filter( packet_info *pi ) {
char* buf = malloc(1024);
! if( pi->ipproto == 6 ) {
! /* TCP */
sprintf( buf,
"(ip.addr eq %s and ip.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)",
! ip_to_str( (guint8 *) &pi->ip_src),
! ip_to_str( (guint8 *) &pi->ip_dst),
pi->srcport, pi->destport );
}
else {
free( buf );
return NULL;
}
! ip_address[0] = pi->ip_src;
! ip_address[1] = pi->ip_dst;
tcp_port[0] = pi->srcport;
tcp_port[1] = pi->destport;
return buf;
--- 63,83 ----
char*
build_follow_filter( packet_info *pi ) {
char* buf = malloc(1024);
! if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4
! && pi->ipproto == 6 ) {
! /* TCP over IPv4 */
sprintf( buf,
"(ip.addr eq %s and ip.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)",
! ip_to_str( pi->net_src.data),
! ip_to_str( pi->net_dst.data),
pi->srcport, pi->destport );
}
else {
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]);
tcp_port[0] = pi->srcport;
tcp_port[1] = pi->destport;
return buf;
***************
*** 88,103 ****
static tcp_frag *frags[2] = { 0, 0};
static u_long seq[2];
! static u_long src[2] = { 0, 0 };
void
! reassemble_tcp( u_long sequence, u_long length, const char* data, u_long data_length, int synflag, u_long srcx, u_long dstx, u_int srcport, u_int dstport ) {
int src_index, j, first = 0;
u_long newseq;
tcp_frag *tmp_frag;
src_index = -1;
/* first check if this packet should be processed */
if ((srcx != ip_address[0] && srcx != ip_address[1]) ||
(dstx != ip_address[0] && dstx != ip_address[1]) ||
(srcport != tcp_port[0] && srcport != tcp_port[1]) ||
--- 89,111 ----
static tcp_frag *frags[2] = { 0, 0};
static u_long seq[2];
! static guint32 src[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;
u_long newseq;
tcp_frag *tmp_frag;
src_index = -1;
/* first check if this packet should be processed */
+ if (net_src->type != AT_IPv4 || net_dst->type != AT_IPv4)
+ return;
+ 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]) ||
(srcport != tcp_port[0] && srcport != tcp_port[1]) ||
Index: follow.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/follow.h,v
retrieving revision 1.5
diff -c -r1.5 follow.h
*** follow.h 1999/07/31 13:55:16 1.5
--- follow.h 1999/10/17 08:03:02
***************
*** 42,48 ****
char* build_follow_filter( packet_info * );
void reassemble_tcp( u_long, u_long, const char*, u_long, int,
! u_long, u_long, u_int, u_int );
void reset_tcp_reassembly( void );
#endif
--- 42,48 ----
char* build_follow_filter( packet_info * );
void reassemble_tcp( u_long, u_long, const char*, u_long, int,
! address *, address *, u_int, u_int );
void reset_tcp_reassembly( void );
#endif
Index: packet-eth.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-eth.c,v
retrieving revision 1.20
diff -c -r1.20 packet-eth.c
*** packet-eth.c 1999/10/12 06:20:04 1.20
--- packet-eth.c 1999/10/17 08:03:03
***************
*** 118,131 ****
return;
}
! if (check_col(fd, COL_RES_DL_DST))
! col_add_str(fd, COL_RES_DL_DST, get_ether_name((u_char *)&pd[offset+0]));
! if (check_col(fd, COL_RES_DL_SRC))
! col_add_str(fd, COL_RES_DL_SRC, get_ether_name((u_char *)&pd[offset+6]));
! if (check_col(fd, COL_UNRES_DL_DST))
! col_add_str(fd, COL_UNRES_DL_DST, ether_to_str((u_char *)&pd[offset+0]));
! if (check_col(fd, COL_UNRES_DL_SRC))
! col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str((u_char *)&pd[offset+6]));
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "Ethernet");
--- 118,128 ----
return;
}
! SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &pd[offset+6]);
! SET_ADDRESS(&pi.src, AT_ETHER, 6, &pd[offset+6]);
! SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &pd[offset+0]);
! SET_ADDRESS(&pi.dst, AT_ETHER, 6, &pd[offset+0]);
!
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "Ethernet");
Index: packet-fddi.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-fddi.c,v
retrieving revision 1.23
diff -c -r1.23 packet-fddi.c
*** packet-fddi.c 1999/10/16 19:36:56 1.23
--- packet-fddi.c 1999/10/17 08:03:03
***************
*** 254,260 ****
proto_tree *fh_tree;
proto_item *ti;
gchar *fc_str;
! u_char src[6], dst[6];
u_char src_swapped[6], dst_swapped[6];
if (fd->cap_len < FDDI_HEADER_SIZE) {
--- 254,260 ----
proto_tree *fh_tree;
proto_item *ti;
gchar *fc_str;
! static u_char src[6], dst[6];
u_char src_swapped[6], dst_swapped[6];
if (fd->cap_len < FDDI_HEADER_SIZE) {
***************
*** 275,288 ****
fc = (int) pd[FDDI_P_FC];
fc_str = fddifc_to_str(fc);
! if (check_col(fd, COL_RES_DL_SRC))
! col_add_str(fd, COL_RES_DL_SRC, get_ether_name(src));
! if (check_col(fd, COL_RES_DL_DST))
! col_add_str(fd, COL_RES_DL_DST, get_ether_name(dst));
! if (check_col(fd, COL_UNRES_DL_SRC))
! col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str(src));
! if (check_col(fd, COL_UNRES_DL_DST))
! col_add_str(fd, COL_UNRES_DL_DST, ether_to_str(dst));
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "FDDI");
if (check_col(fd, COL_INFO))
--- 275,287 ----
fc = (int) pd[FDDI_P_FC];
fc_str = fddifc_to_str(fc);
! /* XXX - copy them to some buffer associated with "pi", rather than
! just making "src" and "dst" static? */
! SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &src[0]);
! SET_ADDRESS(&pi.src, AT_ETHER, 6, &src[0]);
! SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &dst[0]);
! SET_ADDRESS(&pi.dst, AT_ETHER, 6, &dst[0]);
!
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "FDDI");
if (check_col(fd, COL_INFO))
Index: packet-ip.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-ip.c,v
retrieving revision 1.56
diff -c -r1.56 packet-ip.c
*** packet-ip.c 1999/10/16 20:59:03 1.56
--- packet-ip.c 1999/10/17 08:03:07
***************
*** 173,178 ****
--- 173,192 ----
guint32 ip_dst;
} e_ip;
+ /* Offsets of fields within an IP header. */
+ #define IPH_V_HL 0
+ #define IPH_TOS 1
+ #define IPH_LEN 2
+ #define IPH_ID 4
+ #define IPH_TTL 6
+ #define IPH_OFF 8
+ #define IPH_P 9
+ #define IPH_SUM 10
+ #define IPH_SRC 12
+ #define IPH_DST 16
+
+ #define IPH_MIN_LEN 20
+
/* IP flags. */
#define IP_CE 0x8000 /* Flag: "Congestion" */
#define IP_DF 0x4000 /* Flag: "Don't Fragment" */
***************
*** 721,735 ****
ipprotostr(iph.ip_p), iph.ip_p);
}
- if (check_col(fd, COL_RES_NET_SRC))
- col_add_str(fd, COL_RES_NET_SRC, get_hostname(iph.ip_src));
- if (check_col(fd, COL_UNRES_NET_SRC))
- col_add_str(fd, COL_UNRES_NET_SRC, ip_to_str((guint8 *) &iph.ip_src));
- if (check_col(fd, COL_RES_NET_DST))
- col_add_str(fd, COL_RES_NET_DST, get_hostname(iph.ip_dst));
- if (check_col(fd, COL_UNRES_NET_DST))
- col_add_str(fd, COL_UNRES_NET_DST, ip_to_str((guint8 *) &iph.ip_dst));
-
if (tree) {
switch (IPTOS_TOS(iph.ip_tos)) {
--- 735,740 ----
***************
*** 823,830 ****
pi.ipproto = iph.ip_p;
pi.iplen = iph.ip_len;
pi.iphdrlen = lo_nibble(iph.ip_v_hl);
! pi.ip_src = iph.ip_src;
! pi.ip_dst = iph.ip_dst;
/* Skip over header + options */
offset += hlen;
--- 828,837 ----
pi.ipproto = iph.ip_p;
pi.iplen = iph.ip_len;
pi.iphdrlen = lo_nibble(iph.ip_v_hl);
! SET_ADDRESS(&pi.net_src, AT_IPv4, 4, &pd[offset + IPH_SRC]);
! SET_ADDRESS(&pi.src, AT_IPv4, 4, &pd[offset + IPH_SRC]);
! SET_ADDRESS(&pi.net_dst, AT_IPv4, 4, &pd[offset + IPH_DST]);
! SET_ADDRESS(&pi.dst, AT_IPv4, 4, &pd[offset + IPH_DST]);
/* Skip over header + options */
offset += hlen;
Index: packet-ipv6.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-ipv6.c,v
retrieving revision 1.23
diff -c -r1.23 packet-ipv6.c
*** packet-ipv6.c 1999/10/15 16:59:12 1.23
--- packet-ipv6.c 1999/10/17 08:03:08
***************
*** 252,267 ****
memcpy(&ipv6, (void *) &pd[offset], sizeof(ipv6));
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "IPv6");
- if (check_col(fd, COL_RES_NET_SRC))
- col_add_str(fd, COL_RES_NET_SRC, get_hostname6(&ipv6.ip6_src));
- if (check_col(fd, COL_UNRES_NET_SRC))
- col_add_str(fd, COL_UNRES_NET_SRC, ip6_to_str(&ipv6.ip6_src));
- if (check_col(fd, COL_RES_NET_DST))
- col_add_str(fd, COL_RES_NET_DST, get_hostname6(&ipv6.ip6_dst));
- if (check_col(fd, COL_UNRES_NET_DST))
- col_add_str(fd, COL_UNRES_NET_DST, ip6_to_str(&ipv6.ip6_dst));
if (tree) {
/* !!! specify length */
--- 252,264 ----
memcpy(&ipv6, (void *) &pd[offset], sizeof(ipv6));
+ 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]);
+ SET_ADDRESS(&pi.dst, AT_IPv6, 16, &pd[offset + IP6H_DST]);
+
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "IPv6");
if (tree) {
/* !!! specify length */
Index: packet-ipv6.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-ipv6.h,v
retrieving revision 1.6
diff -c -r1.6 packet-ipv6.h
*** packet-ipv6.h 1999/10/14 05:41:30 1.6
--- packet-ipv6.h 1999/10/17 08:03:08
***************
*** 86,91 ****
--- 86,101 ----
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+ /* Offsets of fields within an IPv6 header. */
+ #define IP6H_CTL 0
+ #define IP6H_CTL_FLOW 0
+ #define IP6H_CTL_PLEN 4
+ #define IP6H_CTL_NXT 6
+ #define IP6H_CTL_HLIM 7
+ #define IP6H_CTL_VFC 0
+ #define IP6H_SRC 8
+ #define IP6H_DST 24
+
#define IPV6_VERSION 0x60
#define IPV6_VERSION_MASK 0xf0
Index: packet-ipx.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-ipx.c,v
retrieving revision 1.28
diff -c -r1.28 packet-ipx.c
*** packet-ipx.c 1999/10/12 06:20:10 1.28
--- packet-ipx.c 1999/10/17 08:03:10
***************
*** 256,262 ****
ipx_length = pntohs(&pd[offset+2]);
/* Length of IPX datagram plus headers above it. */
! len = ipx_length + offset;
/* Set the payload and captured-payload lengths to the minima of
(the IPX length plus the length of the headers above it) and
--- 256,262 ----
ipx_length = pntohs(&pd[offset+2]);
/* Length of IPX datagram plus headers above it. */
! len = ipx_length + offset;
/* Set the payload and captured-payload lengths to the minima of
(the IPX length plus the length of the headers above it) and
***************
*** 266,277 ****
if (pi.captured_len > len)
pi.captured_len = len;
! if (check_col(fd, COL_RES_DL_DST))
! col_add_str(fd, COL_RES_DL_DST,
! ipx_addr_to_str(pntohl(ipx_dnet), ipx_dnode));
! if (check_col(fd, COL_RES_DL_SRC))
! col_add_str(fd, COL_RES_DL_SRC,
! ipx_addr_to_str(pntohl(ipx_snet), ipx_snode));
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "IPX");
--- 266,275 ----
if (pi.captured_len > len)
pi.captured_len = len;
! SET_ADDRESS(&pi.net_src, AT_IPX, 10, &pd[offset+18]);
! SET_ADDRESS(&pi.src, AT_IPX, 10, &pd[offset+18]);
! SET_ADDRESS(&pi.net_dst, AT_IPX, 10, &pd[offset+6]);
! SET_ADDRESS(&pi.dst, AT_IPX, 10, &pd[offset+6]);
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "IPX");
Index: packet-smb.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-smb.c,v
retrieving revision 1.30
diff -c -r1.30 packet-smb.c
*** packet-smb.c 1999/10/16 20:26:37 1.30
--- packet-smb.c 1999/10/17 08:03:26
***************
*** 42,47 ****
--- 42,48 ----
#include <string.h>
#include <glib.h>
#include "packet.h"
+ #include "conversation.h"
#include "smb.h"
#include "alignment.h"
***************
*** 60,67 ****
int smb_packet_init_count = 200;
struct smb_request_key {
! guint32 ip_src, ip_dst;
! guint16 port_src, port_dst;
guint16 mid;
};
--- 61,67 ----
int smb_packet_init_count = 200;
struct smb_request_key {
! guint32 conversation;
guint16 mid;
};
***************
*** 74,97 ****
GMemChunk *smb_request_keys = NULL;
GMemChunk *smb_request_vals = NULL;
/* Hash Functions */
gint
smb_equal(gconstpointer v, gconstpointer w)
{
struct smb_request_key *v1 = (struct smb_request_key *)v;
struct smb_request_key *v2 = (struct smb_request_key *)w;
! #if defined(DEBUG_SMB_HASH)
! printf("Comparing %08X:%08X:%d:%d:%d\n and %08X:%08X:%d:%d:%d\n",
! v1 -> ip_src, v1 -> ip_dst, v1 -> port_src, v1 -> port_dst, v1 -> mid,
! v2 -> ip_src, v2 -> ip_dst, v2 -> port_src, v2 -> port_dst, v2 -> mid);
! #endif
!
! if (v1 -> ip_src == v2 -> ip_src &&
! v1 -> ip_dst == v2 -> ip_dst &&
! v1 -> port_src == v2 -> port_src &&
! v1 -> port_dst == v2 -> port_dst &&
! v1 -> mid == v2 -> mid) {
return 1;
--- 74,96 ----
GMemChunk *smb_request_keys = NULL;
GMemChunk *smb_request_vals = NULL;
+ #define DEBUG_SMB_HASH
+
/* Hash Functions */
gint
smb_equal(gconstpointer v, gconstpointer w)
{
struct smb_request_key *v1 = (struct smb_request_key *)v;
struct smb_request_key *v2 = (struct smb_request_key *)w;
+
+ #if defined(DEBUG_SMB_HASH)
+ printf("Comparing %08X:%u\n and %08X:%u\n",
+ v1 -> conversation, v1 -> mid,
+ v2 -> conversation, v2 -> mid);
+ #endif
! if (v1 -> conversation == v2 -> conversation &&
! v1 -> mid == v2 -> mid) {
return 1;
***************
*** 106,117 ****
struct smb_request_key *key = (struct smb_request_key *)v;
guint val;
! val = key -> ip_src + key -> ip_dst + key -> port_src + key -> port_dst +
! key -> mid;
! #if defined(DEBUG_SMB_HASH)
! printf("SMB Hash calculated as %d\n", val);
! #endif
return val;
--- 105,115 ----
struct smb_request_key *key = (struct smb_request_key *)v;
guint val;
! val = key -> conversation + key -> mid;
! #if defined(DEBUG_SMB_HASH)
! printf("SMB Hash calculated as %u\n", val);
! #endif
return val;
***************
*** 124,132 ****
void
smb_init_protocol(void)
{
! #if defined(DEBUG_SMB_HASH)
printf("Initializing SMB hashtable area\n");
! #endif
if (smb_request_hash)
g_hash_table_destroy(smb_request_hash);
--- 122,130 ----
void
smb_init_protocol(void)
{
! #if defined(DEBUG_SMB_HASH)
printf("Initializing SMB hashtable area\n");
! #endif
if (smb_request_hash)
g_hash_table_destroy(smb_request_hash);
***************
*** 8179,8184 ****
--- 8177,8183 ----
return trans2_cmd_names[code];
}
+
void
dissect_transact2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
***************
*** 8211,8241 ****
guint16 DataCount;
guint16 ByteCount;
const char *TransactName;
struct smb_request_key request_key, *new_request_key;
struct smb_request_val *request_val;
/*
! * Check for and insert entry in hash table if does not exist
! * Since we want request and response to hash to the same, we make
! * sure that src and dst swapped for response
*/
! request_key.ip_src = ((dirn == 0) ? pi.ip_src : pi.ip_dst);
! request_key.ip_dst = ((dirn == 0) ? pi.ip_dst : pi.ip_src);
! request_key.port_src = ((dirn == 0) ? pi.srcport : pi.destport);
! request_key.port_dst = ((dirn == 0) ? pi.destport : pi.srcport);
! request_key.mid = si.mid;
request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
if (!request_val) { /* Create one */
new_request_key = g_mem_chunk_alloc(smb_request_keys);
! new_request_key -> ip_src = ((dirn == 0) ? pi.ip_src : pi.ip_dst);
! new_request_key -> ip_dst = ((dirn == 0) ? pi.ip_dst : pi.ip_src);
! new_request_key -> port_src = ((dirn == 0) ? pi.srcport : pi.destport);
! new_request_key -> port_dst = ((dirn == 0) ? pi.destport : pi.srcport);
! new_request_key -> mid = si.mid;
request_val = g_mem_chunk_alloc(smb_request_vals);
request_val -> mid = si.mid;
--- 8210,8248 ----
guint16 DataCount;
guint16 ByteCount;
const char *TransactName;
+ guint32 conversation;
struct smb_request_key request_key, *new_request_key;
struct smb_request_val *request_val;
/*
! * Find out what conversation this packet is part of, or add it to a
! * new conversation if it's not already part of one.
! * XXX - this should really be done by the transport-layer protocol,
! * although for connectionless transports, we may not want to do that
! * unless we know some higher-level protocol will want it - or we
! * may want to do it, so you can say e.g. "show only the packets in
! * this UDP 'connection'".
! *
! * Note that we don't have to worry about the direction this packet
! * was going - the conversation code handles that for us, treating
! * packets from A:X to B:Y as being part of the same conversation as
! * packets from B:Y to A:X.
*/
+ conversation = add_to_conversation(&pi.src, &pi.dst, pi.srcport, pi.destport);
! /*
! * Check for and insert entry in request hash table if does not exist
! */
! request_key.conversation = conversation;
! request_key.mid = si.mid;
request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
if (!request_val) { /* Create one */
new_request_key = g_mem_chunk_alloc(smb_request_keys);
! new_request_key -> conversation = conversation;
! new_request_key -> mid = si.mid;
request_val = g_mem_chunk_alloc(smb_request_vals);
request_val -> mid = si.mid;
Index: packet-tcp.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-tcp.c,v
retrieving revision 1.37
diff -c -r1.37 packet-tcp.c
*** packet-tcp.c 1999/10/15 17:00:46 1.37
--- packet-tcp.c 1999/10/17 08:03:27
***************
*** 529,536 ****
( pd+offset ), /* data */
( pi.captured_len - offset ), /* captured data length */
( th.th_flags & TH_SYN ), /* is syn set? */
! pi.ip_src,
! pi.ip_dst,
pi.srcport,
pi.destport);
}
--- 529,536 ----
( pd+offset ), /* data */
( pi.captured_len - offset ), /* captured data length */
( th.th_flags & TH_SYN ), /* is syn set? */
! &pi.net_src,
! &pi.net_dst,
pi.srcport,
pi.destport);
}
Index: packet-tr.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-tr.c,v
retrieving revision 1.29
diff -c -r1.29 packet-tr.c
*** packet-tr.c 1999/10/12 06:20:18 1.29
--- packet-tr.c 1999/10/17 08:03:29
***************
*** 285,291 ****
guint16 trn_rseg[8]; /* routing registers */
/* non-source-routed version of source addr */
! guint8 trn_shost_nonsr[6];
int x;
/* Token-Ring Strings */
--- 285,291 ----
guint16 trn_rseg[8]; /* routing registers */
/* non-source-routed version of source addr */
! static guint8 trn_shost_nonsr[6];
int x;
/* Token-Ring Strings */
***************
*** 397,408 ****
}
}
/* information window */
- if (check_col(fd, COL_RES_DL_DST))
- col_add_str(fd, COL_RES_DL_DST,
- ether_to_str((guint8 *)&pd[offset + 2]));
- if (check_col(fd, COL_RES_DL_SRC))
- col_add_str(fd, COL_RES_DL_SRC, ether_to_str(trn_shost_nonsr));
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "TR");
if (check_col(fd, COL_INFO))
--- 397,410 ----
}
}
+ /* XXX - copy it to some buffer associated with "pi", rather than
+ just making "trn_shost_nonsr" static? */
+ SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &trn_shost_nonsr[0]);
+ SET_ADDRESS(&pi.src, AT_ETHER, 6, &trn_shost_nonsr[0]);
+ SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &pd[offset + 2]);
+ SET_ADDRESS(&pi.dst, AT_ETHER, 6, &pd[offset + 2]);
+
/* information window */
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "TR");
if (check_col(fd, COL_INFO))
Index: packet.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet.c,v
retrieving revision 1.50
diff -c -r1.50 packet.c
*** packet.c 1999/10/15 20:32:57 1.50
--- packet.c 1999/10/17 08:03:30
***************
*** 682,687 ****
--- 682,699 ----
}
}
+ void blank_packetinfo(void)
+ {
+ pi.dl_src.type = AT_NONE;
+ pi.dl_dst.type = AT_NONE;
+ pi.net_src.type = AT_NONE;
+ pi.net_dst.type = AT_NONE;
+ pi.src.type = AT_NONE;
+ pi.dst.type = AT_NONE;
+ pi.ipproto = 0;
+ pi.srcport = 0;
+ pi.destport = 0;
+ }
/* this routine checks the frame type from the cf structure */
void
***************
*** 721,726 ****
--- 733,740 ----
0, 0, fd->cap_len, "Capture Length: %d byte%s", fd->cap_len,
plurality(fd->cap_len, "", "s"));
}
+
+ blank_packetinfo();
/* Set the initial payload to the packet length, and the initial
captured payload to the capture length (other protocols may
Index: packet.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet.h,v
retrieving revision 1.113
diff -c -r1.113 packet.h
*** packet.h 1999/10/15 20:32:57 1.113
--- packet.h 1999/10/17 08:03:32
***************
*** 106,111 ****
--- 106,117 ----
gint total;
} packet_counts;
+ /* XXX - some of this stuff is used only while a packet is being dissected;
+ should we keep around a separate data structure for that, to save
+ memory?
+
+ Also, should the pseudo-header be supplied by Wiretap when you do a
+ seek-and-read, so that we don't have to save it for all frames? */
typedef struct _frame_data {
struct _frame_data *next; /* Next element in list */
guint32 num; /* Frame number */
***************
*** 125,141 ****
union pseudo_header pseudo_header; /* "pseudo-header" from wiretap */
} frame_data;
typedef struct _packet_info {
! int len;
! int captured_len;
! guint32 ip_src;
! guint32 ip_dst;
guint32 ipproto;
guint32 srcport;
guint32 destport;
guint32 match_port;
! int iplen;
! int iphdrlen;
} packet_info;
extern packet_info pi;
--- 131,172 ----
union pseudo_header pseudo_header; /* "pseudo-header" from wiretap */
} frame_data;
+ /* Types of addresses Ethereal knows about. */
+ typedef enum {
+ AT_NONE, /* no link-layer address */
+ AT_ETHER, /* MAC (Ethernet, 802.x, FDDI) address */
+ AT_IPv4, /* IPv4 */
+ AT_IPv6, /* IPv6 */
+ AT_IPX /* IPX */
+ } address_type;
+
+ typedef struct _address {
+ address_type type; /* type of address */
+ int len; /* length of address, in bytes */
+ const guint8 *data; /* bytes that constitute address */
+ } address;
+
+ #define SET_ADDRESS(addr, addr_type, addr_len, addr_data) { \
+ (addr)->type = (addr_type); \
+ (addr)->len = (addr_len); \
+ (addr)->data = (addr_data); \
+ }
+
typedef struct _packet_info {
! int len;
! int captured_len;
! address dl_src; /* link-layer source address */
! address dl_dst; /* link-layer destination address */
! address net_src; /* network-layer source address */
! address net_dst; /* network-layer destination address */
! address src; /* source address (net if present, DL otherwise )*/
! address dst; /* destination address (net if present, DL otherwise )*/
guint32 ipproto;
guint32 srcport;
guint32 destport;
guint32 match_port;
! int iplen;
! int iphdrlen;
} packet_info;
extern packet_info pi;
***************
*** 377,382 ****
--- 408,414 ----
gchar* ip_to_str(const guint8 *);
struct e_in6_addr;
gchar* ip6_to_str(struct e_in6_addr *);
+ gchar* ipx_addr_to_str(guint32, const guint8 *);
gchar* abs_time_to_str(struct timeval*);
gchar* rel_time_to_str(struct timeval*);
gchar* time_secs_to_str(guint32);
***************
*** 408,417 ****
void col_add_str(frame_data *, gint, const gchar *);
void col_append_str(frame_data *, gint, gchar *);
-
void smb_init_protocol(void);
void dissect_packet(const u_char *, frame_data *, proto_tree *);
/*
* Routines in packet-*.c
* Routines should take three args: packet data *, cap_len, packet_counts *
--- 440,451 ----
void col_add_str(frame_data *, gint, const gchar *);
void col_append_str(frame_data *, gint, gchar *);
void smb_init_protocol(void);
+ void blank_packetinfo(void);
+
void dissect_packet(const u_char *, frame_data *, proto_tree *);
+
/*
* Routines in packet-*.c
* Routines should take three args: packet data *, cap_len, packet_counts *
Index: resolv.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/resolv.c,v
retrieving revision 1.15
diff -c -r1.15 resolv.c
*** resolv.c 1999/10/14 06:55:10 1.15
--- resolv.c 1999/10/17 08:03:33
***************
*** 484,490 ****
} /* get_ethbyname */
! static ether_t *get_ethbyaddr(u_char *addr)
{
ether_t *eth;
--- 484,490 ----
} /* get_ethbyname */
! static ether_t *get_ethbyaddr(const u_char *addr)
{
ether_t *eth;
***************
*** 538,544 ****
} /* add_manuf_name */
! static hashmanuf_t *manuf_name_lookup(u_char *addr)
{
hashmanuf_t *tp;
--- 538,544 ----
} /* add_manuf_name */
! static hashmanuf_t *manuf_name_lookup(const u_char *addr)
{
hashmanuf_t *tp;
***************
*** 591,597 ****
} /* add_eth_name */
! static u_char *eth_name_lookup(u_char *addr)
{
hashmanuf_t *manufp;
hashether_t *tp;
--- 591,597 ----
} /* add_eth_name */
! static u_char *eth_name_lookup(const u_char *addr)
{
hashmanuf_t *manufp;
hashether_t *tp;
***************
*** 795,801 ****
} /* get_tcp_port */
! extern u_char *get_ether_name(u_char *addr)
{
if (!g_resolving_actif)
return ether_to_str((guint8 *)addr);
--- 795,801 ----
} /* get_tcp_port */
! extern u_char *get_ether_name(const u_char *addr)
{
if (!g_resolving_actif)
return ether_to_str((guint8 *)addr);
Index: resolv.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/resolv.h,v
retrieving revision 1.8
diff -c -r1.8 resolv.h
*** resolv.h 1999/10/15 03:11:52 1.8
--- resolv.h 1999/10/17 08:03:33
***************
*** 60,66 ****
/* get_ether_name returns the logical name if found in ethers files else
"<vendor>_%02x:%02x:%02x" if the vendor code is known else
"%02x:%02x:%02x:%02x:%02x:%02x" */
! extern u_char *get_ether_name(u_char *addr);
/* get_manuf_name returns the vendor name or "%02x:%02x:%02x" if not known */
extern u_char *get_manuf_name(u_char *addr);
--- 60,66 ----
/* get_ether_name returns the logical name if found in ethers files else
"<vendor>_%02x:%02x:%02x" if the vendor code is known else
"%02x:%02x:%02x:%02x:%02x:%02x" */
! extern u_char *get_ether_name(const u_char *addr);
/* get_manuf_name returns the vendor name or "%02x:%02x:%02x" if not known */
extern u_char *get_manuf_name(u_char *addr);
Index: gtk/main.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.23
diff -c -r1.23 main.c
*** main.c 1999/10/15 20:33:06 1.23
--- main.c 1999/10/17 08:03:36
***************
*** 403,416 ****
gtk_exit(0);
}
- void blank_packetinfo() {
- pi.ip_src = 0;
- pi.ip_dst = 0;
- pi.ipproto = 0;
- pi.srcport = 0;
- pi.destport = 0;
- }
-
/* call initialization routines at program startup time */
static void
ethereal_proto_init(void) {
--- 403,408 ----
/* conversation.c
* Routines for building lists of packets that are part of a "conversation"
*
* $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxx>
* Copyright 1998 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#include <string.h>
#include <glib.h>
#include "packet.h"
static GHashTable *conversation_hashtable = NULL;
static GMemChunk *conversation_key_chunk = NULL;
static GMemChunk *conversation_val_chunk = NULL;
typedef struct conversation_key {
struct conversation_key *next;
address src;
address dst;
guint16 port_src;
guint16 port_dst;
} conversation_key;
/*
* Linked list of conversation keys, so we can, before freeing them all,
* free the address data allocations associated with them.
*/
static conversation_key *conversation_keys;
typedef struct conversation_val {
struct conversation_val *next;
guint32 index;
} conversation_val;
static guint32 new_index;
static int conversation_init_count = 200;
/*
* Compare two conversation keys.
*/
static gint
conversation_equal(gconstpointer v, gconstpointer w)
{
conversation_key *v1 = (conversation_key *)v;
conversation_key *v2 = (conversation_key *)w;
/*
* We assume that a source and a destination address for a given
* packet in a conversation have the same type.
*/
if (v1->src.type != v2->src.type)
return 0; /* different types of addresses */
if (v1->src.len == v2->src.len &&
memcmp(v1->src.data, v2->src.data, v1->src.len) == 0) {
/*
* The first and second source addresses are the same.
*/
if (v1->dst.len == v2->dst.len &&
memcmp(v1->dst.data, v2->dst.data, v1->dst.len) == 0) {
/*
* The first and second destination addresses
* are the same, so they're both going from
* the same machine and they're both going to
* the same machine.
*/
if (v1->port_src == v2->port_src &&
v1->port_dst == v2->port_dst) {
/*
* The first and second source ports
* are the same, and the first and second
* destination ports are the same, so
* it's the same conversation, and the two
* address/port pairs are going in the same
* direction.
*/
return 1;
}
}
} else if (v1->src.len == v2->dst.len &&
memcmp(v1->src.data, v2->dst.data, v1->src.len) == 0) {
/*
* The first source address is the same as the second
* destination address.
*/
if (v1->dst.len == v2->src.len &&
memcmp(v1->dst.data, v2->src.data, v1->dst.len) == 0) {
/*
* The first destination address is the same as
* the second source address, so they're going
* between the same machines, but in opposite
* directions.
*/
if (v1->port_src == v2->port_dst &&
v1->port_dst == v2->port_src) {
/*
* The first source port is the same as
* the second destination port, and the
* first destination port is the same as
* the second source port, so it's
* the same conversation, and the two
* address/port pairs are going in
* opposite directions.
*/
return 1;
}
}
}
/*
* The addresses or the ports don't match.
*/
return 0;
}
/*
* Compute the hash value for a given set of source and destination
* addresses and ports.
*/
static guint
conversation_hash(gconstpointer v)
{
conversation_key *key = (conversation_key *)v;
guint hash_val;
int i;
hash_val = 0;
for (i = 0; i < key->src.len; i++)
hash_val += key->src.data[i];
for (i = 0; i < key->dst.len; i++)
hash_val += key->dst.data[i];
hash_val += key->port_src + key->port_dst;
return hash_val;
}
/*
* Initialize some variables every time a file is loaded or re-loaded.
* Destroy all existing conversations, and create a new hash table
* for the conversations in the new file.
*/
void
conversation_init(void)
{
conversation_key *key;
/*
* Free the addresses associated with the conversation keys.
*/
for (key = conversation_keys; key != NULL; key = key->next) {
/*
* Grr. I guess the theory here is that freeing
* something sure as heck modifies it, so you
* want to ban attempts to free it, but, alas,
* if we make the "data" field of an "address"
* structure not a "const", the compiler whines if
* we try to make it point into the data for a packet,
* as that's a "const" array (and should be, as dissectors
* shouldn't trash it).
*
* So we cast the complaint into oblivion, and rely on
* the fact that these addresses are known to have had
* their data mallocated, i.e. they don't point into,
* say, the middle of the data for a packet.
*/
g_free((gpointer)key->src.data);
g_free((gpointer)key->dst.data);
}
if (conversation_hashtable != NULL)
g_hash_table_destroy(conversation_hashtable);
if (conversation_key_chunk != NULL)
g_mem_chunk_destroy(conversation_key_chunk);
if (conversation_val_chunk != NULL)
g_mem_chunk_destroy(conversation_val_chunk);
conversation_hashtable = g_hash_table_new(conversation_hash,
conversation_equal);
conversation_key_chunk = g_mem_chunk_new("conversation_key_chunk",
sizeof(conversation_key),
conversation_init_count * sizeof(struct conversation_key),
G_ALLOC_AND_FREE);
conversation_val_chunk = g_mem_chunk_new("conversation_val_chunk",
sizeof(conversation_val),
conversation_init_count * sizeof(struct conversation_val),
G_ALLOC_AND_FREE);
/*
* Start the conversation indices over at 0.
*/
new_index = 0;
}
/*
* Copy an address, allocating a new buffer for the address data.
*/
static void
copy_address(address *to, address *from)
{
guint8 *data;
to->type = from->type;
to->len = from->len;
data = g_malloc(from->len);
memcpy(data, from->data, from->len);
to->data = data;
}
/*
* Given source and destination addresses and ports for a packet, add
* it to the conversation containing packets between those address/port
* pairs, creating a new conversation if none exists between them.
*
* Returns an index to use to refer to the conversation.
*/
guint32
add_to_conversation(address *src, address *dst, guint16 src_port,
guint16 dst_port)
{
conversation_val *conversation;
conversation_key key, *new_key;
/*
* We don't make a copy of the address data, we just copy the
* pointer to it, as "key" disappears when we return.
*/
key.src = *src;
key.dst = *dst;
key.port_src = src_port;
key.port_dst = dst_port;
conversation =
(conversation_val *)g_hash_table_lookup(conversation_hashtable,
&key);
if (conversation == NULL) {
/*
* No such conversation yet.
* Allocate a new one.
* Here, we *do* have to copy the address data.
*/
new_key = g_mem_chunk_alloc(conversation_key_chunk);
new_key->next = conversation_keys;
conversation_keys = new_key;
copy_address(&new_key->src, src);
copy_address(&new_key->dst, dst);
new_key->port_src = src_port;
new_key->port_dst = dst_port;
conversation = g_mem_chunk_alloc(conversation_val_chunk);
conversation->index = new_index;
new_index++;
g_hash_table_insert(conversation_hashtable, new_key,
conversation);
}
return conversation->index;
}
/* conversation.h
* Routines for building lists of packets that are part of a "conversation"
*
* $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxx>
* Copyright 1998 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
extern void conversation_init(void);
extern guint32 add_to_conversation(address *src, address *dst, guint16 src_port,
guint16 dst_port);
- References:
- [ethereal-dev] Keeping state for SMB decodes
- From: Richard Sharpe
- [ethereal-dev] Keeping state for SMB decodes
- Prev by Date: Re: [ethereal-dev] Keeping state for SMB decodes
- Next by Date: [ethereal-dev] More directories?
- Previous by thread: Re: [ethereal-dev] Keeping state for SMB decodes
- Next by thread: [ethereal-dev] CVS WEB
- Index(es):





