busybox-1.4.1-tftp.patch 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. --- busybox-1.4.1/include/libbb.h Wed Jan 24 22:34:48 2007
  2. +++ busybox-1.4.1-tftp/include/libbb.h Sat Mar 3 00:02:34 2007
  3. @@ -290,7 +290,7 @@
  4. /* "new" (ipv4+ipv6) API */
  5. typedef struct len_and_sockaddr {
  6. - int len;
  7. + socklen_t len;
  8. union {
  9. struct sockaddr sa;
  10. struct sockaddr_in sin;
  11. --- busybox-1.4.1/networking/tftp.c Wed Jan 24 22:34:34 2007
  12. +++ busybox-1.4.1-tftp/networking/tftp.c Sat Mar 3 00:02:56 2007
  13. @@ -132,7 +132,7 @@
  14. #if ENABLE_FEATURE_TFTP_GET && ENABLE_FEATURE_TFTP_PUT
  15. const int cmd,
  16. #endif
  17. - const len_and_sockaddr *peer_lsa,
  18. + len_and_sockaddr *peer_lsa,
  19. const char *remotefile, const int localfd,
  20. unsigned port, int tftp_bufsize)
  21. {
  22. @@ -149,6 +149,9 @@
  23. USE_FEATURE_TFTP_BLOCKSIZE(int want_option_ack = 0;)
  24. + unsigned org_port;
  25. + len_and_sockaddr *const from = alloca(offsetof(len_and_sockaddr, sa) + peer_lsa->len);
  26. +
  27. /* Can't use RESERVE_CONFIG_BUFFER here since the allocation
  28. * size varies meaning BUFFERS_GO_ON_STACK would fail */
  29. /* We must keep the transmit and receive buffers seperate */
  30. @@ -156,7 +159,7 @@
  31. char *xbuf = xmalloc(tftp_bufsize += 4);
  32. char *rbuf = xmalloc(tftp_bufsize);
  33. - port = htons(port);
  34. + port = org_port = htons(port);
  35. socketfd = xsocket(peer_lsa->sa.sa_family, SOCK_DGRAM, 0);
  36. @@ -167,10 +170,10 @@
  37. }
  38. while (1) {
  39. -
  40. cp = xbuf;
  41. /* first create the opcode part */
  42. + /* (this 16bit store is aligned) */
  43. *((uint16_t*)cp) = htons(opcode);
  44. cp += 2;
  45. @@ -222,6 +225,7 @@
  46. /* add ack and data */
  47. if (CMD_GET(cmd) ? (opcode == TFTP_ACK) : (opcode == TFTP_DATA)) {
  48. + /* TODO: unaligned access! */
  49. *((uint16_t*)cp) = htons(block_nr);
  50. cp += 2;
  51. block_nr++;
  52. @@ -273,28 +277,26 @@
  53. FD_SET(socketfd, &rfds);
  54. switch (select(socketfd + 1, &rfds, NULL, NULL, &tv)) {
  55. - struct sockaddr *from;
  56. - socklen_t fromlen;
  57. -
  58. + unsigned from_port;
  59. case 1:
  60. - fromlen = peer_lsa->len;
  61. - from = alloca(fromlen);
  62. - memset(from, 0, fromlen);
  63. -
  64. + from->len = peer_lsa->len;
  65. + memset(&from->sa, 0, peer_lsa->len);
  66. len = recvfrom(socketfd, rbuf, tftp_bufsize, 0,
  67. - from, &fromlen);
  68. + &from->sa, &from->len);
  69. if (len < 0) {
  70. bb_perror_msg("recvfrom");
  71. break;
  72. }
  73. -#if ENABLE_FEATURE_IPV6
  74. - if (from->sa_family == AF_INET6)
  75. - if (((struct sockaddr_in6*)from)->sin6_port != port)
  76. - goto recv_again;
  77. -#endif
  78. - if (from->sa_family == AF_INET)
  79. - if (((struct sockaddr_in*)from)->sin_port != port)
  80. - goto recv_again;
  81. + from_port = get_nport(from);
  82. + if (port == org_port) {
  83. + /* Our first query went to port 69
  84. + * but reply will come from different one.
  85. + * Remember and use this new port */
  86. + port = from_port;
  87. + set_nport(peer_lsa, from_port);
  88. + }
  89. + if (port != from_port)
  90. + goto recv_again;
  91. timeout = 0;
  92. break;
  93. case 0:
  94. @@ -317,6 +319,7 @@
  95. }
  96. /* process received packet */
  97. + /* (both accesses seems to be aligned) */
  98. opcode = ntohs( ((uint16_t*)rbuf)[0] );
  99. tmp = ntohs( ((uint16_t*)rbuf)[1] );