xref: /freebsd/contrib/tcpdump/print-tftp.c (revision 70fe064ad7cab6c0444b91622f60ec6a462f308a)
1 /*
2  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
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
25 static const char rcsid[] =
26     "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.31 1999/11/21 09:37:03 fenner Exp $ (LBL)";
27 #endif
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include <sys/param.h>
34 #include <sys/time.h>
35 
36 #include <netinet/in.h>
37 
38 #ifdef SEGSIZE
39 #undef SEGSIZE					/* SINIX sucks */
40 #endif
41 #include <arpa/tftp.h>
42 
43 #include <ctype.h>
44 #include <stdio.h>
45 #include <string.h>
46 
47 #include "interface.h"
48 #include "addrtoname.h"
49 
50 /* op code to string mapping */
51 static struct tok op2str[] = {
52 	{ RRQ,		"RRQ" },	/* read request */
53 	{ WRQ,		"WRQ" },	/* write request */
54 	{ DATA,		"DATA" },	/* data packet */
55 	{ ACK,		"ACK" },	/* acknowledgement */
56 	{ ERROR,	"ERROR" },	/* error code */
57 	{ 0,		NULL }
58 };
59 
60 /* error code to string mapping */
61 static struct tok err2str[] = {
62 	{ EUNDEF,	"EUNDEF" },	/* not defined */
63 	{ ENOTFOUND,	"ENOTFOUND" },	/* file not found */
64 	{ EACCESS,	"EACCESS" },	/* access violation */
65 	{ ENOSPACE,	"ENOSPACE" },	/* disk full or allocation exceeded */
66 	{ EBADOP,	"EBADOP" },	/* illegal TFTP operation */
67 	{ EBADID,	"EBADID" },	/* unknown transfer ID */
68 	{ EEXISTS,	"EEXISTS" },	/* file already exists */
69 	{ ENOUSER,	"ENOUSER" },	/* no such user */
70 	{ 0,		NULL }
71 };
72 
73 /*
74  * Print trivial file transfer program requests
75  */
76 void
77 tftp_print(register const u_char *bp, u_int length)
78 {
79 	register const struct tftphdr *tp;
80 	register const char *cp;
81 	register const u_char *p;
82 	register int opcode, i;
83 	static char tstr[] = " [|tftp]";
84 
85 	tp = (const struct tftphdr *)bp;
86 
87 	/* Print length */
88 	printf(" %d", length);
89 
90 	/* Print tftp request type */
91 	TCHECK(tp->th_opcode);
92 	opcode = ntohs(tp->th_opcode);
93 	cp = tok2str(op2str, "tftp-#%d", opcode);
94 	printf(" %s", cp);
95 	/* Bail if bogus opcode */
96 	if (*cp == 't')
97 		return;
98 
99 	switch (opcode) {
100 
101 	case RRQ:
102 	case WRQ:
103 		/*
104 		 * XXX Not all arpa/tftp.h's specify th_stuff as any
105 		 * array; use address of th_block instead
106 		 */
107 #ifdef notdef
108 		p = (u_char *)tp->th_stuff;
109 #else
110 		p = (u_char *)&tp->th_block;
111 #endif
112 		fputs(" \"", stdout);
113 		i = fn_print(p, snapend);
114 		putchar('"');
115 		if (i)
116 			goto trunc;
117 		break;
118 
119 	case ACK:
120 	case DATA:
121 		TCHECK(tp->th_block);
122 		printf(" block %d", ntohs(tp->th_block));
123 		break;
124 
125 	case ERROR:
126 		/* Print error code string */
127 		TCHECK(tp->th_code);
128 		printf(" %s ", tok2str(err2str, "tftp-err-#%d \"",
129 				       ntohs(tp->th_code)));
130 		/* Print error message string */
131 		i = fn_print((const u_char *)tp->th_data, snapend);
132 		putchar('"');
133 		if (i)
134 			goto trunc;
135 		break;
136 
137 	default:
138 		/* We shouldn't get here */
139 		printf("(unknown #%d)", opcode);
140 		break;
141 	}
142 	return;
143 trunc:
144 	fputs(tstr, stdout);
145 	return;
146 }
147