1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_ieee802154_test, LOG_LEVEL_DBG);
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/ztest.h>
12 
13 
14 #include <zephyr/crypto/crypto.h>
15 #include <zephyr/net/ethernet.h>
16 #include <zephyr/net/ieee802154.h>
17 #include <zephyr/net/ieee802154_mgmt.h>
18 #include <zephyr/net/ieee802154_radio.h>
19 #include <zephyr/net/net_core.h>
20 #include <zephyr/net/net_ip.h>
21 #include <zephyr/net/net_pkt.h>
22 #include <zephyr/net/socket.h>
23 
24 #include "net_private.h"
25 #include <ieee802154_frame.h>
26 #include <ieee802154_priv.h>
27 #include <ipv6.h>
28 
29 struct ieee802154_pkt_test {
30 	char *name;
31 	struct in6_addr src;
32 	struct in6_addr dst;
33 	uint8_t *pkt;
34 	uint8_t sequence;
35 	uint8_t length;
36 	uint8_t payload_length;
37 	struct {
38 		struct ieee802154_fcf_seq *fc_seq;
39 		struct ieee802154_address_field *dst_addr;
40 		struct ieee802154_address_field *src_addr;
41 	} mhr_check;
42 };
43 
44 /* Sample NS packet with extended address. */
45 uint8_t ns_pkt[] = {
46 	0x41, 0xd8, /* FCF */
47 	0x45, /* Sequence Number */
48 	0xcd, 0xab, /* PAN ID */
49 	0xff, 0xff, /* Destination Address (Broadcast) */
50 	0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
51 	0x7b, 0x09, /* IPHC Header */
52 	0x3a, /* Next Header: ICMPv6 */
53 	0x20, 0x01, 0xdb, 0x08, 0x00, 0x00, 0x00, 0x00, /* IPv6 Source Address */
54 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
55 	0x02, 0x01, 0xff, 0x00, 0x00, 0x01, /* IPv6 Destination Address */
56 	0x87, /* ICMPv6 Type: Neighbour Solicitation */
57 	0x00, /* Code */
58 	0x91, 0x11, /* Checksum */
59 	0x00, 0x00, 0x00, 0x00, /* Reserved */
60 	0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target Address */
61 	0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01,
62 	0x01, /* ICMPv6 Option: Source LL Address */
63 	0x02, /* Length */
64 	0x00, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2, /* LL Address */
65 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Padding */
66 };
67 
68 struct ieee802154_pkt_test test_ns_pkt = {
69 	.name = "NS frame",
70 	.src =  { { { 0x20, 0x01, 0xdb, 0x08, 0x00, 0x00, 0x00, 0x00,
71 		      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } },
72 	.dst =  { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 		      0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01 } } },
74 	.pkt = ns_pkt,
75 	.sequence = 69U,
76 	.length = sizeof(ns_pkt),
77 	.payload_length = 65U,
78 	.mhr_check = {
79 		.fc_seq = (struct ieee802154_fcf_seq *)ns_pkt,
80 		.dst_addr = (struct ieee802154_address_field *)(ns_pkt + 3),
81 		.src_addr = (struct ieee802154_address_field *)(ns_pkt + 7),
82 	}};
83 
84 uint8_t ack_pkt[] = {
85 	0x02, 0x10, /* FCF */
86 	0x16 /* Sequence Number */
87 };
88 
89 struct ieee802154_pkt_test test_ack_pkt = {
90 	.name = "ACK frame",
91 	.sequence = 22U,
92 	.pkt = ack_pkt,
93 	.length = sizeof(ack_pkt),
94 	.payload_length = 0U,
95 	.mhr_check = {
96 		.fc_seq = (struct ieee802154_fcf_seq *)ack_pkt,
97 		.dst_addr = NULL,
98 		.src_addr = NULL,
99 	}};
100 
101 uint8_t beacon_pkt[] = {
102 	0x00, 0xd0, /* FCF */
103 	0x11, /* Sequence Number */
104 	0xcd, 0xab, /* Source PAN ID */
105 	0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
106 	0x00, 0x00, /* Superframe Specification */
107 	0x00, /* GTS */
108 	0x00, /* Pending Addresses */
109 	0x00, 0x00 /* Payload */
110 };
111 
112 struct ieee802154_pkt_test test_beacon_pkt = {
113 	.name = "Empty beacon frame",
114 	.sequence = 17U,
115 	.pkt = beacon_pkt,
116 	.length = sizeof(beacon_pkt),
117 	.payload_length = 6U,
118 	.mhr_check = {
119 		.fc_seq = (struct ieee802154_fcf_seq *)beacon_pkt,
120 		.dst_addr = NULL,
121 		.src_addr = (struct ieee802154_address_field *)(beacon_pkt + 3),
122 	}};
123 
124 uint8_t sec_data_pkt[] = {
125 	0x49, 0xd8, /* FCF */
126 	0x45, /* Sequence Number */
127 	0xcd, 0xab, /* Destination PAN */
128 	0xff, 0xff, /* Destination Address */
129 	0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
130 	0x07,			/* Security Control Field */
131 	0x03, 0x00, 0x00, 0x00, /* Frame Counter */
132 	0x98, 0x49, 0x1f, 0x57, /* Encrypted Payload */
133 	0x99, 0xf9, 0x10, 0x5e, 0x5b, 0x8c, 0x31, 0x0b, /* MIC (128 bit) */
134 	0xa1, 0x70, 0x99, 0x14, 0x0a, 0x6a, 0x38, 0x47,
135 };
136 
137 struct ieee802154_pkt_test test_sec_data_pkt = {
138 	.name = "Secured data frame",
139 	.sequence = 69U,
140 	.pkt = sec_data_pkt,
141 	.length = sizeof(sec_data_pkt),
142 	.payload_length = 4U /* encrypted payload */ + 16U /* MIC */,
143 	.mhr_check = {
144 		.fc_seq = (struct ieee802154_fcf_seq *)sec_data_pkt,
145 		.dst_addr = (struct ieee802154_address_field *)(sec_data_pkt + 3),
146 		.src_addr = (struct ieee802154_address_field *)(sec_data_pkt + 7),
147 	}};
148 
149 /* Construct raw packet payload, length and FCS gets added in the radio driver,
150  * see https://github.com/linux-wpan/wpan-tools/blob/master/examples/af_packet_tx.c
151  */
152 uint8_t raw_payload[] = {
153 	0x01, 0xc8, /* FCF */
154 	0x8b,	    /* Sequence number */
155 	0xff, 0xff, /* Destination PAN ID 0xffff */
156 	0x02, 0x00, /* Destination short address 0x0002 */
157 	0x23, 0x00, /* Source PAN ID 0x0023 */
158 	0x60, 0xe2, 0x16, 0x21,
159 	0x1c, 0x4a, 0xc2, 0xae, /* Source extended address ae:c2:4a:1c:21:16:e2:60 */
160 	0xAA, 0xBB, 0xCC,	/* MAC Payload */
161 };
162 #define RAW_MAC_PAYLOAD_START_INDEX 17
163 #define RAW_MAC_PAYLOAD_LENGTH 3
164 
165 #define MOCK_PAN_ID 0xabcd
166 
167 extern struct net_pkt *current_pkt;
168 extern struct k_sem driver_lock;
169 
170 static struct net_if *net_iface;
171 
pkt_hexdump(uint8_t * pkt,uint8_t length)172 static void pkt_hexdump(uint8_t *pkt, uint8_t length)
173 {
174 	int i;
175 
176 	printk(" -> Packet content:\n");
177 
178 	for (i = 0; i < length;) {
179 		int j;
180 
181 		printk("\t");
182 
183 		for (j = 0; j < 10 && i < length; j++, i++) {
184 			printk("%02x ", *pkt);
185 			pkt++;
186 		}
187 
188 		printk("\n");
189 	}
190 }
191 
ieee_addr_hexdump(uint8_t * addr,uint8_t length)192 static void ieee_addr_hexdump(uint8_t *addr, uint8_t length)
193 {
194 	int i;
195 
196 	printk(" -> IEEE 802.15.4 Address: ");
197 
198 	for (i = 0; i < length-1; i++) {
199 		printk("%02x:", *addr);
200 		addr++;
201 	}
202 
203 	printk("%02x\n", *addr);
204 }
205 
disassociate(struct net_if * iface,struct ieee802154_context * ctx)206 static int disassociate(struct net_if *iface, struct ieee802154_context *ctx)
207 {
208 	uint16_t short_addr_not_associated = IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED;
209 	int ret;
210 
211 	if (ctx->short_addr == IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED) {
212 		return 0;
213 	}
214 
215 	ret = net_mgmt(NET_REQUEST_IEEE802154_SET_SHORT_ADDR, iface,
216 		       &short_addr_not_associated,
217 		       sizeof(short_addr_not_associated));
218 	if (ret) {
219 		NET_ERR("*** Failed to %s.", __func__);
220 		return ret;
221 	}
222 
223 	return 0;
224 }
225 
associate(struct net_if * iface,struct ieee802154_context * ctx,uint16_t short_addr)226 static int associate(struct net_if *iface, struct ieee802154_context *ctx, uint16_t short_addr)
227 {
228 	uint16_t mock_pan_id = MOCK_PAN_ID;
229 	int ret;
230 
231 	if (ctx->short_addr == short_addr) {
232 		return -EALREADY;
233 	}
234 
235 	ret = net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, iface, &mock_pan_id,
236 		       sizeof(mock_pan_id));
237 	if (ret) {
238 		NET_ERR("*** Failed to set PAN ID in %s.", __func__);
239 		return ret;
240 	}
241 
242 	ret = net_mgmt(NET_REQUEST_IEEE802154_SET_SHORT_ADDR, iface, &short_addr,
243 		       sizeof(short_addr));
244 	if (ret) {
245 		NET_ERR("*** Failed to set short addr in %s.", __func__);
246 		return ret;
247 	}
248 
249 	return 0;
250 }
251 
set_up_short_addr(struct net_if * iface,struct ieee802154_context * ctx)252 static int set_up_short_addr(struct net_if *iface, struct ieee802154_context *ctx)
253 {
254 	const uint16_t mock_short_addr = 0x5678;
255 	int ret;
256 
257 	ret = disassociate(iface, ctx);
258 	if (ret) {
259 		return ret;
260 	}
261 
262 	ret = associate(iface, ctx, mock_short_addr);
263 	if (ret) {
264 		return ret;
265 	}
266 
267 	return 0;
268 }
269 
tear_down_short_addr(struct net_if * iface,struct ieee802154_context * ctx)270 static int tear_down_short_addr(struct net_if *iface, struct ieee802154_context *ctx)
271 {
272 	uint16_t no_short_addr_assigned = IEEE802154_NO_SHORT_ADDRESS_ASSIGNED;
273 	int ret;
274 
275 	if (ctx->linkaddr.len != IEEE802154_SHORT_ADDR_LENGTH) {
276 		/* nothing to do */
277 		return 0;
278 	}
279 
280 	ret = disassociate(iface, ctx);
281 	if (ret) {
282 		return ret;
283 	}
284 
285 	ret = associate(iface, ctx, no_short_addr_assigned);
286 	if (ret) {
287 		return ret;
288 	}
289 
290 	return 0;
291 }
292 
get_data_pkt_with_ar(void)293 static struct net_pkt *get_data_pkt_with_ar(void)
294 {
295 	/* Incoming IEEE 802.15.4 packet with payload header compression. */
296 	static uint8_t data_pkt_with_ar[] = {
297 		/* IEEE 802.15.4 MHR */
298 		0x61, 0xd8,					/* FCF with AR bit set */
299 		0x16,						/* Sequence */
300 		0xcd, 0xab,					/* Destination PAN */
301 		0x78, 0x56,					/* Destination Address */
302 		0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
303 		/* IEEE 802.15.4 MAC Payload */
304 		0x7b, 0x39, /* IPHC header, SAM: compressed, DAM: 48-bits inline */
305 		0x3a,	    /* Next header: ICMPv6 */
306 		0x02, 0x01, 0xff, 0x4b, 0x12, 0x00, /* IPv6 Destination */
307 		0x87,				    /* Type: NS */
308 		0x00,				    /* Code*/
309 		0xb7, 0x45,			    /* Checksum */
310 		0x00, 0x00, 0x00, 0x00,		    /* Reserved */
311 		0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x14, 0xa6, 0x1c, 0x00, 0x4b,
312 		0x12, 0x00, /* Target Address */
313 		0x01,	    /* ICMPv6 Option: Source LL address */
314 		0x02,	    /* Length */
315 		0xe5, 0xac, 0xa1, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* LL address */
316 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		/* Padding */
317 	};
318 	struct net_pkt *pkt;
319 
320 	pkt = net_pkt_rx_alloc_with_buffer(net_iface, sizeof(data_pkt_with_ar), AF_UNSPEC, 0,
321 					   K_FOREVER);
322 	if (!pkt) {
323 		NET_ERR("*** No buffer to allocate");
324 		return NULL;
325 	}
326 
327 	net_buf_add_mem(pkt->frags, data_pkt_with_ar, sizeof(data_pkt_with_ar));
328 
329 	return pkt;
330 }
331 
332 #ifdef CONFIG_NET_SOCKETS
set_up_security(uint8_t security_level)333 static bool set_up_security(uint8_t security_level)
334 {
335 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
336 	uint16_t saved_short_addr = ctx->short_addr;
337 	struct ieee802154_security_params params;
338 
339 	if (security_level == IEEE802154_SECURITY_LEVEL_NONE) {
340 		return true;
341 	}
342 
343 	if (disassociate(net_iface, ctx) != 0) {
344 		return false;
345 	}
346 
347 	params = (struct ieee802154_security_params){
348 		.key = {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
349 			0xcc, 0xcd, 0xce, 0xcf},
350 		.key_len = 16U,
351 		.key_mode = IEEE802154_KEY_ID_MODE_IMPLICIT,
352 		.level = security_level,
353 	};
354 
355 	if (net_mgmt(NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS, net_iface, &params,
356 		     sizeof(struct ieee802154_security_params))) {
357 		NET_ERR("*** Failed to set security settings");
358 		return false;
359 	}
360 
361 	if (saved_short_addr != IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED &&
362 	    associate(net_iface, ctx, saved_short_addr) != 0) {
363 		return false;
364 	}
365 
366 	return true;
367 }
368 
tear_down_security(void)369 static bool tear_down_security(void)
370 {
371 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
372 	uint16_t saved_short_addr = ctx->short_addr;
373 	struct ieee802154_security_params params = {
374 		.level = IEEE802154_SECURITY_LEVEL_NONE,
375 	};
376 
377 	if (disassociate(net_iface, ctx) != 0) {
378 		return false;
379 	}
380 
381 	if (net_mgmt(NET_REQUEST_IEEE802154_SET_SECURITY_SETTINGS, net_iface, &params,
382 		     sizeof(struct ieee802154_security_params))) {
383 		NET_ERR("*** Failed to tear down security settings");
384 		return false;
385 	}
386 
387 	if (saved_short_addr != IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED &&
388 	    associate(net_iface, ctx, saved_short_addr) != 0) {
389 		return false;
390 	}
391 
392 	return true;
393 }
394 
set_up_recv_socket(enum net_sock_type socket_type)395 static int set_up_recv_socket(enum net_sock_type socket_type)
396 {
397 	struct sockaddr_ll socket_sll = {
398 		.sll_ifindex = net_if_get_by_iface(net_iface),
399 		.sll_family = AF_PACKET,
400 		.sll_protocol = htons(ETH_P_IEEE802154),
401 	};
402 	struct timeval timeo_optval = {
403 		.tv_sec = 1,
404 		.tv_usec = 0,
405 	};
406 	int fd;
407 
408 	fd = zsock_socket(AF_PACKET, socket_type, htons(ETH_P_IEEE802154));
409 	if (fd < 0) {
410 		NET_ERR("*** Failed to create recv socket : %d", errno);
411 		return fd;
412 	}
413 
414 	if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
415 		NET_ERR("*** Failed to bind packet socket : %d", errno);
416 		goto release_fd;
417 	}
418 
419 	if (zsock_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_optval, sizeof(timeo_optval))) {
420 		NET_ERR("*** Failed to set reception timeout on packet socket : %d", errno);
421 		goto release_fd;
422 	}
423 
424 	return fd;
425 
426 release_fd:
427 	zsock_close(fd);
428 	return -EFAULT;
429 }
430 #endif /* CONFIG_NET_SOCKETS */
431 
test_packet_parsing(struct ieee802154_pkt_test * t)432 static bool test_packet_parsing(struct ieee802154_pkt_test *t)
433 {
434 	struct ieee802154_mpdu mpdu = {0};
435 
436 	NET_INFO("- Parsing packet 0x%p of frame %s", t->pkt, t->name);
437 
438 	if (!ieee802154_validate_frame(t->pkt, t->length, &mpdu)) {
439 		NET_ERR("*** Could not validate frame %s", t->name);
440 		return false;
441 	}
442 
443 	if (mpdu.mhr.fs != t->mhr_check.fc_seq ||
444 	    mpdu.mhr.dst_addr != t->mhr_check.dst_addr ||
445 	    mpdu.mhr.src_addr != t->mhr_check.src_addr) {
446 		NET_INFO("d: %p vs %p -- s: %p vs %p",
447 			 mpdu.mhr.dst_addr, t->mhr_check.dst_addr,
448 			 mpdu.mhr.src_addr, t->mhr_check.src_addr);
449 		NET_ERR("*** Wrong MPDU information on frame %s", t->name);
450 
451 		return false;
452 	}
453 
454 	if (mpdu.mhr.fs->sequence != t->sequence) {
455 		NET_ERR("*** Invalid sequence number for frame %s", t->name);
456 		return false;
457 	}
458 
459 	if (mpdu.payload_length != t->payload_length) {
460 		NET_ERR("*** Invalid payload length for frame %s", t->name);
461 		return false;
462 	}
463 
464 	return true;
465 }
466 
test_ns_sending(struct ieee802154_pkt_test * t,bool with_short_addr)467 static bool test_ns_sending(struct ieee802154_pkt_test *t, bool with_short_addr)
468 {
469 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
470 	struct ieee802154_mpdu mpdu;
471 	bool result = false;
472 
473 	NET_INFO("- Sending NS packet");
474 
475 	/* ensure reproducible results */
476 	ctx->sequence = t->sequence;
477 
478 	if (with_short_addr && set_up_short_addr(net_iface, ctx)) {
479 		goto out;
480 	}
481 
482 	if (net_ipv6_send_ns(net_iface, NULL, &t->src, &t->dst, &t->dst, false)) {
483 		NET_ERR("*** Could not create IPv6 NS packet");
484 		tear_down_short_addr(net_iface, ctx);
485 		goto out;
486 	}
487 
488 	tear_down_short_addr(net_iface, ctx);
489 
490 	k_yield();
491 	k_sem_take(&driver_lock, K_SECONDS(1));
492 
493 	if (!current_pkt->frags) {
494 		NET_ERR("*** Could not send IPv6 NS packet");
495 		goto out;
496 	}
497 
498 	pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
499 
500 	if (!with_short_addr) {
501 		if (net_pkt_get_len(current_pkt) != t->length ||
502 		    memcmp(net_pkt_data(current_pkt), t->pkt, t->length)) {
503 			NET_ERR("*** Sent packet deviates from expected packet");
504 			goto release_frag;
505 		}
506 	}
507 
508 	if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
509 				       net_pkt_get_len(current_pkt), &mpdu)) {
510 		NET_ERR("*** Sent packet is not valid");
511 		goto release_frag;
512 	}
513 
514 	result = true;
515 
516 release_frag:
517 	net_pkt_frag_unref(current_pkt->frags);
518 	current_pkt->frags = NULL;
519 out:
520 	return result;
521 }
522 
test_wait_for_ack(struct ieee802154_pkt_test * t)523 static bool test_wait_for_ack(struct ieee802154_pkt_test *t)
524 {
525 	struct ieee802154_mpdu mpdu;
526 	struct net_pkt *one_ack_pkt;
527 	struct net_pkt *tx_pkt;
528 	bool result = false;
529 	bool ack_required;
530 
531 	NET_INFO("- Waiting for ACK reply when sending a data packet");
532 
533 	tx_pkt = get_data_pkt_with_ar();
534 	if (!tx_pkt) {
535 		goto out;
536 	}
537 
538 	ack_required = ieee802154_prepare_for_ack(net_iface, tx_pkt, tx_pkt->frags);
539 	if (!ack_required) {
540 		NET_ERR("*** Expected AR flag to be set");
541 		goto release_tx_pkt;
542 	}
543 
544 	if (!ieee802154_validate_frame(net_pkt_data(tx_pkt), net_pkt_get_len(tx_pkt), &mpdu)) {
545 		NET_ERR("*** Could not parse data pkt.");
546 		goto release_tx_pkt;
547 	}
548 
549 	one_ack_pkt = net_pkt_rx_alloc_with_buffer(net_iface, IEEE802154_ACK_PKT_LENGTH,
550 						   AF_UNSPEC, 0, K_FOREVER);
551 	if (!one_ack_pkt) {
552 		NET_ERR("*** Could not allocate ack pkt.");
553 		goto release_tx_pkt;
554 	}
555 
556 	if (!ieee802154_create_ack_frame(net_iface, one_ack_pkt, mpdu.mhr.fs->sequence)) {
557 		NET_ERR("*** Could not create ack frame.");
558 		goto release_tx_pkt;
559 	}
560 
561 	pkt_hexdump(net_pkt_data(one_ack_pkt), net_pkt_get_len(one_ack_pkt));
562 
563 	if (ieee802154_handle_ack(net_iface, one_ack_pkt) != NET_OK) {
564 		NET_ERR("*** Ack frame was not handled.");
565 		goto release_ack_pkt;
566 	}
567 
568 	if (ieee802154_wait_for_ack(net_iface, ack_required) != 0) {
569 		NET_ERR("*** Ack frame was not recorded.");
570 		goto release_ack_pkt;
571 	}
572 
573 	result = true;
574 
575 release_ack_pkt:
576 	net_pkt_unref(one_ack_pkt);
577 release_tx_pkt:
578 	net_pkt_unref(tx_pkt);
579 out:
580 	return result;
581 }
582 
test_packet_cloning_with_cb(void)583 static bool test_packet_cloning_with_cb(void)
584 {
585 	struct net_pkt *pkt;
586 	struct net_pkt *cloned_pkt;
587 
588 	NET_INFO("- Cloning packet");
589 
590 	pkt = net_pkt_rx_alloc_with_buffer(net_iface, 64, AF_UNSPEC, 0, K_NO_WAIT);
591 	if (!pkt) {
592 		NET_ERR("*** No buffer to allocate");
593 		return false;
594 	}
595 
596 	/* Set some arbitrary flags and data */
597 	net_pkt_set_ieee802154_ack_fpb(pkt, true);
598 	net_pkt_set_ieee802154_lqi(pkt, 50U);
599 	net_pkt_set_ieee802154_frame_secured(pkt, true);
600 
601 	cloned_pkt = net_pkt_clone(pkt, K_NO_WAIT);
602 	zassert_not_equal(net_pkt_cb(cloned_pkt), net_pkt_cb(pkt));
603 
604 	zassert_true(net_pkt_ieee802154_ack_fpb(cloned_pkt));
605 	zassert_true(net_pkt_ieee802154_frame_secured(cloned_pkt));
606 	zassert_false(net_pkt_ieee802154_mac_hdr_rdy(cloned_pkt));
607 	zassert_equal(net_pkt_ieee802154_lqi(cloned_pkt), 50U);
608 	zassert_equal(net_pkt_ieee802154_rssi(cloned_pkt), 0U);
609 
610 	net_pkt_unref(pkt);
611 	net_pkt_unref(cloned_pkt);
612 
613 	return true;
614 }
615 
test_packet_rssi_conversion(void)616 static bool test_packet_rssi_conversion(void)
617 {
618 	uint8_t raw_signed_rssi_dbm;
619 	int8_t signed_rssi_dbm;
620 	struct net_pkt *pkt;
621 
622 	NET_INFO("- RSSI conversion between unsigned and signed representation");
623 
624 	pkt = net_pkt_rx_alloc_on_iface(net_iface, K_NO_WAIT);
625 	if (!pkt) {
626 		NET_ERR("*** No pkt to allocate");
627 		return false;
628 	}
629 
630 	/* Test setting/getting of unsigned RSSI. */
631 	net_pkt_set_ieee802154_rssi(pkt, 50U);
632 	zassert_equal(net_pkt_ieee802154_rssi(pkt), 50U);
633 
634 	/* Test setting/getting of signed RSSI (in range). */
635 	net_pkt_set_ieee802154_rssi_dbm(pkt, IEEE802154_MAC_RSSI_DBM_MIN);
636 	zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MIN);
637 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MIN);
638 	net_pkt_set_ieee802154_rssi_dbm(pkt, IEEE802154_MAC_RSSI_DBM_MAX);
639 	zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MAX);
640 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MAX);
641 	net_pkt_set_ieee802154_rssi_dbm(pkt, 0);
642 	zassert_equal(net_pkt_ieee802154_rssi(pkt), 174U);
643 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), 0);
644 
645 	/* Test setting/getting of signed RSSI (outside range). */
646 	net_pkt_set_ieee802154_rssi_dbm(pkt, INT16_MIN + 1);
647 	zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MIN);
648 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MIN);
649 	net_pkt_set_ieee802154_rssi_dbm(pkt, INT16_MAX);
650 	zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_MAX);
651 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_MAX);
652 
653 	/* Test setting/getting of signed RSSI (special value - "no RSSI available"). */
654 	net_pkt_set_ieee802154_rssi_dbm(pkt, IEEE802154_MAC_RSSI_DBM_UNDEFINED);
655 	zassert_equal(net_pkt_ieee802154_rssi(pkt), IEEE802154_MAC_RSSI_UNDEFINED);
656 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), IEEE802154_MAC_RSSI_DBM_UNDEFINED);
657 
658 	/* Demonstrate setting/getting of signed RSSI represented as a raw
659 	 * two-complements value in uint8_t (explicit cast required).
660 	 */
661 	raw_signed_rssi_dbm = (uint8_t)-2;
662 	net_pkt_set_ieee802154_rssi_dbm(pkt, (int8_t) raw_signed_rssi_dbm);
663 	zassert_equal(net_pkt_ieee802154_rssi(pkt), 172U);
664 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), -2);
665 
666 	/* Demonstrate setting/getting of signed RSSI represented as int8_t
667 	 * (no explicit cast required)
668 	 */
669 	signed_rssi_dbm = -2;
670 	net_pkt_set_ieee802154_rssi_dbm(pkt, signed_rssi_dbm);
671 	zassert_equal(net_pkt_ieee802154_rssi(pkt), 172U);
672 	zassert_equal(net_pkt_ieee802154_rssi_dbm(pkt), -2);
673 
674 	net_pkt_unref(pkt);
675 	return true;
676 }
677 
678 #ifdef CONFIG_NET_SOCKETS
test_dgram_packet_sending(void * dst_sll,uint8_t dst_sll_halen,uint32_t security_level)679 static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint32_t security_level)
680 {
681 	/* tests should be run sequentially, so no need for context locking */
682 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
683 	struct sockaddr_ll socket_sll = {.sll_ifindex = net_if_get_by_iface(net_iface),
684 					 .sll_family = AF_PACKET,
685 					 .sll_protocol = htons(ETH_P_IEEE802154)};
686 	struct sockaddr_ll pkt_dst_sll = {
687 		.sll_halen = dst_sll_halen,
688 		.sll_protocol = htons(ETH_P_IEEE802154),
689 	};
690 	uint8_t payload[] = {0x01, 0x02, 0x03, 0x04};
691 	struct ieee802154_mpdu mpdu;
692 	bool result = false;
693 	int fd;
694 
695 	if (!set_up_security(security_level)) {
696 		goto out;
697 	}
698 
699 	NET_INFO("- Sending DGRAM packet via AF_PACKET socket");
700 	fd = zsock_socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IEEE802154));
701 	if (fd < 0) {
702 		NET_ERR("*** Failed to create DGRAM socket : %d", errno);
703 		goto reset_security;
704 	}
705 
706 	/* In case we have a short destination address
707 	 * we simulate an associated device.
708 	 */
709 	/* TODO: support short addresses with encryption (requires neighbour cache) */
710 	memcpy(pkt_dst_sll.sll_addr, dst_sll, dst_sll_halen);
711 	bool bind_short_address = pkt_dst_sll.sll_halen == IEEE802154_SHORT_ADDR_LENGTH &&
712 				  security_level == IEEE802154_SECURITY_LEVEL_NONE;
713 
714 	if (bind_short_address && set_up_short_addr(net_iface, ctx)) {
715 		goto release_fd;
716 	}
717 
718 	if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
719 		NET_ERR("*** Failed to bind packet socket : %d", errno);
720 		goto release_fd;
721 	}
722 
723 	if (zsock_sendto(fd, payload, sizeof(payload), 0, (const struct sockaddr *)&pkt_dst_sll,
724 			 sizeof(struct sockaddr_ll)) != sizeof(payload)) {
725 		NET_ERR("*** Failed to send, errno %d", errno);
726 		goto release_fd;
727 	}
728 
729 	k_yield();
730 	k_sem_take(&driver_lock, K_SECONDS(1));
731 
732 	if (!current_pkt->frags) {
733 		NET_ERR("*** Could not send DGRAM packet");
734 		goto release_fd;
735 	}
736 
737 	pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
738 
739 	if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
740 				       net_pkt_get_len(current_pkt), &mpdu)) {
741 		NET_ERR("*** Sent packet is not valid");
742 		goto release_frag;
743 	}
744 
745 	(void)net_linkaddr_copy(net_pkt_lladdr_src(current_pkt),
746 				net_if_get_link_addr(net_iface));
747 
748 	if (!ieee802154_decipher_data_frame(net_iface, current_pkt, &mpdu)) {
749 		NET_ERR("*** Cannot decipher/authenticate packet");
750 		goto release_frag;
751 	}
752 
753 	if (memcmp(mpdu.payload, payload, sizeof(payload)) != 0) {
754 		NET_ERR("*** Payload of sent packet is incorrect");
755 		goto release_frag;
756 	}
757 
758 	result = true;
759 
760 release_frag:
761 	net_pkt_frag_unref(current_pkt->frags);
762 	current_pkt->frags = NULL;
763 release_fd:
764 	tear_down_short_addr(net_iface, ctx);
765 	zsock_close(fd);
766 reset_security:
767 	tear_down_security();
768 out:
769 	return result;
770 }
771 
772 /* src_ll_addr is always big endian */
test_dgram_packet_reception(void * src_ll_addr,uint8_t src_ll_addr_len,uint32_t security_level,bool is_broadcast)773 static bool test_dgram_packet_reception(void *src_ll_addr, uint8_t src_ll_addr_len,
774 					uint32_t security_level, bool is_broadcast)
775 {
776 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
777 	uint8_t our_ext_addr[IEEE802154_EXT_ADDR_LENGTH]; /* big endian */
778 	uint8_t payload[] = {0x01, 0x02, 0x03, 0x04};
779 	uint16_t our_short_addr = ctx->short_addr; /* CPU byte order */
780 	uint8_t ll_hdr_len = 0, authtag_len = 0;
781 	struct sockaddr_ll recv_src_sll = {0};
782 	uint8_t received_payload[4] = {0};
783 	socklen_t recv_src_sll_len;
784 	struct net_buf *frame_buf;
785 	struct net_pkt *pkt;
786 	bool frame_result;
787 	int received_len;
788 	bool result;
789 	int fd;
790 
791 	result = false;
792 
793 	sys_memcpy_swap(our_ext_addr, ctx->ext_addr, sizeof(our_ext_addr));
794 
795 	if (!set_up_security(security_level)) {
796 		goto out;
797 	}
798 
799 	NET_INFO("- Receiving DGRAM packet via AF_PACKET socket");
800 
801 	fd = set_up_recv_socket(SOCK_DGRAM);
802 	if (fd < 0) {
803 		goto reset_security;
804 	}
805 
806 	pkt = net_pkt_rx_alloc(K_FOREVER);
807 	if (!pkt) {
808 		NET_ERR("*** Failed to allocate net pkt.");
809 		goto release_fd;
810 	}
811 
812 	pkt->lladdr_dst.type = NET_LINK_IEEE802154;
813 	if (is_broadcast) {
814 		memset(pkt->lladdr_dst.addr, 0, sizeof(pkt->lladdr_dst.addr));
815 		pkt->lladdr_dst.len = 0;
816 	} else {
817 		memcpy(pkt->lladdr_dst.addr, our_ext_addr, sizeof(our_ext_addr));
818 		pkt->lladdr_dst.len = sizeof(ctx->ext_addr);
819 	}
820 
821 	if (src_ll_addr_len == IEEE802154_SHORT_ADDR_LENGTH ||
822 	    src_ll_addr_len == IEEE802154_EXT_ADDR_LENGTH) {
823 		memcpy(pkt->lladdr_src.addr, src_ll_addr, src_ll_addr_len);
824 	} else {
825 		NET_ERR("*** Illegal L2 source address length.");
826 		goto release_pkt;
827 	}
828 	pkt->lladdr_src.len = src_ll_addr_len;
829 	pkt->lladdr_src.type = NET_LINK_IEEE802154;
830 
831 	frame_buf = net_pkt_get_frag(pkt, IEEE802154_MTU, K_FOREVER);
832 	if (!frame_buf) {
833 		NET_ERR("*** Failed to allocate net pkt frag.");
834 		goto release_pkt;
835 	}
836 
837 	ieee802154_compute_header_and_authtag_len(
838 		net_iface, net_pkt_lladdr_dst(pkt), net_pkt_lladdr_src(pkt),
839 		&ll_hdr_len, &authtag_len);
840 
841 	net_buf_add(frame_buf, ll_hdr_len);
842 	net_buf_add_mem(frame_buf, payload, sizeof(payload));
843 	net_buf_add(frame_buf, authtag_len);
844 
845 	/* Temporarily set the ctx address to the given source address so
846 	 * we can use ieee802154_create_data_frame().
847 	 */
848 	if (src_ll_addr_len == IEEE802154_SHORT_ADDR_LENGTH) {
849 		ctx->short_addr = ntohs(*(uint16_t *)src_ll_addr);
850 	} else if (src_ll_addr_len == IEEE802154_EXT_ADDR_LENGTH) {
851 		sys_memcpy_swap(ctx->ext_addr, src_ll_addr, sizeof(ctx->ext_addr));
852 	} else {
853 		NET_ERR("*** Illegal L2 source address length.");
854 		goto release_pkt;
855 	}
856 
857 	frame_result = ieee802154_create_data_frame(ctx, net_pkt_lladdr_dst(pkt),
858 						    net_pkt_lladdr_src(pkt), frame_buf, ll_hdr_len);
859 
860 	if (src_ll_addr_len == IEEE802154_SHORT_ADDR_LENGTH) {
861 		ctx->short_addr = our_short_addr;
862 	} else {
863 		sys_memcpy_swap(ctx->ext_addr, pkt->lladdr_dst.addr,
864 				sizeof(ctx->ext_addr));
865 	}
866 
867 	if (!frame_result) {
868 		NET_ERR("*** Error while creating data frame.");
869 		goto release_pkt;
870 	};
871 
872 	net_pkt_frag_add(pkt, frame_buf);
873 
874 	if (net_recv_data(net_iface, pkt)) {
875 		NET_ERR("*** Error while processing packet.");
876 		goto release_pkt;
877 	}
878 
879 	if (current_pkt->frags) {
880 		NET_ERR("*** Generated unexpected (ACK?) packet when processing packet.");
881 		net_pkt_frag_unref(current_pkt->frags);
882 		current_pkt->frags = NULL;
883 		goto release_pkt;
884 	}
885 
886 	recv_src_sll_len = sizeof(recv_src_sll);
887 	received_len = zsock_recvfrom(fd, received_payload, sizeof(received_payload), 0,
888 				      (struct sockaddr *)&recv_src_sll, &recv_src_sll_len);
889 	if (received_len < 0) {
890 		NET_ERR("*** Failed to receive packet, errno %d", errno);
891 		goto release_pkt;
892 	}
893 
894 	pkt_hexdump(received_payload, received_len);
895 
896 	if (received_len != sizeof(payload) || memcmp(received_payload, payload, sizeof(payload))) {
897 		NET_ERR("*** Payload of received packet is incorrect");
898 		goto release_pkt;
899 	}
900 
901 	if (recv_src_sll_len != sizeof(struct sockaddr_ll) ||
902 	    recv_src_sll.sll_family != AF_PACKET ||
903 	    recv_src_sll.sll_protocol != htons(ETH_P_IEEE802154) ||
904 	    recv_src_sll.sll_ifindex != net_if_get_by_iface(net_iface) ||
905 	    recv_src_sll.sll_halen != src_ll_addr_len ||
906 	    memcmp(recv_src_sll.sll_addr, src_ll_addr, src_ll_addr_len)) {
907 		NET_ERR("*** Source L2 address of received packet is incorrect");
908 		goto release_pkt;
909 	}
910 
911 	result = true;
912 
913 release_pkt:
914 	net_pkt_unref(pkt);
915 release_fd:
916 	zsock_close(fd);
917 reset_security:
918 	tear_down_security();
919 out:
920 	return result;
921 }
922 
test_raw_packet_sending(void)923 static bool test_raw_packet_sending(void)
924 {
925 	/* tests should be run sequentially, so no need for context locking */
926 	struct sockaddr_ll socket_sll = {0};
927 	struct ieee802154_mpdu mpdu;
928 	struct msghdr msg = {0};
929 	struct iovec io_vector;
930 	bool result = false;
931 	int fd;
932 
933 	NET_INFO("- Sending RAW packet via AF_PACKET socket");
934 
935 	fd = zsock_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154));
936 	if (fd < 0) {
937 		NET_ERR("*** Failed to create RAW socket : %d", errno);
938 		goto out;
939 	}
940 
941 	socket_sll.sll_ifindex = net_if_get_by_iface(net_iface);
942 	socket_sll.sll_family = AF_PACKET;
943 	socket_sll.sll_protocol = htons(ETH_P_IEEE802154);
944 
945 	if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
946 		NET_ERR("*** Failed to bind packet socket : %d", errno);
947 		goto release_fd;
948 	}
949 
950 	io_vector.iov_base = raw_payload;
951 	io_vector.iov_len = sizeof(raw_payload);
952 	msg.msg_iov = &io_vector;
953 	msg.msg_iovlen = 1;
954 
955 	if (zsock_sendmsg(fd, &msg, 0) != sizeof(raw_payload)) {
956 		NET_ERR("*** Failed to send, errno %d", errno);
957 		goto release_fd;
958 	}
959 
960 	k_yield();
961 	k_sem_take(&driver_lock, K_SECONDS(1));
962 
963 	if (!current_pkt->frags) {
964 		NET_ERR("*** Could not send RAW packet");
965 		goto release_fd;
966 	}
967 
968 	pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
969 
970 	if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
971 				       net_pkt_get_len(current_pkt), &mpdu)) {
972 		NET_ERR("*** Sent packet is not valid");
973 		goto release_frag;
974 	}
975 
976 	if (memcmp(mpdu.payload, &raw_payload[RAW_MAC_PAYLOAD_START_INDEX],
977 		   RAW_MAC_PAYLOAD_LENGTH) != 0) {
978 		NET_ERR("*** Payload of sent packet is incorrect");
979 		goto release_frag;
980 	}
981 
982 	result = true;
983 
984 release_frag:
985 	net_pkt_frag_unref(current_pkt->frags);
986 	current_pkt->frags = NULL;
987 release_fd:
988 	zsock_close(fd);
989 out:
990 	return result;
991 }
992 
test_raw_packet_reception(void)993 static bool test_raw_packet_reception(void)
994 {
995 	uint8_t received_payload[sizeof(raw_payload)] = {0};
996 	struct net_buf *frame_buf;
997 	struct net_pkt *pkt;
998 	int received_len;
999 	bool result;
1000 	int fd;
1001 
1002 	result = false;
1003 
1004 	NET_INFO("- Receiving RAW packet via AF_PACKET socket");
1005 
1006 	fd = set_up_recv_socket(SOCK_RAW);
1007 	if (fd < 0) {
1008 		goto out;
1009 	}
1010 
1011 	pkt = net_pkt_rx_alloc(K_FOREVER);
1012 	if (!pkt) {
1013 		NET_ERR("*** Failed to allocate net pkt.");
1014 		goto release_fd;
1015 	}
1016 
1017 	frame_buf = net_pkt_get_frag(pkt, sizeof(raw_payload), K_FOREVER);
1018 	if (!frame_buf) {
1019 		NET_ERR("*** Failed to allocate net pkt frag.");
1020 		goto release_pkt;
1021 	}
1022 
1023 	net_buf_add_mem(frame_buf, raw_payload, sizeof(raw_payload));
1024 	net_pkt_frag_add(pkt, frame_buf);
1025 
1026 	if (net_recv_data(net_iface, pkt)) {
1027 		NET_ERR("*** Error while processing packet.");
1028 		goto release_pkt;
1029 	}
1030 
1031 	if (current_pkt->frags) {
1032 		NET_ERR("*** Generated unexpected packet when processing packet.");
1033 		net_pkt_frag_unref(current_pkt->frags);
1034 		current_pkt->frags = NULL;
1035 		goto release_pkt;
1036 	}
1037 
1038 	/* TODO: For POSIX compliance raw packets should be parsed and a LL header be
1039 	 *       extracted. We'll only be able to do so when Zephyr provides hooks to
1040 	 *       call out to L2 from raw socket contexts.
1041 	 */
1042 	received_len = zsock_recv(fd, received_payload, sizeof(received_payload), 0);
1043 	if (received_len < 0) {
1044 		NET_ERR("*** Failed to receive packet, errno %d", errno);
1045 		goto release_pkt;
1046 	}
1047 
1048 	pkt_hexdump(received_payload, received_len);
1049 
1050 	/* TODO: The received raw packet should actually contain an FCS
1051 	 *       for full compatibility with Linux's raw socket implementation.
1052 	 *       This will only be possible once we
1053 	 *         1) let HW drivers include FCS if they have it and
1054 	 *         2) provide a hook for mangling raw packets that allows us
1055 	 *            to include a synthetic FCS if the HW driver does not
1056 	 *            provide one.
1057 	 */
1058 	if (received_len != sizeof(raw_payload) ||
1059 	    memcmp(received_payload, raw_payload, sizeof(raw_payload))) {
1060 		NET_ERR("*** Payload of received packet is incorrect");
1061 		goto release_pkt;
1062 	}
1063 
1064 	result = true;
1065 
1066 release_pkt:
1067 	net_pkt_unref(pkt);
1068 release_fd:
1069 	zsock_close(fd);
1070 out:
1071 	return result;
1072 }
1073 
test_recv_and_send_ack_reply(struct ieee802154_pkt_test * t)1074 static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t)
1075 {
1076 	/* Expected uncompressed IPv6 payload. */
1077 	static uint8_t expected_rx_pkt[] = {
1078 		0x60, 0x00, 0x00, 0x00, /* IPv6, Traffic Class, Flow Label */
1079 		0x00, 0x28,		/* Payload Length */
1080 		0x3a,			/* Next header: ICMPv6 */
1081 		0xff,			/* Hop Limit */
1082 		0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1083 		0x02, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2, /* Source */
1084 		0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1085 		0x00, 0x00, 0x00, 0x01, 0xff, 0x4b, 0x12, 0x00, /* Destination */
1086 		0x87,						/* Type: NS */
1087 		0x00,						/* Code*/
1088 		0xb7, 0x45,					/* Checksum */
1089 		0x00, 0x00, 0x00, 0x00,				/* Reserved */
1090 		0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1091 		0x70, 0x14, 0xa6, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* Target Address */
1092 		0x01, /* ICMPv6 Option: Source LL address */
1093 		0x02, /* Length */
1094 		0xe5, 0xac, 0xa1, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* LL address */
1095 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		/* Padding */
1096 	};
1097 	struct ieee802154_context *ctx = net_if_l2_data(net_iface);
1098 	struct sockaddr_ll recv_src_sll = {0};
1099 	struct sockaddr_ll socket_sll = {
1100 		.sll_ifindex = net_if_get_by_iface(net_iface),
1101 		.sll_family = AF_PACKET,
1102 		.sll_protocol = htons(ETH_P_IEEE802154),
1103 	};
1104 	uint8_t received_payload[80] = {0};
1105 	struct timeval timeo_optval = {
1106 		.tv_sec = 1,
1107 		.tv_usec = 0,
1108 	};
1109 	struct ieee802154_mpdu mpdu;
1110 	socklen_t recv_src_sll_len;
1111 	struct net_pkt *rx_pkt;
1112 	bool result = false;
1113 	uint8_t mac_be[8];
1114 	int received_len;
1115 	int fd;
1116 
1117 	NET_INFO("- Sending ACK reply to a data packet");
1118 
1119 	fd = zsock_socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IEEE802154));
1120 	if (fd < 0) {
1121 		NET_ERR("*** Failed to create DGRAM socket : %d", errno);
1122 		goto out;
1123 	}
1124 
1125 	if (zsock_bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
1126 		NET_ERR("*** Failed to bind packet socket : %d", errno);
1127 		goto release_fd;
1128 	}
1129 
1130 	if (zsock_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_optval, sizeof(timeo_optval))) {
1131 		NET_ERR("*** Failed to set reception timeout on packet socket : %d", errno);
1132 		goto release_fd;
1133 	}
1134 
1135 	if (set_up_short_addr(net_iface, ctx)) {
1136 		goto release_fd;
1137 	}
1138 
1139 	rx_pkt = get_data_pkt_with_ar();
1140 	if (!rx_pkt) {
1141 		goto reset_short_addr;
1142 	}
1143 
1144 	if (net_recv_data(net_iface, rx_pkt) < 0) {
1145 		NET_ERR("Recv data failed");
1146 		goto release_rx_pkt;
1147 	}
1148 
1149 	recv_src_sll_len = sizeof(recv_src_sll);
1150 	received_len = zsock_recvfrom(fd, received_payload, sizeof(received_payload), 0,
1151 				      (struct sockaddr *)&recv_src_sll, &recv_src_sll_len);
1152 	if (received_len < 0) {
1153 		NET_ERR("*** Failed to receive packet, errno %d", errno);
1154 		goto release_rx_pkt;
1155 	}
1156 
1157 	sys_memcpy_swap(mac_be, ctx->ext_addr, IEEE802154_EXT_ADDR_LENGTH);
1158 	if (recv_src_sll_len != sizeof(struct sockaddr_ll) ||
1159 	    recv_src_sll.sll_ifindex != net_if_get_by_iface(net_iface) ||
1160 	    recv_src_sll.sll_family != AF_PACKET ||
1161 	    recv_src_sll.sll_protocol != htons(ETH_P_IEEE802154) ||
1162 	    recv_src_sll.sll_halen != IEEE802154_EXT_ADDR_LENGTH ||
1163 	    memcmp(recv_src_sll.sll_addr, mac_be, IEEE802154_EXT_ADDR_LENGTH)) {
1164 		NET_ERR("*** Received socket address does not compare (%d)", -errno);
1165 		goto release_rx_pkt;
1166 	}
1167 
1168 	pkt_hexdump(received_payload, received_len);
1169 
1170 	if (memcmp(expected_rx_pkt, received_payload,
1171 		   sizeof(expected_rx_pkt))) {
1172 		NET_ERR("*** Received uncompressed IPv6 payload does not compare");
1173 		goto release_rx_pkt;
1174 	}
1175 
1176 	k_yield();
1177 	k_sem_take(&driver_lock, K_SECONDS(1));
1178 
1179 	/* an ACK packet should be in current_pkt */
1180 	if (!current_pkt->frags) {
1181 		NET_ERR("*** No ACK reply sent");
1182 		goto release_rx_pkt;
1183 	}
1184 
1185 	pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
1186 
1187 	if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
1188 				       net_pkt_get_len(current_pkt), &mpdu)) {
1189 		NET_ERR("*** ACK Reply is invalid");
1190 		goto release_tx_frag;
1191 	}
1192 
1193 	if (memcmp(mpdu.mhr.fs, t->mhr_check.fc_seq,
1194 		   sizeof(struct ieee802154_fcf_seq))) {
1195 		NET_ERR("*** ACK Reply does not compare");
1196 		goto release_tx_frag;
1197 	}
1198 
1199 	if (mpdu.mhr.fs->sequence != t->sequence) {
1200 		NET_ERR("*** Sequence number invalid");
1201 		goto release_tx_frag;
1202 	}
1203 
1204 	result = true;
1205 
1206 release_tx_frag:
1207 	net_pkt_frag_unref(current_pkt->frags);
1208 	current_pkt->frags = NULL;
1209 release_rx_pkt:
1210 	net_pkt_unref(rx_pkt);
1211 reset_short_addr:
1212 	tear_down_short_addr(net_iface, ctx);
1213 release_fd:
1214 	zsock_close(fd);
1215 out:
1216 	return result;
1217 }
1218 #endif /* CONFIG_NET_SOCKETS */
1219 
initialize_test_environment(void)1220 static bool initialize_test_environment(void)
1221 {
1222 	uint16_t mock_pan_id = MOCK_PAN_ID;
1223 	const struct device *dev;
1224 
1225 	k_sem_reset(&driver_lock);
1226 
1227 	current_pkt = net_pkt_rx_alloc(K_FOREVER);
1228 	if (!current_pkt) {
1229 		NET_ERR("*** No buffer to allocate");
1230 		return false;
1231 	}
1232 
1233 	dev = device_get_binding("fake_ieee802154");
1234 	if (!dev) {
1235 		NET_ERR("*** Could not get fake device");
1236 		goto release_pkt;
1237 	}
1238 
1239 	net_iface = net_if_lookup_by_dev(dev);
1240 	if (!net_iface) {
1241 		NET_ERR("*** Could not get fake iface");
1242 		goto release_pkt;
1243 	}
1244 
1245 	if (net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, net_iface,
1246 		     &mock_pan_id, sizeof(mock_pan_id))) {
1247 		NET_ERR("*** Failed to set PAN ID in %s.", __func__);
1248 		goto release_pkt;
1249 	}
1250 
1251 	NET_INFO("Fake IEEE 802.15.4 network interface ready");
1252 
1253 	ieee_addr_hexdump(net_if_get_link_addr(net_iface)->addr, 8);
1254 
1255 	return true;
1256 
1257 release_pkt:
1258 	net_pkt_unref(current_pkt);
1259 	return false;
1260 }
1261 
test_setup(void)1262 static void *test_setup(void)
1263 {
1264 	bool ret;
1265 
1266 	ret = initialize_test_environment();
1267 
1268 	zassert_true(ret, "Test initialization");
1269 
1270 	return NULL;
1271 }
1272 
test_teardown(void * test_fixture)1273 static void test_teardown(void *test_fixture)
1274 {
1275 	ARG_UNUSED(test_fixture);
1276 
1277 	net_pkt_unref(current_pkt);
1278 	current_pkt = NULL;
1279 }
1280 
ZTEST(ieee802154_l2,test_parsing_ns_pkt)1281 ZTEST(ieee802154_l2, test_parsing_ns_pkt)
1282 {
1283 	bool ret;
1284 
1285 	ret = test_packet_parsing(&test_ns_pkt);
1286 
1287 	zassert_true(ret, "NS parsed");
1288 }
1289 
ZTEST(ieee802154_l2,test_sending_ns_pkt)1290 ZTEST(ieee802154_l2, test_sending_ns_pkt)
1291 {
1292 	bool ret;
1293 
1294 	ret = test_ns_sending(&test_ns_pkt, false);
1295 
1296 	zassert_true(ret, "NS sent");
1297 }
1298 
ZTEST(ieee802154_l2,test_sending_ns_pkt_with_short_addr)1299 ZTEST(ieee802154_l2, test_sending_ns_pkt_with_short_addr)
1300 {
1301 	bool ret;
1302 
1303 	ret = test_ns_sending(&test_ns_pkt, true);
1304 
1305 	zassert_true(ret, "NS sent");
1306 }
1307 
ZTEST(ieee802154_l2,test_parsing_ack_pkt)1308 ZTEST(ieee802154_l2, test_parsing_ack_pkt)
1309 {
1310 	bool ret;
1311 
1312 	ret = test_packet_parsing(&test_ack_pkt);
1313 
1314 	zassert_true(ret, "ACK parsed");
1315 }
1316 
ZTEST(ieee802154_l2,test_waiting_for_ack_pkt)1317 ZTEST(ieee802154_l2, test_waiting_for_ack_pkt)
1318 {
1319 	bool ret;
1320 
1321 	ret = test_wait_for_ack(&test_ack_pkt);
1322 
1323 	zassert_true(ret, "ACK received");
1324 }
1325 
ZTEST(ieee802154_l2,test_parsing_beacon_pkt)1326 ZTEST(ieee802154_l2, test_parsing_beacon_pkt)
1327 {
1328 	bool ret;
1329 
1330 	ret = test_packet_parsing(&test_beacon_pkt);
1331 
1332 	zassert_true(ret, "Beacon parsed");
1333 }
1334 
ZTEST(ieee802154_l2,test_parsing_sec_data_pkt)1335 ZTEST(ieee802154_l2, test_parsing_sec_data_pkt)
1336 {
1337 	bool ret;
1338 
1339 	ret = test_packet_parsing(&test_sec_data_pkt);
1340 
1341 	zassert_true(ret, "Secured data frame parsed");
1342 }
1343 
ZTEST(ieee802154_l2,test_clone_cb)1344 ZTEST(ieee802154_l2, test_clone_cb)
1345 {
1346 	bool ret;
1347 
1348 	ret = test_packet_cloning_with_cb();
1349 
1350 	zassert_true(ret, "IEEE 802.15.4 net_pkt control block correctly cloned.");
1351 }
1352 
ZTEST(ieee802154_l2,test_convert_rssi)1353 ZTEST(ieee802154_l2, test_convert_rssi)
1354 {
1355 	bool ret;
1356 
1357 	ret = test_packet_rssi_conversion();
1358 
1359 	zassert_true(ret, "IEEE 802.15.4 net_pkt RSSI value correctly converted between dBm and "
1360 			  "normalized value.");
1361 }
1362 
1363 ZTEST_SUITE(ieee802154_l2, NULL, test_setup, NULL, NULL, test_teardown);
1364 
1365 #ifdef CONFIG_NET_SOCKETS
ZTEST(ieee802154_l2_sockets,test_receiving_pkt_and_replying_ack_pkt)1366 ZTEST(ieee802154_l2_sockets, test_receiving_pkt_and_replying_ack_pkt)
1367 {
1368 	bool ret;
1369 
1370 	ret = test_recv_and_send_ack_reply(&test_ack_pkt);
1371 
1372 	zassert_true(ret, "ACK sent");
1373 }
1374 
ZTEST(ieee802154_l2_sockets,test_sending_broadcast_dgram_pkt)1375 ZTEST(ieee802154_l2_sockets, test_sending_broadcast_dgram_pkt)
1376 {
1377 	uint16_t dst_short_addr = htons(IEEE802154_BROADCAST_ADDRESS);
1378 	bool ret;
1379 
1380 	ret = test_dgram_packet_sending(&dst_short_addr, sizeof(dst_short_addr),
1381 					IEEE802154_SECURITY_LEVEL_NONE);
1382 
1383 	zassert_true(ret, "Broadcast DGRAM packet sent");
1384 }
1385 
ZTEST(ieee802154_l2_sockets,test_receiving_broadcast_dgram_pkt)1386 ZTEST(ieee802154_l2_sockets, test_receiving_broadcast_dgram_pkt)
1387 {
1388 	uint16_t src_short_addr = htons(0x1234);
1389 	bool ret;
1390 
1391 	ret = test_dgram_packet_reception(&src_short_addr, sizeof(src_short_addr),
1392 					  IEEE802154_SECURITY_LEVEL_NONE, true);
1393 
1394 	zassert_true(ret, "Broadcast DGRAM packet received");
1395 }
1396 
ZTEST(ieee802154_l2_sockets,test_sending_authenticated_dgram_pkt)1397 ZTEST(ieee802154_l2_sockets, test_sending_authenticated_dgram_pkt)
1398 {
1399 	uint16_t dst_short_addr = htons(0x1234);
1400 	bool ret;
1401 
1402 	ret = test_dgram_packet_sending(&dst_short_addr, sizeof(dst_short_addr),
1403 					IEEE802154_SECURITY_LEVEL_MIC_128);
1404 
1405 	zassert_true(ret, "Authenticated DGRAM packet sent");
1406 }
1407 
ZTEST(ieee802154_l2_sockets,test_receiving_authenticated_dgram_pkt)1408 ZTEST(ieee802154_l2_sockets, test_receiving_authenticated_dgram_pkt)
1409 {
1410 	/* TODO: Receiving authenticated packages with short addresses is not
1411 	 * yet supported (requires neighbour cache).
1412 	 */
1413 	uint8_t src_ext_addr[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1414 	bool ret;
1415 
1416 	ret = test_dgram_packet_reception(src_ext_addr, sizeof(src_ext_addr),
1417 					  IEEE802154_SECURITY_LEVEL_MIC_128, false);
1418 
1419 	zassert_true(ret, "Authenticated DGRAM packet received");
1420 }
1421 
ZTEST(ieee802154_l2_sockets,test_sending_encrypted_and_authenticated_dgram_pkt)1422 ZTEST(ieee802154_l2_sockets, test_sending_encrypted_and_authenticated_dgram_pkt)
1423 {
1424 	uint8_t dst_ext_addr[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1425 	bool ret;
1426 
1427 	ret = test_dgram_packet_sending(dst_ext_addr, sizeof(dst_ext_addr),
1428 					IEEE802154_SECURITY_LEVEL_ENC_MIC_128);
1429 
1430 	zassert_true(ret, "Encrypted and authenticated DGRAM packet sent");
1431 }
1432 
ZTEST(ieee802154_l2_sockets,test_receiving_encrypted_and_authenticated_dgram_pkt)1433 ZTEST(ieee802154_l2_sockets, test_receiving_encrypted_and_authenticated_dgram_pkt)
1434 {
1435 	uint8_t src_ext_addr[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1436 	bool ret;
1437 
1438 	ret = test_dgram_packet_reception(src_ext_addr, sizeof(src_ext_addr),
1439 					  IEEE802154_SECURITY_LEVEL_ENC_MIC_128, false);
1440 
1441 	zassert_true(ret, "Encrypted and authenticated DGRAM packet received");
1442 }
1443 
ZTEST(ieee802154_l2_sockets,test_sending_raw_pkt)1444 ZTEST(ieee802154_l2_sockets, test_sending_raw_pkt)
1445 {
1446 	bool ret;
1447 
1448 	ret = test_raw_packet_sending();
1449 
1450 	zassert_true(ret, "RAW packet sent");
1451 }
1452 
ZTEST(ieee802154_l2_sockets,test_receiving_raw_pkt)1453 ZTEST(ieee802154_l2_sockets, test_receiving_raw_pkt)
1454 {
1455 	bool ret;
1456 
1457 	ret = test_raw_packet_reception();
1458 
1459 	zassert_true(ret, "RAW packet received");
1460 }
1461 
1462 ZTEST_SUITE(ieee802154_l2_sockets, NULL, test_setup, NULL, NULL, test_teardown);
1463 #endif /* CONFIG_NET_SOCKETS */
1464