25 #ifndef CURL_DISABLE_TFTP 27 #ifdef HAVE_NETINET_IN_H 28 #include <netinet/in.h> 33 #ifdef HAVE_ARPA_INET_H 34 #include <arpa/inet.h> 39 #ifdef HAVE_SYS_IOCTL_H 40 #include <sys/ioctl.h> 43 #ifdef HAVE_SYS_PARAM_H 44 #include <sys/param.h> 69 #define TFTP_BLKSIZE_DEFAULT 512 70 #define TFTP_BLKSIZE_MIN 8 71 #define TFTP_BLKSIZE_MAX 65464 72 #define TFTP_OPTION_BLKSIZE "blksize" 75 #define TFTP_OPTION_TSIZE "tsize" 76 #define TFTP_OPTION_INTERVAL "timeout" 153 bool dead_connection);
219 maxtime = (time_t)(timeout_ms + 500) / 1000;
240 maxtime = (time_t)(timeout_ms + 500) / 1000;
265 "set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
285 packet->
data[0] = (
unsigned char)(num >> 8);
286 packet->
data[1] = (
unsigned char)(num & 0xff);
292 packet->
data[2] = (
unsigned char)(num >> 8);
293 packet->
data[3] = (
unsigned char)(num & 0xff);
298 return (
unsigned short)((packet->
data[0] << 8) | packet->
data[1]);
303 return (
unsigned short)((packet->
data[2] << 8) | packet->
data[3]);
308 const char *end = memchr(
string,
'\0', maxlen);
309 return end ? (
size_t) (end -
string) : maxlen;
313 const char **option,
const char **
value)
329 *value = &buf[strlen(*option) + 1];
337 const char *tmp =
ptr;
343 while(tmp < ptr + len) {
344 const char *option, *
value;
348 failf(data,
"Malformed ACK packet, rejecting");
352 infof(data,
"got option=(%s) value=(%s)\n", option, value);
357 blksize = strtol(value, NULL, 10);
360 failf(data,
"invalid blocksize value in OACK packet");
364 failf(data,
"%s (%d)",
"blksize is larger than max supported",
369 failf(data,
"%s (%d)",
"blksize is smaller than min supported",
377 failf(data,
"%s (%ld)",
378 "server requested blksize larger than allocated", blksize);
383 infof(data,
"%s (%d) %s (%d)\n",
"blksize parsed from OACK",
389 tsize = strtol(value, NULL, 10);
390 infof(data,
"%s (%ld)\n",
"tsize parsed from OACK", tsize);
396 failf(data,
"invalid tsize -:%s:- value in OACK packet", value);
408 char *
buf,
const char *option)
410 if(( strlen(option) + csize + 1) > (
size_t)state->
blksize)
413 return strlen(option) + 1;
420 #ifndef CURL_DISABLE_VERBOSE_STRINGS 423 infof(data,
"%s\n",
"Connected for transmit");
436 #ifndef CURL_DISABLE_VERBOSE_STRINGS 439 infof(data,
"%s\n",
"Connected for receive");
452 const char *mode =
"octet";
490 &filename, NULL,
FALSE);
494 if(strlen(filename) > (state->
blksize - strlen(mode) - 4)) {
495 failf(data,
"TFTP file name too long\n");
502 "%s%c%s%c", filename,
'\0', mode,
'\0');
503 sbytes = 4 + strlen(filename) + strlen(mode);
542 if(senddata != (
ssize_t)sbytes) {
579 #define NEXT_BLOCKNUM(x) (((x) + 1)&0xffff) 603 else if(state->
block == rblock) {
606 infof(data,
"Received last DATA packet block %d again.\n", rblock);
611 "Received unexpected DATA packet block %d, expecting block %d\n",
617 state->
block = (
unsigned short)rblock;
663 "Timeout waiting for block %d ACK. Retries = %d\n",
695 failf(data,
"%s",
"tftp_rx: internal error");
726 if(rblock != state->
block &&
732 !(state->
block == 0 && rblock == 65535)) {
734 infof(data,
"Received ACK for block %d, expecting %d\n",
735 rblock, state->
block);
739 failf(data,
"tftp_tx: giving up waiting for block %d ack",
806 infof(data,
"Timeout waiting for block %d ACK. " 842 failf(data,
"tftp_tx: internal error, event: %i", (
int)(event));
914 switch(state->
state) {
921 result =
tftp_rx(state, event);
925 result =
tftp_tx(state, event);
928 infof(data,
"%s\n",
"TFTP finished");
932 failf(data,
"%s",
"Internal state machine error");
950 (void) dead_connection;
1012 ((
struct sockaddr *)&state->
local_addr)->sa_family =
1109 fromlen =
sizeof(fromaddr);
1114 (
struct sockaddr *)&fromaddr,
1123 failf(data,
"Received too short packet");
1132 switch(state->
event) {
1144 k->bytecount += state->
rbytes-4;
1167 failf(data,
"%s",
"Internal error: Unexpected packet");
1198 (
long)current, (
long)state->
max_time));
1233 if(timeout_ms <= 0) {
1234 failf(data,
"TFTP response timeout");
1313 *dophase_done =
FALSE;
1377 type = strstr(data->
state.
path,
";mode=");
static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
#define TFTP_BLKSIZE_DEFAULT
static unsigned short getrpacketblock(const tftp_packet_t *packet)
CURLcode Curl_urldecode(struct Curl_easy *data, const char *string, size_t length, char **ostring, size_t *olen, bool reject_ctrl)
static CURLcode tftp_connect_for_tx(tftp_state_data_t *state, tftp_event_t event)
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
struct connectdata * conn
#define PROTOPT_NOURLQUERY
static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks)
static CURLcode tftp_connect_for_rx(tftp_state_data_t *state, tftp_event_t event)
static CURLcode tftp_connect(struct connectdata *conn, bool *done)
int Curl_pgrsDone(struct connectdata *conn)
UNITTEST_START char * ptr
#define GETSOCK_READSOCK(x)
#define TFTP_OPTION_TSIZE
const struct Curl_handler Curl_handler_tftp
void Curl_pgrsStartNow(struct Curl_easy *data)
UNITTEST_START int result
static CURLcode tftp_done(struct connectdata *conn, CURLcode, bool premature)
struct Curl_sockaddr_storage local_addr
struct sockaddr * ai_addr
int Curl_pgrsUpdate(struct connectdata *conn)
memcpy(filename, filename1, strlen(filename1))
static CURLcode tftp_setup_connection(struct connectdata *conn)
CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t
static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
void Curl_setup_transfer(struct connectdata *conn, int sockindex, curl_off_t size, bool getheader, curl_off_t *bytecountp, int writesockindex, curl_off_t *writecountp)
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
ROSLIB_DECL std::string command(const std::string &cmd)
const char * Curl_strerror(struct connectdata *conn, int err)
#define TFTP_OPTION_BLKSIZE
#define SOCKET_READABLE(x, z)
static const char * tftp_option_get(const char *buf, size_t len, const char **option, const char **value)
static size_t tftp_option_add(tftp_state_data_t *state, size_t csize, char *buf, const char *option)
curl_socklen_t remote_addrlen
static void setpacketevent(tftp_packet_t *packet, unsigned short num)
void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
CURL_TYPEOF_CURL_OFF_T curl_off_t
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
CURLcode Curl_speedcheck(struct Curl_easy *data, struct curltime now)
static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
static CURLcode tftp_parse_option_ack(tftp_state_data_t *state, const char *ptr, int len)
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len)
#define Curl_safefree(ptr)
static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
static curl_socklen_t fromlen
curl_off_t writebytecount
static CURLcode tftp_state_machine(tftp_state_data_t *state, tftp_event_t event)
struct tftp_packet tftp_packet_t
static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
struct Curl_sockaddr_storage remote_addr
static CURLcode tftp_translate_code(tftp_error_t error)
static size_t Curl_strnlen(const char *string, size_t maxlen)
static size_t cb(char *d, size_t n, size_t l, void *p)
static CURLcode tftp_do(struct connectdata *conn, bool *done)
static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
static void setpacketblock(tftp_packet_t *packet, unsigned short num)
struct tftp_state_data tftp_state_data_t
UNITTEST_START int * value
static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
curl_socklen_t ai_addrlen
#define TFTP_OPTION_INTERVAL
#define checkprefix(a, b)
static CURLcode tftp_receive_packet(struct connectdata *conn)
union connectdata::@34 proto
static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
struct tftp_state_data * tftpc
static unsigned short getrpacketevent(const tftp_packet_t *packet)
char Curl_raw_toupper(char in)
#define calloc(nbelem, size)
#define CURL_FORMAT_CURL_OFF_T