12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Format and print trivial file transfer protocol packets.
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef lint
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ =
2653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca Exp $ (LBL)";
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef SEGSIZE
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#undef SEGSIZE					/* SINIX sucks */
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h"
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "tftp.h"
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* op code to string mapping */
4853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok op2str[] = {
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ RRQ,		"RRQ" },	/* read request */
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ WRQ,		"WRQ" },	/* write request */
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ DATA,		"DATA" },	/* data packet */
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ ACK,		"ACK" },	/* acknowledgement */
5353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	{ TFTP_ERROR,	"ERROR" },	/* error code */
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ OACK,		"OACK" },	/* option acknowledgement */
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 0,		NULL }
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* error code to string mapping */
5953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok err2str[] = {
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ EUNDEF,	"EUNDEF" },	/* not defined */
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ EACCESS,	"EACCESS" },	/* access violation */
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ EBADID,	"EBADID" },	/* unknown transfer ID */
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ EEXISTS,	"EEXISTS" },	/* file already exists */
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ ENOUSER,	"ENOUSER" },	/* no such user */
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{ 0,		NULL }
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Print trivial file transfer program requests
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttftp_print(register const u_char *bp, u_int length)
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register const struct tftphdr *tp;
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register const char *cp;
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register const u_char *p;
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register int opcode, i;
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static char tstr[] = " [|tftp]";
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	tp = (const struct tftphdr *)bp;
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Print length */
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" %d", length);
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Print tftp request type */
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	TCHECK(tp->th_opcode);
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	opcode = EXTRACT_16BITS(&tp->th_opcode);
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	cp = tok2str(op2str, "tftp-#%d", opcode);
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" %s", cp);
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Bail if bogus opcode */
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (*cp == 't')
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (opcode) {
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case RRQ:
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case WRQ:
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case OACK:
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p = (u_char *)tp->th_stuff;
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		putchar(' ');
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Print filename or first option */
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (opcode != OACK)
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			putchar('"');
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		i = fn_print(p, snapend);
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (opcode != OACK)
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			putchar('"');
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Print the mode (RRQ and WRQ only) and any options */
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) {
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (length <= (u_int)(p - (const u_char *)&tp->th_block))
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p++;
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (*p != '\0') {
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				putchar(' ');
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				fn_print(p, snapend);
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (i)
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ACK:
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case DATA:
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(tp->th_block);
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" block %d", EXTRACT_16BITS(&tp->th_block));
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case TFTP_ERROR:
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Print error code string */
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK(tp->th_code);
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"",
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				       EXTRACT_16BITS(&tp->th_code)));
1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Print error message string */
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		i = fn_print((const u_char *)tp->th_data, snapend);
1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		putchar('"');
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (i)
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* We shouldn't get here */
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("(unknown #%d)", opcode);
1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	fputs(tstr, stdout);
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
154