test_ip4.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #include "test_ip4.h"
  2. #include "lwip/icmp.h"
  3. #include "lwip/ip4.h"
  4. #include "lwip/etharp.h"
  5. #include "lwip/inet_chksum.h"
  6. #include "lwip/stats.h"
  7. #include "lwip/prot/ip.h"
  8. #include "lwip/prot/ip4.h"
  9. #include "lwip/tcpip.h"
  10. #if !LWIP_IPV4 || !IP_REASSEMBLY || !MIB2_STATS || !IPFRAG_STATS
  11. #error "This tests needs LWIP_IPV4, IP_REASSEMBLY; MIB2- and IPFRAG-statistics enabled"
  12. #endif
  13. static struct netif test_netif;
  14. static ip4_addr_t test_ipaddr, test_netmask, test_gw;
  15. static int linkoutput_ctr;
  16. static int linkoutput_byte_ctr;
  17. static u16_t linkoutput_pkt_len;
  18. static u8_t linkoutput_pkt[100];
  19. /* reference internal lwip variable in netif.c */
  20. static err_t
  21. test_netif_linkoutput(struct netif *netif, struct pbuf *p)
  22. {
  23. fail_unless(netif == &test_netif);
  24. fail_unless(p != NULL);
  25. linkoutput_ctr++;
  26. linkoutput_byte_ctr += p->tot_len;
  27. /* Copy start of packet into buffer */
  28. linkoutput_pkt_len = pbuf_copy_partial(p, linkoutput_pkt, sizeof(linkoutput_pkt), 0);
  29. return ERR_OK;
  30. }
  31. static err_t
  32. test_netif_init(struct netif *netif)
  33. {
  34. fail_unless(netif != NULL);
  35. netif->linkoutput = test_netif_linkoutput;
  36. netif->output = etharp_output;
  37. netif->mtu = 1500;
  38. netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
  39. netif->hwaddr_len = ETHARP_HWADDR_LEN;
  40. return ERR_OK;
  41. }
  42. static void
  43. test_netif_add(void)
  44. {
  45. IP4_ADDR(&test_gw, 192,168,0,1);
  46. IP4_ADDR(&test_ipaddr, 192,168,0,1);
  47. IP4_ADDR(&test_netmask, 255,255,0,0);
  48. fail_unless(netif_default == NULL);
  49. netif_add(&test_netif, &test_ipaddr, &test_netmask, &test_gw,
  50. NULL, test_netif_init, NULL);
  51. netif_set_default(&test_netif);
  52. netif_set_up(&test_netif);
  53. }
  54. static void
  55. test_netif_remove(void)
  56. {
  57. if (netif_default == &test_netif) {
  58. netif_remove(&test_netif);
  59. }
  60. }
  61. /* Helper functions */
  62. static void
  63. create_ip4_input_fragment(u16_t ip_id, u16_t start, u16_t len, int last)
  64. {
  65. struct pbuf *p;
  66. struct netif *input_netif = netif_list; /* just use any netif */
  67. fail_unless((start & 7) == 0);
  68. fail_unless(((len & 7) == 0) || last);
  69. fail_unless(input_netif != NULL);
  70. p = pbuf_alloc(PBUF_RAW, len + sizeof(struct ip_hdr), PBUF_RAM);
  71. fail_unless(p != NULL);
  72. if (p != NULL) {
  73. err_t err;
  74. struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
  75. IPH_VHL_SET(iphdr, 4, sizeof(struct ip_hdr) / 4);
  76. IPH_TOS_SET(iphdr, 0);
  77. IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
  78. IPH_ID_SET(iphdr, lwip_htons(ip_id));
  79. if (last) {
  80. IPH_OFFSET_SET(iphdr, lwip_htons(start / 8));
  81. } else {
  82. IPH_OFFSET_SET(iphdr, lwip_htons((start / 8) | IP_MF));
  83. }
  84. IPH_TTL_SET(iphdr, 5);
  85. IPH_PROTO_SET(iphdr, IP_PROTO_UDP);
  86. IPH_CHKSUM_SET(iphdr, 0);
  87. ip4_addr_copy(iphdr->src, *netif_ip4_addr(input_netif));
  88. iphdr->src.addr = lwip_htonl(lwip_htonl(iphdr->src.addr) + 1);
  89. ip4_addr_copy(iphdr->dest, *netif_ip4_addr(input_netif));
  90. IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, sizeof(struct ip_hdr)));
  91. err = ip4_input(p, input_netif);
  92. if (err != ERR_OK) {
  93. pbuf_free(p);
  94. }
  95. fail_unless(err == ERR_OK);
  96. }
  97. }
  98. static err_t arpless_output(struct netif *netif, struct pbuf *p,
  99. const ip4_addr_t *ipaddr) {
  100. LWIP_UNUSED_ARG(ipaddr);
  101. return netif->linkoutput(netif, p);
  102. }
  103. /* Setups/teardown functions */
  104. static void
  105. ip4_setup(void)
  106. {
  107. lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
  108. }
  109. static void
  110. ip4_teardown(void)
  111. {
  112. if (netif_list->loop_first != NULL) {
  113. pbuf_free(netif_list->loop_first);
  114. netif_list->loop_first = NULL;
  115. }
  116. netif_list->loop_last = NULL;
  117. /* poll until all memory is released... */
  118. tcpip_thread_poll_one();
  119. lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
  120. test_netif_remove();
  121. netif_set_up(netif_get_loopif());
  122. }
  123. /* Test functions */
  124. START_TEST(test_ip4_frag)
  125. {
  126. struct pbuf *data = pbuf_alloc(PBUF_IP, 8000, PBUF_RAM);
  127. ip_addr_t peer_ip = IPADDR4_INIT_BYTES(192,168,0,5);
  128. err_t err;
  129. LWIP_UNUSED_ARG(_i);
  130. linkoutput_ctr = 0;
  131. /* Verify that 8000 byte payload is split into six packets */
  132. fail_unless(data != NULL);
  133. test_netif_add();
  134. test_netif.output = arpless_output;
  135. err = ip4_output_if_src(data, &test_ipaddr, ip_2_ip4(&peer_ip),
  136. 16, 0, IP_PROTO_UDP, &test_netif);
  137. fail_unless(err == ERR_OK);
  138. fail_unless(linkoutput_ctr == 6);
  139. fail_unless(linkoutput_byte_ctr == (8000 + (6 * IP_HLEN)));
  140. pbuf_free(data);
  141. test_netif_remove();
  142. }
  143. END_TEST
  144. START_TEST(test_ip4_reass)
  145. {
  146. const u16_t ip_id = 128;
  147. LWIP_UNUSED_ARG(_i);
  148. memset(&lwip_stats.mib2, 0, sizeof(lwip_stats.mib2));
  149. create_ip4_input_fragment(ip_id, 8*200, 200, 1);
  150. fail_unless(lwip_stats.ip_frag.recv == 1);
  151. fail_unless(lwip_stats.ip_frag.err == 0);
  152. fail_unless(lwip_stats.ip_frag.memerr == 0);
  153. fail_unless(lwip_stats.ip_frag.drop == 0);
  154. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  155. create_ip4_input_fragment(ip_id, 0*200, 200, 0);
  156. fail_unless(lwip_stats.ip_frag.recv == 2);
  157. fail_unless(lwip_stats.ip_frag.err == 0);
  158. fail_unless(lwip_stats.ip_frag.memerr == 0);
  159. fail_unless(lwip_stats.ip_frag.drop == 0);
  160. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  161. create_ip4_input_fragment(ip_id, 1*200, 200, 0);
  162. fail_unless(lwip_stats.ip_frag.recv == 3);
  163. fail_unless(lwip_stats.ip_frag.err == 0);
  164. fail_unless(lwip_stats.ip_frag.memerr == 0);
  165. fail_unless(lwip_stats.ip_frag.drop == 0);
  166. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  167. create_ip4_input_fragment(ip_id, 2*200, 200, 0);
  168. fail_unless(lwip_stats.ip_frag.recv == 4);
  169. fail_unless(lwip_stats.ip_frag.err == 0);
  170. fail_unless(lwip_stats.ip_frag.memerr == 0);
  171. fail_unless(lwip_stats.ip_frag.drop == 0);
  172. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  173. create_ip4_input_fragment(ip_id, 3*200, 200, 0);
  174. fail_unless(lwip_stats.ip_frag.recv == 5);
  175. fail_unless(lwip_stats.ip_frag.err == 0);
  176. fail_unless(lwip_stats.ip_frag.memerr == 0);
  177. fail_unless(lwip_stats.ip_frag.drop == 0);
  178. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  179. create_ip4_input_fragment(ip_id, 4*200, 200, 0);
  180. fail_unless(lwip_stats.ip_frag.recv == 6);
  181. fail_unless(lwip_stats.ip_frag.err == 0);
  182. fail_unless(lwip_stats.ip_frag.memerr == 0);
  183. fail_unless(lwip_stats.ip_frag.drop == 0);
  184. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  185. create_ip4_input_fragment(ip_id, 7*200, 200, 0);
  186. fail_unless(lwip_stats.ip_frag.recv == 7);
  187. fail_unless(lwip_stats.ip_frag.err == 0);
  188. fail_unless(lwip_stats.ip_frag.memerr == 0);
  189. fail_unless(lwip_stats.ip_frag.drop == 0);
  190. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  191. create_ip4_input_fragment(ip_id, 6*200, 200, 0);
  192. fail_unless(lwip_stats.ip_frag.recv == 8);
  193. fail_unless(lwip_stats.ip_frag.err == 0);
  194. fail_unless(lwip_stats.ip_frag.memerr == 0);
  195. fail_unless(lwip_stats.ip_frag.drop == 0);
  196. fail_unless(lwip_stats.mib2.ipreasmoks == 0);
  197. create_ip4_input_fragment(ip_id, 5*200, 200, 0);
  198. fail_unless(lwip_stats.ip_frag.recv == 9);
  199. fail_unless(lwip_stats.ip_frag.err == 0);
  200. fail_unless(lwip_stats.ip_frag.memerr == 0);
  201. fail_unless(lwip_stats.ip_frag.drop == 0);
  202. fail_unless(lwip_stats.mib2.ipreasmoks == 1);
  203. }
  204. END_TEST
  205. /* packets to 127.0.0.1 shall not be sent out to netif_default */
  206. START_TEST(test_127_0_0_1)
  207. {
  208. ip4_addr_t localhost;
  209. struct pbuf* p;
  210. LWIP_UNUSED_ARG(_i);
  211. linkoutput_ctr = 0;
  212. test_netif_add();
  213. netif_set_down(netif_get_loopif());
  214. IP4_ADDR(&localhost, 127, 0, 0, 1);
  215. p = pbuf_alloc(PBUF_IP, 10, PBUF_POOL);
  216. if(ip4_output(p, netif_ip4_addr(netif_default), &localhost, 0, 0, IP_PROTO_UDP) != ERR_OK) {
  217. pbuf_free(p);
  218. }
  219. fail_unless(linkoutput_ctr == 0);
  220. }
  221. END_TEST
  222. START_TEST(test_ip4addr_aton)
  223. {
  224. ip4_addr_t ip_addr;
  225. LWIP_UNUSED_ARG(_i);
  226. fail_unless(ip4addr_aton("192.168.0.1", &ip_addr) == 1);
  227. fail_unless(ip4addr_aton("192.168.0.0001", &ip_addr) == 1);
  228. fail_unless(ip4addr_aton("192.168.0.zzz", &ip_addr) == 0);
  229. fail_unless(ip4addr_aton("192.168.1", &ip_addr) == 1);
  230. fail_unless(ip4addr_aton("192.168.0xd3", &ip_addr) == 1);
  231. fail_unless(ip4addr_aton("192.168.0xz5", &ip_addr) == 0);
  232. fail_unless(ip4addr_aton("192.168.095", &ip_addr) == 0);
  233. }
  234. END_TEST
  235. /* Test for bug #59364 */
  236. START_TEST(test_ip4_icmp_replylen_short)
  237. {
  238. /* IP packet to 192.168.0.1 using proto 0x22 and 1 byte payload */
  239. const u8_t unknown_proto[] = {
  240. 0x45, 0x00, 0x00, 0x15, 0xd4, 0x31, 0x00, 0x00, 0xff, 0x22,
  241. 0x66, 0x41, 0xc0, 0xa8, 0x00, 0x02, 0xc0, 0xa8, 0x00, 0x01,
  242. 0xaa };
  243. struct pbuf *p;
  244. const int icmp_len = IP_HLEN + sizeof(struct icmp_hdr);
  245. LWIP_UNUSED_ARG(_i);
  246. linkoutput_ctr = 0;
  247. test_netif_add();
  248. test_netif.output = arpless_output;
  249. p = pbuf_alloc(PBUF_IP, sizeof(unknown_proto), PBUF_RAM);
  250. pbuf_take(p, unknown_proto, sizeof(unknown_proto));
  251. fail_unless(ip4_input(p, &test_netif) == ERR_OK);
  252. fail_unless(linkoutput_ctr == 1);
  253. /* Verify outgoing ICMP packet has no extra data */
  254. fail_unless(linkoutput_pkt_len == icmp_len + sizeof(unknown_proto));
  255. fail_if(memcmp(&linkoutput_pkt[icmp_len], unknown_proto, sizeof(unknown_proto)));
  256. }
  257. END_TEST
  258. START_TEST(test_ip4_icmp_replylen_first_8)
  259. {
  260. /* IP packet to 192.168.0.1 using proto 0x22 and 11 bytes payload */
  261. const u8_t unknown_proto[] = {
  262. 0x45, 0x00, 0x00, 0x1f, 0xd4, 0x31, 0x00, 0x00, 0xff, 0x22,
  263. 0x66, 0x37, 0xc0, 0xa8, 0x00, 0x02, 0xc0, 0xa8, 0x00, 0x01,
  264. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
  265. 0xaa };
  266. struct pbuf *p;
  267. const int icmp_len = IP_HLEN + sizeof(struct icmp_hdr);
  268. const int unreach_len = IP_HLEN + 8;
  269. LWIP_UNUSED_ARG(_i);
  270. linkoutput_ctr = 0;
  271. test_netif_add();
  272. test_netif.output = arpless_output;
  273. p = pbuf_alloc(PBUF_IP, sizeof(unknown_proto), PBUF_RAM);
  274. pbuf_take(p, unknown_proto, sizeof(unknown_proto));
  275. fail_unless(ip4_input(p, &test_netif) == ERR_OK);
  276. fail_unless(linkoutput_ctr == 1);
  277. fail_unless(linkoutput_pkt_len == icmp_len + unreach_len);
  278. fail_if(memcmp(&linkoutput_pkt[icmp_len], unknown_proto, unreach_len));
  279. }
  280. END_TEST
  281. /** Create the suite including all tests for this module */
  282. Suite *
  283. ip4_suite(void)
  284. {
  285. testfunc tests[] = {
  286. TESTFUNC(test_ip4_frag),
  287. TESTFUNC(test_ip4_reass),
  288. TESTFUNC(test_127_0_0_1),
  289. TESTFUNC(test_ip4addr_aton),
  290. TESTFUNC(test_ip4_icmp_replylen_short),
  291. TESTFUNC(test_ip4_icmp_replylen_first_8),
  292. };
  293. return create_suite("IPv4", tests, sizeof(tests)/sizeof(testfunc), ip4_setup, ip4_teardown);
  294. }