print-tftp.c revision 17680
1/*
2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * Format and print trivial file transfer protocol packets.
22 */
23
24#ifndef lint
25static char rcsid[] =
26    "@(#) $Header: print-tftp.c,v 1.27 96/07/23 14:17:28 leres Exp $ (LBL)";
27#endif
28
29#include <sys/param.h>
30#include <sys/time.h>
31
32#include <netinet/in.h>
33
34#include <arpa/tftp.h>
35
36#include <ctype.h>
37#include <stdio.h>
38#include <string.h>
39
40#include "interface.h"
41#include "addrtoname.h"
42
43/* op code to string mapping */
44static struct tok op2str[] = {
45	{ RRQ,		"RRQ" },	/* read request */
46	{ WRQ,		"WRQ" },	/* write request */
47	{ DATA,		"DATA" },	/* data packet */
48	{ ACK,		"ACK" },	/* acknowledgement */
49	{ ERROR,	"ERROR" },	/* error code */
50	{ 0,		NULL }
51};
52
53/* error code to string mapping */
54static struct tok err2str[] = {
55	{ EUNDEF,	"EUNDEF" },	/* not defined */
56	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
57	{ EACCESS,	"EACCESS" },	/* access violation */
58	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
59	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
60	{ EBADID,	"EBADID" },	/* unknown transfer ID */
61	{ EEXISTS,	"EEXISTS" },	/* file already exists */
62	{ ENOUSER,	"ENOUSER" },	/* no such user */
63	{ 0,		NULL }
64};
65
66/*
67 * Print trivial file transfer program requests
68 */
69void
70tftp_print(register const u_char *bp, u_int length)
71{
72	register const struct tftphdr *tp;
73	register const char *cp;
74	register const u_char *p;
75	register int opcode, i;
76	static char tstr[] = " [|tftp]";
77
78	tp = (const struct tftphdr *)bp;
79
80	/* Print length */
81	printf(" %d", length);
82
83	/* Print tftp request type */
84	TCHECK(tp->th_opcode);
85	opcode = ntohs(tp->th_opcode);
86	cp = tok2str(op2str, "tftp-#%d", opcode);
87	printf(" %s", cp);
88	/* Bail if bogus opcode */
89	if (*cp == 't')
90		return;
91
92	switch (opcode) {
93
94	case RRQ:
95	case WRQ:
96		/*
97		 * XXX Not all arpa/tftp.h's specify th_stuff as any
98		 * array; use address of th_block instead
99		 */
100#ifdef notdef
101		p = (u_char *)tp->th_stuff;
102#else
103		p = (u_char *)&tp->th_block;
104#endif
105		fputs(" \"", stdout);
106		i = fn_print(p, snapend);
107		putchar('"');
108		if (i)
109			goto trunc;
110		break;
111
112	case ACK:
113	case DATA:
114		TCHECK(tp->th_block);
115		printf(" block %d", ntohs(tp->th_block));
116		break;
117
118	case ERROR:
119		/* Print error code string */
120		TCHECK(tp->th_code);
121		printf(" %s ", tok2str(err2str, "tftp-err-#%d \"",
122				       ntohs(tp->th_code)));
123		/* Print error message string */
124		i = fn_print((const u_char *)tp->th_data, snapend);
125		putchar('"');
126		if (i)
127			goto trunc;
128		break;
129
130	default:
131		/* We shouldn't get here */
132		printf("(unknown #%d)", opcode);
133		break;
134	}
135	return;
136trunc:
137	fputs(tstr, stdout);
138	return;
139}
140