blob: 6600c9cf673100acf5650734acb9663a197317d2 [file] [log] [blame]
The Android Open Source Project2949f582009-03-03 19:30:46 -08001/*
2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The Android Open Source Project2949f582009-03-03 19:30:46 -080020 */
21
Elliott Hughese2e3bd12017-05-15 10:59:29 -070022/* \summary: Trivial File Transfer Protocol (TFTP) printer */
23
The Android Open Source Project2949f582009-03-03 19:30:46 -080024#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
Elliott Hughese2e3bd12017-05-15 10:59:29 -070028#include <netdissect-stdinc.h>
The Android Open Source Project2949f582009-03-03 19:30:46 -080029
The Android Open Source Project2949f582009-03-03 19:30:46 -080030#include <string.h>
31
Elliott Hughese2e3bd12017-05-15 10:59:29 -070032#include "netdissect.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080033#include "extract.h"
Elliott Hughes892a68b2015-10-19 14:43:53 -070034
35/*
36 * Trivial File Transfer Protocol (IEN-133)
37 */
38
39/*
40 * Packet types.
41 */
42#define RRQ 01 /* read request */
43#define WRQ 02 /* write request */
44#define DATA 03 /* data packet */
45#define ACK 04 /* acknowledgement */
46#define TFTP_ERROR 05 /* error code */
47#define OACK 06 /* option acknowledgement */
48
Elliott Hughes892a68b2015-10-19 14:43:53 -070049/*
50 * Error codes.
51 */
52#define EUNDEF 0 /* not defined */
53#define ENOTFOUND 1 /* file not found */
54#define EACCESS 2 /* access violation */
55#define ENOSPACE 3 /* disk full or allocation exceeded */
56#define EBADOP 4 /* illegal TFTP operation */
57#define EBADID 5 /* unknown transfer ID */
58#define EEXISTS 6 /* file already exists */
59#define ENOUSER 7 /* no such user */
60
61static const char tstr[] = " [|tftp]";
The Android Open Source Project2949f582009-03-03 19:30:46 -080062
63/* op code to string mapping */
JP Abgrall53f17a92014-02-12 14:02:41 -080064static const struct tok op2str[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -080065 { RRQ, "RRQ" }, /* read request */
66 { WRQ, "WRQ" }, /* write request */
67 { DATA, "DATA" }, /* data packet */
68 { ACK, "ACK" }, /* acknowledgement */
JP Abgrall53f17a92014-02-12 14:02:41 -080069 { TFTP_ERROR, "ERROR" }, /* error code */
The Android Open Source Project2949f582009-03-03 19:30:46 -080070 { OACK, "OACK" }, /* option acknowledgement */
71 { 0, NULL }
72};
73
74/* error code to string mapping */
JP Abgrall53f17a92014-02-12 14:02:41 -080075static const struct tok err2str[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -080076 { EUNDEF, "EUNDEF" }, /* not defined */
77 { ENOTFOUND, "ENOTFOUND" }, /* file not found */
78 { EACCESS, "EACCESS" }, /* access violation */
79 { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */
80 { EBADOP, "EBADOP" }, /* illegal TFTP operation */
81 { EBADID, "EBADID" }, /* unknown transfer ID */
82 { EEXISTS, "EEXISTS" }, /* file already exists */
83 { ENOUSER, "ENOUSER" }, /* no such user */
84 { 0, NULL }
85};
86
87/*
88 * Print trivial file transfer program requests
89 */
90void
Elliott Hughes892a68b2015-10-19 14:43:53 -070091tftp_print(netdissect_options *ndo,
92 register const u_char *bp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -080093{
The Android Open Source Project2949f582009-03-03 19:30:46 -080094 register const char *cp;
Elliott Hughese2e3bd12017-05-15 10:59:29 -070095 register int opcode;
96 u_int ui;
The Android Open Source Project2949f582009-03-03 19:30:46 -080097
The Android Open Source Project2949f582009-03-03 19:30:46 -080098 /* Print length */
Elliott Hughes892a68b2015-10-19 14:43:53 -070099 ND_PRINT((ndo, " %d", length));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800100
101 /* Print tftp request type */
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700102 if (length < 2)
103 goto trunc;
Elliott Hughescec480a2017-12-19 16:54:57 -0800104 ND_TCHECK_16BITS(bp);
105 opcode = EXTRACT_16BITS(bp);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800106 cp = tok2str(op2str, "tftp-#%d", opcode);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700107 ND_PRINT((ndo, " %s", cp));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800108 /* Bail if bogus opcode */
109 if (*cp == 't')
110 return;
Elliott Hughescec480a2017-12-19 16:54:57 -0800111 bp += 2;
112 length -= 2;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800113
114 switch (opcode) {
115
116 case RRQ:
117 case WRQ:
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700118 if (length == 0)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800119 goto trunc;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700120 ND_PRINT((ndo, " "));
121 /* Print filename */
122 ND_PRINT((ndo, "\""));
Elliott Hughescec480a2017-12-19 16:54:57 -0800123 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700124 ND_PRINT((ndo, "\""));
125 if (ui == 0)
126 goto trunc;
Elliott Hughescec480a2017-12-19 16:54:57 -0800127 bp += ui;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700128 length -= ui;
129
130 /* Print the mode - RRQ and WRQ only */
131 if (length == 0)
132 goto trunc; /* no mode */
133 ND_PRINT((ndo, " "));
Elliott Hughescec480a2017-12-19 16:54:57 -0800134 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700135 if (ui == 0)
136 goto trunc;
Elliott Hughescec480a2017-12-19 16:54:57 -0800137 bp += ui;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700138 length -= ui;
139
140 /* Print options, if any */
141 while (length != 0) {
Elliott Hughescec480a2017-12-19 16:54:57 -0800142 ND_TCHECK(*bp);
143 if (*bp != '\0')
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700144 ND_PRINT((ndo, " "));
Elliott Hughescec480a2017-12-19 16:54:57 -0800145 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700146 if (ui == 0)
147 goto trunc;
Elliott Hughescec480a2017-12-19 16:54:57 -0800148 bp += ui;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700149 length -= ui;
150 }
151 break;
152
153 case OACK:
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700154 /* Print options */
155 while (length != 0) {
Elliott Hughescec480a2017-12-19 16:54:57 -0800156 ND_TCHECK(*bp);
157 if (*bp != '\0')
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700158 ND_PRINT((ndo, " "));
Elliott Hughescec480a2017-12-19 16:54:57 -0800159 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700160 if (ui == 0)
161 goto trunc;
Elliott Hughescec480a2017-12-19 16:54:57 -0800162 bp += ui;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700163 length -= ui;
164 }
The Android Open Source Project2949f582009-03-03 19:30:46 -0800165 break;
166
167 case ACK:
168 case DATA:
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700169 if (length < 2)
170 goto trunc; /* no block number */
Elliott Hughescec480a2017-12-19 16:54:57 -0800171 ND_TCHECK_16BITS(bp);
172 ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800173 break;
174
JP Abgrall53f17a92014-02-12 14:02:41 -0800175 case TFTP_ERROR:
The Android Open Source Project2949f582009-03-03 19:30:46 -0800176 /* Print error code string */
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700177 if (length < 2)
178 goto trunc; /* no error code */
Elliott Hughescec480a2017-12-19 16:54:57 -0800179 ND_TCHECK_16BITS(bp);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700180 ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
Elliott Hughescec480a2017-12-19 16:54:57 -0800181 EXTRACT_16BITS(bp))));
182 bp += 2;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700183 length -= 2;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800184 /* Print error message string */
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700185 if (length == 0)
186 goto trunc; /* no error message */
187 ND_PRINT((ndo, " \""));
Elliott Hughescec480a2017-12-19 16:54:57 -0800188 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700189 ND_PRINT((ndo, "\""));
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700190 if (ui == 0)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800191 goto trunc;
192 break;
193
194 default:
195 /* We shouldn't get here */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700196 ND_PRINT((ndo, "(unknown #%d)", opcode));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800197 break;
198 }
199 return;
200trunc:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700201 ND_PRINT((ndo, "%s", tstr));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800202 return;
203}