]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-tftp.c
ident(1): Normalizing date format
[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
22 /* \summary: Trivial File Transfer Protocol (TFTP) printer */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <netdissect-stdinc.h>
29
30 #include <string.h>
31
32 #include "netdissect.h"
33 #include "extract.h"
34
35 /*
36  * Trivial File Transfer Protocol (IEN-133)
37  */
38
39 /*
40  * Packet types.
41  */
42 #define RRQ     01                      /* read request */
43 #define WRQ     02                      /* write request */
44 #define DATA    03                      /* data packet */
45 #define ACK     04                      /* acknowledgement */
46 #define TFTP_ERROR      05                      /* error code */
47 #define OACK    06                      /* option acknowledgement */
48
49 /*
50  * Error codes.
51  */
52 #define EUNDEF          0               /* not defined */
53 #define ENOTFOUND       1               /* file not found */
54 #define EACCESS         2               /* access violation */
55 #define ENOSPACE        3               /* disk full or allocation exceeded */
56 #define EBADOP          4               /* illegal TFTP operation */
57 #define EBADID          5               /* unknown transfer ID */
58 #define EEXISTS         6               /* file already exists */
59 #define ENOUSER         7               /* no such user */
60
61 static const char tstr[] = " [|tftp]";
62
63 /* op code to string mapping */
64 static const struct tok op2str[] = {
65         { RRQ,          "RRQ" },        /* read request */
66         { WRQ,          "WRQ" },        /* write request */
67         { DATA,         "DATA" },       /* data packet */
68         { ACK,          "ACK" },        /* acknowledgement */
69         { TFTP_ERROR,   "ERROR" },      /* error code */
70         { OACK,         "OACK" },       /* option acknowledgement */
71         { 0,            NULL }
72 };
73
74 /* error code to string mapping */
75 static const struct tok err2str[] = {
76         { EUNDEF,       "EUNDEF" },     /* not defined */
77         { ENOTFOUND,    "ENOTFOUND" },  /* file not found */
78         { EACCESS,      "EACCESS" },    /* access violation */
79         { ENOSPACE,     "ENOSPACE" },   /* disk full or allocation exceeded */
80         { EBADOP,       "EBADOP" },     /* illegal TFTP operation */
81         { EBADID,       "EBADID" },     /* unknown transfer ID */
82         { EEXISTS,      "EEXISTS" },    /* file already exists */
83         { ENOUSER,      "ENOUSER" },    /* no such user */
84         { 0,            NULL }
85 };
86
87 /*
88  * Print trivial file transfer program requests
89  */
90 void
91 tftp_print(netdissect_options *ndo,
92            register const u_char *bp, u_int length)
93 {
94         register const char *cp;
95         register int opcode;
96         u_int ui;
97
98         /* Print length */
99         ND_PRINT((ndo, " %d", length));
100
101         /* Print tftp request type */
102         if (length < 2)
103                 goto trunc;
104         ND_TCHECK_16BITS(bp);
105         opcode = EXTRACT_16BITS(bp);
106         cp = tok2str(op2str, "tftp-#%d", opcode);
107         ND_PRINT((ndo, " %s", cp));
108         /* Bail if bogus opcode */
109         if (*cp == 't')
110                 return;
111         bp += 2;
112         length -= 2;
113
114         switch (opcode) {
115
116         case RRQ:
117         case WRQ:
118                 if (length == 0)
119                         goto trunc;
120                 ND_PRINT((ndo, " "));
121                 /* Print filename */
122                 ND_PRINT((ndo, "\""));
123                 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
124                 ND_PRINT((ndo, "\""));
125                 if (ui == 0)
126                         goto trunc;
127                 bp += ui;
128                 length -= ui;
129
130                 /* Print the mode - RRQ and WRQ only */
131                 if (length == 0)
132                         goto trunc;     /* no mode */
133                 ND_PRINT((ndo, " "));
134                 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
135                 if (ui == 0)
136                         goto trunc;
137                 bp += ui;
138                 length -= ui;
139
140                 /* Print options, if any */
141                 while (length != 0) {
142                         ND_TCHECK(*bp);
143                         if (*bp != '\0')
144                                 ND_PRINT((ndo, " "));
145                         ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
146                         if (ui == 0)
147                                 goto trunc;
148                         bp += ui;
149                         length -= ui;
150                 }
151                 break;
152
153         case OACK:
154                 /* Print options */
155                 while (length != 0) {
156                         ND_TCHECK(*bp);
157                         if (*bp != '\0')
158                                 ND_PRINT((ndo, " "));
159                         ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
160                         if (ui == 0)
161                                 goto trunc;
162                         bp += ui;
163                         length -= ui;
164                 }
165                 break;
166
167         case ACK:
168         case DATA:
169                 if (length < 2)
170                         goto trunc;     /* no block number */
171                 ND_TCHECK_16BITS(bp);
172                 ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
173                 break;
174
175         case TFTP_ERROR:
176                 /* Print error code string */
177                 if (length < 2)
178                         goto trunc;     /* no error code */
179                 ND_TCHECK_16BITS(bp);
180                 ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
181                                        EXTRACT_16BITS(bp))));
182                 bp += 2;
183                 length -= 2;
184                 /* Print error message string */
185                 if (length == 0)
186                         goto trunc;     /* no error message */
187                 ND_PRINT((ndo, " \""));
188                 ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
189                 ND_PRINT((ndo, "\""));
190                 if (ui == 0)
191                         goto trunc;
192                 break;
193
194         default:
195                 /* We shouldn't get here */
196                 ND_PRINT((ndo, "(unknown #%d)", opcode));
197                 break;
198         }
199         return;
200 trunc:
201         ND_PRINT((ndo, "%s", tstr));
202         return;
203 }