Lines Matching refs:xfer

53 struct xfer {
85 struct xfer xfers[TFTP_MAX_XFERS];
90 int (*getopt)(struct xfer *, const char *);
91 int (*ackopt)(struct xfer *, char **, size_t *);
101 static void tftp_recv_ack(struct xfer *, u16_t);
102 static void tftp_fillbuf(struct xfer *);
103 static void tftp_send(struct xfer *);
106 static struct xfer *tftp_xfer_alloc(ip_addr_t *, u16_t);
107 static int tftp_xfer_create_pcb(struct xfer *);
108 static void tftp_xfer_free(struct xfer *);
110 static int tftp_parse_filename(struct xfer *, char **, size_t *);
111 static int tftp_parse_mode(struct xfer *, char **, size_t *);
112 static int tftp_parse_option(struct xfer *, char **, size_t *);
114 static int tftp_opt_blksize(struct xfer *, const char *);
115 static int tftp_opt_timeout(struct xfer *, const char *);
116 static int tftp_opt_tsize(struct xfer *, const char *);
118 static char *tftp_getstr(struct xfer *, const char *, char **, size_t *);
120 static int tftp_ack_blksize(struct xfer *, char **, size_t *);
121 static int tftp_ack_timeout(struct xfer *, char **, size_t *);
122 static int tftp_ack_tsize(struct xfer *, char **, size_t *);
128 static int tftp_internal_error(struct xfer *);
129 static int tftp_error(struct xfer *, u16_t, const char *, ...) __attribute__((format(printf, 3, 4)));
221 struct xfer *xfer;
227 xfer = tftp_xfer_alloc(addr, port);
228 if (xfer == NULL) {
241 status = tftp_parse_filename(xfer, &s, &len);
246 status = tftp_parse_mode(xfer, &s, &len);
253 status = tftp_parse_option(xfer, &s, &len);
265 xfer->oack = pbuf_alloc(PBUF_RAW, 128, PBUF_RAM);
266 if (xfer->oack != NULL) {
269 ((u16_t *)xfer->oack->payload)[0] = PP_HTONS(TFTP_OACK);
271 s = (char *)xfer->oack->payload + sizeof(u16_t);
272 len = xfer->oack->len - sizeof(u16_t);
275 status = (*o->ackopt)(xfer, &s, &len);
277 pbuf_free(xfer->oack);
278 xfer->oack = NULL;
283 if (xfer->oack != NULL) {
284 pbuf_realloc(xfer->oack, xfer->oack->len - len);
293 xfer->pbuf = pbuf_alloc(PBUF_RAW, xfer->blksize + 4, PBUF_RAM);
294 if (xfer->pbuf == NULL) {
295 tftp_internal_error(xfer);
298 ((u16_t *)xfer->pbuf->payload)[0] = PP_HTONS(TFTP_DATA);
305 status = tftp_xfer_create_pcb(xfer);
310 if (xfer->oack) {
311 tftp_send(xfer);
315 tftp_recv_ack(xfer, 0);
322 tftp_xfer_free(xfer);
330 struct xfer *xfer = (struct xfer *)arg;
337 LWIP_ASSERT1(xfer->pcb == pcb);
340 tftp_error(xfer, TFTP_ENOSYS, "Short packet");
341 tftp_xfer_free(xfer);
351 tftp_error(xfer, TFTP_ENOSYS, "Short packet");
352 tftp_xfer_free(xfer);
358 tftp_recv_ack(xfer, ack);
361 tftp_xfer_free(xfer);
364 tftp_error(xfer, TFTP_ENOSYS, "Unexpected opcode %d", op);
365 tftp_xfer_free(xfer);
373 tftp_recv_ack(struct xfer *xfer, u16_t ack)
375 if (ack != (u16_t)xfer->ack) {
377 __func__, (u16_t)xfer->ack, xfer->ack, ack));
381 sys_untimeout(tftp_timeout, xfer);
382 xfer->rexmit = 0;
384 if (xfer->pbuf->len < xfer->blksize) {
386 __func__, (u16_t)xfer->ack, xfer->ack));
387 tftp_xfer_free(xfer);
391 if (xfer->oack != NULL) {
392 pbuf_free(xfer->oack);
393 xfer->oack = NULL;
396 ++xfer->ack;
397 tftp_fillbuf(xfer);
398 tftp_send(xfer);
403 tftp_send(struct xfer *xfer)
407 pbuf = xfer->oack ? xfer->oack : xfer->pbuf;
408 udp_send(xfer->pcb, pbuf);
409 sys_timeout(xfer->timeout * 1000, tftp_timeout, xfer);
416 struct xfer *xfer = (struct xfer *)arg;
419 maxrexmit = xfer->timeout < 60 ? 5 : 3;
420 if (++xfer->rexmit < maxrexmit) {
421 tftp_send(xfer);
424 tftp_xfer_free(xfer);
430 tftp_fillbuf(struct xfer *xfer)
434 DPRINTF2(("%s: reading block %u\n", __func__, xfer->ack));
436 ((u16_t *)xfer->pbuf->payload)[1] = htons(xfer->ack);
437 nread = read(xfer->fd, (char *)xfer->pbuf->payload + 4, xfer->blksize);
440 tftp_error(xfer, TFTP_EUNDEF, "Read failed");
444 pbuf_realloc(xfer->pbuf, nread + 4);
463 static struct xfer *
466 struct xfer *xfer;
469 /* Find free xfer slot */
470 xfer = NULL;
473 xfer = &tftpd.xfers[i];
478 if (xfer == NULL) {
486 ipX_addr_copy(0, xfer->peer_ip, *ip_2_ipX(addr));
487 xfer->peer_port = port;
489 xfer->ack = 0;
491 xfer->pbuf = NULL;
492 xfer->oack = NULL;
493 xfer->rexmit = 0;
495 xfer->blksize = 512;
496 xfer->blksize_from_opt = 0;
498 xfer->timeout = 1;
499 xfer->timeout_from_opt = 0;
501 xfer->tsize = -1;
502 xfer->tsize_from_opt = 0;
504 return xfer;
509 tftp_xfer_create_pcb(struct xfer *xfer)
527 error = udp_connect(pcb, ipX_2_ip(&xfer->peer_ip), xfer->peer_port);
536 tftp_error(xfer, TFTP_EUNDEF, "Failed to create connection");
541 xfer->pcb = pcb;
542 udp_recv(xfer->pcb, tftp_xfer_recv, xfer);
549 tftp_xfer_free(struct xfer *xfer)
551 sys_untimeout(tftp_timeout, xfer);
553 if (xfer->pcb != NULL) {
554 udp_remove(xfer->pcb);
555 xfer->pcb = NULL;
558 if (xfer->fd > 0) {
559 close(xfer->fd);
560 xfer->fd = -1;
563 if (xfer->oack != NULL) {
564 pbuf_free(xfer->oack);
565 xfer->oack = NULL;
568 if (xfer->pbuf != NULL) {
569 pbuf_free(xfer->pbuf);
570 xfer->pbuf = NULL;
573 if (xfer->filename != NULL) {
574 free(xfer->filename);
575 xfer->filename = NULL;
581 tftp_parse_filename(struct xfer *xfer, char **ps, size_t *plen)
590 filename = tftp_getstr(xfer, "filename", ps, plen);
596 xfer->filename = strdup(filename);
597 if (xfer->filename == NULL) {
598 return tftp_internal_error(xfer);
602 s = xfer->filename;
608 if (strncmp(xfer->filename, "../", 3) == 0
609 || strstr(xfer->filename, "/../") != NULL)
611 return tftp_error(xfer, TFTP_ENOENT, "Permission denied");
614 len = strlen(tftpd.root) + 1 /*slash*/ + strlen(xfer->filename) + 1 /*nul*/;
617 return tftp_internal_error(xfer);
620 status = RTStrPrintf(pathname, len, "%s/%s", tftpd.root, xfer->filename);
622 return tftp_internal_error(xfer);
626 xfer->fd = open(pathname, O_RDONLY);
627 if (xfer->fd < 0) {
629 return tftp_error(xfer, TFTP_ENOENT, "Permission denied");
632 return tftp_error(xfer, TFTP_ENOENT, "File not found");
636 status = fstat(xfer->fd, &st);
638 return tftp_internal_error(xfer);
642 return tftp_error(xfer, TFTP_ENOENT, "File not found");
645 xfer->tsize = st.st_size;
651 tftp_parse_mode(struct xfer *xfer, char **ps, size_t *plen)
655 modename = tftp_getstr(xfer, "mode", ps, plen);
661 xfer->octet = 1;
664 xfer->octet = 0;
666 return tftp_error(xfer, TFTP_ENOSYS, "Mode \"netascii\" not supported");
669 return tftp_error(xfer, TFTP_ENOSYS, "Mode \"mail\" not supported");
672 return tftp_error(xfer, TFTP_ENOSYS, "Unknown mode \"%s\"", modename);
680 tftp_parse_option(struct xfer *xfer, char **ps, size_t *plen)
686 opt = tftp_getstr(xfer, "option name", ps, plen);
692 return tftp_error(xfer, TFTP_EUNDEF, "Missing option value");
695 val = tftp_getstr(xfer, "option value", ps, plen);
703 return (*o->getopt)(xfer, val);
712 tftp_opt_blksize(struct xfer *xfer, const char *optval)
731 xfer->blksize = blksize;
732 xfer->blksize_from_opt = 1;
738 tftp_opt_timeout(struct xfer *xfer, const char *optval)
740 LWIP_UNUSED_ARG(xfer);
747 tftp_opt_tsize(struct xfer *xfer, const char *optval)
751 if (xfer->tsize < 0) {
755 xfer->tsize_from_opt = 1;
761 tftp_getstr(struct xfer *xfer, const char *msg, char **ps, size_t *plen)
769 tftp_error(xfer, TFTP_EUNDEF, "Unterminated %s", msg);
781 tftp_ack_blksize(struct xfer *xfer, char **ps, size_t *plen)
783 if (!xfer->blksize_from_opt) {
787 return tftp_add_oack(ps, plen, "blksize", "%u", xfer->blksize);
792 tftp_ack_timeout(struct xfer *xfer, char **ps, size_t *plen)
794 if (!xfer->timeout_from_opt) {
798 return tftp_add_oack(ps, plen, "timeout", "%u", xfer->timeout);
803 tftp_ack_tsize(struct xfer *xfer, char **ps, size_t *plen)
805 if (!xfer->tsize_from_opt) {
809 LWIP_ASSERT1(xfer->tsize >= 0);
812 "%lu", (unsigned long)xfer->tsize);
862 tftp_internal_error(struct xfer *xfer)
865 tftp_error(xfer, TFTP_EUNDEF, "Internal error");
886 tftp_error(struct xfer *xfer, u16_t error, const char *fmt, ...)
891 LWIP_ASSERT1(xfer != NULL);
901 if (xfer->pcb != NULL) {
902 udp_send(xfer->pcb, q);
905 udp_sendto(tftpd.pcb, q, ipX_2_ip(&xfer->peer_ip), xfer->peer_port);