From 94553814b57fb5196068eac015a25c3aa4d067b1 Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Sun, 28 Jun 2015 19:19:38 +0300 Subject: fs/tftp: handle incoming packets in the separate tftp_recv() function The separation of incoming packets handling makes it much easier to run barebox tftp client on top of picotcp network stack in the future. Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- fs/tftp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/fs/tftp.c b/fs/tftp.c index 72e4983a01..d970c601b9 100644 --- a/fs/tftp.c +++ b/fs/tftp.c @@ -253,15 +253,12 @@ static void tftp_timer_reset(struct file_priv *priv) priv->progress_timeout = priv->resend_timeout = get_time_ns(); } -static void tftp_handler(void *ctx, char *packet, unsigned len) +static void tftp_recv(struct file_priv *priv, + uint8_t *pkt, unsigned len, uint16_t uh_sport) { - struct file_priv *priv = ctx; uint16_t proto; uint16_t *s; - char *pkt = net_eth_to_udp_payload(packet); - struct udphdr *udp = net_eth_to_udphdr(packet); - len = net_eth_to_udplen(packet); if (len < 2) return; @@ -296,14 +293,14 @@ static void tftp_handler(void *ctx, char *packet, unsigned len) priv->state = STATE_DONE; break; } - priv->tftp_con->udp->uh_dport = udp->uh_sport; + priv->tftp_con->udp->uh_dport = uh_sport; priv->state = STATE_WDATA; break; case TFTP_OACK: tftp_parse_oack(priv, pkt, len); - priv->server_port = ntohs(udp->uh_sport); - priv->tftp_con->udp->uh_dport = udp->uh_sport; + priv->server_port = ntohs(uh_sport); + priv->tftp_con->udp->uh_dport = uh_sport; if (priv->push) { /* send first block */ @@ -326,8 +323,8 @@ static void tftp_handler(void *ctx, char *packet, unsigned len) if (priv->state == STATE_RRQ || priv->state == STATE_OACK) { /* first block received */ priv->state = STATE_RDATA; - priv->tftp_con->udp->uh_dport = udp->uh_sport; - priv->server_port = ntohs(udp->uh_sport); + priv->tftp_con->udp->uh_dport = uh_sport; + priv->server_port = ntohs(uh_sport); priv->last_block = 0; if (priv->block != 1) { /* Assertion */ @@ -376,6 +373,16 @@ static void tftp_handler(void *ctx, char *packet, unsigned len) } } +static void tftp_handler(void *ctx, char *packet, unsigned len) +{ + struct file_priv *priv = ctx; + char *pkt = net_eth_to_udp_payload(packet); + struct udphdr *udp = net_eth_to_udphdr(packet); + + (void)len; + tftp_recv(priv, pkt, net_eth_to_udplen(packet), udp->uh_sport); +} + static struct file_priv *tftp_do_open(struct device_d *dev, int accmode, const char *filename) { -- cgit v1.2.3 From fb6f3318de9eef90a9fc6bc7a7029ced221f78ac Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Sun, 28 Jun 2015 19:19:39 +0300 Subject: tftp_recv(): according to RFC1350 minimal tftp packet length is 4 bytes Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- fs/tftp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/tftp.c b/fs/tftp.c index d970c601b9..e36c1c8a41 100644 --- a/fs/tftp.c +++ b/fs/tftp.c @@ -259,7 +259,8 @@ static void tftp_recv(struct file_priv *priv, uint16_t proto; uint16_t *s; - if (len < 2) + /* according to RFC1350 minimal tftp packet length is 4 bytes */ + if (len < 4) return; len -= 2; @@ -315,8 +316,6 @@ static void tftp_recv(struct file_priv *priv, break; case TFTP_DATA: - if (len < 2) - return; len -= 2; priv->block = ntohs(*(uint16_t *)pkt); -- cgit v1.2.3 From 69957c548101c2c2a2e9cc5e588c610fb08d71a1 Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Sun, 28 Jun 2015 19:19:40 +0300 Subject: tftp_recv(): handle opcode field in a more natural way RFC1350 uses the 'opcode' term for the first 2-bytes field of TFTP packet. But the U-boot tftp code uses the 'proto' term for the same thing. The patch takes back original term and makes opcode calculation more clear. Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- fs/tftp.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/tftp.c b/fs/tftp.c index e36c1c8a41..0de215e5e9 100644 --- a/fs/tftp.c +++ b/fs/tftp.c @@ -256,22 +256,21 @@ static void tftp_timer_reset(struct file_priv *priv) static void tftp_recv(struct file_priv *priv, uint8_t *pkt, unsigned len, uint16_t uh_sport) { - uint16_t proto; - uint16_t *s; + uint16_t opcode; /* according to RFC1350 minimal tftp packet length is 4 bytes */ if (len < 4) return; - len -= 2; + opcode = ntohs(*(uint16_t *)pkt); - s = (uint16_t *)pkt; - proto = *s++; - pkt = (unsigned char *)s; + /* skip tftp opcode 2-byte field */ + len -= 2; + pkt += 2; - debug("%s: proto 0x%04x\n", __func__, proto); + debug("%s: opcode 0x%04x\n", __func__, opcode); - switch (ntohs(proto)) { + switch (opcode) { case TFTP_RRQ: case TFTP_WRQ: default: -- cgit v1.2.3 From 8bbc1064c78cdf658c837b996170b8eab8cbcb3d Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Wed, 1 Jul 2015 00:32:54 +0300 Subject: dns: handle incoming packets in the separate dns_recv() function The separation of incoming packets handling makes it much easier to run barebox dns client on top of picotcp network stack in the future. Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- net/dns.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/dns.c b/net/dns.c index 0a8ce8b244..0e16ea2c9d 100644 --- a/net/dns.c +++ b/net/dns.c @@ -116,9 +116,8 @@ static int dns_send(char *name) return ret; } -static void dns_handler(void *ctx, char *packet, unsigned len) +static void dns_recv(struct header *header, unsigned len) { - struct header *header; unsigned char *p, *e, *s; u16 type; int found, stop, dlen; @@ -127,7 +126,6 @@ static void dns_handler(void *ctx, char *packet, unsigned len) debug("%s\n", __func__); /* We sent 1 query. We want to see more that 1 answer. */ - header = (struct header *)net_eth_to_udp_payload(packet); if (ntohs(header->nqueries) != 1) return; @@ -140,7 +138,7 @@ static void dns_handler(void *ctx, char *packet, unsigned len) /* Skip host name */ s = &header->data[0]; - e = packet + len; + e = ((uint8_t *)header) + len; for (p = s; p < e && *p != '\0'; p++) continue; @@ -194,6 +192,13 @@ static void dns_handler(void *ctx, char *packet, unsigned len) } } +static void dns_handler(void *ctx, char *packet, unsigned len) +{ + (void)ctx; + dns_recv((struct header *)net_eth_to_udp_payload(packet), + net_eth_to_udplen(packet)); +} + IPaddr_t resolv(char *host) { IPaddr_t ip; -- cgit v1.2.3