Added Richard Sharpe's TFTP support.

svn path=/trunk/; revision=190
This commit is contained in:
Guy Harris 1999-02-15 06:36:57 +00:00
parent 58778fd8ad
commit 38a04d2660
5 changed files with 287 additions and 15 deletions

View File

@ -40,6 +40,7 @@ ethereal_SOURCES = \
packet-raw.c \
packet-rip.c \
packet-tcp.c \
packet-tftp.c \
packet-tr.c \
packet-trmac.c \
packet-udp.c \

View File

@ -115,6 +115,7 @@ ethereal_SOURCES = \
packet-raw.c \
packet-rip.c \
packet-tcp.c \
packet-tftp.c \
packet-tr.c \
packet-trmac.c \
packet-udp.c \
@ -188,9 +189,9 @@ packet-atalk.o packet-bootp.o packet-cdp.o packet-data.o packet-dns.o \
packet-eth.o packet-fddi.o packet-giop.o packet-http.o packet-llc.o \
packet-lpd.o packet-ip.o packet-ipv6.o packet-ipx.o packet-nbipx.o \
packet-nbns.o packet-ncp.o packet-null.o packet-osi.o packet-ospf.o \
packet-ppp.o packet-raw.o packet-rip.o packet-tcp.o packet-tr.o \
packet-trmac.o packet-udp.o packet-vines.o prefs.o print.o ps.o \
resolv.o util.o
packet-ppp.o packet-raw.o packet-rip.o packet-tcp.o packet-tftp.o \
packet-tr.o packet-trmac.o packet-udp.o packet-vines.o prefs.o print.o \
ps.o resolv.o util.o
ethereal_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
@ -222,9 +223,9 @@ DEP_FILES = .deps/capture.P .deps/column.P .deps/ethereal.P \
.deps/packet-nbns.P .deps/packet-ncp.P .deps/packet-null.P \
.deps/packet-osi.P .deps/packet-ospf.P .deps/packet-ppp.P \
.deps/packet-raw.P .deps/packet-rip.P .deps/packet-tcp.P \
.deps/packet-tr.P .deps/packet-trmac.P .deps/packet-udp.P \
.deps/packet-vines.P .deps/packet.P .deps/prefs.P .deps/print.P \
.deps/ps.P .deps/resolv.P .deps/snprintf.P .deps/util.P
.deps/packet-tftp.P .deps/packet-tr.P .deps/packet-trmac.P \
.deps/packet-udp.P .deps/packet-vines.P .deps/packet.P .deps/prefs.P \
.deps/print.P .deps/ps.P .deps/resolv.P .deps/snprintf.P .deps/util.P
SOURCES = $(ethereal_SOURCES) $(EXTRA_ethereal_SOURCES)
OBJECTS = $(ethereal_OBJECTS)

146
packet-tftp.c Normal file
View File

