xref: /freebsd/contrib/tcpdump/print-tftp.c (revision 5b0fe47811aa43b75fc69dbf7338cace232a4d48)
14edb46e9SPaul Traina /*
24644f044SBill Fenner  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
34edb46e9SPaul Traina  *	The Regents of the University of California.  All rights reserved.
44edb46e9SPaul Traina  *
54edb46e9SPaul Traina  * Redistribution and use in source and binary forms, with or without
64edb46e9SPaul Traina  * modification, are permitted provided that: (1) source code distributions
74edb46e9SPaul Traina  * retain the above copyright notice and this paragraph in its entirety, (2)
84edb46e9SPaul Traina  * distributions including binary code include the above copyright notice and
94edb46e9SPaul Traina  * this paragraph in its entirety in the documentation or other materials
104edb46e9SPaul Traina  * provided with the distribution, and (3) all advertising materials mentioning
114edb46e9SPaul Traina  * features or use of this software display the following acknowledgement:
124edb46e9SPaul Traina  * ``This product includes software developed by the University of California,
134edb46e9SPaul Traina  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
144edb46e9SPaul Traina  * the University nor the names of its contributors may be used to endorse
154edb46e9SPaul Traina  * or promote products derived from this software without specific prior
164edb46e9SPaul Traina  * written permission.
174edb46e9SPaul Traina  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
184edb46e9SPaul Traina  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
194edb46e9SPaul Traina  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
204edb46e9SPaul Traina  *
214edb46e9SPaul Traina  * Format and print trivial file transfer protocol packets.
224edb46e9SPaul Traina  */
234edb46e9SPaul Traina 
244edb46e9SPaul Traina #ifndef lint
255b0fe478SBruce M Simpson static const char rcsid[] _U_ =
265b0fe478SBruce M Simpson     "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.35.2.2 2003/11/16 08:51:50 guy Exp $ (LBL)";
27b0453382SBill Fenner #endif
28b0453382SBill Fenner 
29b0453382SBill Fenner #ifdef HAVE_CONFIG_H
30b0453382SBill Fenner #include "config.h"
314edb46e9SPaul Traina #endif
324edb46e9SPaul Traina 
335b0fe478SBruce M Simpson #include <tcpdump-stdinc.h>
344edb46e9SPaul Traina 
354644f044SBill Fenner #ifdef SEGSIZE
364644f044SBill Fenner #undef SEGSIZE					/* SINIX sucks */
374644f044SBill Fenner #endif
384edb46e9SPaul Traina #include <arpa/tftp.h>
394edb46e9SPaul Traina 
404edb46e9SPaul Traina #include <stdio.h>
414edb46e9SPaul Traina #include <string.h>
424edb46e9SPaul Traina 
434edb46e9SPaul Traina #include "interface.h"
444edb46e9SPaul Traina #include "addrtoname.h"
455b0fe478SBruce M Simpson #include "extract.h"
464edb46e9SPaul Traina 
474edb46e9SPaul Traina /* op code to string mapping */
484edb46e9SPaul Traina static struct tok op2str[] = {
494edb46e9SPaul Traina 	{ RRQ,		"RRQ" },	/* read request */
504edb46e9SPaul Traina 	{ WRQ,		"WRQ" },	/* write request */
514edb46e9SPaul Traina 	{ DATA,		"DATA" },	/* data packet */
524edb46e9SPaul Traina 	{ ACK,		"ACK" },	/* acknowledgement */
534edb46e9SPaul Traina 	{ ERROR,	"ERROR" },	/* error code */
544edb46e9SPaul Traina 	{ 0,		NULL }
554edb46e9SPaul Traina };
564edb46e9SPaul Traina 
574edb46e9SPaul Traina /* error code to string mapping */
584edb46e9SPaul Traina static struct tok err2str[] = {
594edb46e9SPaul Traina 	{ EUNDEF,	"EUNDEF" },	/* not defined */
604edb46e9SPaul Traina 	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
614edb46e9SPaul Traina 	{ EACCESS,	"EACCESS" },	/* access violation */
624edb46e9SPaul Traina 	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
634edb46e9SPaul Traina 	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
644edb46e9SPaul Traina 	{ EBADID,	"EBADID" },	/* unknown transfer ID */
654edb46e9SPaul Traina 	{ EEXISTS,	"EEXISTS" },	/* file already exists */
664edb46e9SPaul Traina 	{ ENOUSER,	"ENOUSER" },	/* no such user */
674edb46e9SPaul Traina 	{ 0,		NULL }
684edb46e9SPaul Traina };
694edb46e9SPaul Traina 
704edb46e9SPaul Traina /*
714edb46e9SPaul Traina  * Print trivial file transfer program requests
724edb46e9SPaul Traina  */
734edb46e9SPaul Traina void
744edb46e9SPaul Traina tftp_print(register const u_char *bp, u_int length)
754edb46e9SPaul Traina {
764edb46e9SPaul Traina 	register const struct tftphdr *tp;
774edb46e9SPaul Traina 	register const char *cp;
784edb46e9SPaul Traina 	register const u_char *p;
794edb46e9SPaul Traina 	register int opcode, i;
804edb46e9SPaul Traina 	static char tstr[] = " [|tftp]";
814edb46e9SPaul Traina 
824edb46e9SPaul Traina 	tp = (const struct tftphdr *)bp;
834edb46e9SPaul Traina 
844edb46e9SPaul Traina 	/* Print length */
854edb46e9SPaul Traina 	printf(" %d", length);
864edb46e9SPaul Traina 
874edb46e9SPaul Traina 	/* Print tftp request type */
884edb46e9SPaul Traina 	TCHECK(tp->th_opcode);
895b0fe478SBruce M Simpson 	opcode = EXTRACT_16BITS(&tp->th_opcode);
904edb46e9SPaul Traina 	cp = tok2str(op2str, "tftp-#%d", opcode);
914edb46e9SPaul Traina 	printf(" %s", cp);
924edb46e9SPaul Traina 	/* Bail if bogus opcode */
934edb46e9SPaul Traina 	if (*cp == 't')
944edb46e9SPaul Traina 		return;
954edb46e9SPaul Traina 
964edb46e9SPaul Traina 	switch (opcode) {
974edb46e9SPaul Traina 
984edb46e9SPaul Traina 	case RRQ:
994edb46e9SPaul Traina 	case WRQ:
1004edb46e9SPaul Traina 		/*
1014edb46e9SPaul Traina 		 * XXX Not all arpa/tftp.h's specify th_stuff as any
1024edb46e9SPaul Traina 		 * array; use address of th_block instead
1034edb46e9SPaul Traina 		 */
1044edb46e9SPaul Traina #ifdef notdef
1054edb46e9SPaul Traina 		p = (u_char *)tp->th_stuff;
1064edb46e9SPaul Traina #else
1074edb46e9SPaul Traina 		p = (u_char *)&tp->th_block;
1084edb46e9SPaul Traina #endif
1094edb46e9SPaul Traina 		fputs(" \"", stdout);
1104edb46e9SPaul Traina 		i = fn_print(p, snapend);
1114edb46e9SPaul Traina 		putchar('"');
1125b0fe478SBruce M Simpson 
1135b0fe478SBruce M Simpson 		/* Print the mode and any options */
1145b0fe478SBruce M Simpson 		while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) {
1155b0fe478SBruce M Simpson 			if (length <= (u_int)(p - (const u_char *)&tp->th_block))
1165b0fe478SBruce M Simpson 				break;
1175b0fe478SBruce M Simpson 			p++;
1185b0fe478SBruce M Simpson 			if (*p != '\0') {
1195b0fe478SBruce M Simpson 				putchar(' ');
1205b0fe478SBruce M Simpson 				fn_print(p, snapend);
1215b0fe478SBruce M Simpson 			}
1225b0fe478SBruce M Simpson 		}
1235b0fe478SBruce M Simpson 
1244edb46e9SPaul Traina 		if (i)
1254edb46e9SPaul Traina 			goto trunc;
1264edb46e9SPaul Traina 		break;
1274edb46e9SPaul Traina 
1284edb46e9SPaul Traina 	case ACK:
1294edb46e9SPaul Traina 	case DATA:
1304edb46e9SPaul Traina 		TCHECK(tp->th_block);
1315b0fe478SBruce M Simpson 		printf(" block %d", EXTRACT_16BITS(&tp->th_block));
1324edb46e9SPaul Traina 		break;
1334edb46e9SPaul Traina 
1344edb46e9SPaul Traina 	case ERROR:
1354edb46e9SPaul Traina 		/* Print error code string */
1364edb46e9SPaul Traina 		TCHECK(tp->th_code);
1374edb46e9SPaul Traina 		printf(" %s ", tok2str(err2str, "tftp-err-#%d \"",
1385b0fe478SBruce M Simpson 				       EXTRACT_16BITS(&tp->th_code)));
1394edb46e9SPaul Traina 		/* Print error message string */
1404edb46e9SPaul Traina 		i = fn_print((const u_char *)tp->th_data, snapend);
1414edb46e9SPaul Traina 		putchar('"');
1424edb46e9SPaul Traina 		if (i)
1434edb46e9SPaul Traina 			goto trunc;
1444edb46e9SPaul Traina 		break;
1454edb46e9SPaul Traina 
1464edb46e9SPaul Traina 	default:
1474edb46e9SPaul Traina 		/* We shouldn't get here */
1484edb46e9SPaul Traina 		printf("(unknown #%d)", opcode);
1494edb46e9SPaul Traina 		break;
1504edb46e9SPaul Traina 	}
1514edb46e9SPaul Traina 	return;
1524edb46e9SPaul Traina trunc:
1534edb46e9SPaul Traina 	fputs(tstr, stdout);
1544edb46e9SPaul Traina 	return;
1554edb46e9SPaul Traina }
156