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):