@ -0,0 +1,146 @@
/* packet-tftp.c
* Routines for tftp packet dissection
*
* Richard Sharpe <rsharpe@ns.aus.com>
*
* $Id: packet-tftp.c,v 1.1 1999/02/15 06:36:56 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@unicom.net>
* Copyright 1998 Gerald Combs
*
* Copied from packet-bootp.c
*
* 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
#include <gtk/gtk.h>
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#include <arpa/tftp.h>
#include "ethereal.h"
#include "packet.h"
#include "etypes.h"
char *tftp_opcodes[8] = {
"Unknown Request",
"Read Request",
"Write Request",
"Data Packet",
"Acknowledgement",
"Error Code",
"Unknown Request",
"Unknown Request"
};
char *tftp_errors[8] = {
"Not defined",
"File not found",
"Access violation",
"Disk full or allocation exceeded",
"Illegal TFTP Operation",
"Unknown transfer ID",
"File already exists",
"No such user"
};
void
dissect_tftp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
{
GtkWidget *tftp_tree, *ti;
struct tftphdr *tftp_pack = (struct tftphdr *)&pd[offset]; /* Want the hdr */
u_int i1;
if (check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "TFTP");
if (check_col(fd, COL_INFO)) {
i1 = ntohs(tftp_pack -> th_opcode);
col_add_fstr(fd, COL_INFO, "TFTP %s", i1 <= ERROR ? tftp_opcodes[i1 % 8] : "Unknown Request");
}
if (tree) {
ti = add_item_to_tree(GTK_WIDGET(tree), offset, END_OF_FRAME,
"Trivial File Transfer Protocol");
tftp_tree = gtk_tree_new();
add_subtree(ti, tftp_tree, ETT_TFTP);
switch (i1 = ntohs(tftp_pack -> th_opcode)) {
case RRQ:
add_item_to_tree(tftp_tree, offset, 2, "Read Request");
offset += 2;
i1 = strlen(pd+offset);
add_item_to_tree(tftp_tree, offset, i1+1, "Source File: %s", pd+offset);
offset += i1 + 1;
add_item_to_tree(tftp_tree, offset, END_OF_FRAME, "Type: %s",pd+offset);
break;
case WRQ:
add_item_to_tree(tftp_tree, offset, 2, "Write Request");
offset += 2;
i1 = strlen(pd+offset);
add_item_to_tree(tftp_tree, offset, i1+1, "Destination File: %s", pd+offset);
offset += i1 + 1;
add_item_to_tree(tftp_tree, offset+2, END_OF_FRAME, "Type: %s",pd+offset);
break;
case DATA:
add_item_to_tree(tftp_tree, offset, 2, "Data Packet");
offset += 2;
i1 = ntohs(*(short *)(pd + offset));
add_item_to_tree(tftp_tree, offset, 2, "Block = %u", i1);
offset += 2;
add_item_to_tree(tftp_tree, offset, END_OF_FRAME,
"Data (%d bytes)", END_OF_FRAME);
break;
case ACK:
add_item_to_tree(tftp_tree, offset, 2, "Acknowledgement");
offset += 2;
i1 = ntohs(*(short *)(pd + offset));
add_item_to_tree(tftp_tree, offset, END_OF_FRAME, "Block = %u", i1);
break;
case ERROR:
add_item_to_tree(tftp_tree, offset, 2, "Error Code");
offset += 2;
i1 = ntohs(*(short *)(pd + offset));
add_item_to_tree(tftp_tree, offset, 2, "Code = %s", tftp_errors[i1 % 8]);
offset += 2;
add_item_to_tree(tftp_tree, offset, END_OF_FRAME, "Error Message: %s", pd + offset);
break;
default:
add_item_to_tree(tftp_tree, offset, 2, "Unknown TFTP Request: %0X.", i1);
offset += 2;
add_item_to_tree(tftp_tree, offset, END_OF_FRAME,
"Data (%d bytes)", END_OF_FRAME);
break;
}
}
}

View File

