wget.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2022 Linaro
  4. *
  5. * (C) Copyright 2022
  6. * Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
  7. */
  8. #include <common.h>
  9. #include <command.h>
  10. #include <dm.h>
  11. #include <env.h>
  12. #include <fdtdec.h>
  13. #include <log.h>
  14. #include <malloc.h>
  15. #include <net.h>
  16. #include <net/tcp.h>
  17. #include <net/wget.h>
  18. #include <asm/eth.h>
  19. #include <dm/test.h>
  20. #include <dm/device-internal.h>
  21. #include <dm/uclass-internal.h>
  22. #include <test/lib.h>
  23. #include <test/test.h>
  24. #include <test/ut.h>
  25. #define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4)
  26. #define LEN_B_TO_DW(x) ((x) >> 2)
  27. static int sb_arp_handler(struct udevice *dev, void *packet,
  28. unsigned int len)
  29. {
  30. struct eth_sandbox_priv *priv = dev_get_priv(dev);
  31. struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
  32. int ret = 0;
  33. if (ntohs(arp->ar_op) == ARPOP_REQUEST) {
  34. priv->fake_host_ipaddr = net_read_ip(&arp->ar_spa);
  35. ret = sandbox_eth_recv_arp_req(dev);
  36. if (ret)
  37. return ret;
  38. ret = sandbox_eth_arp_req_to_reply(dev, packet, len);
  39. return ret;
  40. }
  41. return -EPROTONOSUPPORT;
  42. }
  43. static int sb_syn_handler(struct udevice *dev, void *packet,
  44. unsigned int len)
  45. {
  46. struct eth_sandbox_priv *priv = dev_get_priv(dev);
  47. struct ethernet_hdr *eth = packet;
  48. struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE;
  49. struct ethernet_hdr *eth_send;
  50. struct ip_tcp_hdr *tcp_send;
  51. /* Don't allow the buffer to overrun */
  52. if (priv->recv_packets >= PKTBUFSRX)
  53. return 0;
  54. eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets];
  55. memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN);
  56. memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN);
  57. eth_send->et_protlen = htons(PROT_IP);
  58. tcp_send = (void *)eth_send + ETHER_HDR_SIZE;
  59. tcp_send->tcp_src = tcp->tcp_dst;
  60. tcp_send->tcp_dst = tcp->tcp_src;
  61. tcp_send->tcp_seq = htonl(0);
  62. tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1);
  63. tcp_send->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
  64. tcp_send->tcp_flags = TCP_SYN | TCP_ACK;
  65. tcp_send->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE);
  66. tcp_send->tcp_xsum = 0;
  67. tcp_send->tcp_ugr = 0;
  68. tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)tcp_send,
  69. tcp->ip_src,
  70. tcp->ip_dst,
  71. TCP_HDR_SIZE,
  72. IP_TCP_HDR_SIZE);
  73. net_set_ip_header((uchar *)tcp_send,
  74. tcp->ip_src,
  75. tcp->ip_dst,
  76. IP_TCP_HDR_SIZE,
  77. IPPROTO_TCP);
  78. priv->recv_packet_length[priv->recv_packets] =
  79. ETHER_HDR_SIZE + IP_TCP_HDR_SIZE;
  80. ++priv->recv_packets;
  81. return 0;
  82. }
  83. static int sb_ack_handler(struct udevice *dev, void *packet,
  84. unsigned int len)
  85. {
  86. struct eth_sandbox_priv *priv = dev_get_priv(dev);
  87. struct ethernet_hdr *eth = packet;
  88. struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE;
  89. struct ethernet_hdr *eth_send;
  90. struct ip_tcp_hdr *tcp_send;
  91. void *data;
  92. int pkt_len;
  93. int payload_len = 0;
  94. const char *payload1 = "HTTP/1.1 200 OK\r\n"
  95. "Content-Length: 30\r\n\r\n\r\n"
  96. "<html><body>Hi</body></html>\r\n";
  97. /* Don't allow the buffer to overrun */
  98. if (priv->recv_packets >= PKTBUFSRX)
  99. return 0;
  100. eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets];
  101. memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN);
  102. memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN);
  103. eth_send->et_protlen = htons(PROT_IP);
  104. tcp_send = (void *)eth_send + ETHER_HDR_SIZE;
  105. tcp_send->tcp_src = tcp->tcp_dst;
  106. tcp_send->tcp_dst = tcp->tcp_src;
  107. data = (void *)tcp_send + IP_TCP_HDR_SIZE;
  108. if (ntohl(tcp->tcp_seq) == 1 && ntohl(tcp->tcp_ack) == 1) {
  109. tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack));
  110. tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1);
  111. payload_len = strlen(payload1);
  112. memcpy(data, payload1, payload_len);
  113. tcp_send->tcp_flags = TCP_ACK;
  114. } else if (ntohl(tcp->tcp_seq) == 2) {
  115. tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack));
  116. tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1);
  117. payload_len = 0;
  118. tcp_send->tcp_flags = TCP_ACK | TCP_FIN;
  119. }
  120. tcp_send->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
  121. tcp_send->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE);
  122. tcp_send->tcp_xsum = 0;
  123. tcp_send->tcp_ugr = 0;
  124. pkt_len = IP_TCP_HDR_SIZE + payload_len;
  125. tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)tcp_send,
  126. tcp->ip_src,
  127. tcp->ip_dst,
  128. pkt_len - IP_HDR_SIZE,
  129. pkt_len);
  130. net_set_ip_header((uchar *)tcp_send,
  131. tcp->ip_src,
  132. tcp->ip_dst,
  133. pkt_len,
  134. IPPROTO_TCP);
  135. if (ntohl(tcp->tcp_seq) == 1 || ntohl(tcp->tcp_seq) == 2) {
  136. priv->recv_packet_length[priv->recv_packets] =
  137. ETHER_HDR_SIZE + IP_TCP_HDR_SIZE + payload_len;
  138. ++priv->recv_packets;
  139. }
  140. return 0;
  141. }
  142. static int sb_http_handler(struct udevice *dev, void *packet,
  143. unsigned int len)
  144. {
  145. struct ethernet_hdr *eth = packet;
  146. struct ip_hdr *ip;
  147. struct ip_tcp_hdr *tcp;
  148. if (ntohs(eth->et_protlen) == PROT_ARP) {
  149. return sb_arp_handler(dev, packet, len);
  150. } else if (ntohs(eth->et_protlen) == PROT_IP) {
  151. ip = packet + ETHER_HDR_SIZE;
  152. if (ip->ip_p == IPPROTO_TCP) {
  153. tcp = packet + ETHER_HDR_SIZE;
  154. if (tcp->tcp_flags == TCP_SYN)
  155. return sb_syn_handler(dev, packet, len);
  156. else if (tcp->tcp_flags & TCP_ACK && !(tcp->tcp_flags & TCP_SYN))
  157. return sb_ack_handler(dev, packet, len);
  158. return 0;
  159. }
  160. return -EPROTONOSUPPORT;
  161. }
  162. return -EPROTONOSUPPORT;
  163. }
  164. static int net_test_wget(struct unit_test_state *uts)
  165. {
  166. sandbox_eth_set_tx_handler(0, sb_http_handler);
  167. sandbox_eth_set_priv(0, uts);
  168. env_set("ethact", "eth@10002000");
  169. env_set("ethrotate", "no");
  170. env_set("loadaddr", "0x20000");
  171. ut_assertok(run_command("wget ${loadaddr} 1.1.2.2:/index.html", 0));
  172. sandbox_eth_set_tx_handler(0, NULL);
  173. ut_assertok(console_record_reset_enable());
  174. run_command("md5sum ${loadaddr} ${filesize}", 0);
  175. ut_assert_nextline("md5 for 00020000 ... 0002001f ==> 234af48e94b0085060249ecb5942ab57");
  176. ut_assertok(ut_check_console_end(uts));
  177. return 0;
  178. }
  179. LIB_TEST(net_test_wget, 0);