diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2007-03-15 08:36:18 +0000 |
---|---|---|
committer | Peter Korsgaard <jacmet@sunsite.dk> | 2007-03-15 08:36:18 +0000 |
commit | 5b582fdaa0fb518a9b3c8bfe1cbd4151efad3c62 (patch) | |
tree | 54e4d883aa6d584cab082f8a4ab393d819082ccf /package/busybox | |
parent | 7920c869d9523e383d6d191e89ba66153af322db (diff) |
tftp patch
Diffstat (limited to 'package/busybox')
-rw-r--r-- | package/busybox/busybox-1.4.1-tftp.patch | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/package/busybox/busybox-1.4.1-tftp.patch b/package/busybox/busybox-1.4.1-tftp.patch new file mode 100644 index 000000000..6faf5c728 --- /dev/null +++ b/package/busybox/busybox-1.4.1-tftp.patch @@ -0,0 +1,112 @@ +--- busybox-1.4.1/include/libbb.h Wed Jan 24 22:34:48 2007 ++++ busybox-1.4.1-tftp/include/libbb.h Sat Mar 3 00:02:34 2007 +@@ -290,7 +290,7 @@ + + /* "new" (ipv4+ipv6) API */ + typedef struct len_and_sockaddr { +- int len; ++ socklen_t len; + union { + struct sockaddr sa; + struct sockaddr_in sin; +--- busybox-1.4.1/networking/tftp.c Wed Jan 24 22:34:34 2007 ++++ busybox-1.4.1-tftp/networking/tftp.c Sat Mar 3 00:02:56 2007 +@@ -132,7 +132,7 @@ + #if ENABLE_FEATURE_TFTP_GET && ENABLE_FEATURE_TFTP_PUT + const int cmd, + #endif +- const len_and_sockaddr *peer_lsa, ++ len_and_sockaddr *peer_lsa, + const char *remotefile, const int localfd, + unsigned port, int tftp_bufsize) + { +@@ -149,6 +149,9 @@ + + USE_FEATURE_TFTP_BLOCKSIZE(int want_option_ack = 0;) + ++ unsigned org_port; ++ len_and_sockaddr *const from = alloca(offsetof(len_and_sockaddr, sa) + peer_lsa->len); ++ + /* Can't use RESERVE_CONFIG_BUFFER here since the allocation + * size varies meaning BUFFERS_GO_ON_STACK would fail */ + /* We must keep the transmit and receive buffers seperate */ +@@ -156,7 +159,7 @@ + char *xbuf = xmalloc(tftp_bufsize += 4); + char *rbuf = xmalloc(tftp_bufsize); + +- port = htons(port); ++ port = org_port = htons(port); + + socketfd = xsocket(peer_lsa->sa.sa_family, SOCK_DGRAM, 0); + +@@ -167,10 +170,10 @@ + } + + while (1) { +- + cp = xbuf; + + /* first create the opcode part */ ++ /* (this 16bit store is aligned) */ + *((uint16_t*)cp) = htons(opcode); + cp += 2; + +@@ -222,6 +225,7 @@ + /* add ack and data */ + + if (CMD_GET(cmd) ? (opcode == TFTP_ACK) : (opcode == TFTP_DATA)) { ++ /* TODO: unaligned access! */ + *((uint16_t*)cp) = htons(block_nr); + cp += 2; + block_nr++; +@@ -273,28 +277,26 @@ + FD_SET(socketfd, &rfds); + + switch (select(socketfd + 1, &rfds, NULL, NULL, &tv)) { +- struct sockaddr *from; +- socklen_t fromlen; +- ++ unsigned from_port; + case 1: +- fromlen = peer_lsa->len; +- from = alloca(fromlen); +- memset(from, 0, fromlen); +- ++ from->len = peer_lsa->len; ++ memset(&from->sa, 0, peer_lsa->len); + len = recvfrom(socketfd, rbuf, tftp_bufsize, 0, +- from, &fromlen); ++ &from->sa, &from->len); + if (len < 0) { + bb_perror_msg("recvfrom"); + break; + } +-#if ENABLE_FEATURE_IPV6 +- if (from->sa_family == AF_INET6) +- if (((struct sockaddr_in6*)from)->sin6_port != port) +- goto recv_again; +-#endif +- if (from->sa_family == AF_INET) +- if (((struct sockaddr_in*)from)->sin_port != port) +- goto recv_again; ++ from_port = get_nport(from); ++ if (port == org_port) { ++ /* Our first query went to port 69 ++ * but reply will come from different one. ++ * Remember and use this new port */ ++ port = from_port; ++ set_nport(peer_lsa, from_port); ++ } ++ if (port != from_port) ++ goto recv_again; + timeout = 0; + break; + case 0: +@@ -317,6 +319,7 @@ + } + + /* process received packet */ ++ /* (both accesses seems to be aligned) */ + + opcode = ntohs( ((uint16_t*)rbuf)[0] ); + tmp = ntohs( ((uint16_t*)rbuf)[1] ); |