1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
#ifndef TFTP_H
#define TFTP_H
/** @file */
#include <gpxe/in.h>
#include <gpxe/buffer.h>
#include "nic.h"
#include "ip.h"
#include "udp.h"
#define TFTP_PORT 69 /**< Default TFTP server port */
#define TFTP_DEFAULT_BLKSIZE 512
#define TFTP_MAX_BLKSIZE 1432 /* 512 */
#define TFTP_RRQ 1
#define TFTP_WRQ 2
#define TFTP_DATA 3
#define TFTP_ACK 4
#define TFTP_ERROR 5
#define TFTP_OACK 6
#define TFTP_ERR_FILE_NOT_FOUND 1 /**< File not found */
#define TFTP_ERR_ACCESS_DENIED 2 /**< Access violation */
#define TFTP_ERR_DISK_FULL 3 /**< Disk full or allocation exceeded */
#define TFTP_ERR_ILLEGAL_OP 4 /**< Illegal TFTP operation */
#define TFTP_ERR_UNKNOWN_TID 5 /**< Unknown transfer ID */
#define TFTP_ERR_FILE_EXISTS 6 /**< File already exists */
#define TFTP_ERR_UNKNOWN_USER 7 /**< No such user */
#define TFTP_ERR_BAD_OPTS 8 /**< Option negotiation failed */
/** A TFTP request (RRQ) packet */
struct tftp_rrq {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
char data[TFTP_DEFAULT_BLKSIZE];
} PACKED;
/** A TFTP data (DATA) packet */
struct tftp_data {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
uint16_t block;
uint8_t data[TFTP_MAX_BLKSIZE];
} PACKED;
/** A TFTP acknowledgement (ACK) packet */
struct tftp_ack {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
uint16_t block;
} PACKED;
/** A TFTP error (ERROR) packet */
struct tftp_error {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
uint16_t errcode;
char errmsg[TFTP_DEFAULT_BLKSIZE];
} PACKED;
/** A TFTP options acknowledgement (OACK) packet */
struct tftp_oack {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
uint8_t data[TFTP_DEFAULT_BLKSIZE];
} PACKED;
/** The common header of all TFTP packets */
struct tftp_common {
struct iphdr ip;
struct udphdr udp;
uint16_t opcode;
} PACKED;
/** A union encapsulating all TFTP packet types */
union tftp_any {
struct tftp_common common;
struct tftp_rrq rrq;
struct tftp_data data;
struct tftp_ack ack;
struct tftp_error error;
struct tftp_oack oack;
};
/**
* TFTP state
*
* This data structure holds the state for an ongoing TFTP transfer.
*/
struct tftp_state {
/** TFTP server address
*
* This is the IP address and UDP port from which data packets
* will be sent, and to which ACK packets should be sent.
*/
struct sockaddr_in server;
/** TFTP client port
*
* This is the UDP port from which the open request will be
* sent, and to which any unicast data packets will be sent.
*/
uint16_t lport;
/** TFTP multicast address
*
* This is the IP address and UDP port to which multicast data
* packets, if any, will be sent.
*/
struct sockaddr_in multicast;
/** Master client
*
* This will be true if the client is the master client for a
* multicast protocol (i.e. MTFTP or TFTM). (It will always
* be true for a non-multicast protocol, i.e. plain old TFTP).
*/
int master;
/** Data block size
*
* This is the "blksize" option negotiated with the TFTP
* server. (If the TFTP server does not support TFTP options,
* this will default to 512).
*/
unsigned int blksize;
/** File size
*
* This is the value returned in the "tsize" option from the
* TFTP server. If the TFTP server does not support the
* "tsize" option, this value will be zero.
*/
off_t tsize;
/** Last received block
*
* The block number of the most recent block received from the
* TFTP server. Note that the first data block is block 1; a
* value of 0 indicates that no data blocks have yet been
* received.
*
* For multicast TFTP protocols, where the blocks may not be
* received in strict order, the meaning of this field changes
* slightly, to "first missing block minus one". For example,
* suppose that we have received blocks 1, 2, 4 and 5; this
* field would then have the value 2, since the first missing
* block is block 3. If the blocks do arrive in strict order,
* this definition is exactly equivalent to "most recently
* received block".
*/
unsigned int block;
};
struct tftpreq_info_t {
struct sockaddr_in *server;
const char *name;
unsigned short blksize;
} PACKED;
struct tftpblk_info_t {
char *data;
unsigned int block;
unsigned int len;
int eof;
} PACKED;
#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
#endif /* TFTP_H */
|