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 <zephyr/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 <zephyr/sys/printk.h>
20 #include <zephyr/sys/crc.h>
21
22 #include <zephyr/ztest.h>
23
24 #include <zephyr/net/ethernet.h>
25 #include <zephyr/net/dummy.h>
26 #include <zephyr/net/buf.h>
27 #include <zephyr/net/net_ip.h>
28 #include <zephyr/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 *net_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 net_iface = net_if_get_first_by_type(&NET_L2_GET_NAME(PPP));
212 zassert_not_null(net_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(net_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", net_iface);
249
250 ret = send_iface(net_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", net_iface);
261
262 ret = send_iface(net_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(net_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(net_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", net_iface);
449
450 ret = send_iface(net_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", net_iface);
465
466 ret = send_iface(net_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", net_iface);
481
482 ret = send_iface(net_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", net_iface);
497
498 ret = send_iface(net_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", net_iface);
513
514 ret = send_iface(net_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", net_iface);
529
530 ret = send_iface(net_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
ZTEST(net_ppp_test_suite,test_net_ppp)540 ZTEST(net_ppp_test_suite, test_net_ppp)
541 {
542 test_iface_setup();
543 test_send_ppp_pkt_with_escapes();
544 test_send_ppp_pkt_with_full_and_partial();
545 test_ppp_verify_fcs_1();
546 test_ppp_calc_fcs_1();
547 test_ppp_verify_fcs_3();
548 test_send_ppp_3();
549 test_send_ppp_4();
550 test_send_ppp_5();
551 test_send_ppp_6();
552 test_send_ppp_7();
553 test_send_ppp_8();
554 }
555
556 ZTEST_SUITE(net_ppp_test_suite, NULL, NULL, NULL, NULL, NULL);
557