diff options
author | Guy Harris <guy@alum.mit.edu> | 1999-02-15 06:36:57 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 1999-02-15 06:36:57 +0000 |
commit | 38a04d266041d513504124245ab1c344ca89bfbd (patch) | |
tree | de9add6ec01e36d58ad3d8b4a4dbcb00ab570d55 | |
parent | 58778fd8ad5d56f3a57fb60e52f6b1c0ae47951c (diff) |
Added Richard Sharpe's TFTP support.
svn path=/trunk/; revision=190
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | Makefile.in | 13 | ||||
-rw-r--r-- | packet-tftp.c | 146 | ||||
-rw-r--r-- | packet-udp.c | 135 | ||||
-rw-r--r-- | packet.h | 7 |
5 files changed, 287 insertions, 15 deletions
diff --git a/Makefile.am b/Makefile.am index 5b187f6252..45463caca7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/Makefile.in b/Makefile.in index 9d688f9431..c2df92c6ee 100644 --- a/Makefile.in +++ b/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) diff --git a/packet-tftp.c b/packet-tftp.c new file mode 100644 index 0000000000..dbb07dd8ca --- /dev/null +++ b/packet-tftp.c @@ -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; + } + + } +} diff --git a/packet-udp.c b/packet-udp.c index 19c4a5018b..a5d6f86e78 100644 --- a/packet-udp.c +++ b/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); + } } } @@ -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, |