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