@ -1,12 +1,14 @@
/* packet-udp.c
* Routines for UDP packet disassembly
*
* $Id: packet-udp.c,v 1.11 1998/12/29 04:05:36 gerald Exp $
* $Id: packet-udp.c,v 1.12 1999/02/15 06:36:57 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
* Richard Sharpe, 13-Feb-1999, added dispatch table support and
* support for tftp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -43,10 +45,99 @@
#include "packet.h"
#include "resolv.h"
struct hash_struct {
guint16 proto;
void (*dissect)(const u_char *, int, frame_data *, GtkTree *);
struct hash_struct *next;
};
struct hash_struct *hash_table[256];
/*
* These routines are for UDP, will be generalized soon: RJS
*
* XXX - note that they should probably check the IP address as well as
* the port number, so that we don't mistakenly identify packets as, say,
* TFTP, merely because they have a source or destination port number
* equal to the port being used by a TFTP daemon on some machine other
* than the one they're going to or from.
*/
struct hash_struct *udp_find_hash_ent(guint16 proto) {
int idx = proto % 256;
struct hash_struct *hash_ent = hash_table[idx];
while (hash_ent != NULL) {
if (hash_ent -> proto == proto)
return hash_ent;
hash_ent = hash_ent -> next;
}
return NULL;
}
void udp_hash_add(guint16 proto,
void (*dissect)(const u_char *, int, frame_data *, GtkTree *)) {
int idx = proto % 256; /* Simply take the remainder, hope for no collisions */
struct hash_struct *hash_ent = (struct hash_struct *)malloc(sizeof(struct hash_struct));
struct hash_struct *hash_ent2;
hash_ent -> proto = proto;
hash_ent -> dissect = dissect;
hash_ent -> next = NULL;
if (hash_ent == NULL) {
fprintf(stderr, "Could not allocate space for hash structure in dissect_udp\n");
exit(1);
}
if (hash_table[idx]) { /* Something, add on end */
hash_ent2 = hash_table[idx];
while (hash_ent2 -> next != NULL)
hash_ent2 = hash_ent2 -> next;
hash_ent2 -> next = hash_ent; /* Bad in pathalogical cases */
}
else {
hash_table[idx] = hash_ent;
}
}
void init_dissect_udp(void) {
int i;
for (i = 0; i < 256; i++) {
hash_table[i] = NULL;
}
/* Now add the protocols we know about */
udp_hash_add(UDP_PORT_BOOTPS, dissect_bootp);
udp_hash_add(UDP_PORT_TFTP, dissect_tftp);
}
void
dissect_udp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
e_udphdr uh;
guint16 uh_sport, uh_dport, uh_ulen, uh_sum;
struct hash_struct *dissect_routine = NULL;
GtkWidget *udp_tree, *ti;
/* To do: Check for {cap len,pkt len} < struct len */
@ -99,12 +190,12 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
/* we should check the source port too (RIP: UDP src and dst port 520) */
dissect_rip(pd, offset, fd, tree);
break;
case UDP_PORT_NBNS:
dissect_nbns(pd, offset, fd, tree);
break;
case UDP_PORT_NBDGM:
dissect_nbdgm(pd, offset, fd, tree);
break;
case UDP_PORT_NBNS:
dissect_nbns(pd, offset, fd, tree);
break;
case UDP_PORT_NBDGM:
dissect_nbdgm(pd, offset, fd, tree);
break;
case UDP_PORT_IPX: /* RFC 1234 */
dissect_ipx(pd, offset, fd, tree);
break;
@ -112,7 +203,35 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
/* FIXME: AFAIK, src and dst port must be the same */
dissect_vines_frp(pd, offset, fd, tree);
break;
case UDP_PORT_TFTP:
/* This is the first point of call, but it adds a dynamic call */
udp_hash_add(MAX(uh_sport, uh_dport), dissect_tftp); /* Add to table */
dissect_tftp(pd, offset, fd, tree);
break;
default:
dissect_data(pd, offset, fd, tree);
/* OK, find a routine in the table, else use the default */
if ((dissect_routine = udp_find_hash_ent(uh_sport))) {
struct hash_struct *dr2 = udp_find_hash_ent(uh_dport);
if (dr2 == NULL) { /* Not in the table, add */
udp_hash_add(uh_dport, dissect_tftp);
}
dissect_routine -> dissect(pd, offset, fd, tree);
}
else if ((dissect_routine = udp_find_hash_ent(uh_dport))) {
dissect_routine -> dissect(pd, offset, fd, tree);
}
else {
dissect_data(pd, offset, fd, tree);
}
}
}

View File

@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
* $Id: packet.h,v 1.37 1999/02/12 09:03:40 guy Exp $
* $Id: packet.h,v 1.38 1999/02/15 06:36:57 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -361,6 +361,7 @@ typedef struct _e_udphdr {
#define UDP_PORT_DNS 53
#define UDP_PORT_BOOTPS 67
#define UDP_PORT_TFTP 69
#define UDP_PORT_IPX 213
#define UDP_PORT_NBNS 137
#define UDP_PORT_NBDGM 138
@ -452,6 +453,7 @@ enum {
ETT_NBDGM,
ETT_CDP,
ETT_HTTP,
ETT_TFTP,
NUM_TREE_TYPES /* last item number plus one */
};
@ -590,6 +592,7 @@ void dissect_ospf(const u_char *, int, frame_data *, GtkTree *);
void dissect_ospf_hello(const u_char *, int, frame_data *, GtkTree *);
void dissect_rip(const u_char *, int, frame_data *, GtkTree *);
void dissect_tcp(const u_char *, int, frame_data *, GtkTree *);
void dissect_tftp(const u_char *, int, frame_data *, GtkTree *);
void dissect_trmac(const u_char *, int, frame_data *, GtkTree *);
void dissect_udp(const u_char *, int, frame_data *, GtkTree *);
void dissect_vines(const u_char *, int, frame_data *, GtkTree *);
@ -600,6 +603,8 @@ void dissect_vines_ipc(const u_char *, int, frame_data *, GtkTree *);
void dissect_vines_rtp(const u_char *, int, frame_data *, GtkTree *);
void dissect_vines_spp(const u_char *, int, frame_data *, GtkTree *);
void init_dissect_udp(void);
/* These functions are in ethertype.c */
gchar *ethertype_to_str(guint16 etype, const char *fmt);
void capture_ethertype(guint16 etype, int offset,