print-tftp.c revision 127668
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_ =
26127668Sbms    "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.35.2.2 2003/11/16 08:51:50 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#include <arpa/tftp.h>
3917680Spst
4017680Spst#include <stdio.h>
4117680Spst#include <string.h>
4217680Spst
4317680Spst#include "interface.h"
4417680Spst#include "addrtoname.h"
45127668Sbms#include "extract.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 */
5417680Spst	{ 0,		NULL }
5517680Spst};
5617680Spst
5717680Spst/* error code to string mapping */
5817680Spststatic struct tok err2str[] = {
5917680Spst	{ EUNDEF,	"EUNDEF" },	/* not defined */
6017680Spst	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
6117680Spst	{ EACCESS,	"EACCESS" },	/* access violation */
6217680Spst	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
6317680Spst	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
6417680Spst	{ EBADID,	"EBADID" },	/* unknown transfer ID */
6517680Spst	{ EEXISTS,	"EEXISTS" },	/* file already exists */
6617680Spst	{ ENOUSER,	"ENOUSER" },	/* no such user */
6717680Spst	{ 0,		NULL }
6817680Spst};
6917680Spst
7017680Spst/*
7117680Spst * Print trivial file transfer program requests
7217680Spst */
7317680Spstvoid
7417680Spsttftp_print(register const u_char *bp, u_int length)
7517680Spst{
7617680Spst	register const struct tftphdr *tp;
7717680Spst	register const char *cp;
7817680Spst	register const u_char *p;
7917680Spst	register int opcode, i;
8017680Spst	static char tstr[] = " [|tftp]";
8117680Spst
8217680Spst	tp = (const struct tftphdr *)bp;
8317680Spst
8417680Spst	/* Print length */
8517680Spst	printf(" %d", length);
8617680Spst
8717680Spst	/* Print tftp request type */
8817680Spst	TCHECK(tp->th_opcode);
89127668Sbms	opcode = EXTRACT_16BITS(&tp->th_opcode);
9017680Spst	cp = tok2str(op2str, "tftp-#%d", opcode);
9117680Spst	printf(" %s", cp);
9217680Spst	/* Bail if bogus opcode */
9317680Spst	if (*cp == 't')
9417680Spst		return;
9517680Spst
9617680Spst	switch (opcode) {
9717680Spst
9817680Spst	case RRQ:
9917680Spst	case WRQ:
10017680Spst		/*
10117680Spst		 * XXX Not all arpa/tftp.h's specify th_stuff as any
10217680Spst		 * array; use address of th_block instead
10317680Spst		 */
10417680Spst#ifdef notdef
10517680Spst		p = (u_char *)tp->th_stuff;
10617680Spst#else
10717680Spst		p = (u_char *)&tp->th_block;
10817680Spst#endif
10917680Spst		fputs(" \"", stdout);
11017680Spst		i = fn_print(p, snapend);
11117680Spst		putchar('"');
112127668Sbms
113127668Sbms		/* Print the mode and any options */
114127668Sbms		while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) {
115127668Sbms			if (length <= (u_int)(p - (const u_char *)&tp->th_block))
116127668Sbms				break;
117127668Sbms			p++;
118127668Sbms			if (*p != '\0') {
119127668Sbms				putchar(' ');
120127668Sbms				fn_print(p, snapend);
121127668Sbms			}
122127668Sbms		}
123127668Sbms
12417680Spst		if (i)
12517680Spst			goto trunc;
12617680Spst		break;
12717680Spst
12817680Spst	case ACK:
12917680Spst	case DATA:
13017680Spst		TCHECK(tp->th_block);
131127668Sbms		printf(" block %d", EXTRACT_16BITS(&tp->th_block));
13217680Spst		break;
13317680Spst
13417680Spst	case ERROR:
13517680Spst		/* Print error code string */
13617680Spst		TCHECK(tp->th_code);
13717680Spst		printf(" %s ", tok2str(err2str, "tftp-err-#%d \"",
138127668Sbms				       EXTRACT_16BITS(&tp->th_code)));
13917680Spst		/* Print error message string */
14017680Spst		i = fn_print((const u_char *)tp->th_data, snapend);
14117680Spst		putchar('"');
14217680Spst		if (i)
14317680Spst			goto trunc;
14417680Spst		break;
14517680Spst
14617680Spst	default:
14717680Spst		/* We shouldn't get here */
14817680Spst		printf("(unknown #%d)", opcode);
14917680Spst		break;
15017680Spst	}
15117680Spst	return;
15217680Spsttrunc:
15317680Spst	fputs(tstr, stdout);
15417680Spst	return;
15517680Spst}
156