slirp: support dynamic block size for TFTP transfers
The blocksize option is defined in RFC 1783 and RFC 2348. We now support block sizes between 1 and 1428 bytes, instead of 512 only. Signed-off-by: Hervé Poussineau <hpoussin@reactos.org> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
This commit is contained in:
parent
893dcdbfa9
commit
9443598d7e
26
slirp/tftp.c
26
slirp/tftp.c
@ -72,6 +72,7 @@ static int tftp_session_allocate(Slirp *slirp, struct sockaddr_storage *srcsas,
|
||||
memset(spt, 0, sizeof(*spt));
|
||||
spt->client_addr = *srcsas;
|
||||
spt->fd = -1;
|
||||
spt->block_size = 512;
|
||||
spt->client_port = tp->udp.uh_sport;
|
||||
spt->slirp = slirp;
|
||||
|
||||
@ -115,7 +116,7 @@ static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr,
|
||||
}
|
||||
|
||||
if (len) {
|
||||
lseek(spt->fd, block_nr * 512, SEEK_SET);
|
||||
lseek(spt->fd, block_nr * spt->block_size, SEEK_SET);
|
||||
|
||||
bytes_read = read(spt->fd, buf, len);
|
||||
}
|
||||
@ -189,7 +190,8 @@ static int tftp_send_oack(struct tftp_session *spt,
|
||||
values[i]) + 1;
|
||||
}
|
||||
|
||||
m->m_len = sizeof(struct tftp_t) - 514 + n - sizeof(struct udphdr);
|
||||
m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + n
|
||||
- sizeof(struct udphdr);
|
||||
tftp_udp_output(spt, m, recv_tp);
|
||||
|
||||
return 0;
|
||||
@ -214,7 +216,7 @@ static void tftp_send_error(struct tftp_session *spt,
|
||||
tp->x.tp_error.tp_error_code = htons(errorcode);
|
||||
pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);
|
||||
|
||||
m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg)
|
||||
m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + 3 + strlen(msg)
|
||||
- sizeof(struct udphdr);
|
||||
tftp_udp_output(spt, m, recv_tp);
|
||||
|
||||
@ -240,7 +242,8 @@ static void tftp_send_next_block(struct tftp_session *spt,
|
||||
tp->tp_op = htons(TFTP_DATA);
|
||||
tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff);
|
||||
|
||||
nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, 512);
|
||||
nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf,
|
||||
spt->block_size);
|
||||
|
||||
if (nobytes < 0) {
|
||||
m_free(m);
|
||||
@ -252,10 +255,11 @@ static void tftp_send_next_block(struct tftp_session *spt,
|
||||
return;
|
||||
}
|
||||
|
||||
m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - sizeof(struct udphdr);
|
||||
m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX - nobytes)
|
||||
- sizeof(struct udphdr);
|
||||
tftp_udp_output(spt, m, recv_tp);
|
||||
|
||||
if (nobytes == 512) {
|
||||
if (nobytes == spt->block_size) {
|
||||
tftp_session_update(spt);
|
||||
}
|
||||
else {
|
||||
@ -385,13 +389,11 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
|
||||
} else if (strcasecmp(key, "blksize") == 0) {
|
||||
int blksize = atoi(value);
|
||||
|
||||
/* If blksize option is bigger than what we will
|
||||
* emit, accept the option with our packet size.
|
||||
* Otherwise, simply do as we didn't see the option.
|
||||
*/
|
||||
if (blksize >= 512) {
|
||||
/* Accept blksize up to our maximum size */
|
||||
if (blksize > 0) {
|
||||
spt->block_size = MIN(blksize, TFTP_BLOCKSIZE_MAX);
|
||||
option_name[nb_options] = "blksize";
|
||||
option_value[nb_options] = 512;
|
||||
option_value[nb_options] = spt->block_size;
|
||||
nb_options++;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define TFTP_OACK 6
|
||||
|
||||
#define TFTP_FILENAME_MAX 512
|
||||
#define TFTP_BLOCKSIZE_MAX 1428
|
||||
|
||||
struct tftp_t {
|
||||
struct udphdr udp;
|
||||
@ -22,13 +23,13 @@ struct tftp_t {
|
||||
union {
|
||||
struct {
|
||||
uint16_t tp_block_nr;
|
||||
uint8_t tp_buf[512];
|
||||
uint8_t tp_buf[TFTP_BLOCKSIZE_MAX];
|
||||
} tp_data;
|
||||
struct {
|
||||
uint16_t tp_error_code;
|
||||
uint8_t tp_msg[512];
|
||||
uint8_t tp_msg[TFTP_BLOCKSIZE_MAX];
|
||||
} tp_error;
|
||||
char tp_buf[512 + 2];
|
||||
char tp_buf[TFTP_BLOCKSIZE_MAX + 2];
|
||||
} x;
|
||||
} __attribute__((packed));
|
||||
|
||||
@ -36,6 +37,7 @@ struct tftp_session {
|
||||
Slirp *slirp;
|
||||
char *filename;
|
||||
int fd;
|
||||
uint16_t block_size;
|
||||
|
||||
struct sockaddr_storage client_addr;
|
||||
uint16_t client_port;
|
||||
|
Loading…
Reference in New Issue
Block a user