print-tftp.c revision 172683
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 * Format and print trivial file transfer protocol packets.
2217680Spst */
2317680Spst
2417680Spst#ifndef lint
25127668Sbmsstatic const char rcsid[] _U_ =
26172683Smlaier    "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.37.2.1 2007/09/14 01:03:12 guy Exp $ (LBL)";
2717680Spst#endif
2817680Spst
2956893Sfenner#ifdef HAVE_CONFIG_H
3056893Sfenner#include "config.h"
3156893Sfenner#endif
3256893Sfenner
33127668Sbms#include <tcpdump-stdinc.h>
3417680Spst
3539297Sfenner#ifdef SEGSIZE
3639297Sfenner#undef SEGSIZE					/* SINIX sucks */
3739297Sfenner#endif
3817680Spst
3917680Spst#include <stdio.h>
4017680Spst#include <string.h>
4117680Spst
4217680Spst#include "interface.h"
4317680Spst#include "addrtoname.h"
44127668Sbms#include "extract.h"
45172683Smlaier#include "tftp.h"
4617680Spst
4717680Spst/* op code to string mapping */
4817680Spststatic struct tok op2str[] = {
4917680Spst	{ RRQ,		"RRQ" },	/* read request */
5017680Spst	{ WRQ,		"WRQ" },	/* write request */
5117680Spst	{ DATA,		"DATA" },	/* data packet */
5217680Spst	{ ACK,		"ACK" },	/* acknowledgement */
5317680Spst	{ ERROR,	"ERROR" },	/* error code */
54172683Smlaier	{ OACK,		"OACK" },	/* option acknowledgement */
5517680Spst	{ 0,		NULL }
5617680Spst};
5717680Spst
5817680Spst/* error code to string mapping */
5917680Spststatic struct tok err2str[] = {
6017680Spst	{ EUNDEF,	"EUNDEF" },	/* not defined */
6117680Spst	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
6217680Spst	{ EACCESS,	"EACCESS" },	/* access violation */
6317680Spst	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
6417680Spst	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
6517680Spst	{ EBADID,	"EBADID" },	/* unknown transfer ID */
6617680Spst	{ EEXISTS,	"EEXISTS" },	/* file already exists */
6717680Spst	{ ENOUSER,	"ENOUSER" },	/* no such user */
6817680Spst	{ 0,		NULL }
6917680Spst};
7017680Spst
7117680Spst/*
7217680Spst * Print trivial file transfer program requests
7317680Spst */
7417680Spstvoid
7517680Spsttftp_print(register const u_char *bp, u_int length)
7617680Spst{
7717680Spst	register const struct tftphdr *tp;
7817680Spst	register const char *cp;
7917680Spst	register const u_char *p;
8017680Spst	register int opcode, i;
8117680Spst	static char tstr[] = " [|tftp]";
8217680Spst
8317680Spst	tp = (const struct tftphdr *)bp;
8417680Spst
8517680Spst	/* Print length */
8617680Spst	printf(" %d", length);
8717680Spst
8817680Spst	/* Print tftp request type */
8917680Spst	TCHECK(tp->th_opcode);
90127668Sbms	opcode = EXTRACT_16BITS(&tp->th_opcode);
9117680Spst	cp = tok2str(op2str, "tftp-#%d", opcode);
9217680Spst	printf(" %s", cp);
9317680Spst	/* Bail if bogus opcode */
9417680Spst	if (*cp == 't')
9517680Spst		return;
9617680Spst
9717680Spst	switch (opcode) {
9817680Spst
9917680Spst	case RRQ:
10017680Spst	case WRQ:
101172683Smlaier	case OACK:
10217680Spst		/*
10317680Spst		 * XXX Not all arpa/tftp.h's specify th_stuff as any
10417680Spst		 * array; use address of th_block instead
10517680Spst		 */
10617680Spst#ifdef notdef
10717680Spst		p = (u_char *)tp->th_stuff;
10817680Spst#else
10917680Spst		p = (u_char *)&tp->th_block;
11017680Spst#endif
111172683Smlaier		putchar(' ');
112172683Smlaier		/* Print filename or first option */
113172683Smlaier		if (opcode != OACK)
114172683Smlaier			putchar('"');
11517680Spst		i = fn_print(p, snapend);
116172683Smlaier		if (opcode != OACK)
117172683Smlaier			putchar('"');
118127668Sbms
119172683Smlaier		/* Print the mode (RRQ and WRQ only) and any options */
120127668Sbms		while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) {
121127668Sbms			if (length <= (u_int)(p - (const u_char *)&tp->th_block))
122127668Sbms				break;
123127668Sbms			p++;
124127668Sbms			if (*p != '\0') {
125127668Sbms				putchar(' ');
126127668Sbms				fn_print(p, snapend);
127127668Sbms			}
128127668Sbms		}
129127668Sbms
13017680Spst		if (i)
13117680Spst			goto trunc;
13217680Spst		break;
13317680Spst
13417680Spst	case ACK:
13517680Spst	case DATA:
13617680Spst		TCHECK(tp->th_block);
137127668Sbms		printf(" block %d", EXTRACT_16BITS(&tp->th_block));
13817680Spst		break;
13917680Spst
14017680Spst	case ERROR:
14117680Spst		/* Print error code string */
14217680Spst		TCHECK(tp->th_code);
143172683Smlaier		printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"",
144127668Sbms				       EXTRACT_16BITS(&tp->th_code)));
14517680Spst		/* Print error message string */
14617680Spst		i = fn_print((const u_char *)tp->th_data, snapend);
14717680Spst		putchar('"');
14817680Spst		if (i)
14917680Spst			goto trunc;
15017680Spst		break;
15117680Spst
15217680Spst	default:
15317680Spst		/* We shouldn't get here */
15417680Spst		printf("(unknown #%d)", opcode);
15517680Spst		break;
15617680Spst	}
15717680Spst	return;
15817680Spsttrunc:
15917680Spst	fputs(tstr, stdout);
16017680Spst	return;
16117680Spst}
162