Added Richard Sharpe's TFTP support.
svn path=/trunk/; revision=190
This commit is contained in:
parent
58778fd8ad
commit
38a04d2660
|
@ -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 \
|
||||
|
|
13
Makefile.in
13
Makefile.in
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
135
packet-udp.c
135
packet-udp.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
7
packet.h
7
packet.h
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue