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