117680Spst/*
239297Sfenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
317680Spst *	The Regents of the University of California.  All rights reserved.
417680Spst *
517680Spst * Redistribution and use in source and binary forms, with or without
617680Spst * modification, are permitted provided that: (1) source code distributions
717680Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817680Spst * distributions including binary code include the above copyright notice and
917680Spst * this paragraph in its entirety in the documentation or other materials
1017680Spst * provided with the distribution, and (3) all advertising materials mentioning
1117680Spst * features or use of this software display the following acknowledgement:
1217680Spst * ``This product includes software developed by the University of California,
1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417680Spst * the University nor the names of its contributors may be used to endorse
1517680Spst * or promote products derived from this software without specific prior
1617680Spst * written permission.
1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2017680Spst */
2117680Spst
22313537Sglebius/* \summary: Trivial File Transfer Protocol (TFTP) printer */
23313537Sglebius
2456893Sfenner#ifdef HAVE_CONFIG_H
2556893Sfenner#include "config.h"
2656893Sfenner#endif
2756893Sfenner
28313537Sglebius#include <netdissect-stdinc.h>
2917680Spst
3017680Spst#include <string.h>
3117680Spst
32313537Sglebius#include "netdissect.h"
33127668Sbms#include "extract.h"
3417680Spst
35276788Sdelphij/*
36276788Sdelphij * Trivial File Transfer Protocol (IEN-133)
37276788Sdelphij */
38276788Sdelphij
39276788Sdelphij/*
40276788Sdelphij * Packet types.
41276788Sdelphij */
42276788Sdelphij#define	RRQ	01			/* read request */
43276788Sdelphij#define	WRQ	02			/* write request */
44276788Sdelphij#define	DATA	03			/* data packet */
45276788Sdelphij#define	ACK	04			/* acknowledgement */
46276788Sdelphij#define	TFTP_ERROR	05			/* error code */
47276788Sdelphij#define OACK	06			/* option acknowledgement */
48276788Sdelphij
49276788Sdelphij/*
50276788Sdelphij * Error codes.
51276788Sdelphij */
52276788Sdelphij#define	EUNDEF		0		/* not defined */
53276788Sdelphij#define	ENOTFOUND	1		/* file not found */
54276788Sdelphij#define	EACCESS		2		/* access violation */
55276788Sdelphij#define	ENOSPACE	3		/* disk full or allocation exceeded */
56276788Sdelphij#define	EBADOP		4		/* illegal TFTP operation */
57276788Sdelphij#define	EBADID		5		/* unknown transfer ID */
58276788Sdelphij#define	EEXISTS		6		/* file already exists */
59276788Sdelphij#define	ENOUSER		7		/* no such user */
60276788Sdelphij
61276788Sdelphijstatic const char tstr[] = " [|tftp]";
62276788Sdelphij
6317680Spst/* op code to string mapping */
64276788Sdelphijstatic const struct tok op2str[] = {
6517680Spst	{ RRQ,		"RRQ" },	/* read request */
6617680Spst	{ WRQ,		"WRQ" },	/* write request */
6717680Spst	{ DATA,		"DATA" },	/* data packet */
6817680Spst	{ ACK,		"ACK" },	/* acknowledgement */
69190207Srpaulo	{ TFTP_ERROR,	"ERROR" },	/* error code */
70172683Smlaier	{ OACK,		"OACK" },	/* option acknowledgement */
7117680Spst	{ 0,		NULL }
7217680Spst};
7317680Spst
7417680Spst/* error code to string mapping */
75276788Sdelphijstatic const struct tok err2str[] = {
7617680Spst	{ EUNDEF,	"EUNDEF" },	/* not defined */
7717680Spst	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
7817680Spst	{ EACCESS,	"EACCESS" },	/* access violation */
7917680Spst	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
8017680Spst	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
8117680Spst	{ EBADID,	"EBADID" },	/* unknown transfer ID */
8217680Spst	{ EEXISTS,	"EEXISTS" },	/* file already exists */
8317680Spst	{ ENOUSER,	"ENOUSER" },	/* no such user */
8417680Spst	{ 0,		NULL }
8517680Spst};
8617680Spst
8717680Spst/*
8817680Spst * Print trivial file transfer program requests
8917680Spst */
9017680Spstvoid
91276788Sdelphijtftp_print(netdissect_options *ndo,
92276788Sdelphij           register const u_char *bp, u_int length)
9317680Spst{
9417680Spst	register const char *cp;
95313537Sglebius	register int opcode;
96313537Sglebius	u_int ui;
9717680Spst
9817680Spst	/* Print length */
99276788Sdelphij	ND_PRINT((ndo, " %d", length));
10017680Spst
10117680Spst	/* Print tftp request type */
102313537Sglebius	if (length < 2)
103313537Sglebius		goto trunc;
104327234Semaste	ND_TCHECK_16BITS(bp);
105327234Semaste	opcode = EXTRACT_16BITS(bp);
10617680Spst	cp = tok2str(op2str, "tftp-#%d", opcode);
107276788Sdelphij	ND_PRINT((ndo, " %s", cp));
10817680Spst	/* Bail if bogus opcode */
10917680Spst	if (*cp == 't')
11017680Spst		return;
111327234Semaste	bp += 2;
112327234Semaste	length -= 2;
11317680Spst
11417680Spst	switch (opcode) {
11517680Spst
11617680Spst	case RRQ:
11717680Spst	case WRQ:
118313537Sglebius		if (length == 0)
119313537Sglebius			goto trunc;
120276788Sdelphij		ND_PRINT((ndo, " "));
121313537Sglebius		/* Print filename */
122313537Sglebius		ND_PRINT((ndo, "\""));
123327234Semaste		ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
124313537Sglebius		ND_PRINT((ndo, "\""));
125313537Sglebius		if (ui == 0)
126313537Sglebius			goto trunc;
127327234Semaste		bp += ui;
128313537Sglebius		length -= ui;
129127668Sbms
130313537Sglebius		/* Print the mode - RRQ and WRQ only */
131313537Sglebius		if (length == 0)
132313537Sglebius			goto trunc;	/* no mode */
133313537Sglebius		ND_PRINT((ndo, " "));
134327234Semaste		ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
135313537Sglebius		if (ui == 0)
136313537Sglebius			goto trunc;
137327234Semaste		bp += ui;
138313537Sglebius		length -= ui;
139313537Sglebius
140313537Sglebius		/* Print options, if any */
141313537Sglebius		while (length != 0) {
142327234Semaste			ND_TCHECK(*bp);
143327234Semaste			if (*bp != '\0')
144276788Sdelphij				ND_PRINT((ndo, " "));
145327234Semaste			ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
146313537Sglebius			if (ui == 0)
147313537Sglebius				goto trunc;
148327234Semaste			bp += ui;
149313537Sglebius			length -= ui;
150127668Sbms		}
151313537Sglebius		break;
152276788Sdelphij
153313537Sglebius	case OACK:
154313537Sglebius		/* Print options */
155313537Sglebius		while (length != 0) {
156327234Semaste			ND_TCHECK(*bp);
157327234Semaste			if (*bp != '\0')
158313537Sglebius				ND_PRINT((ndo, " "));
159327234Semaste			ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
160313537Sglebius			if (ui == 0)
161313537Sglebius				goto trunc;
162327234Semaste			bp += ui;
163313537Sglebius			length -= ui;
164313537Sglebius		}
16517680Spst		break;
16617680Spst
16717680Spst	case ACK:
16817680Spst	case DATA:
169313537Sglebius		if (length < 2)
170313537Sglebius			goto trunc;	/* no block number */
171327234Semaste		ND_TCHECK_16BITS(bp);
172327234Semaste		ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
17317680Spst		break;
17417680Spst
175190207Srpaulo	case TFTP_ERROR:
17617680Spst		/* Print error code string */
177313537Sglebius		if (length < 2)
178313537Sglebius			goto trunc;	/* no error code */
179327234Semaste		ND_TCHECK_16BITS(bp);
180313537Sglebius		ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
181327234Semaste				       EXTRACT_16BITS(bp))));
182327234Semaste		bp += 2;
183313537Sglebius		length -= 2;
18417680Spst		/* Print error message string */
185313537Sglebius		if (length == 0)
186313537Sglebius			goto trunc;	/* no error message */
187313537Sglebius		ND_PRINT((ndo, " \""));
188327234Semaste		ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
189276788Sdelphij		ND_PRINT((ndo, "\""));
190313537Sglebius		if (ui == 0)
19117680Spst			goto trunc;
19217680Spst		break;
19317680Spst
19417680Spst	default:
19517680Spst		/* We shouldn't get here */
196276788Sdelphij		ND_PRINT((ndo, "(unknown #%d)", opcode));
19717680Spst		break;
19817680Spst	}
19917680Spst	return;
20017680Spsttrunc:
201276788Sdelphij	ND_PRINT((ndo, "%s", tstr));
20217680Spst	return;
20317680Spst}
204