File indexing completed on 2025-05-11 08:24:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #ifdef HAVE_CONFIG_H
0050 #include "config.h"
0051 #endif
0052
0053 #include <stdio.h>
0054 #include <stdlib.h>
0055 #include <inttypes.h>
0056 #include <errno.h>
0057 #include <malloc.h>
0058 #include <string.h>
0059 #include <unistd.h>
0060 #include <fcntl.h>
0061 #include <rtems.h>
0062 #include <rtems/tftp.h>
0063 #include <sys/types.h>
0064 #include <sys/socket.h>
0065 #include <netinet/in.h>
0066 #include <arpa/inet.h>
0067 #include <netdb.h>
0068
0069 #include "tftp_driver.h"
0070
0071
0072
0073
0074 #define UDP_PORT_BASE 3180
0075
0076
0077
0078
0079 #define PACKET_FIRST_TIMEOUT_MILLISECONDS 400L
0080 #define TFTP_WINDOW_SIZE_MIN 1
0081 #define TFTP_BLOCK_SIZE_MIN 8
0082 #define TFTP_BLOCK_SIZE_MAX 65464
0083
0084 #define TFTP_BLOCK_SIZE_OPTION "blksize"
0085 #define TFTP_WINDOW_SIZE_OPTION "windowsize"
0086 #define TFTP_DECIMAL_BASE 10
0087
0088 #define TFTP_DEFAULT_SERVER_PORT 69
0089
0090
0091
0092
0093 #define TFTP_RFC7440_DATA_RETRANSMISSIONS 6
0094 #define TFTP_RFC7440_TIMEOUT_MILLISECONDS 1000
0095
0096
0097
0098
0099 #define TFTP_OPCODE_RRQ 1
0100 #define TFTP_OPCODE_WRQ 2
0101 #define TFTP_OPCODE_DATA 3
0102 #define TFTP_OPCODE_ACK 4
0103 #define TFTP_OPCODE_ERROR 5
0104 #define TFTP_OPCODE_OACK 6
0105
0106
0107
0108
0109 #define TFTP_ERROR_CODE_NOT_DEFINED 0
0110 #define TFTP_ERROR_CODE_NOT_FOUND 1
0111 #define TFTP_ERROR_CODE_NO_ACCESS 2
0112 #define TFTP_ERROR_CODE_DISK_FULL 3
0113 #define TFTP_ERROR_CODE_ILLEGAL 4
0114 #define TFTP_ERROR_CODE_UNKNOWN_ID 5
0115 #define TFTP_ERROR_CODE_FILE_EXISTS 6
0116 #define TFTP_ERROR_CODE_NO_USER 7
0117 #define TFTP_ERROR_CODE_OPTION_NEGO 8
0118
0119
0120
0121
0122
0123 #define GOT_EXPECTED_PACKET 0
0124 #define GOT_DUPLICATE_OF_CURRENT_PACKET -1
0125 #define GOT_OLD_PACKET -2
0126 #define GOT_FIRST_OUT_OF_ORDER_PACKET -3
0127
0128
0129
0130
0131 #define GET_PACKET_DONT_WAIT -1
0132
0133
0134
0135
0136
0137 #define DO_NOT_SEND_PACKET 0
0138
0139 #define PKT_SIZE_FROM_BLK_SIZE(_blksize) ((_blksize) + 2 * sizeof (uint16_t))
0140 #define BLK_SIZE_FROM_PKT_SIZE(_pktsize) ((_pktsize) - 2 * sizeof (uint16_t))
0141 #define MUST_SEND_OPTIONS(_options) (\
0142 (_options).block_size != TFTP_RFC1350_BLOCK_SIZE || \
0143 (_options).window_size != TFTP_RFC1350_WINDOW_SIZE )
0144
0145
0146
0147
0148 union tftpPacket {
0149
0150
0151
0152 struct tftpRWRQ {
0153 uint16_t opcode;
0154 char filename_mode[];
0155 } tftpRWRQ;
0156
0157
0158
0159
0160 struct tftpDATA {
0161 uint16_t opcode;
0162 uint16_t blocknum;
0163 uint8_t data[];
0164 } tftpDATA;
0165
0166
0167
0168
0169 struct tftpACK {
0170 uint16_t opcode;
0171 uint16_t blocknum;
0172 } tftpACK;
0173
0174
0175
0176
0177 struct tftpOACK {
0178 uint16_t opcode;
0179 char options[];
0180 } tftpOACK;
0181
0182
0183
0184
0185 struct tftpERROR {
0186 uint16_t opcode;
0187 uint16_t errorCode;
0188 char errorMessage[];
0189 } tftpERROR;
0190 };
0191
0192
0193
0194
0195 struct tftpStream {
0196
0197
0198
0199
0200 union tftpPacket *receive_buf;
0201 union tftpPacket *send_buf;
0202
0203
0204
0205
0206 uint16_t blocknum;
0207
0208
0209
0210
0211 size_t block_size;
0212
0213
0214
0215
0216
0217 size_t packet_size;
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 uint16_t send_buf_size_in_pkts;
0231
0232
0233
0234
0235
0236
0237
0238 uint16_t blocknum_last_filled;
0239
0240
0241
0242
0243
0244
0245 uint16_t blocknum_eof_block;
0246
0247
0248
0249
0250 int socket;
0251 struct sockaddr_in myAddress;
0252 struct sockaddr_in farAddress;
0253
0254
0255
0256
0257
0258
0259
0260 int nleft;
0261 int nused;
0262
0263
0264
0265
0266 int firstReply;
0267 bool at_eof;
0268 bool is_for_reading;
0269
0270
0271
0272
0273 ssize_t (*prepare_packet_for_sending) (
0274 struct tftpStream *tp,
0275 bool force_retransmission,
0276 union tftpPacket **send_buf,
0277 bool *wait_for_packet_reception,
0278 const void *create_packet_data
0279 );
0280 int (*process_data_packet) (struct tftpStream *tp, ssize_t len);
0281 int (*process_ack_packet) (struct tftpStream *tp, ssize_t len);
0282 int (*process_oack_packet) (struct tftpStream *tp, ssize_t len);
0283 int (*process_error_packet) (struct tftpStream *tp, ssize_t len);
0284 int retransmission_error_code;
0285 bool ignore_out_of_order_packets;
0286 int32_t blocknum_of_first_packet_of_window;
0287 int error;
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 tftp_net_config config;
0298 tftp_options server_options;
0299 };
0300
0301
0302
0303
0304 static ssize_t prepare_data_packet_for_sending (
0305 struct tftpStream *tp,
0306 bool force_retransmission,
0307 union tftpPacket **send_buf,
0308 bool *wait_for_packet_reception,
0309 const void *path_name
0310 );
0311 static ssize_t prepare_ack_packet_for_sending (
0312 struct tftpStream *tp,
0313 bool force_retransmission,
0314 union tftpPacket **send_buf,
0315 bool *wait_for_packet_reception,
0316 const void *path_name
0317 );
0318
0319
0320
0321
0322 static union tftpPacket *get_send_buffer_packet (
0323 struct tftpStream *tp,
0324 uint16_t packet_num
0325 )
0326 {
0327 return (union tftpPacket *) ( ( (char *) tp->send_buf) + tp->packet_size *
0328 (packet_num % tp->send_buf_size_in_pkts) );
0329 }
0330
0331
0332
0333
0334 static size_t create_request (
0335 union tftpPacket *send_buf,
0336 size_t data_size,
0337 bool is_for_reading,
0338 const char *path,
0339 const tftp_options *options
0340 )
0341 {
0342 size_t res_size;
0343 char *cur = send_buf->tftpRWRQ.filename_mode;
0344
0345 send_buf->tftpRWRQ.opcode = htons (
0346 is_for_reading ? TFTP_OPCODE_RRQ : TFTP_OPCODE_WRQ
0347 );
0348
0349 res_size = snprintf (cur, data_size, "%s%c%s", path, 0, "octet");
0350 if (res_size >= data_size) {
0351 return -1;
0352 }
0353 res_size++;
0354 data_size -= res_size;
0355 cur += res_size;
0356
0357 if (options->block_size != TFTP_RFC1350_BLOCK_SIZE) {
0358 res_size = snprintf (
0359 cur,
0360 data_size,
0361 "%s%c%"PRIu16,
0362 TFTP_BLOCK_SIZE_OPTION,
0363 0,
0364 options->block_size
0365 );
0366 if (res_size >= data_size) {
0367 return -1;
0368 }
0369 res_size++;
0370 data_size -= res_size;
0371 cur += res_size;
0372 }
0373
0374 if (options->window_size != TFTP_RFC1350_WINDOW_SIZE) {
0375 res_size = snprintf (
0376 cur,
0377 data_size,
0378 "%s%c%"PRIu16,
0379 TFTP_WINDOW_SIZE_OPTION,
0380 0,
0381 options->window_size
0382 );
0383 if (res_size >= data_size) {
0384 return -1;
0385 }
0386 res_size++;
0387 data_size -= res_size;
0388 cur += res_size;
0389 }
0390
0391 return cur - (char *)send_buf;
0392 }
0393
0394 static bool parse_decimal_number (
0395 char **pos,
0396 size_t *remain,
0397 long min,
0398 long max,
0399 uint16_t *variable
0400 )
0401 {
0402 long value;
0403 const char *start = *pos;
0404 if (*remain < 2) {
0405 return false;
0406 }
0407 value = strtoul(start, pos, TFTP_DECIMAL_BASE);
0408 if (value < min || value > max || **pos != 0) {
0409 return false;
0410 }
0411 *variable = (uint16_t) value;
0412 (*pos)++;
0413 *remain -= *pos - start;
0414
0415 return true;
0416 }
0417
0418
0419
0420
0421 static int tftpErrno (uint16_t error_code)
0422 {
0423 unsigned int tftpError;
0424 static const int errorMap[] = {
0425 EINVAL,
0426 ENOENT,
0427 EPERM,
0428 ENOSPC,
0429 EINVAL,
0430 ENXIO,
0431 EEXIST,
0432 ESRCH,
0433 ENOTSUP,
0434 };
0435
0436 tftpError = ntohs (error_code);
0437 if (tftpError < (sizeof errorMap / sizeof errorMap[0]))
0438 return errorMap[tftpError];
0439 else
0440 return 1000 + tftpError;
0441 }
0442
0443
0444
0445
0446 static bool parse_options (
0447 union tftpPacket *receive_buf,
0448 size_t packet_size,
0449 tftp_options *options_in,
0450 tftp_options *options_out
0451 )
0452 {
0453 char *pos = receive_buf->tftpOACK.options;
0454 size_t remain = packet_size - sizeof (receive_buf->tftpOACK.opcode);
0455
0456
0457
0458
0459 if (remain > 0 && pos[remain - 1] != 0) {
0460 return false;
0461 }
0462
0463 while (remain > 0) {
0464 if (strcasecmp(pos, TFTP_BLOCK_SIZE_OPTION) == 0 &&
0465 options_in->block_size != TFTP_RFC1350_BLOCK_SIZE) {
0466 remain -= sizeof (TFTP_BLOCK_SIZE_OPTION);
0467 pos += sizeof (TFTP_BLOCK_SIZE_OPTION);
0468 if (!parse_decimal_number (
0469 &pos,
0470 &remain,
0471 TFTP_BLOCK_SIZE_MIN,
0472 options_in->block_size,
0473 &options_out->block_size)) {
0474 return false;
0475 };
0476
0477 } else if (strcasecmp(pos, TFTP_WINDOW_SIZE_OPTION) == 0 &&
0478 options_in->window_size != TFTP_RFC1350_WINDOW_SIZE) {
0479 remain -= sizeof (TFTP_WINDOW_SIZE_OPTION);
0480 pos += sizeof (TFTP_WINDOW_SIZE_OPTION);
0481 if (!parse_decimal_number (
0482 &pos,
0483 &remain,
0484 TFTP_WINDOW_SIZE_MIN,
0485 options_in->window_size,
0486 &options_out->window_size)) {
0487 return false;
0488 };
0489
0490 } else {
0491 return false;
0492 }
0493 }
0494
0495 return true;
0496 }
0497
0498
0499
0500
0501 static void send_error (
0502 struct tftpStream *tp,
0503 struct sockaddr_in *to,
0504 uint8_t error_code,
0505 const char *error_message
0506 )
0507 {
0508 int len;
0509 struct {
0510 uint16_t opcode;
0511 uint16_t errorCode;
0512 char errorMessage[80];
0513 } msg;
0514
0515
0516
0517
0518 msg.opcode = htons (TFTP_OPCODE_ERROR);
0519 msg.errorCode = htons (error_code);
0520 len = snprintf (msg.errorMessage, sizeof (msg.errorMessage), error_message);
0521 if (len >= sizeof (msg.errorMessage)) {
0522 len = sizeof (msg.errorMessage) - 1;
0523 }
0524 len += sizeof (msg.opcode) + sizeof (msg.errorCode) + 1;
0525
0526
0527
0528
0529
0530
0531 (void) sendto (tp->socket, (char *)&msg, len, 0, (struct sockaddr *)to, sizeof *to);
0532 }
0533
0534
0535
0536
0537 static void sendStifle (struct tftpStream *tp, struct sockaddr_in *to)
0538 {
0539 send_error (tp, to, TFTP_ERROR_CODE_UNKNOWN_ID, "GO AWAY");
0540 }
0541
0542
0543
0544
0545 static ssize_t
0546 getPacket (struct tftpStream *tp, int retryCount)
0547 {
0548 ssize_t len;
0549 struct timeval tv;
0550 int flags = 0;
0551
0552 if (retryCount == GET_PACKET_DONT_WAIT) {
0553 flags = MSG_DONTWAIT;
0554 } else if (retryCount == 0) {
0555 tv.tv_sec = tp->config.first_timeout / 1000L;
0556 tv.tv_usec = (tp->config.first_timeout % 1000L) * 1000L;
0557
0558
0559
0560
0561 (void) setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv,
0562 sizeof tv);
0563 } else {
0564 tv.tv_sec = tp->config.timeout / 1000L;
0565 tv.tv_usec = (tp->config.timeout % 1000L) * 1000L;
0566
0567
0568
0569
0570 (void) setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv,
0571 sizeof tv);
0572 }
0573 for (;;) {
0574 union {
0575 struct sockaddr s;
0576 struct sockaddr_in i;
0577 } from;
0578 socklen_t fromlen = sizeof from;
0579 len = recvfrom (tp->socket,
0580 tp->receive_buf,
0581 tp->packet_size,
0582 flags,
0583 &from.s,
0584 &fromlen
0585 );
0586 if (len < 0)
0587 break;
0588 if (from.i.sin_addr.s_addr == tp->farAddress.sin_addr.s_addr) {
0589 if (tp->firstReply) {
0590 tp->firstReply = 0;
0591 tp->farAddress.sin_port = from.i.sin_port;
0592 }
0593 if (tp->farAddress.sin_port == from.i.sin_port)
0594 break;
0595 }
0596
0597
0598
0599
0600
0601 sendStifle (tp, &from.i);
0602 }
0603 if (retryCount != GET_PACKET_DONT_WAIT) {
0604 tv.tv_sec = 0;
0605 tv.tv_usec = 0;
0606
0607
0608
0609
0610 (void) setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv,
0611 sizeof tv);
0612 }
0613 return len;
0614 }
0615
0616 static int process_unexpected_packet (struct tftpStream *tp, ssize_t len)
0617 {
0618 (void) len;
0619 send_error (
0620 tp,
0621 &tp->farAddress,
0622 TFTP_ERROR_CODE_ILLEGAL,
0623 "Got packet with unexpected opcode from server"
0624 );
0625 return EPROTO;
0626 }
0627
0628 static int process_malformed_packet (struct tftpStream *tp, ssize_t len)
0629 {
0630 (void) len;
0631 send_error (
0632 tp,
0633 &tp->farAddress,
0634 TFTP_ERROR_CODE_ILLEGAL,
0635 "Got malformed packet from server"
0636 );
0637 return EPROTO;
0638 }
0639
0640 static int process_error_packet (struct tftpStream *tp, ssize_t len)
0641 {
0642 (void) len;
0643 return tftpErrno (tp->receive_buf->tftpERROR.errorCode);
0644 }
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662 static int process_error_packet_option_negotiation (
0663 struct tftpStream *tp, ssize_t len
0664 )
0665 {
0666 (void) len;
0667
0668
0669
0670
0671
0672
0673 tp->config.options.block_size = TFTP_RFC1350_BLOCK_SIZE;
0674 tp->config.options.window_size = TFTP_RFC1350_WINDOW_SIZE;
0675 tp->server_options.block_size = TFTP_RFC1350_BLOCK_SIZE;
0676 tp->server_options.window_size = TFTP_RFC1350_WINDOW_SIZE;
0677
0678 tp->process_error_packet = process_error_packet;
0679
0680
0681
0682 return GOT_FIRST_OUT_OF_ORDER_PACKET;
0683 }
0684
0685 static int process_data_packet (struct tftpStream *tp, ssize_t len)
0686 {
0687 ssize_t plen;
0688 int32_t pkt_blocknum;
0689 union tftpPacket *send_buf;
0690
0691 if (len < sizeof (tp->receive_buf->tftpACK)) {
0692 return process_malformed_packet (tp, len);
0693 }
0694 pkt_blocknum = (int32_t) ntohs (tp->receive_buf->tftpACK.blocknum);
0695 if (pkt_blocknum == 0) {
0696 return process_malformed_packet (tp, len);
0697 }
0698
0699
0700
0701
0702
0703
0704
0705
0706 if (pkt_blocknum < tp->blocknum_of_first_packet_of_window &&
0707 pkt_blocknum >= (int32_t) tp->blocknum + 1 -
0708 (int32_t) tp->server_options.window_size) {
0709 tp->blocknum_of_first_packet_of_window = pkt_blocknum;
0710 }
0711 if (!tp->ignore_out_of_order_packets &&
0712 pkt_blocknum > (int32_t) tp->blocknum + 1) {
0713 tp->ignore_out_of_order_packets = true;
0714 return GOT_FIRST_OUT_OF_ORDER_PACKET;
0715 } else if (pkt_blocknum == (int32_t) tp->blocknum) {
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725 return GOT_DUPLICATE_OF_CURRENT_PACKET;
0726 } else if (pkt_blocknum != (int32_t) tp->blocknum + 1) {
0727 return GOT_OLD_PACKET;
0728 }
0729 tp->ignore_out_of_order_packets = false;
0730
0731 tp->blocknum++;
0732 tp->nused = 0;
0733 tp->nleft = BLK_SIZE_FROM_PKT_SIZE (len);
0734 tp->at_eof = (tp->nleft < tp->server_options.block_size);
0735
0736
0737
0738 if (tp->at_eof) {
0739 plen = prepare_ack_packet_for_sending (tp, true, &send_buf, NULL, NULL);
0740
0741
0742
0743
0744 (void) sendto (
0745 tp->socket,
0746 send_buf,
0747 plen,
0748 0,
0749 (struct sockaddr *) &tp->farAddress,
0750 sizeof (tp->farAddress)
0751 );
0752 }
0753 tp->prepare_packet_for_sending = prepare_ack_packet_for_sending;
0754 return GOT_EXPECTED_PACKET;
0755 }
0756
0757 static int process_ack_packet (struct tftpStream *tp, ssize_t len)
0758 {
0759 uint16_t blocknum_ack;
0760 if (len < sizeof (tp->receive_buf->tftpACK)) {
0761 return process_malformed_packet (tp, len);
0762 }
0763 blocknum_ack = ntohs (tp->receive_buf->tftpACK.blocknum);
0764 if ((int32_t) blocknum_ack == tp->blocknum_of_first_packet_of_window - 1 &&
0765 blocknum_ack != 0
0766 ) {
0767 tp->blocknum = tp->blocknum_of_first_packet_of_window;
0768 return GOT_DUPLICATE_OF_CURRENT_PACKET;
0769 }
0770 if ((int32_t) blocknum_ack < tp->blocknum_of_first_packet_of_window ||
0771 blocknum_ack > tp->blocknum_last_filled) {
0772 return GOT_OLD_PACKET;
0773 }
0774 tp->blocknum = blocknum_ack + 1;
0775 tp->blocknum_of_first_packet_of_window = (int32_t) tp->blocknum;
0776 tp->prepare_packet_for_sending = prepare_data_packet_for_sending;
0777 return GOT_EXPECTED_PACKET;
0778 }
0779
0780 static ssize_t prepare_data_packet_for_sending (
0781 struct tftpStream *tp,
0782 bool force_retransmission,
0783 union tftpPacket **send_buf,
0784 bool *wait_for_packet_reception,
0785 const void *not_used
0786 )
0787 {
0788 (void) not_used;
0789 ssize_t len;
0790 *send_buf = get_send_buffer_packet (tp, tp->blocknum);
0791
0792 len = PKT_SIZE_FROM_BLK_SIZE (
0793 (tp->blocknum == tp->blocknum_eof_block) ? tp->nused : tp->block_size
0794 );
0795 (*send_buf)->tftpDATA.opcode = htons (TFTP_OPCODE_DATA);
0796 (*send_buf)->tftpDATA.blocknum = htons (tp->blocknum);
0797
0798
0799
0800
0801
0802
0803
0804
0805 if ((int32_t) tp->blocknum + 1 >=
0806 tp->blocknum_of_first_packet_of_window + tp->send_buf_size_in_pkts ||
0807 tp->blocknum == tp->blocknum_eof_block) {
0808 tp->blocknum = (uint16_t) tp->blocknum_of_first_packet_of_window;
0809 } else {
0810 tp->blocknum++;
0811 *wait_for_packet_reception = false;
0812 }
0813
0814 tp->process_data_packet = process_unexpected_packet;
0815 tp->process_ack_packet = process_ack_packet;
0816 tp->process_oack_packet = process_unexpected_packet;
0817 tp->process_error_packet = process_error_packet;
0818
0819
0820
0821
0822 if (tp->blocknum == tp->blocknum_eof_block) {
0823 tp->retransmission_error_code = 0;
0824 }
0825
0826 return len;
0827 }
0828
0829 static ssize_t prepare_ack_packet_for_sending (
0830 struct tftpStream *tp,
0831 bool force_retransmission,
0832 union tftpPacket **send_buf,
0833 bool *wait_for_packet_reception,
0834 const void *path_name
0835 )
0836 {
0837 (void) wait_for_packet_reception;
0838 if (!force_retransmission &&
0839 tp->blocknum_of_first_packet_of_window - 1 +
0840 (int32_t) tp->server_options.window_size > (int32_t) tp->blocknum) {
0841 return DO_NOT_SEND_PACKET;
0842 }
0843 tp->blocknum_of_first_packet_of_window = (int32_t) tp->blocknum + 1;
0844
0845
0846
0847
0848 *send_buf = tp->send_buf;
0849 (*send_buf)->tftpACK.opcode = htons (TFTP_OPCODE_ACK);
0850 (*send_buf)->tftpACK.blocknum = htons (tp->blocknum);
0851
0852 tp->process_data_packet = process_data_packet;
0853 tp->process_ack_packet = process_unexpected_packet;
0854 tp->process_oack_packet = process_unexpected_packet;
0855 tp->process_error_packet = process_error_packet;
0856
0857 return sizeof (tp->send_buf->tftpACK);
0858 }
0859
0860 static int process_oack_packet (struct tftpStream *tp, ssize_t len)
0861 {
0862 if (!parse_options(tp->receive_buf,
0863 len,
0864 &tp->config.options,
0865 &tp->server_options)) {
0866 send_error (
0867 tp,
0868 &tp->farAddress,
0869 TFTP_ERROR_CODE_OPTION_NEGO,
0870 "Bad options, option values or malformed OACK packet"
0871 );
0872 return EPROTO;
0873 }
0874 if (tp->is_for_reading) {
0875
0876
0877
0878
0879 tp->nleft = 0;
0880 tp->prepare_packet_for_sending = prepare_ack_packet_for_sending;
0881 } else {
0882 tp->blocknum_of_first_packet_of_window = 1;
0883 tp->blocknum = (uint16_t) tp->blocknum_of_first_packet_of_window;
0884 tp->prepare_packet_for_sending = prepare_data_packet_for_sending;
0885 }
0886 return GOT_EXPECTED_PACKET;
0887 }
0888
0889 static ssize_t prepare_request_packet_for_sending (
0890 struct tftpStream *tp,
0891 bool force_retransmission,
0892 union tftpPacket **send_buf,
0893 bool *wait_for_packet_reception,
0894 const void *path_name
0895 )
0896 {
0897 (void) wait_for_packet_reception;
0898 ssize_t len;
0899 *send_buf = tp->send_buf;
0900 len = create_request (
0901 *send_buf,
0902 tp->block_size,
0903 tp->is_for_reading,
0904 path_name,
0905 &tp->config.options
0906 );
0907
0908 if (len < 0) {
0909 tp->error = ENAMETOOLONG;
0910 } else {
0911 tp->process_data_packet = tp->is_for_reading ?
0912 process_data_packet : process_unexpected_packet;
0913 tp->process_ack_packet = tp->is_for_reading ?
0914 process_unexpected_packet : process_ack_packet;
0915 tp->process_oack_packet = MUST_SEND_OPTIONS(tp->config.options) ?
0916 process_oack_packet : process_unexpected_packet;
0917 tp->process_error_packet = MUST_SEND_OPTIONS(tp->config.options) ?
0918 process_error_packet_option_negotiation : process_error_packet;
0919 }
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929 tp->farAddress.sin_port = htons (tp->config.server_port);
0930 tp->firstReply = 1;
0931
0932 return len;
0933 }
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992 static int communicate_with_server (
0993 struct tftpStream *tp,
0994 const void *create_packet_data
0995 )
0996 {
0997 ssize_t len;
0998 uint16_t opcode;
0999 union tftpPacket *send_buf;
1000 bool received_duplicated_or_old_package = false;
1001 bool force_retransmission = false;
1002 bool wait_for_packet_reception;
1003 int retryCount = 0;
1004 while (tp->error == 0) {
1005
1006 if (!received_duplicated_or_old_package) {
1007 wait_for_packet_reception = true;
1008 len = tp->prepare_packet_for_sending (
1009 tp,
1010 force_retransmission,
1011 &send_buf,
1012 &wait_for_packet_reception,
1013 create_packet_data
1014 );
1015 if (len < 0) {
1016 if (tp->error == 0) {
1017 tp->error = EIO;
1018 }
1019 break;
1020 }
1021
1022 if (len != DO_NOT_SEND_PACKET) {
1023
1024
1025
1026 if (sendto (tp->socket, send_buf, len, 0,
1027 (struct sockaddr *)&tp->farAddress,
1028 sizeof tp->farAddress) < 0) {
1029 tp->error = EIO;
1030 break;
1031 }
1032 }
1033 }
1034 received_duplicated_or_old_package = false;
1035 force_retransmission = false;
1036
1037
1038
1039
1040 len = getPacket (
1041 tp,
1042 wait_for_packet_reception ? retryCount : GET_PACKET_DONT_WAIT
1043 );
1044 if (len >= (int) sizeof (tp->receive_buf->tftpDATA.opcode)) {
1045 opcode = ntohs (tp->receive_buf->tftpDATA.opcode);
1046 switch (opcode) {
1047 case TFTP_OPCODE_DATA:
1048 tp->error = tp->process_data_packet (tp, len);
1049 break;
1050 case TFTP_OPCODE_ACK:
1051 tp->error = tp->process_ack_packet (tp, len);
1052 break;
1053 case TFTP_OPCODE_OACK:
1054 tp->error = tp->process_oack_packet (tp, len);
1055 break;
1056 case TFTP_OPCODE_ERROR:
1057 tp->error = tp->process_error_packet (tp, len);
1058 break;
1059 default:
1060 tp->error = process_unexpected_packet (tp, len);
1061 break;
1062 }
1063 if (tp->error == GOT_EXPECTED_PACKET) {
1064 break;
1065 } else if (tp->error == GOT_DUPLICATE_OF_CURRENT_PACKET) {
1066 tp->error = 0;
1067 } else if (tp->error == GOT_OLD_PACKET) {
1068 received_duplicated_or_old_package = true;
1069 tp->error = 0;
1070 } else if (tp->error <= GOT_FIRST_OUT_OF_ORDER_PACKET) {
1071 force_retransmission = true;
1072 tp->error = 0;
1073 }
1074 } else if (len >= 0) {
1075 tp->error = process_malformed_packet (tp, len);
1076 } else if (len < 0 && !wait_for_packet_reception) {
1077 tp->error = 0;
1078 break;
1079 } else {
1080
1081
1082
1083
1084 if (++retryCount >= (int) tp->config.retransmissions) {
1085 tp->error = tp->retransmission_error_code;
1086 break;
1087 }
1088 force_retransmission = true;
1089 }
1090 }
1091
1092 return tp->error;
1093 }
1094
1095
1096
1097
1098
1099
1100 static struct tftpStream *create_stream(
1101 const tftp_net_config *config,
1102 const struct in_addr *farAddress,
1103 bool is_for_reading
1104 )
1105 {
1106 struct tftpStream *tp = NULL;
1107 tp = malloc (sizeof (struct tftpStream));
1108 if (tp == NULL) {
1109 return NULL;
1110 }
1111
1112
1113
1114
1115 tp->receive_buf = NULL;
1116 tp->send_buf = NULL;
1117 tp->socket = 0;
1118
1119
1120
1121
1122 tp->block_size = TFTP_RFC1350_BLOCK_SIZE;
1123 tp->packet_size = PKT_SIZE_FROM_BLK_SIZE (tp->block_size);
1124 tp->receive_buf = malloc (tp->packet_size);
1125 if (tp->receive_buf == NULL) {
1126 _Tftp_Destroy (tp);
1127 return NULL;
1128 }
1129 tp->send_buf = tp->receive_buf;
1130 tp->send_buf_size_in_pkts = 1;
1131
1132
1133
1134
1135 if ((tp->socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
1136 _Tftp_Destroy (tp);
1137 return NULL;
1138 }
1139
1140
1141
1142
1143 if ( config == NULL ) {
1144 tftp_initialize_net_config (&tp->config);
1145 } else {
1146 tp->config = *config;
1147 }
1148
1149
1150
1151
1152
1153 tp->server_options.block_size = TFTP_RFC1350_BLOCK_SIZE;
1154 tp->server_options.window_size = TFTP_RFC1350_WINDOW_SIZE;
1155
1156
1157
1158
1159
1160 tp->farAddress.sin_family = AF_INET;
1161 tp->farAddress.sin_addr = *farAddress;
1162 tp->farAddress.sin_port = htons (tp->config.server_port);
1163
1164 tp->nleft = 0;
1165 tp->nused = 0;
1166 tp->blocknum = 0;
1167 tp->blocknum_last_filled = 0;
1168 tp->blocknum_eof_block = UINT16_MAX;
1169 tp->firstReply = 1;
1170 tp->at_eof = false;
1171 tp->is_for_reading = is_for_reading;
1172
1173 tp->prepare_packet_for_sending = prepare_request_packet_for_sending;
1174 tp->process_data_packet = process_unexpected_packet;
1175 tp->process_ack_packet = process_unexpected_packet;
1176 tp->process_oack_packet = process_unexpected_packet;
1177 tp->process_error_packet = process_error_packet;
1178 tp->retransmission_error_code = EIO;
1179 tp->ignore_out_of_order_packets = false;
1180 tp->blocknum_of_first_packet_of_window = INT32_MIN;
1181 tp->error = 0;
1182
1183 return tp;
1184 }
1185
1186
1187
1188
1189
1190 static struct tftpStream *reallocate_stream_buffer(struct tftpStream *tp)
1191 {
1192 tp->block_size = tp->server_options.block_size;
1193 tp->packet_size = PKT_SIZE_FROM_BLK_SIZE (tp->block_size);
1194
1195
1196
1197 if (tp->receive_buf == tp->send_buf) {
1198 tp->send_buf = NULL;
1199 } else {
1200 free (tp->send_buf);
1201 }
1202
1203 tp->receive_buf = realloc (tp->receive_buf, tp->packet_size);
1204 if (tp->is_for_reading) {
1205 tp->send_buf = tp->receive_buf;
1206 } else {
1207 tp->send_buf_size_in_pkts = tp->server_options.window_size;
1208 tp->send_buf = malloc (
1209 tp->send_buf_size_in_pkts * tp->packet_size
1210 );
1211 }
1212
1213 if (tp->receive_buf == NULL || tp->send_buf == NULL) {
1214 sendStifle (tp, &tp->farAddress);
1215 _Tftp_Destroy (tp);
1216 return NULL;
1217 }
1218 return tp;
1219 }
1220
1221
1222
1223
1224 static struct in_addr *get_ip_address(
1225 const char *hostname,
1226 struct in_addr *farAddress
1227 )
1228 {
1229 struct hostent *he = gethostbyname(hostname);
1230 if (he == NULL) {
1231 return NULL;
1232 }
1233 memcpy (farAddress, he->h_addr, sizeof (*farAddress));
1234 return farAddress;
1235 }
1236
1237 void tftp_initialize_net_config (tftp_net_config *config)
1238 {
1239 static const tftp_net_config default_config = {
1240 .retransmissions = TFTP_RFC7440_DATA_RETRANSMISSIONS,
1241 .server_port = TFTP_DEFAULT_SERVER_PORT,
1242 .timeout = TFTP_RFC7440_TIMEOUT_MILLISECONDS,
1243 .first_timeout = PACKET_FIRST_TIMEOUT_MILLISECONDS,
1244 .options = {
1245 .block_size = TFTP_DEFAULT_BLOCK_SIZE,
1246 .window_size = TFTP_DEFAULT_WINDOW_SIZE
1247 }
1248 };
1249
1250 if (config != NULL) {
1251 memcpy (config, &default_config, sizeof (default_config));
1252 }
1253 }
1254
1255 int tftp_open(
1256 const char *hostname,
1257 const char *path,
1258 bool is_for_reading,
1259 const tftp_net_config *config,
1260 void **tftp_handle
1261 )
1262 {
1263 struct tftpStream *tp;
1264 struct in_addr farAddress;
1265 int err;
1266
1267
1268
1269
1270 if (tftp_handle == NULL) {
1271 return EINVAL;
1272 }
1273 *tftp_handle = NULL;
1274 if (hostname == NULL || path == NULL) {
1275 return EINVAL;
1276 }
1277 if (config != NULL && (
1278 config->options.window_size < TFTP_WINDOW_SIZE_MIN ||
1279 config->options.block_size < TFTP_BLOCK_SIZE_MIN ||
1280 config->options.block_size > TFTP_BLOCK_SIZE_MAX ) ) {
1281 return EINVAL;
1282 }
1283
1284
1285
1286
1287 if (get_ip_address( hostname, &farAddress ) == NULL) {
1288 return ENOENT;
1289 }
1290 tp = create_stream( config, &farAddress, is_for_reading );
1291 if (tp == NULL) {
1292 return ENOMEM;
1293 }
1294
1295
1296
1297
1298 tp->prepare_packet_for_sending = prepare_request_packet_for_sending;
1299 err = communicate_with_server (tp, path);
1300 if ( err != 0 ) {
1301 _Tftp_Destroy (tp);
1302 return err;
1303 }
1304
1305 *tftp_handle = reallocate_stream_buffer ( tp );
1306 if( *tftp_handle == NULL ) {
1307 return ENOMEM;
1308 }
1309
1310 return 0;
1311 }
1312
1313
1314
1315
1316 ssize_t tftp_read(
1317 void *tftp_handle,
1318 void *buffer,
1319 size_t count
1320 )
1321 {
1322 char *bp;
1323 struct tftpStream *tp = tftp_handle;
1324 int nwant;
1325 int err;
1326
1327 if (tp == NULL || !tp->is_for_reading || buffer == NULL)
1328 return -EIO;
1329
1330
1331
1332
1333 bp = buffer;
1334 nwant = count;
1335 while (nwant) {
1336 if (tp->nleft) {
1337 int ncopy;
1338 if (nwant < tp->nleft)
1339 ncopy = nwant;
1340 else
1341 ncopy = tp->nleft;
1342 memcpy (bp, &tp->receive_buf->tftpDATA.data[tp->nused], ncopy);
1343 tp->nused += ncopy;
1344 tp->nleft -= ncopy;
1345 bp += ncopy;
1346 nwant -= ncopy;
1347 if (nwant == 0)
1348 break;
1349 }
1350 if (tp->at_eof) {
1351 break;
1352 }
1353
1354
1355
1356
1357 tp->retransmission_error_code = -EIO;
1358 err = communicate_with_server(tp, NULL);
1359 if (err == tp->retransmission_error_code) {
1360 return -EIO;
1361 }
1362
1363
1364
1365
1366
1367
1368
1369
1370 if (err != 0) {
1371 tp->at_eof = true;
1372 return -err;
1373 }
1374 }
1375 return count - nwant;
1376 }
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390 static int rtems_tftp_flush (struct tftpStream *tp)
1391 {
1392 int err;
1393
1394 if (tp->at_eof) {
1395 return 0;
1396 }
1397
1398 do {
1399 err = communicate_with_server(tp, NULL);
1400
1401
1402
1403
1404
1405
1406
1407
1408 if (err != 0) {
1409 tp->at_eof = true;
1410 return err;
1411 }
1412 } while(
1413 (int32_t) tp->blocknum_last_filled + 1 >=
1414 tp->blocknum_of_first_packet_of_window + tp->send_buf_size_in_pkts ||
1415
1416
1417
1418
1419 (tp->blocknum_eof_block == tp->blocknum_last_filled &&
1420 tp->blocknum_of_first_packet_of_window <=
1421 (int32_t) tp->blocknum_eof_block)
1422 );
1423
1424 return 0;
1425 }
1426
1427
1428
1429
1430 int tftp_close(
1431 void *tftp_handle
1432 )
1433 {
1434 struct tftpStream *tp = tftp_handle;
1435 int e = 0;
1436
1437 if (tp == NULL) {
1438 return 0;
1439 }
1440
1441 if (!tp->is_for_reading) {
1442 tp->blocknum_last_filled++;
1443 tp->blocknum_eof_block = tp->blocknum_last_filled;
1444 e = rtems_tftp_flush (tp);
1445 tp->at_eof = true;
1446 }
1447 if (!tp->at_eof && !tp->firstReply) {
1448
1449
1450
1451 rtems_interval ticksPerSecond;
1452 send_error (
1453 tp,
1454 &tp->farAddress,
1455 TFTP_ERROR_CODE_NO_USER,
1456 "User (client) stopped reading or "
1457 "server stopped sending packets (timeout)"
1458 );
1459 ticksPerSecond = rtems_clock_get_ticks_per_second();
1460 rtems_task_wake_after (1 + ticksPerSecond / 10);
1461 }
1462 _Tftp_Destroy (tp);
1463 return e;
1464 }
1465
1466 ssize_t tftp_write(
1467 void *tftp_handle,
1468 const void *buffer,
1469 size_t count
1470 )
1471 {
1472 const char *bp;
1473 struct tftpStream *tp = tftp_handle;
1474 int nleft, nfree, ncopy;
1475 int err;
1476 union tftpPacket *send_buf;
1477
1478
1479
1480
1481 if (tp == NULL || tp->is_for_reading || tp->at_eof || buffer == NULL) {
1482 return -EIO;
1483 }
1484
1485
1486
1487
1488
1489
1490
1491
1492 bp = buffer;
1493 nleft = count;
1494 while (nleft) {
1495 nfree = tp->block_size - tp->nused;
1496 if (nleft < nfree)
1497 ncopy = nleft;
1498 else
1499 ncopy = nfree;
1500 send_buf = get_send_buffer_packet (tp, tp->blocknum_last_filled + 1);
1501 memcpy (&send_buf->tftpDATA.data[tp->nused], bp, ncopy);
1502 tp->nused += ncopy;
1503 nleft -= ncopy;
1504 bp += ncopy;
1505 if (tp->nused == tp->block_size) {
1506 tp->blocknum_last_filled++;
1507 err = rtems_tftp_flush (tp);
1508 if (err) {
1509 return -err;
1510 }
1511 tp->nused = 0;
1512 }
1513 }
1514 return count;
1515 }
1516
1517 void _Tftp_Destroy(
1518 void *tftp_handle
1519 )
1520 {
1521 struct tftpStream *tp = tftp_handle;
1522 if (tp == NULL) {
1523 return;
1524 }
1525
1526 if (tp->socket >= 0) {
1527 close (tp->socket);
1528 }
1529
1530 if (tp->receive_buf == tp->send_buf) {
1531 tp->send_buf = NULL;
1532 }
1533 free (tp->receive_buf);
1534 free (tp->send_buf);
1535 free (tp);
1536 }