Added Richard Sharpe's TFTP support.
[obnox/wireshark/wip.git] / packet-tftp.c
1 /* packet-tftp.c
2  * Routines for tftp packet dissection
3  *
4  * Richard Sharpe <rsharpe@ns.aus.com>
5  *
6  * $Id: packet-tftp.c,v 1.1 1999/02/15 06:36:56 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@unicom.net>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-bootp.c
13  * 
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  * 
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <gtk/gtk.h>
34
35 #include <stdio.h>
36
37 #ifdef HAVE_SYS_TYPES_H
38 # include <sys/types.h>
39 #endif
40
41 #ifdef HAVE_NETINET_IN_H
42 # include <netinet/in.h>
43 #endif
44
45 #include <arpa/tftp.h>
46
47 #include "ethereal.h"
48 #include "packet.h"
49 #include "etypes.h"
50
51 char *tftp_opcodes[8] = {
52   "Unknown Request",
53   "Read Request",
54   "Write Request",
55   "Data Packet",
56   "Acknowledgement",
57   "Error Code",
58   "Unknown Request",
59   "Unknown Request"
60 };
61
62 char *tftp_errors[8] = {
63   "Not defined",
64   "File not found",
65   "Access violation",
66   "Disk full or allocation exceeded",
67   "Illegal TFTP Operation",
68   "Unknown transfer ID",
69   "File already exists",
70   "No such user"
71 };
72
73 void
74 dissect_tftp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
75 {
76         GtkWidget       *tftp_tree, *ti;
77         struct tftphdr  *tftp_pack = (struct tftphdr *)&pd[offset]; /* Want the hdr */
78         u_int           i1;
79
80         if (check_col(fd, COL_PROTOCOL))
81                 col_add_str(fd, COL_PROTOCOL, "TFTP");
82
83         if (check_col(fd, COL_INFO)) {
84
85           i1 = ntohs(tftp_pack -> th_opcode);
86           col_add_fstr(fd, COL_INFO, "TFTP %s", i1 <= ERROR ? tftp_opcodes[i1 % 8] : "Unknown Request");
87
88         }
89
90         if (tree) {
91
92           ti = add_item_to_tree(GTK_WIDGET(tree), offset, END_OF_FRAME,
93                                 "Trivial File Transfer Protocol");
94           tftp_tree = gtk_tree_new();
95           add_subtree(ti, tftp_tree, ETT_TFTP);
96
97           switch (i1 = ntohs(tftp_pack -> th_opcode)) {
98           case RRQ:
99             add_item_to_tree(tftp_tree, offset, 2, "Read Request");
100             offset += 2;
101             i1 = strlen(pd+offset);
102             add_item_to_tree(tftp_tree, offset, i1+1, "Source File: %s", pd+offset);
103             offset += i1 + 1;
104             add_item_to_tree(tftp_tree, offset, END_OF_FRAME, "Type: %s",pd+offset);
105             break;
106           case WRQ:
107             add_item_to_tree(tftp_tree, offset, 2, "Write Request");
108             offset += 2;
109             i1 = strlen(pd+offset);
110             add_item_to_tree(tftp_tree, offset, i1+1, "Destination File: %s", pd+offset);
111             offset += i1 + 1;
112             add_item_to_tree(tftp_tree, offset+2, END_OF_FRAME, "Type: %s",pd+offset);
113             break;
114           case DATA:
115             add_item_to_tree(tftp_tree, offset, 2, "Data Packet");
116             offset += 2;
117             i1 = ntohs(*(short *)(pd + offset));
118             add_item_to_tree(tftp_tree, offset, 2, "Block = %u", i1);
119             offset += 2;
120             add_item_to_tree(tftp_tree, offset, END_OF_FRAME,
121                 "Data (%d bytes)", END_OF_FRAME);
122             break;
123           case ACK:
124             add_item_to_tree(tftp_tree, offset, 2, "Acknowledgement");
125             offset += 2;
126             i1 = ntohs(*(short *)(pd + offset));
127             add_item_to_tree(tftp_tree, offset, END_OF_FRAME, "Block = %u", i1);
128             break;
129           case ERROR:
130             add_item_to_tree(tftp_tree, offset, 2, "Error Code");
131             offset += 2;
132             i1 = ntohs(*(short *)(pd + offset));
133             add_item_to_tree(tftp_tree, offset, 2, "Code = %s", tftp_errors[i1 % 8]);
134             offset += 2;
135             add_item_to_tree(tftp_tree, offset, END_OF_FRAME, "Error Message: %s", pd + offset);
136             break;
137           default:
138             add_item_to_tree(tftp_tree, offset, 2, "Unknown TFTP Request: %0X.", i1);
139             offset += 2;
140             add_item_to_tree(tftp_tree, offset, END_OF_FRAME,
141                 "Data (%d bytes)", END_OF_FRAME);
142             break;
143           }
144
145         }
146 }