2000-04-08 03:32:10 +00:00
|
|
|
/* packet-rlogin.c
|
|
|
|
* Routines for unix rlogin packet dissection
|
|
|
|
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
|
|
|
|
*
|
2001-01-03 06:56:03 +00:00
|
|
|
* $Id: packet-rlogin.c,v 1.12 2001/01/03 06:55:31 guy Exp $
|
2000-04-08 03:32:10 +00:00
|
|
|
*
|
|
|
|
* 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>
|
2000-08-11 13:37:21 +00:00
|
|
|
|
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
2000-04-08 03:32:10 +00:00
|
|
|
#include "packet.h"
|
|
|
|
#include "resolv.h"
|
|
|
|
#include "globals.h"
|
|
|
|
#include "alignment.h"
|
|
|
|
#include "conversation.h"
|
|
|
|
|
|
|
|
#include "packet-tcp.h"
|
|
|
|
|
|
|
|
|
2000-08-06 08:53:44 +00:00
|
|
|
#define CHECK_PACKET_LENGTH(X) if (!BYTES_ARE_IN_FRAME(offset, X)){ \
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text(tree, NullTVB, offset, 0, "*** FRAME TOO SHORT ***"); \
|
2000-04-08 03:32:10 +00:00
|
|
|
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 NAME_LEN 32
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int state;
|
2000-08-06 05:19:25 +00:00
|
|
|
int info_framenum;
|
2000-04-08 03:32:10 +00:00
|
|
|
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;
|
|
|
|
|
2000-08-06 08:53:44 +00:00
|
|
|
/* Find the length of a '\0'-terminated string, *INCLUDING* the terminating
|
|
|
|
'\0', but don't run past the end of the packet doing so. */
|
|
|
|
static int
|
|
|
|
string_len(const char *str, int maxlen)
|
|
|
|
{
|
|
|
|
const char *str_end;
|
|
|
|
|
|
|
|
str_end = memchr(str, '\0', maxlen);
|
|
|
|
if (str_end == NULL) {
|
|
|
|
/* No '\0' found - return the length as of when we stopped,
|
|
|
|
plus one to force the length to be too long and and
|
|
|
|
CHECK_PACKET_LENGTH to fail. */
|
|
|
|
return maxlen + 1;
|
|
|
|
}
|
|
|
|
return str_end - str + 1;
|
|
|
|
}
|
|
|
|
|
2000-04-08 03:32:10 +00:00
|
|
|
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;
|
2000-08-06 05:19:25 +00:00
|
|
|
hash_info->info_framenum = fd->num;
|
2000-04-08 03:32:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* expect user data here */
|
|
|
|
/*$$$ may need to do more checking here */
|
|
|
|
else if ( hash_info->state == USER_INFO_WAIT) {
|
|
|
|
hash_info->state = DONE;
|
2000-08-06 05:19:25 +00:00
|
|
|
hash_info->info_framenum = fd->num;
|
2000-04-08 03:32:10 +00:00
|
|
|
/* 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;
|
2000-08-06 08:53:44 +00:00
|
|
|
int str_len;
|
2000-04-08 03:32:10 +00:00
|
|
|
proto_item *user_info_item, *window_info_item;
|
|
|
|
|
2000-05-11 08:18:09 +00:00
|
|
|
ti = proto_tree_add_item( tree, proto_rlogin, NullTVB, offset,
|
2000-05-31 05:09:07 +00:00
|
|
|
END_OF_FRAME, FALSE);
|
2000-04-08 03:32:10 +00:00
|
|
|
|
|
|
|
rlogin_tree = proto_item_add_subtree(ti, ett_rlogin);
|
|
|
|
|
2000-08-06 08:53:44 +00:00
|
|
|
if ( !IS_DATA_IN_FRAME(offset)) /* exit if no data */
|
2000-04-08 03:32:10 +00:00
|
|
|
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 */
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text( rlogin_tree, NullTVB, offset, i - offset,
|
2000-04-08 03:32:10 +00:00
|
|
|
"Data");
|
|
|
|
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text( rlogin_tree, NullTVB, i, 1, "Control byte: %u (%s)",
|
2000-04-08 03:32:10 +00:00
|
|
|
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 */
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text(rlogin_tree, NullTVB, offset, 1,
|
2000-04-08 03:32:10 +00:00
|
|
|
"Startup info received flag (0x00)");
|
|
|
|
|
|
|
|
else
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text(rlogin_tree, NullTVB, offset, 1,
|
2000-04-08 03:32:10 +00:00
|
|
|
"Client Startup Flag (0x00)");
|
|
|
|
++offset;
|
|
|
|
}
|
|
|
|
|
2000-08-06 08:53:44 +00:00
|
|
|
if (!IS_DATA_IN_FRAME(offset))
|
|
|
|
return; /* No more data to check */
|
2000-04-08 03:32:10 +00:00
|
|
|
|
2000-08-06 08:53:44 +00:00
|
|
|
if ( hash_info->info_framenum == fd->num){ /* user info ?*/
|
2000-05-11 08:18:09 +00:00
|
|
|
user_info_item = proto_tree_add_item( rlogin_tree, hf_user_info, NullTVB,
|
2000-05-31 05:09:07 +00:00
|
|
|
offset, END_OF_FRAME, FALSE);
|
2000-04-08 03:32:10 +00:00
|
|
|
|
|
|
|
str = &pd[ offset]; /* do server user name */
|
2000-08-06 08:53:44 +00:00
|
|
|
str_len = string_len( str, END_OF_FRAME);
|
|
|
|
CHECK_PACKET_LENGTH( str_len);
|
2000-04-08 03:32:10 +00:00
|
|
|
user_info_tree = proto_item_add_subtree( user_info_item,
|
|
|
|
ett_rlogin_user_info);
|
2000-08-06 08:53:44 +00:00
|
|
|
proto_tree_add_text( user_info_tree, NullTVB, offset, str_len,
|
|
|
|
"Server User Name: %.*s", str_len, str);
|
|
|
|
offset += str_len;
|
|
|
|
|
|
|
|
if (!IS_DATA_IN_FRAME(offset))
|
|
|
|
return; /* No more data to check */
|
2000-04-08 03:32:10 +00:00
|
|
|
str = &pd[ offset]; /* do client user name */
|
2000-08-06 08:53:44 +00:00
|
|
|
str_len = string_len( str, END_OF_FRAME);
|
|
|
|
CHECK_PACKET_LENGTH( str_len);
|
|
|
|
proto_tree_add_text( user_info_tree, NullTVB, offset, str_len,
|
|
|
|
"Client User Name: %.*s", str_len, str);
|
|
|
|
offset += str_len;
|
2000-04-08 03:32:10 +00:00
|
|
|
|
2000-08-06 08:53:44 +00:00
|
|
|
if (!IS_DATA_IN_FRAME(offset))
|
|
|
|
return; /* No more data to check */
|
2000-04-08 03:32:10 +00:00
|
|
|
str = &pd[ offset]; /* do terminal type/speed */
|
2000-08-06 08:53:44 +00:00
|
|
|
str_len = string_len( str, END_OF_FRAME);
|
|
|
|
CHECK_PACKET_LENGTH( str_len);
|
|
|
|
proto_tree_add_text( user_info_tree, NullTVB, offset, str_len,
|
|
|
|
"Terminal Type/Speed: %.*s", str_len, str);
|
|
|
|
offset += str_len;
|
2000-04-08 03:32:10 +00:00
|
|
|
}
|
|
|
|
|
2000-08-06 08:53:44 +00:00
|
|
|
if (!IS_DATA_IN_FRAME(offset))
|
|
|
|
return; /* No more data to check */
|
|
|
|
|
2000-04-08 03:32:10 +00:00
|
|
|
/* 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*/
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text( rlogin_tree, NullTVB, offset,
|
2000-04-08 03:32:10 +00:00
|
|
|
(ti_offset - offset), "Data");
|
|
|
|
offset = ti_offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
CHECK_PACKET_LENGTH( 12);
|
|
|
|
window_info_item = proto_tree_add_item( rlogin_tree,
|
2000-05-31 05:09:07 +00:00
|
|
|
hf_window_info, NullTVB, offset, 12, FALSE );
|
2000-04-08 03:32:10 +00:00
|
|
|
|
|
|
|
window_tree = proto_item_add_subtree( window_info_item,
|
|
|
|
ett_rlogin_window);
|
|
|
|
|
|
|
|
CHECK_PACKET_LENGTH( 2);
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text( window_tree, NullTVB, offset, 2,
|
2000-04-08 03:32:10 +00:00
|
|
|
"Magic Cookie: (0xff, 0xff)");
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
CHECK_PACKET_LENGTH( 2);
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text( window_tree, NullTVB, offset, 2,
|
2000-04-08 03:32:10 +00:00
|
|
|
"Window size marker: 'ss'");
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
CHECK_PACKET_LENGTH( 2);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint( window_tree, hf_window_info_rows, NullTVB, offset,
|
2000-04-08 03:32:10 +00:00
|
|
|
2, pntohs( &pd[offset]));
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
CHECK_PACKET_LENGTH( 2);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint( window_tree, hf_window_info_cols, NullTVB, offset,
|
2000-04-08 03:32:10 +00:00
|
|
|
2, pntohs( &pd[offset]) );
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
CHECK_PACKET_LENGTH( 2);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint( window_tree, hf_window_info_x_pixels, NullTVB,
|
2000-04-08 03:32:10 +00:00
|
|
|
offset, 2, pntohs( &pd[offset]));
|
|
|
|
offset += 2;
|
|
|
|
|
|
|
|
CHECK_PACKET_LENGTH( 2);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint( window_tree, hf_window_info_y_pixels, NullTVB,
|
2000-04-08 03:32:10 +00:00
|
|
|
offset, 2, pntohs( &pd[offset]) );
|
|
|
|
offset += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( END_OF_FRAME != 0) /* if more data */
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_text(rlogin_tree, NullTVB, offset, END_OF_FRAME, "Data");
|
2000-04-08 03:32:10 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
Add the "Edit:Protocols..." feature which currently only implements
the following:
It is now possible to enable/disable a particular protocol decoding
(i.e. the protocol dissector is void or not). When a protocol
is disabled, it is displayed as Data and of course, all linked
sub-protocols are disabled as well.
Disabling a protocol could be interesting:
- in case of buggy dissectors
- in case of wrong heuristics
- for performance reasons
- to decode the data as another protocol (TODO)
Currently (if I am not wrong), all dissectors but NFS can be disabled
(and dissectors that do not register protocols :-)
I do not like the way the RPC sub-dissectors are disabled (in the
sub-dissectors) since this could be done in the RPC dissector itself,
knowing the sub-protocol hfinfo entry (this is why, I've not modified
the NFS one yet).
Two functions are added in proto.c :
gboolean proto_is_protocol_enabled(int n);
void proto_set_decoding(int n, gboolean enabled);
and two MACROs which can be used in dissectors:
OLD_CHECK_DISPLAY_AS_DATA(index, pd, offset, fd, tree)
CHECK_DISPLAY_AS_DATA(index, tvb, pinfo, tree)
See also the XXX in proto_dlg.c and proto.c around the new functions.
svn path=/trunk/; revision=2267
2000-08-13 14:09:15 +00:00
|
|
|
OLD_CHECK_DISPLAY_AS_DATA(proto_rlogin, pd, offset, fd, tree);
|
|
|
|
|
2000-04-08 03:32:10 +00:00
|
|
|
/* Lookup this connection*/
|
|
|
|
conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
|
2000-10-21 05:52:28 +00:00
|
|
|
pi.srcport, pi.destport, 0);
|
2000-04-08 03:32:10 +00:00
|
|
|
|
|
|
|
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;
|
2000-08-06 05:19:25 +00:00
|
|
|
hash_info->info_framenum = -1;
|
2000-04-08 03:32:10 +00:00
|
|
|
hash_info->name[ 0] = 0;
|
|
|
|
|
|
|
|
conversation_new( &pi.src, &pi.dst, pi.ptype,
|
2000-10-21 05:52:28 +00:00
|
|
|
pi.srcport, pi.destport, hash_info, 0);
|
2000-04-08 03:32:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (check_col(fd, COL_PROTOCOL)) /* update protocol */
|
2000-11-19 08:54:37 +00:00
|
|
|
col_set_str(fd, COL_PROTOCOL, "Rlogin");
|
2000-04-08 03:32:10 +00:00
|
|
|
|
|
|
|
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 (
|
2001-01-03 06:56:03 +00:00
|
|
|
"Rlogin Protocol", "Rlogin", "rlogin");
|
2000-04-08 03:32:10 +00:00
|
|
|
|
|
|
|
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 */
|
|
|
|
|
Allow either old-style (pre-tvbuff) or new-style (tvbuffified)
dissectors to be registered as dissectors for particular ports,
registered as heuristic dissectors, and registered as dissectors for
conversations, and have routines to be used both by old-style and
new-style dissectors to call registered dissectors.
Have the code that calls those dissectors translate the arguments as
necessary. (For conversation dissectors, replace
"find_conversation_dissector()", which just returns a pointer to the
dissector, with "old_try_conversation_dissector()" and
"try_conversation_dissector()", which actually call the dissector, so
that there's a single place at which we can do that translation. Also
make "dissector_lookup()" static and, instead of calling it and, if it
returns a non-null pointer, calling that dissector, just use
"old_dissector_try_port()" or "dissector_try_port()", for the same
reason.)
This allows some dissectors that took old-style arguments and
immediately translated them to new-style arguments to just take
new-style arguments; make them do so. It also allows some new-style
dissectors not to have to translate arguments before calling routines to
look up and call dissectors; make them not do so.
Get rid of checks for too-short frames in new-style dissectors - the
tvbuff code does those checks for you.
Give the routines to register old-style dissectors, and to call
dissectors from old-style dissectors, names beginning with "old_", with
the routines for new-style dissectors not having the "old_". Update the
dissectors that use those routines appropriately.
Rename "dissect_data()" to "old_dissect_data()", and
"dissect_data_tvb()" to "dissect_data()".
svn path=/trunk/; revision=2218
2000-08-07 03:21:25 +00:00
|
|
|
old_dissector_add("tcp.port", TCP_PORT_RLOGIN, dissect_rlogin);
|
2000-04-08 03:32:10 +00:00
|
|
|
}
|