aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2000-04-08 03:32:10 +0000
committerGuy Harris <guy@alum.mit.edu>2000-04-08 03:32:10 +0000
commit160928a318385aa2fb59af968ab1cd85847ad963 (patch)
tree9823911ac8dc8aa920a050318f9ea098f41393e7
parent43c9217ba4083abf6632cdd35b8e0233fc67afb7 (diff)
Jeff Foster's rlogin dissector, and changes to the TCP dissector to
export the urgent pointer (as the rlogin dissector needs it). svn path=/trunk/; revision=1822
-rw-r--r--AUTHORS3
-rw-r--r--Makefile.am3
-rw-r--r--packet-rlogin.c480
-rw-r--r--packet-tcp.c10
-rw-r--r--packet-tcp.h4
5 files changed, 496 insertions, 4 deletions
diff --git a/AUTHORS b/AUTHORS
index 9b91ca929f..e3ff5a4813 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -145,6 +145,9 @@ Jeff Foster <jfoste@woodward.com> {
original NetBIOS encapsulation)
SMB Mailslot and Netlogin protocol support
Popup packet windows
+ Support for protocols registering themselves with dissectors for
+ protocols on top of which they run
+ Rlogin support
}
Peter Torvals <petertv@xoommail.com> {
diff --git a/Makefile.am b/Makefile.am
index 974cd6bcdb..062e4c9d88 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.178 2000/04/05 11:04:46 gram Exp $
+# $Id: Makefile.am,v 1.179 2000/04/08 03:32:09 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -180,6 +180,7 @@ DISSECTOR_SOURCES = \
packet-rip.h \
packet-ripng.c \
packet-ripng.h \
+ packet-rlogin.c \
packet-rpc.c \
packet-rpc.h \
packet-rsvp.c \
diff --git a/packet-rlogin.c b/packet-rlogin.c
new file mode 100644
index 0000000000..d07393c441
--- /dev/null
+++ b/packet-rlogin.c
@@ -0,0 +1,480 @@
+/* packet-rlogin.c
+ * Routines for unix rlogin packet dissection
+ * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
+ *
+ * $Id: packet-rlogin.c,v 1.1 2000/04/08 03:32:09 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 1998 Gerald Combs
+ *
+ *
+ * Based upon RFC-1282 - BSD Rlogin
+ *
+ *
+ * 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
+
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include "packet.h"
+#include "resolv.h"
+#include "globals.h"
+#include "alignment.h"
+#include "conversation.h"
+
+#include "packet-tcp.h"
+
+#ifdef NEED_SNPRINTF_H
+# ifdef HAVE_STDARG_H
+# include <stdarg.h>
+# else
+# include <varargs.h>
+# endif
+# include "snprintf.h"
+#endif
+
+#define CHECK_PACKET_LENGTH(X) if ((offset+X) > fd->cap_len){ \
+ proto_tree_add_text(tree, offset, 0, "*** FRAME TOO SHORT ***"); \
+ return; }
+
+
+#define TCP_PORT_RLOGIN 513
+
+static int proto_rlogin = -1;
+
+static int ett_rlogin = -1;
+static int ett_rlogin_window = -1;
+static int ett_rlogin_user_info = -1;
+static int ett_rlogin_window_rows = -1;
+static int ett_rlogin_window_cols = -1;
+static int ett_rlogin_window_x_pixels = -1;
+static int ett_rlogin_window_y_pixels = -1;
+
+
+static int hf_user_info = -1;
+static int hf_window_info = -1;
+static int hf_window_info_rows = -1;
+static int hf_window_info_cols = -1;
+static int hf_window_info_x_pixels = -1;
+static int hf_window_info_y_pixels = -1;
+
+
+#define RLOGIN_PORT 513
+
+#define row_pointer_t frame_data*
+#define compare_packet_ptr(X) (X == (fd))
+#define get_packet_ptr (fd)
+
+#define NAME_LEN 32
+
+typedef struct {
+ int state;
+ row_pointer_t info_row;
+ row_pointer_t last_row;
+ char name[ NAME_LEN];
+
+}rlogin_hash_entry_t;
+
+
+#define NONE 0
+#define USER_INFO_WAIT 1
+#define DONE 2
+#define BAD 2
+
+
+static GMemChunk *rlogin_vals = NULL;
+
+#define rlogin_hash_init_count 20
+
+static guint32 last_abs_sec = 0;
+static guint32 last_abs_usec= 0;
+
+static void
+rlogin_init( void){
+
+/* Routine to initialize rlogin protocol before each capture or filter pass. */
+/* Release any memory if needed. Then setup the memory chunks. */
+
+ last_abs_sec = 0;
+ last_abs_usec= 0;
+
+ if (rlogin_vals)
+ g_mem_chunk_destroy(rlogin_vals);
+
+ rlogin_vals = g_mem_chunk_new("rlogin_vals",
+ sizeof( rlogin_hash_entry_t),
+ rlogin_hash_init_count * sizeof( rlogin_hash_entry_t),
+ G_ALLOC_AND_FREE);
+}
+
+
+/**************** Decoder State Machine ******************/
+
+static void
+rlogin_state_machine( rlogin_hash_entry_t *hash_info, const u_char *pd,
+ int offset, frame_data *fd) {
+
+/* rlogin stream decoder */
+/* Just watched for second packet from client with the user name and */
+/* terminal type information. */
+
+
+ if ( pi.destport != RLOGIN_PORT) /* not from client */
+ return;
+ /* exit if not needed */
+ if (( hash_info->state == DONE) || ( hash_info->state == BAD))
+ return;
+
+ /* test timestamp */
+ if (( last_abs_sec > fd->abs_secs) ||
+ (( last_abs_sec == fd->abs_secs) && ( last_abs_usec >= fd->abs_usecs)))
+ return;
+
+ last_abs_sec = fd->abs_secs; /* save timestamp */
+ last_abs_usec = fd->abs_usecs;
+
+ if ( !IS_DATA_IN_FRAME(offset)) /* exit if no data */
+ return;
+
+ if ( hash_info->state == NONE){ /* new connection*/
+
+ if ( GBYTE( pd, offset + 1)) { /* expect a NULL */
+ hash_info->state = DONE; /* quit, no NULL */
+ return;
+ }
+ else {
+ if (( END_OF_FRAME) <= 1) /* if no data */
+ hash_info->state = USER_INFO_WAIT;
+ else {
+ hash_info->state = DONE;
+ hash_info->info_row = get_packet_ptr;
+ }
+ }
+ } /* expect user data here */
+/*$$$ may need to do more checking here */
+ else if ( hash_info->state == USER_INFO_WAIT) {
+ hash_info->state = DONE;
+ hash_info->info_row = get_packet_ptr;
+ /* save name for later*/
+ strncpy( hash_info->name, &pd[ offset], NAME_LEN);
+
+ hash_info->name[ NAME_LEN] = 0;
+
+ if (check_col(fd, COL_INFO)) /* update summary */
+ col_append_str( fd, COL_INFO, ", User information");
+
+ }
+}
+
+
+static void rlogin_display( rlogin_hash_entry_t *hash_info, const u_char *pd,
+ int offset, frame_data *fd, proto_tree *tree) {
+
+/* Display the proto tree */
+
+ proto_tree *rlogin_tree, *user_info_tree, *window_tree;
+ proto_item *ti;
+ guint8 *Ptr;
+ const char *str;
+ proto_item *user_info_item, *window_info_item;
+
+ ti = proto_tree_add_item( tree, proto_rlogin, offset,
+ END_OF_FRAME, NULL, "Rlogin:" );
+
+ rlogin_tree = proto_item_add_subtree(ti, ett_rlogin);
+
+ if ( !END_OF_FRAME) /* exit if no data */
+ return;
+
+ if ( tcp_urgent_pointer && /* if control message */
+ BYTES_ARE_IN_FRAME(offset + tcp_urgent_pointer - 1, 1)) {
+
+ int i = offset + tcp_urgent_pointer - 1;
+ guint16 Temp = GBYTE( pd, i);
+
+ if ( i < offset) /* check for data in front */
+ proto_tree_add_text( rlogin_tree, offset, i - offset,
+ "Data");
+
+ proto_tree_add_text( rlogin_tree, i, 1, "Control byte: %u (%s)",
+ Temp,
+ (Temp == 2) ? "Clear buffer" :
+ (Temp == 0x10) ? "Raw mode" :
+ (Temp == 0x20) ? "Cooked mode" :
+ (Temp == 0x80) ? "Window size request" :
+ "Unknown");
+ offset = i; /* adjust offset */
+ }
+
+ else if ( !GBYTE( pd, offset)){ /* startup */
+ if ( pi.srcport== RLOGIN_PORT) /* from server */
+ proto_tree_add_text(rlogin_tree, offset, 1,
+ "Startup info received flag (0x00)");
+
+ else
+ proto_tree_add_text(rlogin_tree, offset, 1,
+ "Client Startup Flag (0x00)");
+ ++offset;
+ }
+
+ if ( compare_packet_ptr( hash_info->info_row)){ /* user info ?*/
+
+ user_info_item = proto_tree_add_item( rlogin_tree, hf_user_info,
+ offset, END_OF_FRAME, NULL );
+
+ str = &pd[ offset]; /* do server user name */
+
+ CHECK_PACKET_LENGTH( strlen( str));
+
+ user_info_tree = proto_item_add_subtree( user_info_item,
+ ett_rlogin_user_info);
+
+ proto_tree_add_text( user_info_tree, offset, strlen( str) + 1,
+ "Server User Name: %s", str);
+
+ offset += strlen( str) + 1;
+ str = &pd[ offset]; /* do client user name */
+ CHECK_PACKET_LENGTH( strlen( str));
+ proto_tree_add_text( user_info_tree, offset, strlen( str) + 1,
+ "Client User Name: %s", str);
+
+ offset += strlen( str) + 1;
+
+ str = &pd[ offset]; /* do terminal type/speed */
+ CHECK_PACKET_LENGTH( strlen( str));
+ proto_tree_add_text( user_info_tree, offset, strlen( str) + 1,
+ "Terminal Type/Speed: %s", str);
+
+ offset += strlen( str) + 1;
+ }
+
+/* test for terminal information, the data will have 2 0xff bytes */
+
+ /* look for first 0xff byte */
+ Ptr = (guint8*)memchr( &pd[ offset], 0xff, END_OF_FRAME);
+
+ if (( Ptr) && (*(Ptr + 1) == 0xff)) { /* found terminal info */
+
+ int ti_offset = Ptr - pd; /* get offset */
+
+ if ( ti_offset < offset){ /*if data before terminal info*/
+ proto_tree_add_text( rlogin_tree, offset,
+ (ti_offset - offset), "Data");
+ offset = ti_offset;
+ }
+
+ CHECK_PACKET_LENGTH( 12);
+ window_info_item = proto_tree_add_item( rlogin_tree,
+ hf_window_info, offset, 12, NULL );
+
+ window_tree = proto_item_add_subtree( window_info_item,
+ ett_rlogin_window);
+
+ CHECK_PACKET_LENGTH( 2);
+ proto_tree_add_text( window_tree, offset, 2,
+ "Magic Cookie: (0xff, 0xff)");
+ offset += 2;
+
+ CHECK_PACKET_LENGTH( 2);
+ proto_tree_add_text( window_tree, offset, 2,
+ "Window size marker: 'ss'");
+ offset += 2;
+
+ CHECK_PACKET_LENGTH( 2);
+ proto_tree_add_item( window_tree, hf_window_info_rows, offset,
+ 2, pntohs( &pd[offset]));
+ offset += 2;
+
+ CHECK_PACKET_LENGTH( 2);
+ proto_tree_add_item( window_tree, hf_window_info_cols, offset,
+ 2, pntohs( &pd[offset]) );
+ offset += 2;
+
+ CHECK_PACKET_LENGTH( 2);
+ proto_tree_add_item( window_tree, hf_window_info_x_pixels,
+ offset, 2, pntohs( &pd[offset]));
+ offset += 2;
+
+ CHECK_PACKET_LENGTH( 2);
+ proto_tree_add_item( window_tree, hf_window_info_y_pixels,
+ offset, 2, pntohs( &pd[offset]) );
+ offset += 2;
+ }
+
+ if ( END_OF_FRAME != 0) /* if more data */
+ proto_tree_add_text(rlogin_tree, offset, END_OF_FRAME, "Data");
+
+}
+
+
+
+static void
+dissect_rlogin(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+
+ guint8 *Ptr;
+ rlogin_hash_entry_t *hash_info = 0;
+ conversation_t *conversation;
+
+ /* Lookup this connection*/
+ conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
+ pi.srcport, pi.destport);
+
+ if ( conversation) /* conversation found */
+ hash_info = conversation->data;
+
+ /* new conversation create local data structure */
+ else {
+ hash_info = g_mem_chunk_alloc(rlogin_vals);
+ hash_info->state = NONE;
+ hash_info->info_row = 0;
+ hash_info->name[ 0] = 0;
+
+ conversation_new( &pi.src, &pi.dst, pi.ptype,
+ pi.srcport, pi.destport, hash_info);
+ }
+
+ if (check_col(fd, COL_PROTOCOL)) /* update protocol */
+ col_add_str(fd, COL_PROTOCOL, "Rlogin");
+
+ if (check_col(fd, COL_INFO)){ /* display packet info*/
+
+ char temp[1000];
+
+ if ( hash_info->name[0]) {
+ strcpy( temp, "User name: ");
+ strcat( temp, hash_info->name);
+ strcat( temp, ", ");
+ }
+ else
+ temp[0] = 0;
+
+ if ( !GBYTE(pd, offset))
+ strcat( temp, "Start Handshake");
+ else if ( tcp_urgent_pointer)
+ strcat( temp, "Control Message");
+
+ else { /* check for terminal info */
+ Ptr = (guint8*)memchr( &pd[ offset], 0xff, END_OF_FRAME);
+
+ if (( Ptr) && (*(Ptr + 1) == 0xff))
+ strcat( temp, "Terminal Info");
+ else {
+ int i;
+ strcat( temp, "Data:");
+ i = strlen( temp);
+ strncat( temp, &pd[ offset], 128);
+ temp[ i + MIN( 128, END_OF_FRAME)] = 0;
+ }
+ }
+
+ col_add_str(fd, COL_INFO, temp);
+ }
+
+ rlogin_state_machine( hash_info, pd, offset, fd);
+
+ if ( tree) /* if proto tree, decode data */
+ rlogin_display( hash_info, pd, offset, fd, tree);
+}
+
+
+void
+proto_register_rlogin( void){
+
+/* Prep the rlogin protocol, for now, just register it */
+
+ static gint *ett[] = {
+ &ett_rlogin,
+ &ett_rlogin_window,
+ &ett_rlogin_window_rows,
+ &ett_rlogin_window_cols,
+ &ett_rlogin_window_x_pixels,
+ &ett_rlogin_window_y_pixels,
+ &ett_rlogin_user_info
+ };
+
+ static hf_register_info hf[] = {
+
+ { &hf_user_info,
+ { "User Info", "rlogin.user_info", FT_NONE, BASE_NONE,
+ NULL, 0x0, ""
+ }
+ },
+ { &hf_window_info,
+ { "Window Info", "rlogin.window_size", FT_NONE, BASE_NONE,
+ NULL, 0x0, ""
+ }
+ },
+ { &hf_window_info_rows,
+ { "Rows", "rlogin.window_size.rows", FT_UINT16, BASE_DEC,
+ NULL, 0x0, ""
+ }
+ },
+ { &hf_window_info_cols,
+ { "Columns", "rlogin.window_size.cols", FT_UINT16, BASE_DEC,
+ NULL, 0x0, ""
+ }
+ },
+ { &hf_window_info_x_pixels,
+ { "X Pixels", "rlogin.window_size.x_pixels", FT_UINT16, BASE_DEC,
+ NULL, 0x0, ""
+ }
+ },
+ { &hf_window_info_y_pixels,
+ { "Y Pixels", "rlogin.window_size.y_pixels", FT_UINT16, BASE_DEC,
+ NULL, 0x0, ""
+ }
+ }
+ };
+
+
+ proto_rlogin = proto_register_protocol (
+ "Rlogin Protocol", "rlogin");
+
+ proto_register_field_array(proto_rlogin, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ register_init_routine( &rlogin_init); /* register re-init routine */
+
+
+}
+
+void
+proto_reg_handoff_rlogin(void) {
+
+ /* dissector install routine */
+
+ dissector_add("tcp.port", TCP_PORT_RLOGIN, dissect_rlogin);
+}
diff --git a/packet-tcp.c b/packet-tcp.c
index 49157119aa..03b9f3f049 100644
--- a/packet-tcp.c
+++ b/packet-tcp.c
@@ -1,7 +1,7 @@
/* packet-tcp.c
* Routines for TCP packet disassembly
*
- * $Id: packet-tcp.c,v 1.64 2000/04/04 22:26:35 oabad Exp $
+ * $Id: packet-tcp.c,v 1.65 2000/04/08 03:32:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -78,6 +78,8 @@
extern FILE* data_out_file;
+guint16 tcp_urgent_pointer;
+
static gchar info_str[COL_MAX_LEN];
static int info_len;
@@ -417,7 +419,11 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
th.th_urp = ntohs(th.th_urp);
th.th_seq = ntohl(th.th_seq);
th.th_ack = ntohl(th.th_ack);
-
+
+ /* Export the urgent pointer, for the benefit of protocols such as
+ rlogin. */
+ tcp_urgent_pointer = th.th_urp;
+
info_len = 0;
if (check_col(fd, COL_PROTOCOL) || tree) {
diff --git a/packet-tcp.h b/packet-tcp.h
index 1185675528..ee77c53248 100644
--- a/packet-tcp.h
+++ b/packet-tcp.h
@@ -1,6 +1,6 @@
/* packet-tcp.h
*
- * $Id: packet-tcp.h,v 1.1 2000/02/15 21:03:17 gram Exp $
+ * $Id: packet-tcp.h,v 1.2 2000/04/08 03:32:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -22,5 +22,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+/* Urgent pointer value for the current packet. */
+extern guint16 tcp_urgent_pointer;
void dissect_tcp(const u_char *, int, frame_data *, proto_tree *);