1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/linker/sections.h>
12 #include <zephyr/ztest.h>
13 #include <zephyr/random/random.h>
14 
15 #include <zephyr/posix/fcntl.h>
16 
17 #include <zephyr/net/ethernet.h>
18 #include <zephyr/net/dummy.h>
19 #include <zephyr/net/net_if.h>
20 #include <zephyr/net/socket.h>
21 
22 struct fake_dev_context {
23 	uint8_t mac_addr[sizeof(struct net_eth_addr)];
24 	struct net_if *iface;
25 };
26 
27 static const char testing_data[] = "Tappara";
28 
fake_dev_send(const struct device * dev,struct net_pkt * pkt)29 static int fake_dev_send(const struct device *dev, struct net_pkt *pkt)
30 {
31 	struct net_pkt *recv_pkt;
32 	int ret;
33 
34 	ARG_UNUSED(dev);
35 	ARG_UNUSED(pkt);
36 
37 	/* Loopback the data back to stack: */
38 	NET_DBG("Dummy device: Loopbacking data (%zd bytes) to iface %d\n", net_pkt_get_len(pkt),
39 	    net_if_get_by_iface(net_pkt_iface(pkt)));
40 
41 	recv_pkt = net_pkt_clone(pkt, K_NO_WAIT);
42 
43 	k_sleep(K_MSEC(10)); /* Let the receiver run */
44 
45 	ret = net_recv_data(net_pkt_iface(recv_pkt), recv_pkt);
46 	zassert_equal(ret, 0, "Cannot receive data (%d)", ret);
47 	return 0;
48 }
49 
fake_dev_get_mac(struct fake_dev_context * ctx)50 static uint8_t *fake_dev_get_mac(struct fake_dev_context *ctx)
51 {
52 	if (ctx->mac_addr[2] == 0x00) {
53 		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
54 		ctx->mac_addr[0] = 0x00;
55 		ctx->mac_addr[1] = 0x00;
56 		ctx->mac_addr[2] = 0x5E;
57 		ctx->mac_addr[3] = 0x00;
58 		ctx->mac_addr[4] = 0x53;
59 		ctx->mac_addr[5] = sys_rand8_get();
60 	}
61 
62 	return ctx->mac_addr;
63 }
64 
fake_dev_iface_init(struct net_if * iface)65 static void fake_dev_iface_init(struct net_if *iface)
66 {
67 	const struct device *dev = net_if_get_device(iface);
68 	struct fake_dev_context *ctx = dev->data;
69 	uint8_t *mac = fake_dev_get_mac(ctx);
70 
71 	net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET);
72 
73 	ctx->iface = iface;
74 }
75 
fake_dev_init(const struct device * dev)76 int fake_dev_init(const struct device *dev)
77 {
78 	ARG_UNUSED(dev);
79 
80 	return 0;
81 }
82 
83 struct fake_dev_context fake_dev_context_data;
84 
85 static struct dummy_api fake_dev_if_api = {
86 	.iface_api.init = fake_dev_iface_init,
87 	.send = fake_dev_send,
88 };
89 
90 #define _ETH_L2_LAYER DUMMY_L2
91 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
92 
93 NET_DEVICE_INIT(fake_dev, "fake_dev", fake_dev_init, NULL, &fake_dev_context_data, NULL,
94 		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &fake_dev_if_api, _ETH_L2_LAYER,
95 		_ETH_L2_CTX_TYPE, 127);
96 
test_setup(void)97 static void *test_setup(void)
98 {
99 	struct net_if *iface;
100 	struct in_addr in4addr_my = { { { 192, 168, 0, 2 } } };
101 	struct net_if_addr *ifaddr;
102 
103 	iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
104 	zassert_not_null(iface, "Could not get dummy iface");
105 
106 	net_if_up(iface);
107 
108 	ifaddr = net_if_ipv4_addr_add(iface, &in4addr_my, NET_ADDR_MANUAL, 0);
109 	zassert_not_null(ifaddr, "Could not add iface address");
110 
111 	return NULL;
112 }
113 
ZTEST(net_sckt_packet_raw_ip,test_sckt_raw_packet_raw_ip)114 ZTEST(net_sckt_packet_raw_ip, test_sckt_raw_packet_raw_ip)
115 {
116 	/* A test case for testing socket combo: AF_PACKET & SOCK_RAW & IPPROTO_RAW: */
117 	struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
118 	int recv_data_len, ret;
119 	struct sockaddr_ll dst = { 0 };
120 	char receive_buffer[128];
121 	int sock;
122 
123 	sock = zsock_socket(AF_PACKET, SOCK_RAW, htons(IPPROTO_RAW));
124 	zassert_true(sock >= 0, "Could not create a socket");
125 
126 	dst.sll_ifindex = net_if_get_by_iface(iface);
127 	dst.sll_family = AF_PACKET;
128 
129 	ret = zsock_bind(sock, (const struct sockaddr *)&dst, sizeof(struct sockaddr_ll));
130 	zassert_true(ret >= 0, "Could not bind the socket");
131 
132 	/* Let's send some data: */
133 	ret = zsock_sendto(sock, testing_data, ARRAY_SIZE(testing_data), 0,
134 			   (const struct sockaddr *)&dst, sizeof(struct sockaddr_ll));
135 	zassert_true(ret > 0, "Could not send data");
136 
137 	/* Receive the same data back: */
138 	recv_data_len = zsock_recv(sock, receive_buffer, sizeof(receive_buffer), 0);
139 	zassert_true(recv_data_len == ARRAY_SIZE(testing_data), "Expected data not received");
140 
141 	NET_DBG("Received successfully data %s", receive_buffer);
142 
143 	zsock_close(sock);
144 }
145 
146 ZTEST_SUITE(net_sckt_packet_raw_ip, NULL, test_setup, NULL, NULL, NULL);
147