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