1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2019 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define NET_LOG_LEVEL CONFIG_NET_PPP_LOG_LEVEL
10 
11 #include <logging/log.h>
12 LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL);
13 
14 #include <zephyr/types.h>
15 #include <stdbool.h>
16 #include <stddef.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <sys/printk.h>
20 #include <sys/crc.h>
21 
22 #include <ztest.h>
23 
24 #include <net/ethernet.h>
25 #include <net/dummy.h>
26 #include <net/buf.h>
27 #include <net/net_ip.h>
28 #include <net/net_if.h>
29 
30 #define NET_LOG_ENABLED 1
31 #include "net_private.h"
32 
33 typedef enum net_verdict (*ppp_l2_callback_t)(struct net_if *iface,
34 					      struct net_pkt *pkt);
35 void ppp_l2_register_pkt_cb(ppp_l2_callback_t cb); /* found in ppp_l2.c */
36 void ppp_driver_feed_data(uint8_t *data, int data_len);
37 
38 static struct net_if *iface;
39 
40 static bool test_failed;
41 static bool test_started;
42 static struct k_sem wait_data;
43 
44 #define WAIT_TIME 250
45 #define WAIT_TIME_LONG K_SECONDS(1)
46 
47 /* If we receive this wire format PPP data, */
48 static uint8_t ppp_recv_data1[] = {
49 	0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21, 0x7d, 0x21,
50 	0x7d, 0x21, 0x7d, 0x20, 0x7d, 0x34, 0x7d, 0x22,
51 	0x7d, 0x26, 0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20,
52 	0x7d, 0x20, 0x7d, 0x25, 0x7d, 0x26, 0x5d, 0x58,
53 	0xcf, 0x41, 0x7d, 0x27, 0x7d, 0x22, 0x7d, 0x28,
54 	0x7d, 0x22, 0xc4, 0xc9, 0x7e,
55 };
56 
57 /* then we should see this FCS checked PPP data */
58 static uint8_t ppp_expect_data1[] = {
59 	0xc0, 0x21, 0x01, 0x01, 0x00, 0x14, 0x02, 0x06,
60 	0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x5d, 0x58,
61 	0xcf, 0x41, 0x07, 0x02, 0x08, 0x02,
62 };
63 
64 static uint8_t ppp_recv_data2[] = {
65 	0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21, 0x7d, 0x21,
66 	0x7d, 0x21, 0x7d, 0x20, 0x7d, 0x34, 0x7d, 0x22,
67 	0x7d, 0x26, 0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20,
68 	0x7d, 0x20, 0x7d, 0x25, 0x7d, 0x26, 0x5d, 0x58,
69 	0xcf, 0x41, 0x7d, 0x27, 0x7d, 0x22, 0x7d, 0x28,
70 	0x7d, 0x22, 0xc4, 0xc9,
71 	/* Second partial msg */
72 	0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21, 0x7d, 0x21,
73 	0x7d, 0x21, 0x7d, 0x20, 0x7d, 0x34, 0x7d, 0x22,
74 };
75 
76 /* This is HDLC encoded PPP message */
77 static uint8_t ppp_recv_data3[] = {
78 	0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21, 0x7d, 0x22,
79 	0x7d, 0x21, 0x7d, 0x20, 0x7d, 0x24, 0x1c, 0x90, 0x7e
80 };
81 
82 static uint8_t ppp_expect_data3[] = {
83 	0xc0, 0x21, 0x02, 0x01, 0x00, 0x04,
84 };
85 
86 static uint8_t ppp_recv_data4[] = {
87 	/* There is FCS error in this packet */
88 	0x7e, 0xff, 0x7d, 0x5d, 0xe4, 0x7d, 0x23, 0xc0,
89 	0x21, 0x7d, 0x22, 0x7d, 0x21, 0x7d, 0x20, 0x7d,
90 	0x24, 0x7d, 0x3c, 0x90, 0x7e,
91 };
92 
93 static uint8_t ppp_expect_data4[] = {
94 	0xff, 0x7d, 0xe4, 0x03, 0xc0, 0x21, 0x02, 0x01,
95 	0x00, 0x04, 0x1c, 0x90,
96 };
97 
98 static uint8_t ppp_recv_data5[] = {
99 	/* Multiple valid packets here */
100 	/* 1st */
101 	0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21, 0x7d, 0x21,
102 	0x7d, 0x23, 0x7d, 0x20, 0x7d, 0x34, 0x7d, 0x22,
103 	0x7d, 0x26, 0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20,
104 	0x7d, 0x20, 0x7d, 0x25, 0x7d, 0x26, 0x66, 0x7d,
105 	0x26, 0xbe, 0x70, 0x7d, 0x27, 0x7d, 0x22, 0x7d,
106 	0x28, 0x7d, 0x22, 0xf2, 0x47, 0x7e,
107 	/* 2nd */
108 	0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21, 0x7d, 0x22,
109 	0x7d, 0x21, 0x7d, 0x20, 0x7d, 0x24, 0x7d, 0x3c,
110 	0x90, 0x7e,
111 	/* 3rd */
112 	0xff, 0x7d, 0x23, 0x80, 0xfd, 0x7d, 0x21, 0x7d,
113 	0x22, 0x7d, 0x20, 0x7d, 0x2f, 0x7d, 0x3a, 0x7d,
114 	0x24, 0x78, 0x7d, 0x20, 0x7d, 0x38, 0x7d, 0x24,
115 	0x78, 0x7d, 0x20, 0x7d, 0x35, 0x7d, 0x23, 0x2f,
116 	0x8f, 0x4e, 0x7e,
117 };
118 
119 static uint8_t ppp_expect_data5[] = {
120 	0xc0, 0x21, 0x01, 0x03, 0x00, 0x14, 0x02, 0x06,
121 	0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x66, 0x06,
122 	0xbe, 0x70, 0x07, 0x02, 0x08, 0x02,
123 };
124 
125 static uint8_t ppp_recv_data6[] = {
126 	0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21, 0x7d, 0x22,
127 	0x7d, 0x21, 0x7d, 0x20, 0x7d, 0x24, 0x7d, 0x3c,
128 	0x90, 0x7e,
129 };
130 
131 static uint8_t ppp_expect_data6[] = {
132 	0xc0, 0x21, 0x02, 0x01, 0x00, 0x04,
133 };
134 
135 static uint8_t ppp_recv_data7[] = {
136 	0x7e, 0xff, 0x7d, 0x23, 0x80, 0x21, 0x7d, 0x22,
137 	0x7d, 0x22, 0x7d, 0x20, 0x7d, 0x2a, 0x7d, 0x23,
138 	0x7d, 0x26, 0xc0, 0x7d, 0x20, 0x7d, 0x22, 0x7d,
139 	0x22, 0x06, 0xa1, 0x7e,
140 };
141 
142 static uint8_t ppp_expect_data7[] = {
143 	0x80, 0x21, 0x02, 0x02, 0x00, 0x0a, 0x03, 0x06,
144 	0xc0, 0x00, 0x02, 0x02,
145 };
146 
147 static uint8_t ppp_recv_data8[] = {
148 	0x7e, 0xff, 0x7d, 0x23, 0x00, 0x57, 0x60, 0x7d,
149 	0x20, 0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20, 0x7d,
150 	0x2c, 0x3a, 0x40, 0xfe, 0x80, 0x7d, 0x20, 0x7d,
151 	0x20, 0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20, 0x7d,
152 	0x20, 0x7d, 0x20, 0x7d, 0x20, 0x5e, 0xff, 0xfe,
153 	0x7d, 0x20, 0x53, 0x44, 0xfe, 0x80, 0x7d, 0x20,
154 	0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20,
155 	0x7d, 0x20, 0xa1, 0x41, 0x6d, 0x45, 0xbf, 0x28,
156 	0x7d, 0x25, 0xd1, 0x80, 0x7d, 0x20, 0x7d, 0x28,
157 	0x6c, 0x7d, 0x5e, 0x32, 0x7d, 0x20, 0x7d, 0x22,
158 	0x5b, 0x2c, 0x7d, 0x3d, 0x25, 0x20, 0x11, 0x7e,
159 };
160 
161 static uint8_t ppp_expect_data8[] = {
162 	0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x3a, 0x40,
163 	0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 	0x00, 0x00, 0x5e, 0xff, 0xfe, 0x00, 0x53, 0x44,
165 	0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 	0xa1, 0x41, 0x6d, 0x45, 0xbf, 0x28, 0x05, 0xd1,
167 	0x80, 0x00, 0x08, 0x6c, 0x7e, 0x32, 0x00, 0x02,
168 	0x5b, 0x2c, 0x1d, 0x25,
169 };
170 
171 static uint8_t *receiving, *expecting;
172 
ppp_l2_recv(struct net_if * iface,struct net_pkt * pkt)173 static enum net_verdict ppp_l2_recv(struct net_if *iface, struct net_pkt *pkt)
174 {
175 	if (!pkt->buffer) {
176 		NET_DBG("No data to recv!");
177 		return NET_DROP;
178 	}
179 
180 	if (test_started) {
181 		struct net_buf *buf = pkt->buffer;
182 		int pos = 0;
183 
184 		while (buf) {
185 			if (memcmp(expecting + pos, buf->data, buf->len)) {
186 				LOG_HEXDUMP_DBG(expecting + pos,
187 						buf->len,
188 						"expecting");
189 				LOG_HEXDUMP_DBG(buf->data, buf->len,
190 						"received");
191 				test_failed = true;
192 				break;
193 			}
194 
195 			pos += buf->len;
196 			buf = buf->frags;
197 		}
198 	}
199 
200 	if (test_failed) {
201 		net_pkt_hexdump(pkt, "received");
202 	}
203 
204 	k_sem_give(&wait_data);
205 
206 	return NET_DROP;
207 }
208 
test_iface_setup(void)209 static void test_iface_setup(void)
210 {
211 	iface = net_if_get_first_by_type(&NET_L2_GET_NAME(PPP));
212 	zassert_not_null(iface, "PPP interface not found!");
213 
214 	/* The semaphore is there to wait the data to be received. */
215 	k_sem_init(&wait_data, 0, UINT_MAX);
216 
217 	ppp_l2_register_pkt_cb(ppp_l2_recv);
218 
219 	net_if_up(iface);
220 
221 	test_failed = false;
222 	test_started = true;
223 }
224 
send_iface(struct net_if * iface,uint8_t * recv,size_t recv_len,uint8_t * expect,size_t expect_len)225 static bool send_iface(struct net_if *iface,
226 		       uint8_t *recv, size_t recv_len,
227 		       uint8_t *expect, size_t expect_len)
228 {
229 	receiving = recv;
230 	expecting = expect;
231 	test_failed = false;
232 
233 	NET_DBG("Feeding %zd bytes data", recv_len);
234 
235 	/* ToDo: Check the expected buffer value */
236 
237 	ppp_driver_feed_data(recv, recv_len);
238 
239 	zassert_false(test_failed, "Test failed");
240 
241 	return true;
242 }
243 
test_send_ppp_pkt_with_escapes(void)244 static void test_send_ppp_pkt_with_escapes(void)
245 {
246 	bool ret;
247 
248 	NET_DBG("Sending data to iface %p", iface);
249 
250 	ret = send_iface(iface, ppp_recv_data1, sizeof(ppp_recv_data1),
251 			 ppp_expect_data1, sizeof(ppp_expect_data1));
252 
253 	zassert_true(ret, "iface");
254 }
255 
test_send_ppp_pkt_with_full_and_partial(void)256 static void test_send_ppp_pkt_with_full_and_partial(void)
257 {
258 	bool ret;
259 
260 	NET_DBG("Sending data to iface %p", iface);
261 
262 	ret = send_iface(iface, ppp_recv_data2, sizeof(ppp_recv_data2),
263 			 ppp_expect_data1, sizeof(ppp_expect_data1));
264 
265 	zassert_true(ret, "iface");
266 }
267 
check_fcs(struct net_pkt * pkt,uint16_t * fcs)268 static bool check_fcs(struct net_pkt *pkt, uint16_t *fcs)
269 {
270 	struct net_buf *buf;
271 	uint16_t crc;
272 
273 	buf = pkt->buffer;
274 	if (!buf) {
275 		return false;
276 	}
277 
278 	crc = crc16_ccitt(0xffff, buf->data, buf->len);
279 
280 	buf = buf->frags;
281 
282 	while (buf) {
283 		crc = crc16_ccitt(crc, buf->data, buf->len);
284 		buf = buf->frags;
285 	}
286 
287 	*fcs = crc;
288 
289 	if (crc != 0xf0b8) {
290 		return false;
291 	}
292 
293 	return true;
294 }
295 
unescape(uint8_t ** ptr)296 static uint8_t unescape(uint8_t **ptr)
297 {
298 	uint8_t *pos = *ptr;
299 	uint8_t val;
300 
301 	if (*pos == 0x7d) {
302 		pos++;
303 		val = (*pos) ^ 0x20;
304 
305 		*ptr += 2;
306 
307 		return val;
308 	}
309 
310 	*ptr += 1;
311 
312 	return *pos;
313 }
314 
ppp_verify_fcs(uint8_t * buf,int len)315 static void ppp_verify_fcs(uint8_t *buf, int len)
316 {
317 	struct net_pkt *pkt;
318 	uint16_t addr_and_ctrl;
319 	uint16_t fcs = 0;
320 	uint8_t *ptr;
321 	bool ret;
322 
323 	pkt = net_pkt_alloc_with_buffer(iface, len, AF_UNSPEC, 0, K_NO_WAIT);
324 	zassert_not_null(pkt, "Cannot create pkt");
325 
326 	ptr = buf;
327 	while (ptr < &buf[len]) {
328 		net_pkt_write_u8(pkt, unescape(&ptr));
329 	}
330 
331 	/* Remove sync byte 0x7e */
332 	(void)net_buf_pull_u8(pkt->buffer);
333 
334 	net_pkt_cursor_init(pkt);
335 
336 	net_pkt_read_be16(pkt, &addr_and_ctrl);
337 
338 	/* Currently we do not support compressed Address and Control
339 	 * fields so they must always be present.
340 	 */
341 	if (addr_and_ctrl != (0xff << 8 | 0x03)) {
342 		zassert_true(false, "Invalid address / control bytes");
343 	}
344 
345 	/* Skip sync byte (1) */
346 	net_buf_frag_last(pkt->buffer)->len -= 1;
347 
348 	ret = check_fcs(pkt, &fcs);
349 	zassert_true(ret, "FCS calc failed, expecting 0x%x got 0x%x",
350 		     0xf0b8, fcs);
351 
352 	net_pkt_unref(pkt);
353 }
354 
test_ppp_verify_fcs_1(void)355 static void test_ppp_verify_fcs_1(void)
356 {
357 	ppp_verify_fcs(ppp_recv_data1, sizeof(ppp_recv_data1));
358 }
359 
calc_fcs(struct net_pkt * pkt,uint16_t * fcs)360 static bool calc_fcs(struct net_pkt *pkt, uint16_t *fcs)
361 {
362 	struct net_buf *buf;
363 	uint16_t crc;
364 
365 	buf = pkt->buffer;
366 	if (!buf) {
367 		return false;
368 	}
369 
370 	crc = crc16_ccitt(0xffff, buf->data, buf->len);
371 
372 	buf = buf->frags;
373 
374 	while (buf) {
375 		crc = crc16_ccitt(crc, buf->data, buf->len);
376 		buf = buf->frags;
377 	}
378 
379 	crc ^= 0xffff;
380 
381 	*fcs = crc;
382 
383 	return true;
384 }
385 
ppp_calc_fcs(uint8_t * buf,int len)386 static void ppp_calc_fcs(uint8_t *buf, int len)
387 {
388 	struct net_pkt *pkt;
389 	uint16_t addr_and_ctrl;
390 	uint16_t pkt_fcs, fcs = 0;
391 	uint8_t *ptr;
392 	bool ret;
393 
394 	pkt = net_pkt_alloc_with_buffer(iface, len, AF_UNSPEC, 0, K_NO_WAIT);
395 	zassert_not_null(pkt, "Cannot create pkt");
396 
397 	ptr = buf;
398 	while (ptr < &buf[len]) {
399 		net_pkt_write_u8(pkt, unescape(&ptr));
400 	}
401 
402 	/* Remove sync byte 0x7e */
403 	(void)net_buf_pull_u8(pkt->buffer);
404 
405 	net_pkt_cursor_init(pkt);
406 
407 	net_pkt_read_be16(pkt, &addr_and_ctrl);
408 
409 	/* Currently we do not support compressed Address and Control
410 	 * fields so they must always be present.
411 	 */
412 	if (addr_and_ctrl != (0xff << 8 | 0x03)) {
413 		zassert_true(false, "Invalid address / control bytes");
414 	}
415 
416 	len = net_pkt_get_len(pkt);
417 
418 	net_pkt_set_overwrite(pkt, true);
419 	net_pkt_skip(pkt, len - sizeof(uint16_t) - (2 + 1));
420 	net_pkt_read_le16(pkt, &pkt_fcs);
421 
422 	/* Skip FCS and sync bytes (2 + 1) */
423 	net_buf_frag_last(pkt->buffer)->len -= 2 + 1;
424 
425 	ret = calc_fcs(pkt, &fcs);
426 	zassert_true(ret, "FCS calc failed");
427 
428 	zassert_equal(pkt_fcs, fcs, "FCS calc failed, expecting 0x%x got 0x%x",
429 		     pkt_fcs, fcs);
430 
431 	net_pkt_unref(pkt);
432 }
433 
test_ppp_calc_fcs_1(void)434 static void test_ppp_calc_fcs_1(void)
435 {
436 	ppp_calc_fcs(ppp_recv_data1, sizeof(ppp_recv_data1));
437 }
438 
test_ppp_verify_fcs_3(void)439 static void test_ppp_verify_fcs_3(void)
440 {
441 	ppp_verify_fcs(ppp_recv_data3, sizeof(ppp_recv_data3));
442 }
443 
test_send_ppp_3(void)444 static void test_send_ppp_3(void)
445 {
446 	bool ret;
447 
448 	NET_DBG("Sending data to iface %p", iface);
449 
450 	ret = send_iface(iface, ppp_recv_data3, sizeof(ppp_recv_data3),
451 			 ppp_expect_data3, sizeof(ppp_expect_data3));
452 
453 	zassert_true(ret, "iface");
454 
455 	if (k_sem_take(&wait_data, WAIT_TIME_LONG)) {
456 		zassert_true(false, "Timeout, packet not received");
457 	}
458 }
459 
test_send_ppp_4(void)460 static void test_send_ppp_4(void)
461 {
462 	bool ret;
463 
464 	NET_DBG("Sending data to iface %p", iface);
465 
466 	ret = send_iface(iface, ppp_recv_data4, sizeof(ppp_recv_data4),
467 			 ppp_expect_data4, sizeof(ppp_expect_data4));
468 
469 	zassert_true(ret, "iface");
470 
471 	if (k_sem_take(&wait_data, WAIT_TIME_LONG)) {
472 		zassert_true(false, "Timeout, packet not received");
473 	}
474 }
475 
test_send_ppp_5(void)476 static void test_send_ppp_5(void)
477 {
478 	bool ret;
479 
480 	NET_DBG("Sending data to iface %p", iface);
481 
482 	ret = send_iface(iface, ppp_recv_data5, sizeof(ppp_recv_data5),
483 			 ppp_expect_data5, sizeof(ppp_expect_data5));
484 
485 	zassert_true(ret, "iface");
486 
487 	if (k_sem_take(&wait_data, WAIT_TIME_LONG)) {
488 		zassert_true(false, "Timeout, packet not received");
489 	}
490 }
491 
test_send_ppp_6(void)492 static void test_send_ppp_6(void)
493 {
494 	bool ret;
495 
496 	NET_DBG("Sending data to iface %p", iface);
497 
498 	ret = send_iface(iface, ppp_recv_data6, sizeof(ppp_recv_data6),
499 			 ppp_expect_data6, sizeof(ppp_expect_data6));
500 
501 	zassert_true(ret, "iface");
502 
503 	if (k_sem_take(&wait_data, WAIT_TIME_LONG)) {
504 		zassert_true(false, "Timeout, packet not received");
505 	}
506 }
507 
test_send_ppp_7(void)508 static void test_send_ppp_7(void)
509 {
510 	bool ret;
511 
512 	NET_DBG("Sending data to iface %p", iface);
513 
514 	ret = send_iface(iface, ppp_recv_data7, sizeof(ppp_recv_data7),
515 			 ppp_expect_data7, sizeof(ppp_expect_data7));
516 
517 	zassert_true(ret, "iface");
518 
519 	if (k_sem_take(&wait_data, WAIT_TIME_LONG)) {
520 		zassert_true(false, "Timeout, packet not received");
521 	}
522 }
523 
test_send_ppp_8(void)524 static void test_send_ppp_8(void)
525 {
526 	bool ret;
527 
528 	NET_DBG("Sending data to iface %p", iface);
529 
530 	ret = send_iface(iface, ppp_recv_data8, sizeof(ppp_recv_data8),
531 			 ppp_expect_data8, sizeof(ppp_expect_data8));
532 
533 	zassert_true(ret, "iface");
534 
535 	if (k_sem_take(&wait_data, WAIT_TIME_LONG)) {
536 		zassert_true(false, "Timeout, packet not received");
537 	}
538 }
539 
test_main(void)540 void test_main(void)
541 {
542 	ztest_test_suite(net_ppp_test,
543 			 ztest_unit_test(test_iface_setup),
544 			 ztest_unit_test(test_send_ppp_pkt_with_escapes),
545 			 ztest_unit_test(test_send_ppp_pkt_with_full_and_partial),
546 			 ztest_unit_test(test_ppp_verify_fcs_1),
547 			 ztest_unit_test(test_ppp_calc_fcs_1),
548 			 ztest_unit_test(test_ppp_verify_fcs_3),
549 			 ztest_unit_test(test_send_ppp_3),
550 			 ztest_unit_test(test_send_ppp_4),
551 			 ztest_unit_test(test_send_ppp_5),
552 			 ztest_unit_test(test_send_ppp_6),
553 			 ztest_unit_test(test_send_ppp_7),
554 			 ztest_unit_test(test_send_ppp_8)
555 		);
556 
557 	ztest_run_test_suite(net_ppp_test);
558 }
559