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
This commit is contained in:
parent
43c9217ba4
commit
160928a318
3
AUTHORS
3
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> {
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
10
packet-tcp.c
10
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) {
|
||||
|
|
|
@ -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 *);
|
||||
|
|
Loading…
Reference in New Issue