Ethereal-users: Re: [ethereal-users] One strange thing about the MS Netmon 2.x capture file
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: Thu, 23 Mar 2000 02:24:45 -0800
> That's because it's using "strlen()" to figure out how much data there > is, and that stops on a '\0'. > > I'll look into making it not do so. I have a patch to do so; I also got rid of some unnecessary temporary string buffers, and cleaned it up some (in part so that I could figure out what the temporary string buffers were doing, and to replace references to them to references to the packet data itself). The patch is attached.
Index: packet-telnet.c =================================================================== RCS file: /usr/local/cvsroot/ethereal/packet-telnet.c,v retrieving revision 1.8 diff -c -r1.8 packet-telnet.c *** packet-telnet.c 2000/01/07 22:05:41 1.8 --- packet-telnet.c 2000/03/23 10:21:45 *************** *** 71,77 **** #define TN_SUSP 237 #define TN_EOF 236 ! char *options[] = { "Binary Transmission", "Echo", "Reconnection", --- 71,77 ---- #define TN_SUSP 237 #define TN_EOF 236 ! static const char *options[] = { "Binary Transmission", "Echo", "Reconnection", *************** *** 115,321 **** "TN3270E" }; ! void telnet_sub_option(proto_tree *telnet_tree, char *rr, int *i, int offset, int max_data) { proto_tree *ti, *option_tree; ! int subneg_len, req, si1, not_found = 1; ! volatile int i1; ! char *opt, sub_opt_data[1500]; ! memset(sub_opt_data, '\0', sizeof(sub_opt_data)); /* Figure out the option and type */ ! ! opt = options[(unsigned int)rr[*i]]; ! req = (unsigned int)rr[*i + 1]; ! ! i1 = *i + 2; si1 = i1; ! while ((i1 < max_data) && (not_found)) { ! ! if ((unsigned char)rr[i1] == (unsigned char)TN_IAC) ! not_found = 0; else ! i1++; ! } ! subneg_len = i1 - *i + 2; ! ti = proto_tree_add_text(telnet_tree, offset, subneg_len, "Suboption Begin: %s", opt); option_tree = proto_item_add_subtree(ti, ett_telnet_subopt); ! proto_tree_add_text(option_tree, offset + 2, subneg_len - 2, "%s %s", (req ? "Send your" : "Here's my"), opt); if (req == 0) { /* Add the value */ ! ! memcpy(sub_opt_data, rr + *i + 2, subneg_len - 2); ! proto_tree_add_text(option_tree, offset + 4, subneg_len - 4, "Value: %s", format_text(sub_opt_data, subneg_len - 4)); ! *i += subneg_len - 2; ! } ! else { ! *i += subneg_len - 2; ! } } ! void telnet_command(proto_tree *telnet_tree, char *rr, int *i, int offset, int max_data) { ! char *opt; ! switch((unsigned char)rr[*i]) { case TN_EOF: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: End of File"); ! (*i)++; break; case TN_SUSP: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Suspend Current Process"); ! (*i)++; break; case TN_ABORT: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Abort Process"); ! (*i)++; break; case TN_EOR: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: End of Record"); ! (*i)++; break; case TN_SE: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Suboption End"); ! (*i)++; break; case TN_NOP: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: No Operation"); ! (*i)++; break; case TN_DM: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Data Mark"); ! (*i)++; break; case TN_BRK: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Break"); ! (*i)++; break; case TN_IP: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Interrupt Process"); ! (*i)++; break; case TN_AO: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Abort Output"); ! (*i)++; break; case TN_AYT: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Are You There?"); ! (*i)++; break; case TN_EC: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Escape Character"); ! (*i)++; break; case TN_EL: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Erase Line"); ! (*i)++; break; case TN_GA: ! ! proto_tree_add_text(telnet_tree, offset, 2, "Command: Go Ahead"); ! (*i)++; break; case TN_SB: ! ! (*i)++; ! telnet_sub_option(telnet_tree, rr, i, offset, max_data); break; case TN_WILL: ! ! if (rr[*i + 1] > (sizeof(options)/sizeof(char *))) ! opt = "<unknown option>"; ! else ! opt = options[(unsigned int)rr[*i + 1]]; ! ! proto_tree_add_text(telnet_tree, offset, 3, "Command: Will %s", opt); ! *i += 2; /* skip two chars */ break; case TN_WONT: ! ! if (rr[*i + 1] > (sizeof(options)/sizeof(char *))) ! opt = "<unknown option>"; ! else ! opt = options[(unsigned int)rr[*i + 1]]; ! ! proto_tree_add_text(telnet_tree, offset, 3, "Command: Won't %s", opt); ! *i += 2; /* skip two chars */ break; case TN_DO: ! ! if (rr[*i + 1] > (sizeof(options)/sizeof(char *))) ! opt = "<unknown option>"; ! else ! opt = options[(unsigned int)rr[*i + 1]]; ! ! proto_tree_add_text(telnet_tree, offset, 3, "Command: Do %s", opt); ! *i += 2; /* skip two chars */ break; case TN_DONT: ! ! if (rr[*i + 1] > (sizeof(options)/sizeof(char *))) ! opt = "<unknown option>"; ! else ! opt = options[(unsigned int)rr[*i + 1]]; ! ! proto_tree_add_text(telnet_tree, offset, 3, "Command: Don't %s", opt); ! *i += 2; /* skip two chars */ break; - } } void dissect_telnet(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { proto_tree *telnet_tree, *ti; - gchar rr[1500]; - int i1; - int i2; int max_data = pi.captured_len - offset; - memset(rr, '\0', sizeof(rr)); - if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "TELNET"); --- 115,302 ---- "TN3270E" }; ! #define NOPTIONS (sizeof options / sizeof options[0]) ! ! static int ! telnet_sub_option(proto_tree *telnet_tree, const u_char *pd, ! int start_offset) { proto_tree *ti, *option_tree; ! int offset = start_offset; ! int subneg_len, req; ! gboolean not_found = TRUE; ! const u_char *opt; ! offset += 2; /* skip IAC and SB */ /* Figure out the option and type */ ! if (pd[offset] > NOPTIONS) ! opt = "<unknown option>"; ! else ! opt = options[pd[offset]]; ! offset++; ! req = pd[offset]; ! offset++; ! ! while (offset < pi.captured_len && not_found) { ! if (pd[offset] == TN_IAC) ! not_found = FALSE; else ! offset++; } ! subneg_len = offset - start_offset; ! ti = proto_tree_add_text(telnet_tree, start_offset, subneg_len, ! "Suboption Begin: %s", opt); option_tree = proto_item_add_subtree(ti, ett_telnet_subopt); ! proto_tree_add_text(option_tree, start_offset + 2, 2, ! "%s %s", (req ? "Send your" : "Here's my"), opt); if (req == 0) { /* Add the value */ ! proto_tree_add_text(option_tree, start_offset + 4, subneg_len - 4, ! "Value: %s", format_text(&pd[start_offset + 4], subneg_len - 4)); } ! return offset; ! } ! static int ! telnet_will_wont_do_dont(proto_tree *telnet_tree, const u_char *pd, ! int start_offset, char *type) ! { ! int offset = start_offset; ! const char *opt; ! offset += 2; /* skip IAC and WILL,WONT,DO,DONT} */ ! if (pd[offset] > NOPTIONS) ! opt = "<unknown option>"; ! else ! opt = options[pd[offset]]; ! offset++; ! ! proto_tree_add_text(telnet_tree, start_offset, 3, ! "Command: %s %s", type, opt); ! return offset; } ! static int ! telnet_command(proto_tree *telnet_tree, const u_char *pd, ! int start_offset, int max_data) { ! int offset = start_offset; ! u_char optcode; ! offset += 1; /* skip IAC */ ! optcode = pd[offset]; ! offset++; ! switch(optcode) { case TN_EOF: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: End of File"); break; case TN_SUSP: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Suspend Current Process"); break; case TN_ABORT: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Abort Process"); break; case TN_EOR: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: End of Record"); break; case TN_SE: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Suboption End"); break; case TN_NOP: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: No Operation"); break; case TN_DM: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Data Mark"); break; case TN_BRK: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Break"); break; case TN_IP: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Interrupt Process"); break; case TN_AO: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Abort Output"); break; case TN_AYT: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Are You There?"); break; case TN_EC: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Escape Character"); break; case TN_EL: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Erase Line"); break; case TN_GA: ! proto_tree_add_text(telnet_tree, start_offset, 2, ! "Command: Go Ahead"); break; case TN_SB: ! offset = telnet_sub_option(telnet_tree, pd, start_offset); break; case TN_WILL: ! offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset, ! "Will"); break; case TN_WONT: ! offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset, ! "Won't"); break; case TN_DO: ! offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset, ! "Do"); break; case TN_DONT: ! offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset, ! "Don't"); break; } + return offset; } void dissect_telnet(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { proto_tree *telnet_tree, *ti; int max_data = pi.captured_len - offset; if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "TELNET"); *************** *** 326,379 **** } if (tree) { - char data[1500]; - int i3; - - memset(data, '\0', sizeof(data)); - - memcpy(rr, pd + offset, max_data); - ti = proto_tree_add_item(tree, proto_telnet, offset, END_OF_FRAME, NULL); telnet_tree = proto_item_add_subtree(ti, ett_telnet); - - i1 = i2 = i3 = 0; - - while (i1 < max_data) { - - if ((unsigned char)rr[i1] == (unsigned char)TN_IAC) { ! if (strlen(data) > 0) { ! proto_tree_add_text(telnet_tree, offset + i2, strlen(data), "Data: %s", format_text(data, strlen(data))); ! memset(data, '\0', sizeof(data)); ! i3 = 0; ! } ! i1++; ! telnet_command(telnet_tree, rr, &i1, offset + i1 - 1, max_data); ! i2 = i1; ! } else { ! ! data[i3] = rr[i1]; ! i3++; ! i1++; ! ! } } - - if (strlen(data) > 0) { /* Still some data to add */ ! proto_tree_add_text(telnet_tree, offset + i2, strlen(data), "Data: %s", format_text(data, strlen(data))); ! } - } - } void --- 307,359 ---- } if (tree) { + int data_offset; + int data_len; ti = proto_tree_add_item(tree, proto_telnet, offset, END_OF_FRAME, NULL); telnet_tree = proto_item_add_subtree(ti, ett_telnet); ! data_offset = offset; ! data_len = 0; ! /* ! * Scan through the buffer looking for an IAC byte. ! */ ! while (offset < pi.captured_len) { ! if (pd[offset] == TN_IAC) { ! /* ! * We found an IAC byte. ! * If there's any data before it, add that data to the ! * tree. ! */ ! if (data_len > 0) { ! proto_tree_add_text(telnet_tree, data_offset, data_len, ! "Data: %s", format_text(&pd[data_offset], data_len)); ! data_len = 0; ! data_offset = offset; } ! /* ! * Now interpret the command. ! */ ! offset = telnet_command(telnet_tree, pd, offset, max_data); ! data_offset = offset; } else { ! data_len++; ! offset++; } } ! /* ! * We've reached the end of the buffer. ! * If there's any data left, add it to the tree. ! */ ! if (data_len > 0) { ! proto_tree_add_text(telnet_tree, data_offset, data_len, "Data: %s", ! format_text(&pd[data_offset], data_len)); } } } void
- Follow-Ups:
- References:
- [ethereal-users] One strange thing about the MS Netmon 2.x capture file
- From: Fabrizio Ammollo
- Re: [ethereal-users] One strange thing about the MS Netmon 2.x capture file
- From: Guy Harris
- [ethereal-users] One strange thing about the MS Netmon 2.x capture file
- Prev by Date: Re: [ethereal-users] One strange thing about the MS Netmon 2.x capture file
- Next by Date: Re: [ethereal-users] One strange thing about the MS Netmon 2.x capture file
- Previous by thread: Re: [ethereal-users] One strange thing about the MS Netmon 2.x capture file
- Next by thread: Re: [ethereal-users] One strange thing about the MS Netmon 2.x capture file
- Index(es):