aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2000-11-09 10:56:33 +0000
committerGuy Harris <guy@alum.mit.edu>2000-11-09 10:56:33 +0000
commit01a890cf95e845edf22625a45274115c364f23b2 (patch)
tree7c9d0a8f4ff08ba78bddcbbc7299fd0fc7831287
parent7271ed28941220c5270b2529b932ba25715310bc (diff)
Tvbuffify the HTTP, NNTP, RSH, RTSP, and Telnet dissectors.
Add "tvb_find_line_end()", to find a CR and/or LF-terminated line in a tvbuff and return its length and the offset of the character after the line end, for the use of those dissectors. Add "tvb_strncaseeql()", which is like "tvb_strneql()" except that it does a case-insensitive comparison. svn path=/trunk/; revision=2590
-rw-r--r--epan/tvbuff.c147
-rw-r--r--epan/tvbuff.h16
-rw-r--r--packet-http.c163
-rw-r--r--packet-http.h4
-rw-r--r--packet-ipp.c5
-rw-r--r--packet-nntp.c141
-rw-r--r--packet-rsh.c60
-rw-r--r--packet-rtsp.c329
-rw-r--r--packet-telnet.c165
9 files changed, 632 insertions, 398 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index 94fbf9bc5a..933c23428f 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -9,7 +9,7 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
- * $Id: tvbuff.c,v 1.2 2000/10/17 08:50:57 guy Exp $
+ * $Id: tvbuff.c,v 1.3 2000/11/09 10:56:33 guy Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@@ -1041,23 +1041,48 @@ tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
gint
tvb_strneql(tvbuff_t *tvb, gint offset, guint8 *str, gint size)
{
- guint8 *ptr;
-
- ptr = ensure_contiguous(tvb, offset, size);
+ guint8 *ptr;
- if (ptr) {
+ ptr = ensure_contiguous(tvb, offset, size);
- int cmp = strncmp(ptr, str, size);
+ if (ptr) {
+ int cmp = strncmp(ptr, str, size);
- return (cmp == 0 ? 0 : -1); /* Make it -1 if comparison failed */
+ /*
+ * Return 0 if equal, -1 otherwise.
+ */
+ return (cmp == 0 ? 0 : -1);
+ } else {
+ /*
+ * Not enough characters in the tvbuff to match the
+ * string.
+ */
+ return -1;
+ }
+}
- }
- else {
+/* Call strncasecmp after checking if enough chars left, otherwise return -1 */
+gint
+tvb_strncaseeql(tvbuff_t *tvb, gint offset, guint8 *str, gint size)
+{
+ guint8 *ptr;
- return -1; /* Not enough chars in the TVB */
+ ptr = ensure_contiguous(tvb, offset, size);
- }
+ if (ptr) {
+ int cmp = strncasecmp(ptr, str, size);
+ /*
+ * Return 0 if equal, -1 otherwise.
+ */
+ return (cmp == 0 ? 0 : -1);
+ } else {
+ /*
+ * Not enough characters in the tvbuff to match the
+ * string.
+ */
+ return -1;
+ }
}
/*
@@ -1141,3 +1166,103 @@ tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer)
return len;
}
}
+
+/*
+ * Given a tvbuff, an offset into the tvbuff, and a length that starts
+ * at that offset (which may be -1 for "all the way to the end of the
+ * tvbuff"), find the end of the (putative) line that starts at the
+ * specified offset in the tvbuff, going no further than the specified
+ * length.
+ *
+ * Return the length of the line (not counting the line terminator at
+ * the end), or the amount of data remaining in the buffer if we don't
+ * find a line terminator.
+ *
+ * Set "*next_offset" to the offset of the character past the line
+ * terminator, or past the end of the buffer if we don't find a line
+ * terminator.
+ */
+int
+tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset)
+{
+ gint eob_offset;
+ gint eol_offset;
+ int linelen;
+
+ if (len == -1)
+ len = tvb_length_remaining(tvb, offset);
+ /*
+ * XXX - what if "len" is still -1, meaning "offset is past the
+ * end of the tvbuff"?
+ */
+ eob_offset = offset + len;
+
+ eol_offset = tvb_find_guint8(tvb, offset, len, '\n');
+ if (eol_offset == -1) {
+ /*
+ * No LF - line is presumably continued in next packet.
+ * We pretend the line runs to the end of the tvbuff.
+ */
+ *next_offset = eob_offset;
+ linelen = eob_offset - offset;
+ } else {
+ /*
+ * Find the number of bytes between the starting offset
+ * and the LF.
+ */
+ linelen = eol_offset - offset;
+
+ /*
+ * Is the LF at the beginning of the line?
+ */
+ if (linelen > 0) {
+ /*
+ * No - is it preceded by a carriage return?
+ * (Perhaps it's supposed to be, but that's not
+ * guaranteed....)
+ */
+ if (tvb_get_guint8(tvb, eol_offset - 1) == '\r') {
+ /*
+ * Yes. The EOL starts with the CR;
+ * don't count it as part of the data
+ * in the line.
+ */
+ linelen--;
+ } else {
+ /*
+ * No. The EOL starts with the LF.
+ */
+
+ /*
+ * I seem to remember that we once saw lines
+ * ending with LF-CR in an HTTP request or
+ * response, so check if it's *followed*
+ * by a carriage return.
+ *
+ * XXX - what about <LF><CR> with the <LF>
+ * not preceded by non-LF/non-CR data?
+ * Should we check for that, or do we
+ * run the risk of misinterpreting a
+ * sequence of multiple <CR><LF> as having
+ * a bunch of <LF><CR> in it?
+ */
+ if (eol_offset + 1 < eob_offset &&
+ tvb_get_guint8(tvb, eol_offset + 1) == '\r') {
+ /*
+ * It's <non-LF><LF><CR>; say it ends
+ * with the CR, and skip past the
+ * LF.
+ */
+ eol_offset++;
+ }
+ }
+ }
+
+ /*
+ * Point to the character after the last character.
+ */
+ eol_offset++;
+ *next_offset = eol_offset;
+ }
+ return linelen;
+}
diff --git a/epan/tvbuff.h b/epan/tvbuff.h
index 2b69584f04..813c28e952 100644
--- a/epan/tvbuff.h
+++ b/epan/tvbuff.h
@@ -9,7 +9,7 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
- * $Id: tvbuff.h,v 1.1 2000/09/27 04:54:54 gram Exp $
+ * $Id: tvbuff.h,v 1.2 2000/11/09 10:56:33 guy Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@@ -272,10 +272,24 @@ gint tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffe
*/
gint tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint maxlength, guint8* buffer);
+/*
+ * Given a tvbuff, an offset into the tvbuff, and a length that starts
+ * at that offset (which may be -1 for "all the way to the end of the
+ * tvbuff"), find the end of the (putative) line that starts at the
+ * specified offset in the tvbuff, going no further than the specified
+ * length.
+ *
+ * Return the offset right past the end of the line as the return value,
+ * and return the offset of the EOL character(s) in "*eol".
+ */
+gint tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *eol);
/* Call strncmp after checking if enough chars left, otherwise return -1 */
gint tvb_strneql(tvbuff_t *tvb, gint offset, guint8 *str, gint size);
+/* Call strncasecmp after checking if enough chars left, otherwise return -1 */
+gint tvb_strncaseeql(tvbuff_t *tvb, gint offset, guint8 *str, gint size);
+
/************** END OF ACCESSORS ****************/
/* Sets pd and offset so that tvbuff's can be used with code
diff --git a/packet-http.c b/packet-http.c
index cc14608a53..85aa18bb10 100644
--- a/packet-http.c
+++ b/packet-http.c
@@ -3,7 +3,7 @@
*
* Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-http.c,v 1.24 2000/10/19 07:38:01 guy Exp $
+ * $Id: packet-http.c,v 1.25 2000/11/09 10:56:31 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -62,75 +62,82 @@ static gint ett_http = -1;
static int is_http_request_or_reply(const u_char *data, int linelen, http_type_t *type);
-void dissect_http(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+void
+dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- gboolean is_ipp = (pi.srcport == 631 || pi.destport == 631);
- proto_item *ti;
- proto_tree *http_tree;
- const u_char *data, *dataend;
- const u_char *linep, *lineend, *eol;
+ gboolean is_ipp = (pinfo->srcport == 631 || pinfo->destport == 631);
+ proto_tree *http_tree = NULL;
+ proto_item *ti = NULL;
+ gint offset = 0;
+ const u_char *line;
+ gint next_offset;
+ const u_char *linep, *lineend;
int linelen;
u_char c;
- http_type_t http_type = HTTP_OTHERS;
+ http_type_t http_type;
+ int datalen;
- OLD_CHECK_DISPLAY_AS_DATA(proto_http, pd, offset, fd, tree);
+ CHECK_DISPLAY_AS_DATA(proto_http, tvb, pinfo, tree);
- data = &pd[offset];
- dataend = data + END_OF_FRAME;
+ pinfo->current_proto = is_ipp ? "IPP" : "HTTP";
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, is_ipp ? "IPP" : "HTTP");
- if (check_col(fd, COL_INFO)) {
+ if (check_col(pinfo->fd, COL_PROTOCOL))
+ col_add_str(pinfo->fd, COL_PROTOCOL, is_ipp ? "IPP" : "HTTP");
+ if (check_col(pinfo->fd, COL_INFO)) {
/*
- * Put the first line from the buffer into the summary,
+ * Put the first line from the buffer into the summary
* if it's an HTTP request or reply (but leave out the
- * "\r\n", or whatever, at the end).
+ * line terminator).
* Otherwise, just call it a continuation.
*/
- lineend = find_line_end(data, dataend, &eol);
- linelen = eol - data;
- if (is_http_request_or_reply(data, linelen, &http_type))
- col_add_str(fd, COL_INFO, format_text(data, linelen));
+ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset);
+ line = tvb_get_ptr(tvb, offset, linelen);
+ if (is_http_request_or_reply(line, linelen, &http_type))
+ col_add_str(pinfo->fd, COL_INFO,
+ format_text(line, linelen));
else
- col_add_str(fd, COL_INFO, "Continuation");
+ col_add_str(pinfo->fd, COL_INFO, "Continuation");
}
if (tree) {
- ti = proto_tree_add_item(tree, proto_http, NullTVB, offset, END_OF_FRAME, FALSE);
+ ti = proto_tree_add_item(tree, proto_http, tvb, offset,
+ tvb_length_remaining(tvb, offset), FALSE);
http_tree = proto_item_add_subtree(ti, ett_http);
- while (data < dataend) {
+ /*
+ * Process the packet data, a line at a time.
+ */
+ while (tvb_length_remaining(tvb, offset)) {
/*
* Find the end of the line.
*/
- lineend = find_line_end(data, dataend, &eol);
- linelen = lineend - data;
+ linelen = tvb_find_line_end(tvb, offset, -1,
+ &next_offset);
+
+ /*
+ * Get a buffer that refers to the line.
+ */
+ line = tvb_get_ptr(tvb, offset, linelen);
+ lineend = line + linelen;
/*
* OK, does it look like an HTTP request or
* response?
*/
- if (is_http_request_or_reply(data, linelen, &http_type))
+ if (is_http_request_or_reply(line, linelen, &http_type))
goto is_http;
/*
* No. Does it look like a blank line (as would
* appear at the end of an HTTP request)?
*/
- if (linelen == 1) {
- if (*data == '\n')
- goto is_http;
- }
- if (linelen == 2) {
- if (strncmp(data, "\r\n", 2) == 0 ||
- strncmp(data, "\n\r", 2) == 0)
- goto is_http;
- }
+ if (linelen == 0)
+ goto is_http;
/*
* No. Does it look like a MIME header?
*/
- linep = data;
+ linep = line;
while (linep < lineend) {
c = *linep++;
if (!isprint(c))
@@ -184,35 +191,51 @@ void dissect_http(const u_char *pd, int offset, frame_data *fd, proto_tree *tree
/*
* Put this line.
*/
- proto_tree_add_text(http_tree, NullTVB, offset, linelen, "%s",
- format_text(data, linelen));
- offset += linelen;
- data = lineend;
+ proto_tree_add_text(http_tree, tvb, offset,
+ next_offset - offset, "%s",
+ tvb_format_text(tvb, offset, next_offset - offset));
+ offset = next_offset;
}
switch (http_type) {
case HTTP_RESPONSE:
proto_tree_add_boolean_hidden(http_tree,
- hf_http_response, NullTVB, 0, 0, 1);
+ hf_http_response, tvb, 0, 0, 1);
break;
case HTTP_REQUEST:
proto_tree_add_boolean_hidden(http_tree,
- hf_http_request, NullTVB, 0, 0, 1);
+ hf_http_request, tvb, 0, 0, 1);
break;
case HTTP_OTHERS:
default:
break;
}
+ }
- if (data < dataend) {
- if (is_ipp)
- dissect_ipp(pd, offset, fd, tree);
- else
- old_dissect_data(&pd[offset], offset, fd, http_tree);
- }
+ datalen = tvb_length_remaining(tvb, offset);
+ if (datalen > 0) {
+ tvbuff_t *new_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ const guint8 *pd;
+
+ if (is_ipp) {
+ /*
+ * Fix up the top-level item so that it doesn't
+ * include the IPP stuff.
+ */
+ if (ti != NULL)
+ proto_item_set_len(ti, offset);
+
+ /*
+ * Now create a tvbuff for the IPP stuff, and dissect
+ * it.
+ */
+ tvb_compat(new_tvb, &pd, &offset);
+ dissect_ipp(pd, offset, pinfo->fd, tree);
+ } else
+ dissect_data(new_tvb, pinfo, http_tree);
}
}
@@ -272,31 +295,31 @@ is_http_request_or_reply(const u_char *data, int linelen, http_type_t *type)
void
proto_register_http(void)
{
-
- static hf_register_info hf[] = {
- { &hf_http_response,
- { "Response", "http.response",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "TRUE if HTTP response" }},
- { &hf_http_request,
- { "Request", "http.request",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "TRUE if HTTP request" }},
- };
- static gint *ett[] = {
- &ett_http,
- };
-
- proto_http = proto_register_protocol("Hypertext Transfer Protocol", "http");
- proto_register_field_array(proto_http, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
+ static hf_register_info hf[] = {
+ { &hf_http_response,
+ { "Response", "http.response",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "TRUE if HTTP response" }},
+ { &hf_http_request,
+ { "Request", "http.request",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "TRUE if HTTP request" }},
+ };
+ static gint *ett[] = {
+ &ett_http,
+ };
+
+ proto_http = proto_register_protocol("Hypertext Transfer Protocol",
+ "http");
+ proto_register_field_array(proto_http, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_http(void)
{
- old_dissector_add("tcp.port", TCP_PORT_HTTP, dissect_http);
- old_dissector_add("tcp.port", TCP_ALT_PORT_HTTP, dissect_http);
- old_dissector_add("tcp.port", TCP_PORT_PROXY_HTTP, dissect_http);
- old_dissector_add("tcp.port", TCP_PORT_PROXY_ADMIN_HTTP, dissect_http);
+ dissector_add("tcp.port", TCP_PORT_HTTP, dissect_http);
+ dissector_add("tcp.port", TCP_ALT_PORT_HTTP, dissect_http);
+ dissector_add("tcp.port", TCP_PORT_PROXY_HTTP, dissect_http);
+ dissector_add("tcp.port", TCP_PORT_PROXY_ADMIN_HTTP, dissect_http);
}
diff --git a/packet-http.h b/packet-http.h
index e9860aa100..5109f5e8fe 100644
--- a/packet-http.h
+++ b/packet-http.h
@@ -1,6 +1,6 @@
/* packet-http.h
*
- * $Id: packet-http.h,v 1.2 2000/08/11 13:34:12 deniel Exp $
+ * $Id: packet-http.h,v 1.3 2000/11/09 10:56:32 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -25,6 +25,6 @@
#ifndef __PACKET_HTTP_H__
#define __PACKET_HTTP_H__
-void dissect_http(const u_char *, int, frame_data *, proto_tree *);
+void dissect_http(tvbuff_t *, packet_info *, proto_tree *);
#endif
diff --git a/packet-ipp.c b/packet-ipp.c
index b5b1e49fa2..a265b439b2 100644
--- a/packet-ipp.c
+++ b/packet-ipp.c
@@ -3,7 +3,7 @@
*
* Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-ipp.c,v 1.12 2000/08/13 14:08:17 deniel Exp $
+ * $Id: packet-ipp.c,v 1.13 2000/11/09 10:56:32 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -586,6 +586,5 @@ proto_reg_handoff_ipp(void)
Or should the HTTP dissector decide that the payload is
IPP based on the MIME headers? */
- old_dissector_add("tcp.port", 631, dissect_http);
+ dissector_add("tcp.port", 631, dissect_http);
}
-
diff --git a/packet-nntp.c b/packet-nntp.c
index 5c8aedeef1..5d2580965d 100644
--- a/packet-nntp.c
+++ b/packet-nntp.c
@@ -2,7 +2,7 @@
* Routines for nntp packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
- * $Id: packet-nntp.c,v 1.13 2000/09/11 16:16:02 gram Exp $
+ * $Id: packet-nntp.c,v 1.14 2000/11/09 10:56:32 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -51,104 +51,103 @@ static gint ett_nntp = -1;
#define TCP_PORT_NNTP 119
static void
-dissect_nntp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+dissect_nntp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
gchar *type;
- proto_tree *nntp_tree, *ti;
- const u_char *data, *dataend;
- const u_char *lineend, *eol;
+ proto_tree *nntp_tree;
+ proto_item *ti;
+ gint offset = 0;
+ const u_char *line;
+ gint next_offset;
int linelen;
- int max_data = pi.captured_len - offset;
- OLD_CHECK_DISPLAY_AS_DATA(proto_nntp, pd, offset, fd, tree);
+ CHECK_DISPLAY_AS_DATA(proto_nntp, tvb, pinfo, tree);
- data = &pd[offset];
- dataend = data + END_OF_FRAME;
- if (dataend > data + max_data)
- dataend = data + max_data;
-
- if (pi.match_port == pi.destport)
+ if (pinfo->match_port == pinfo->destport)
type = "Request";
else
type = "Response";
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, "NNTP");
+ pinfo->current_proto = "NNTP";
+
+ if (check_col(pinfo->fd, COL_PROTOCOL))
+ col_add_str(pinfo->fd, COL_PROTOCOL, "NNTP");
- if (check_col(fd, COL_INFO)) {
+ if (check_col(pinfo->fd, COL_INFO)) {
/*
- * Put the first line from the buffer into the summary.
+ * Put the first line from the buffer into the summary
+ * (but leave out the line terminator).
*/
- lineend = find_line_end(data, dataend, &eol);
- linelen = eol - data;
- col_add_fstr(fd, COL_INFO, "%s: %s", type,
- format_text(data, linelen));
+ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset);
+ line = tvb_get_ptr(tvb, offset, linelen);
+ col_add_fstr(pinfo->fd, COL_INFO, "%s: %s", type,
+ format_text(line, linelen));
}
if (tree) {
-
- ti = proto_tree_add_item(tree, proto_nntp, NullTVB, offset, END_OF_FRAME, FALSE);
- nntp_tree = proto_item_add_subtree(ti, ett_nntp);
-
- if (pi.match_port == pi.destport) {
- proto_tree_add_boolean_hidden(nntp_tree, hf_nntp_request, NullTVB, 0, 0, TRUE);
- } else {
- proto_tree_add_boolean_hidden(nntp_tree, hf_nntp_response, NullTVB, 0, 0, TRUE);
- }
-
- /*
- * Show the request or response as text, a line at a time.
- * XXX - for requests, we could display the stuff after the
- * first line, if any, based on what the request was, and
- * for responses, we could display it based on what the
- * matching request was, although the latter requires us to
- * know what the matching request was....
- */
- while (data < dataend) {
- /*
- * Find the end of the line.
- */
- lineend = find_line_end(data, dataend, &eol);
- linelen = lineend - data;
+ ti = proto_tree_add_item(tree, proto_nntp, tvb, offset,
+ tvb_length_remaining(tvb, offset), FALSE);
+ nntp_tree = proto_item_add_subtree(ti, ett_nntp);
+
+ if (pinfo->match_port == pinfo->destport) {
+ proto_tree_add_boolean_hidden(nntp_tree,
+ hf_nntp_request, tvb, 0, 0, TRUE);
+ } else {
+ proto_tree_add_boolean_hidden(nntp_tree,
+ hf_nntp_response, tvb, 0, 0, TRUE);
+ }
/*
- * Put this line.
+ * Show the request or response as text, a line at a time.
+ * XXX - for requests, we could display the stuff after the
+ * first line, if any, based on what the request was, and
+ * for responses, we could display it based on what the
+ * matching request was, although the latter requires us to
+ * know what the matching request was....
*/
- proto_tree_add_text(nntp_tree, NullTVB, offset, linelen, "%s",
- format_text(data, linelen));
- offset += linelen;
- data = lineend;
- }
+ while (tvb_length_remaining(tvb, offset)) {
+ /*
+ * Find the end of the line.
+ */
+ tvb_find_line_end(tvb, offset, -1, &next_offset);
+
+ /*
+ * Put this line.
+ */
+ proto_tree_add_text(nntp_tree, tvb, offset,
+ next_offset - offset, "%s",
+ tvb_format_text(tvb, offset, next_offset - offset));
+ offset = next_offset;
+ }
}
}
void
proto_register_nntp(void)
{
-
- static hf_register_info hf[] = {
- { &hf_nntp_response,
- { "Response", "nntp.response",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "TRUE if NNTP response" }},
-
- { &hf_nntp_request,
- { "Request", "nntp.request",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "TRUE if NNTP request" }}
- };
- static gint *ett[] = {
- &ett_nntp,
- };
-
- proto_nntp = proto_register_protocol("Network News Transfer Protocol",
+ static hf_register_info hf[] = {
+ { &hf_nntp_response,
+ { "Response", "nntp.response",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "TRUE if NNTP response" }},
+
+ { &hf_nntp_request,
+ { "Request", "nntp.request",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "TRUE if NNTP request" }}
+ };
+ static gint *ett[] = {
+ &ett_nntp,
+ };
+
+ proto_nntp = proto_register_protocol("Network News Transfer Protocol",
"nntp");
- proto_register_field_array(proto_nntp, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
+ proto_register_field_array(proto_nntp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_nntp(void)
{
- old_dissector_add("tcp.port", TCP_PORT_NNTP, dissect_nntp);
+ dissector_add("tcp.port", TCP_PORT_NNTP, dissect_nntp);
}
diff --git a/packet-rsh.c b/packet-rsh.c
index 2facb05e66..5d558fde03 100644
--- a/packet-rsh.c
+++ b/packet-rsh.c
@@ -4,7 +4,7 @@
* Robert Tsai <rtsai@netapp.com>
* Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-rsh.c,v 1.4 2000/09/11 16:16:02 gram Exp $
+ * $Id: packet-rsh.c,v 1.5 2000/11/09 10:56:32 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -48,57 +48,57 @@ static gint ett_rsh = -1;
#define TCP_PORT_RSH 514
void
-dissect_rsh(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+dissect_rsh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_item *ti;
proto_tree *rsh_tree;
- const u_char *data, *dataend;
- const u_char *lineend, *eol;
+ proto_item *ti;
+ gint offset = 0;
+ const u_char *line;
+ gint next_offset;
int linelen;
- OLD_CHECK_DISPLAY_AS_DATA(proto_rsh, pd, offset, fd, tree);
+ CHECK_DISPLAY_AS_DATA(proto_rsh, tvb, pinfo, tree);
- data = &pd[offset];
- dataend = data + END_OF_FRAME;
+ pinfo->current_proto = "RSH";
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, "RSH");
- if (check_col(fd, COL_INFO)) {
+ if (check_col(pinfo->fd, COL_PROTOCOL))
+ col_add_str(pinfo->fd, COL_PROTOCOL, "RSH");
+ if (check_col(pinfo->fd, COL_INFO)) {
/* Put the first line from the buffer into the summary. */
- lineend = find_line_end(data, dataend, &eol);
- linelen = lineend - data;
- col_add_str(fd, COL_INFO, format_text(data, linelen));
+ tvb_find_line_end(tvb, offset, -1, &next_offset);
+ linelen = next_offset - offset; /* include the line terminator */
+ line = tvb_get_ptr(tvb, offset, linelen);
+ col_add_str(pinfo->fd, COL_INFO, format_text(line, linelen));
}
if (tree) {
- ti = proto_tree_add_item(tree, proto_rsh, NullTVB, offset,
- END_OF_FRAME, FALSE);
+ ti = proto_tree_add_item(tree, proto_rsh, tvb, offset,
+ tvb_length_remaining(tvb, offset), FALSE);
rsh_tree = proto_item_add_subtree(ti, ett_rsh);
- while (data < dataend) {
+ /*
+ * Process the packet data, a line at a time.
+ */
+ while (tvb_length_remaining(tvb, offset)) {
/*
* Find the end of the line.
*/
- lineend = find_line_end(data, dataend, &eol);
- linelen = lineend - data;
+ tvb_find_line_end(tvb, offset, -1, &next_offset);
/*
* Put this line.
*/
- proto_tree_add_text(rsh_tree, NullTVB, offset,
- linelen, "%s", format_text(data, linelen));
- offset += linelen;
- data = lineend;
+ proto_tree_add_text(rsh_tree, tvb, offset,
+ next_offset - offset, "%s",
+ tvb_format_text(tvb, offset, next_offset - offset));
+ offset = next_offset;
}
- if (pi.match_port == pi.destport)
+ if (pinfo->match_port == pinfo->destport)
proto_tree_add_boolean_hidden(rsh_tree,
- hf_rsh_request, NullTVB, 0, 0, 1);
+ hf_rsh_request, tvb, 0, 0, 1);
else
proto_tree_add_boolean_hidden(rsh_tree,
- hf_rsh_response, NullTVB, 0, 0, 1);
-
- if (data < dataend)
- old_dissect_data(&pd[offset], offset, fd, rsh_tree);
+ hf_rsh_response, tvb, 0, 0, 1);
}
}
@@ -129,5 +129,5 @@ proto_register_rsh(void)
void
proto_reg_handoff_rsh(void)
{
- old_dissector_add("tcp.port", TCP_PORT_RSH, dissect_rsh);
+ dissector_add("tcp.port", TCP_PORT_RSH, dissect_rsh);
}
diff --git a/packet-rtsp.c b/packet-rtsp.c
index 4f64ac2e9d..f945d1ed07 100644
--- a/packet-rtsp.c
+++ b/packet-rtsp.c
@@ -4,7 +4,7 @@
* Jason Lango <jal@netapp.com>
* Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-rtsp.c,v 1.21 2000/10/21 05:52:22 guy Exp $
+ * $Id: packet-rtsp.c,v 1.22 2000/11/09 10:56:32 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -54,9 +54,53 @@ static int hf_rtsp_status = -1;
#define TCP_PORT_RTSP 554
-static int process_rtsp_request_or_reply(const u_char *data, int offset,
+static void process_rtsp_request(tvbuff_t *tvb, int offset, const u_char *data,
int linelen, proto_tree *tree);
+static void process_rtsp_reply(tvbuff_t *tvb, int offset, const u_char *data,
+ int linelen, proto_tree *tree);
+
+typedef enum {
+ RTSP_REQUEST,
+ RTSP_REPLY,
+ NOT_RTSP
+} rtsp_type_t;
+
+static const char *rtsp_methods[] = {
+ "DESCRIBE", "ANNOUNCE", "GET_PARAMETER", "OPTIONS",
+ "PAUSE", "PLAY", "RECORD", "REDIRECT", "SETUP",
+ "SET_PARAMETER", "TEARDOWN"
+};
+
+#define RTSP_NMETHODS (sizeof rtsp_methods / sizeof rtsp_methods[0])
+
+static rtsp_type_t
+is_rtsp_request_or_reply(const u_char *line, int linelen)
+{
+ int ii;
+
+ /* Is this an RTSP reply? */
+ if (linelen >= 5 && strncasecmp("RTSP/", line, 5) == 0) {
+ /*
+ * Yes.
+ */
+ return RTSP_REPLY;
+ }
+
+ /*
+ * Is this an RTSP request?
+ * Check whether the line begins with one of the RTSP request
+ * methods.
+ */
+ for (ii = 0; ii < RTSP_NMETHODS; ii++) {
+ size_t len = strlen(rtsp_methods[ii]);
+ if (linelen >= len &&
+ strncasecmp(rtsp_methods[ii], line, len) == 0)
+ return RTSP_REQUEST;
+ }
+ return NOT_RTSP;
+}
+
static int
is_content_sdp(const u_char *line, int linelen)
{
@@ -136,84 +180,104 @@ rtsp_create_conversation(const u_char *trans_begin, const u_char *trans_end)
conversation_set_dissector(conv, dissect_rtcp);
}
-static void dissect_rtsp(const u_char *pd, int offset, frame_data *fd,
- proto_tree *tree)
+static void
+dissect_rtsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *rtsp_tree;
- proto_item *ti;
- const u_char *data, *dataend;
- const u_char *linep, *lineend, *eol;
+ proto_item *ti = NULL;
+ gint offset = 0;
+ const u_char *line;
+ gint next_offset;
+ const u_char *linep, *lineend;
int linelen;
u_char c;
- int is_sdp = 0;
- int end_offset;
+ int is_sdp = FALSE;
+ int datalen;
- OLD_CHECK_DISPLAY_AS_DATA(proto_rtsp, pd, offset, fd, tree);
+ CHECK_DISPLAY_AS_DATA(proto_rtsp, tvb, pinfo, tree);
- data = &pd[offset];
- dataend = data + END_OF_FRAME;
- end_offset = offset + END_OF_FRAME;
+ pinfo->current_proto = "RTSP";
rtsp_tree = NULL;
if (tree) {
- ti = proto_tree_add_item(tree, proto_rtsp, NullTVB, offset,
- END_OF_FRAME, FALSE);
+ ti = proto_tree_add_item(tree, proto_rtsp, tvb, offset,
+ tvb_length_remaining(tvb, offset), FALSE);
rtsp_tree = proto_item_add_subtree(ti, ett_rtsp);
}
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, "RTSP");
- if (check_col(fd, COL_INFO)) {
+ if (check_col(pinfo->fd, COL_PROTOCOL))
+ col_add_str(pinfo->fd, COL_PROTOCOL, "RTSP");
+ if (check_col(pinfo->fd, COL_INFO)) {
/*
* Put the first line from the buffer into the summary
- * if it's an RTSP request or reply. Otherwise, just call
- * it a continuation.
+ * if it's an RTSP request or reply (but leave out the
+ * line terminator).
+ * Otherwise, just call it a continuation.
*/
- lineend = find_line_end(data, dataend, &eol);
- linelen = lineend - data;
- if (process_rtsp_request_or_reply(data, offset, linelen,
- rtsp_tree)) {
- col_add_str(fd, COL_INFO,
- format_text(data, eol - data));
- } else
- col_add_str(fd, COL_INFO, "Continuation");
+ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset);
+ line = tvb_get_ptr(tvb, offset, linelen);
+ switch (is_rtsp_request_or_reply(line, linelen)) {
+
+ case RTSP_REQUEST:
+ case RTSP_REPLY:
+ col_add_str(pinfo->fd, COL_INFO,
+ format_text(line, linelen));
+ break;
+
+ default:
+ col_add_str(pinfo->fd, COL_INFO, "Continuation");
+ break;
+ }
}
- if (offset >= end_offset)
- goto bad_len;
- while (data < dataend) {
+ /*
+ * Process the packet data, a line at a time.
+ */
+ while (tvb_length_remaining(tvb, offset)) {
/*
* Find the end of the line.
*/
- lineend = find_line_end(data, dataend, &eol);
- linelen = lineend - data;
+ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset);
+
+ /*
+ * Get a buffer that refers to the line.
+ */
+ line = tvb_get_ptr(tvb, offset, linelen);
+ lineend = line + linelen;
/*
* OK, does it look like an RTSP request or
* response?
*/
- if (process_rtsp_request_or_reply(data, offset, linelen,
- rtsp_tree))
+ switch (is_rtsp_request_or_reply(line, linelen)) {
+
+ case RTSP_REQUEST:
+ if (rtsp_tree != NULL)
+ process_rtsp_request(tvb, offset, line, linelen,
+ rtsp_tree);
+ goto is_rtsp;
+
+ case RTSP_REPLY:
+ if (rtsp_tree != NULL)
+ process_rtsp_reply(tvb, offset, line, linelen,
+ rtsp_tree);
goto is_rtsp;
+ case NOT_RTSP:
+ break;
+ }
+
/*
* No. Does it look like a blank line (as would
* appear at the end of an RTSP request)?
*/
- if (linelen == 1) {
- if (*data == '\n')
- goto is_rtsp;
- }
- if (linelen == 2) {
- if (strncmp(data, "\r\n", 2) == 0 ||
- strncmp(data, "\n\r", 2) == 0)
- goto is_rtsp;
- }
+ if (linelen == 0)
+ goto is_rtsp; /* Yes. */
/*
* No. Does it look like a MIME header?
*/
- linep = data;
+ linep = line;
while (linep < lineend) {
c = *linep++;
if (!isprint(c))
@@ -249,8 +313,8 @@ static void dissect_rtsp(const u_char *pd, int offset, frame_data *fd,
* This ends the token; we consider
* this to be a MIME header.
*/
- if (is_content_sdp(data, linelen))
- is_sdp = 1;
+ if (is_content_sdp(line, linelen))
+ is_sdp = TRUE;
goto is_rtsp;
}
}
@@ -267,103 +331,114 @@ static void dissect_rtsp(const u_char *pd, int offset, frame_data *fd,
* Put this line.
*/
if (rtsp_tree) {
- proto_tree_add_text(rtsp_tree, NullTVB, offset, linelen, "%s",
- format_text(data, linelen));
+ proto_tree_add_text(rtsp_tree, tvb, offset,
+ next_offset - offset, "%s",
+ tvb_format_text(tvb, offset, next_offset - offset));
}
if (linelen > strlen(rtsp_transport) &&
- strncasecmp(data, rtsp_transport,
+ strncasecmp(line, rtsp_transport,
strlen(rtsp_transport)) == 0)
- rtsp_create_conversation(data, data + linelen);
- offset += linelen;
- data = lineend;
+ rtsp_create_conversation(line, line + linelen);
+ offset = next_offset;
}
+ datalen = tvb_length_remaining(tvb, offset);
if (is_sdp) {
- dissect_sdp(pd, offset, fd, tree);
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, "RTSP/SDP");
- }
- else if (data < dataend) {
- proto_tree_add_text(rtsp_tree, NullTVB, offset, END_OF_FRAME,
- "Data (%d bytes)", END_OF_FRAME);
+ if (datalen > 0) {
+ tvbuff_t *new_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ const guint8 *pd;
+
+ /*
+ * Fix up the top-level item so that it doesn't
+ * include the SDP stuff.
+ */
+ if (ti != NULL)
+ proto_item_set_len(ti, offset);
+
+ /*
+ * Now create a tvbuff for the SDP stuff, and dissect
+ * it.
+ */
+ tvb_compat(new_tvb, &pd, &offset);
+ dissect_sdp(pd, offset, pinfo->fd, tree);
+ }
+ if (check_col(pinfo->fd, COL_PROTOCOL))
+ col_add_str(pinfo->fd, COL_PROTOCOL, "RTSP/SDP");
+ } else {
+ if (datalen > 0) {
+ proto_tree_add_text(rtsp_tree, tvb, offset, datalen,
+ "Data (%d bytes)", datalen);
+ }
}
- return;
-
-bad_len:
- proto_tree_add_text(rtsp_tree, NullTVB, end_offset, 0,
- "Unexpected end of packet");
}
-const char *rtsp_methods[] = {
- "DESCRIBE", "ANNOUNCE", "GET_PARAMETER", "OPTIONS",
- "PAUSE", "PLAY", "RECORD", "REDIRECT", "SETUP",
- "SET_PARAMETER", "TEARDOWN"
-};
-const int rtsp_nmethods = sizeof(rtsp_methods) / sizeof(*rtsp_methods);
-
-static int
-process_rtsp_request_or_reply(const u_char *data, int offset, int linelen,
- proto_tree *tree)
+static void
+process_rtsp_request(tvbuff_t *tvb, int offset, const u_char *data,
+ int linelen, proto_tree *tree)
{
- int ii;
const u_char *lineend = data + linelen;
-
- /* Reply */
- if (linelen >= 5 && !strncasecmp("RTSP/", data, 5)) {
- if (tree) {
- /* status code */
- const u_char *status = data;
- const u_char *status_start;
- unsigned int status_i = 0;
- while (status < lineend && !isspace(*status))
- status++;
- while (status < lineend && isspace(*status))
- status++;
- status_start = status;
- while (status < lineend && isdigit(*status))
- status_i = status_i * 10 + *status++ - '0';
- proto_tree_add_uint_hidden(tree, hf_rtsp_status, NullTVB,
- offset + (status_start - data),
- status - status_start, status_i);
- }
- return TRUE;
- }
+ int ii;
+ const u_char *url;
+ const u_char *url_start;
+ u_char *tmp_url;
/* Request Methods */
- for (ii = 0; ii < rtsp_nmethods; ii++) {
+ for (ii = 0; ii < RTSP_NMETHODS; ii++) {
size_t len = strlen(rtsp_methods[ii]);
if (linelen >= len && !strncasecmp(rtsp_methods[ii], data, len))
break;
}
- if (ii == rtsp_nmethods)
- return FALSE;
-
- if (tree) {
- const u_char *url;
- const u_char *url_start;
- u_char *tmp_url;
-
- /* method name */
- proto_tree_add_string_hidden(tree, hf_rtsp_method, NullTVB, offset,
- strlen(rtsp_methods[ii]), rtsp_methods[ii]);
-
- /* URL */
- url = data;
- while (url < lineend && !isspace(*url))
- url++;
- while (url < lineend && isspace(*url))
- url++;
- url_start = url;
- while (url < lineend && !isspace(*url))
- url++;
- tmp_url = g_malloc(url - url_start + 1);
- memcpy(tmp_url, url_start, url - url_start);
- tmp_url[url - url_start] = 0;
- proto_tree_add_string_hidden(tree, hf_rtsp_url, NullTVB,
- offset + (url_start - data), url - url_start, tmp_url);
- g_free(tmp_url);
+ if (ii == RTSP_NMETHODS) {
+ /*
+ * We got here because "is_rtsp_request_or_reply()" returned
+ * RTSP_REQUEST, so we know one of the request methods
+ * matched, so we "can't get here".
+ */
+ g_assert_not_reached();
}
- return TRUE;
+
+ /* Method name */
+ proto_tree_add_string_hidden(tree, hf_rtsp_method, tvb, offset,
+ strlen(rtsp_methods[ii]), rtsp_methods[ii]);
+
+ /* URL */
+ url = data;
+ while (url < lineend && !isspace(*url))
+ url++;
+ while (url < lineend && isspace(*url))
+ url++;
+ url_start = url;
+ while (url < lineend && !isspace(*url))
+ url++;
+ tmp_url = g_malloc(url - url_start + 1);
+ memcpy(tmp_url, url_start, url - url_start);
+ tmp_url[url - url_start] = 0;
+ proto_tree_add_string_hidden(tree, hf_rtsp_url, tvb,
+ offset + (url_start - data), url - url_start, tmp_url);
+ g_free(tmp_url);
+}
+
+static void
+process_rtsp_reply(tvbuff_t *tvb, int offset, const u_char *data,
+ int linelen, proto_tree *tree)
+{
+ const u_char *lineend = data + linelen;
+ const u_char *status = data;
+ const u_char *status_start;
+ unsigned int status_i;
+
+ /* status code */
+ while (status < lineend && !isspace(*status))
+ status++;
+ while (status < lineend && isspace(*status))
+ status++;
+ status_start = status;
+ status_i = 0;
+ while (status < lineend && isdigit(*status))
+ status_i = status_i * 10 + *status++ - '0';
+ proto_tree_add_uint_hidden(tree, hf_rtsp_status, tvb,
+ offset + (status_start - data),
+ status - status_start, status_i);
}
void
@@ -390,5 +465,5 @@ proto_register_rtsp(void)
void
proto_reg_handoff_rtsp(void)
{
- old_dissector_add("tcp.port", TCP_PORT_RTSP, dissect_rtsp);
+ dissector_add("tcp.port", TCP_PORT_RTSP, dissect_rtsp);
}
diff --git a/packet-telnet.c b/packet-telnet.c
index 11e41912ff..d5ca334044 100644
--- a/packet-telnet.c
+++ b/packet-telnet.c
@@ -2,7 +2,7 @@
* Routines for telnet packet dissection
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
*
- * $Id: packet-telnet.c,v 1.17 2000/09/29 19:06:12 guy Exp $
+ * $Id: packet-telnet.c,v 1.18 2000/11/09 10:56:32 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -121,171 +121,175 @@ static const char *options[] = {
#define NOPTIONS (sizeof options / sizeof options[0])
static int
-telnet_sub_option(proto_tree *telnet_tree, const u_char *pd,
- int start_offset)
+telnet_sub_option(proto_tree *telnet_tree, tvbuff_t *tvb, int start_offset)
{
proto_tree *ti, *option_tree;
int offset = start_offset;
+ guint8 opt_byte;
int subneg_len, req;
- gboolean not_found = TRUE;
const u_char *opt;
+ guint len;
offset += 2; /* skip IAC and SB */
/* Figure out the option and type */
- if (pd[offset] > NOPTIONS)
+ opt_byte = tvb_get_guint8(tvb, offset);
+ if (opt_byte > NOPTIONS)
opt = "<unknown option>";
else
- opt = options[pd[offset]];
+ opt = options[opt_byte];
offset++;
- req = pd[offset];
+ req = tvb_get_guint8(tvb, offset);
offset++;
- while (offset < pi.captured_len && not_found) {
- if (pd[offset] == TN_IAC)
- not_found = FALSE;
- else
- offset++;
+ /* Search for an IAC. */
+ len = tvb_length_remaining(tvb, offset);
+ offset = tvb_find_guint8(tvb, offset, len, TN_IAC);
+ if (offset == -1) {
+ /* None found - run to the end of the packet. */
+ offset += len;
}
subneg_len = offset - start_offset;
- ti = proto_tree_add_text(telnet_tree, NullTVB, start_offset, subneg_len,
+ ti = proto_tree_add_text(telnet_tree, tvb, start_offset, subneg_len,
"Suboption Begin: %s", opt);
option_tree = proto_item_add_subtree(ti, ett_telnet_subopt);
- proto_tree_add_text(option_tree, NullTVB, start_offset + 2, 2,
+ proto_tree_add_text(option_tree, tvb, 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, NullTVB, start_offset + 4, subneg_len - 4,
- "Value: %s", format_text(&pd[start_offset + 4], subneg_len - 4));
+ proto_tree_add_text(option_tree, tvb, start_offset + 4, subneg_len - 4,
+ "Value: %s", tvb_format_text(tvb, start_offset + 4, subneg_len - 4));
}
return offset;
}
static int
-telnet_will_wont_do_dont(proto_tree *telnet_tree, const u_char *pd,
+telnet_will_wont_do_dont(proto_tree *telnet_tree, tvbuff_t *tvb,
int start_offset, char *type)
{
int offset = start_offset;
+ guint8 opt_byte;
const char *opt;
offset += 2; /* skip IAC and WILL,WONT,DO,DONT} */
- if (pd[offset] > NOPTIONS)
+ opt_byte = tvb_get_guint8(tvb, offset);
+ if (opt_byte > NOPTIONS)
opt = "<unknown option>";
else
- opt = options[pd[offset]];
+ opt = options[opt_byte];
offset++;
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 3,
+ proto_tree_add_text(telnet_tree, tvb, 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)
+telnet_command(proto_tree *telnet_tree, tvbuff_t *tvb, int start_offset)
{
int offset = start_offset;
u_char optcode;
offset += 1; /* skip IAC */
- optcode = pd[offset];
+ optcode = tvb_get_guint8(tvb, offset);
offset++;
switch(optcode) {
case TN_EOF:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: End of File");
break;
case TN_SUSP:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Suspend Current Process");
break;
case TN_ABORT:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Abort Process");
break;
case TN_EOR:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: End of Record");
break;
case TN_SE:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Suboption End");
break;
case TN_NOP:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: No Operation");
break;
case TN_DM:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Data Mark");
break;
case TN_BRK:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Break");
break;
case TN_IP:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Interrupt Process");
break;
case TN_AO:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Abort Output");
break;
case TN_AYT:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Are You There?");
break;
case TN_EC:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Escape Character");
break;
case TN_EL:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Erase Line");
break;
case TN_GA:
- proto_tree_add_text(telnet_tree, NullTVB, start_offset, 2,
+ proto_tree_add_text(telnet_tree, tvb, start_offset, 2,
"Command: Go Ahead");
break;
case TN_SB:
- offset = telnet_sub_option(telnet_tree, pd, start_offset);
+ offset = telnet_sub_option(telnet_tree, tvb, start_offset);
break;
case TN_WILL:
- offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset,
+ offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
"Will");
break;
case TN_WONT:
- offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset,
+ offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
"Won't");
break;
case TN_DO:
- offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset,
+ offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
"Do");
break;
case TN_DONT:
- offset = telnet_will_wont_do_dont(telnet_tree, pd, start_offset,
+ offset = telnet_will_wont_do_dont(telnet_tree, tvb, start_offset,
"Don't");
break;
}
@@ -294,86 +298,81 @@ telnet_command(proto_tree *telnet_tree, const u_char *pd, int start_offset)
}
static void
-telnet_add_text(proto_tree *tree, tvbuff_t *tvb, const u_char *pd,
- int offset, int len)
+telnet_add_text(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
{
- const u_char *data, *dataend;
- const u_char *lineend, *eol;
+ gint next_offset;
int linelen;
- data = &pd[offset];
- dataend = data + len;
- while (data < dataend) {
+ while (len != 0 && tvb_length_remaining(tvb, offset)) {
/*
* Find the end of the line.
*/
- lineend = find_line_end(data, dataend, &eol);
- linelen = lineend - data;
+ tvb_find_line_end(tvb, offset, len, &next_offset);
+ linelen = next_offset - offset;
- proto_tree_add_text(tree, NullTVB, offset, linelen,
- "Data: %s", format_text(data, linelen));
+ proto_tree_add_text(tree, tvb, offset, linelen,
+ "Data: %s",
+ tvb_format_text(tvb, offset, linelen));
offset += linelen;
- data = lineend;
+ len -= linelen;
}
}
static void
-dissect_telnet(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+dissect_telnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *telnet_tree, *ti;
- OLD_CHECK_DISPLAY_AS_DATA(proto_telnet, pd, offset, fd, tree);
+ CHECK_DISPLAY_AS_DATA(proto_telnet, tvb, pinfo, tree);
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, "TELNET");
+ pinfo->current_proto = "TELNET";
- if (check_col(fd, COL_INFO))
- col_add_fstr(fd, COL_INFO, "Telnet Data ...");
+ if (check_col(pinfo->fd, COL_PROTOCOL))
+ col_add_str(pinfo->fd, COL_PROTOCOL, "TELNET");
+
+ if (check_col(pinfo->fd, COL_INFO))
+ col_add_fstr(pinfo->fd, COL_INFO, "Telnet Data ...");
if (tree) {
- int data_offset;
+ gint offset = 0;
+ guint len;
int data_len;
+ gint iac_offset;
- ti = proto_tree_add_item(tree, proto_telnet, NullTVB, offset, END_OF_FRAME, FALSE);
+ ti = proto_tree_add_item(tree, proto_telnet, tvb, offset,
+ tvb_length_remaining(tvb, offset), FALSE);
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) {
+ while ((len = tvb_length_remaining(tvb, offset)) != 0) {
+ iac_offset = tvb_find_guint8(tvb, offset, len, TN_IAC);
+ if (iac_offset != -1) {
/*
* We found an IAC byte.
* If there's any data before it, add that data to the
* tree, a line at a time.
*/
- if (data_len > 0) {
- telnet_add_text(telnet_tree, NullTVB, pd, data_offset, data_len);
- data_len = 0;
- data_offset = offset;
- }
+ data_len = iac_offset - offset;
+ if (data_len > 0)
+ telnet_add_text(telnet_tree, tvb, offset, data_len);
/*
* Now interpret the command.
*/
- offset = telnet_command(telnet_tree, pd, offset);
- data_offset = offset;
+ offset = telnet_command(telnet_tree, tvb, iac_offset);
}
else {
- data_len++;
- offset++;
+ /*
+ * We found no IAC byte, so what remains in the buffer
+ * is the last of the data in the packet.
+ * Add it to the tree, a line at a time, and then quit.
+ */
+ telnet_add_text(telnet_tree, tvb, offset, len);
+ break;
}
}
-
- /*
- * We've reached the end of the buffer.
- * If there's any data left, add it to the tree.
- */
- if (data_len > 0)
- telnet_add_text(telnet_tree, NullTVB, pd, data_offset, data_len);
}
}
@@ -397,5 +396,5 @@ proto_register_telnet(void)
void
proto_reg_handoff_telnet(void)
{
- old_dissector_add("tcp.port", TCP_PORT_TELNET, dissect_telnet);
+ dissector_add("tcp.port", TCP_PORT_TELNET, dissect_telnet);
}