]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-tftp.c
Catch up with "base" telnet.
[FreeBSD/FreeBSD.git] / contrib / tcpdump / print-tftp.c
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 }