--- /dev/null
+--- 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] );