1 /*
2 * Copyright (c) 2019 Intel Corporation
3 * Copyright (c) 2021 Nordic Semiconductor
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <stdbool.h>
9 #ifdef CONFIG_ARCH_POSIX
10 #include <fcntl.h>
11 #else
12 #include <zephyr/posix/fcntl.h>
13 #endif
14
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(net_sock_packet, CONFIG_NET_SOCKETS_LOG_LEVEL);
17
18 #include <zephyr/kernel.h>
19 #include <zephyr/drivers/entropy.h>
20 #include <zephyr/sys/util.h>
21 #include <zephyr/net/net_context.h>
22 #include <zephyr/net/net_pkt.h>
23 #include <zephyr/net/socket.h>
24 #include <zephyr/net/ethernet.h>
25 #include <zephyr/syscall_handler.h>
26 #include <zephyr/sys/fdtable.h>
27
28 #include "../../ip/net_stats.h"
29
30 #include "sockets_internal.h"
31
32 extern const struct socket_op_vtable sock_fd_op_vtable;
33
34 static const struct socket_op_vtable packet_sock_fd_op_vtable;
35
k_fifo_wait_non_empty(struct k_fifo * fifo,k_timeout_t timeout)36 static inline int k_fifo_wait_non_empty(struct k_fifo *fifo,
37 k_timeout_t timeout)
38 {
39 struct k_poll_event events[] = {
40 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
41 K_POLL_MODE_NOTIFY_ONLY, fifo),
42 };
43
44 return k_poll(events, ARRAY_SIZE(events), timeout);
45 }
46
zpacket_socket(int family,int type,int proto)47 static int zpacket_socket(int family, int type, int proto)
48 {
49 struct net_context *ctx;
50 int fd;
51 int ret;
52
53 fd = z_reserve_fd();
54 if (fd < 0) {
55 return -1;
56 }
57
58 if (proto == 0) {
59 if (type == SOCK_RAW) {
60 proto = IPPROTO_RAW;
61 }
62 }
63
64 ret = net_context_get(family, type, proto, &ctx);
65 if (ret < 0) {
66 z_free_fd(fd);
67 errno = -ret;
68 return -1;
69 }
70
71 /* Initialize user_data, all other calls will preserve it */
72 ctx->user_data = NULL;
73
74 /* recv_q and accept_q are in union */
75 k_fifo_init(&ctx->recv_q);
76 z_finalize_fd(fd, ctx,
77 (const struct fd_op_vtable *)&packet_sock_fd_op_vtable);
78
79 return fd;
80 }
81
zpacket_received_cb(struct net_context * ctx,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,int status,void * user_data)82 static void zpacket_received_cb(struct net_context *ctx,
83 struct net_pkt *pkt,
84 union net_ip_header *ip_hdr,
85 union net_proto_header *proto_hdr,
86 int status,
87 void *user_data)
88 {
89 NET_DBG("ctx=%p, pkt=%p, st=%d, user_data=%p", ctx, pkt, status,
90 user_data);
91
92 /* if pkt is NULL, EOF */
93 if (!pkt) {
94 struct net_pkt *last_pkt = k_fifo_peek_tail(&ctx->recv_q);
95
96 if (!last_pkt) {
97 /* If there're no packets in the queue, recv() may
98 * be blocked waiting on it to become non-empty,
99 * so cancel that wait.
100 */
101 sock_set_eof(ctx);
102 k_fifo_cancel_wait(&ctx->recv_q);
103 NET_DBG("Marked socket %p as peer-closed", ctx);
104 } else {
105 net_pkt_set_eof(last_pkt, true);
106 NET_DBG("Set EOF flag on pkt %p", ctx);
107 }
108
109 return;
110 }
111
112 /* Normal packet */
113 net_pkt_set_eof(pkt, false);
114
115 k_fifo_put(&ctx->recv_q, pkt);
116 }
117
zpacket_bind_ctx(struct net_context * ctx,const struct sockaddr * addr,socklen_t addrlen)118 static int zpacket_bind_ctx(struct net_context *ctx,
119 const struct sockaddr *addr,
120 socklen_t addrlen)
121 {
122 int ret = 0;
123
124 ret = net_context_bind(ctx, addr, addrlen);
125 if (ret < 0) {
126 errno = -ret;
127 return -1;
128 }
129
130 /* For packet socket, we expect to receive packets after call
131 * to bind().
132 */
133 ret = net_context_recv(ctx, zpacket_received_cb, K_NO_WAIT,
134 ctx->user_data);
135 if (ret < 0) {
136 errno = -ret;
137 return -1;
138 }
139
140 return 0;
141 }
142
zpacket_set_eth_pkttype(struct net_if * iface,struct sockaddr_ll * addr,struct net_linkaddr * lladdr)143 static void zpacket_set_eth_pkttype(struct net_if *iface,
144 struct sockaddr_ll *addr,
145 struct net_linkaddr *lladdr)
146 {
147 if (net_eth_is_addr_broadcast((struct net_eth_addr *)lladdr->addr)) {
148 addr->sll_pkttype = PACKET_BROADCAST;
149 } else if (net_eth_is_addr_multicast(
150 (struct net_eth_addr *)lladdr->addr)) {
151 addr->sll_pkttype = PACKET_MULTICAST;
152 } else if (!net_linkaddr_cmp(net_if_get_link_addr(iface), lladdr)) {
153 addr->sll_pkttype = PACKET_HOST;
154 } else {
155 addr->sll_pkttype = PACKET_OTHERHOST;
156 }
157 }
158
zpacket_set_source_addr(struct net_context * ctx,struct net_pkt * pkt,struct sockaddr * src_addr,socklen_t * addrlen)159 static void zpacket_set_source_addr(struct net_context *ctx,
160 struct net_pkt *pkt,
161 struct sockaddr *src_addr,
162 socklen_t *addrlen)
163 {
164 struct sockaddr_ll addr = {0};
165 struct net_if *iface = net_context_get_iface(ctx);
166
167 if (iface == NULL) {
168 return;
169 }
170
171 addr.sll_family = AF_PACKET;
172 addr.sll_ifindex = net_if_get_by_iface(iface);
173
174 if (net_pkt_is_l2_processed(pkt)) {
175 /* L2 has already processed the packet - can copy information
176 * directly from the net_pkt structure
177 */
178 addr.sll_halen = pkt->lladdr_src.len;
179 memcpy(addr.sll_addr, pkt->lladdr_src.addr,
180 MIN(sizeof(addr.sll_addr), pkt->lladdr_src.len));
181
182 addr.sll_protocol = net_pkt_ll_proto_type(pkt);
183
184 if (net_if_get_link_addr(iface)->type == NET_LINK_ETHERNET) {
185 addr.sll_hatype = ARPHRD_ETHER;
186 zpacket_set_eth_pkttype(iface, &addr,
187 net_pkt_lladdr_dst(pkt));
188 }
189 } else if (net_if_get_link_addr(iface)->type == NET_LINK_ETHERNET) {
190 /* Need to extract information from the L2 header. Only
191 * Ethernet L2 supported currently.
192 */
193 struct net_eth_hdr *hdr;
194 struct net_linkaddr dst_addr;
195 struct net_pkt_cursor cur;
196
197 net_pkt_cursor_backup(pkt, &cur);
198 net_pkt_cursor_init(pkt);
199
200 hdr = NET_ETH_HDR(pkt);
201 if (hdr == NULL ||
202 pkt->buffer->len < sizeof(struct net_eth_hdr)) {
203 net_pkt_cursor_restore(pkt, &cur);
204 return;
205 }
206
207 addr.sll_halen = sizeof(struct net_eth_addr);
208 memcpy(addr.sll_addr, hdr->src.addr,
209 sizeof(struct net_eth_addr));
210
211 addr.sll_protocol = ntohs(hdr->type);
212 addr.sll_hatype = ARPHRD_ETHER;
213
214 dst_addr.addr = hdr->dst.addr;
215 dst_addr.len = sizeof(struct net_eth_addr);
216 dst_addr.type = NET_LINK_ETHERNET;
217
218 zpacket_set_eth_pkttype(iface, &addr, &dst_addr);
219 net_pkt_cursor_restore(pkt, &cur);
220 }
221
222 /* Copy the result sockaddr_ll structure into provided buffer. If the
223 * buffer is smaller than the structure size, it will be truncated.
224 */
225 memcpy(src_addr, &addr, MIN(sizeof(struct sockaddr_ll), *addrlen));
226 *addrlen = sizeof(struct sockaddr_ll);
227 }
228
zpacket_sendto_ctx(struct net_context * ctx,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)229 ssize_t zpacket_sendto_ctx(struct net_context *ctx, const void *buf, size_t len,
230 int flags, const struct sockaddr *dest_addr,
231 socklen_t addrlen)
232 {
233 k_timeout_t timeout = K_FOREVER;
234 int status;
235
236 if (!dest_addr) {
237 errno = EDESTADDRREQ;
238 return -1;
239 }
240
241 if ((flags & ZSOCK_MSG_DONTWAIT) || sock_is_nonblock(ctx)) {
242 timeout = K_NO_WAIT;
243 } else {
244 net_context_get_option(ctx, NET_OPT_SNDTIMEO, &timeout, NULL);
245 }
246
247 /* Register the callback before sending in order to receive the response
248 * from the peer.
249 */
250
251 status = net_context_recv(ctx, zpacket_received_cb, K_NO_WAIT,
252 ctx->user_data);
253 if (status < 0) {
254 errno = -status;
255 return -1;
256 }
257
258 status = net_context_sendto(ctx, buf, len, dest_addr, addrlen,
259 NULL, timeout, ctx->user_data);
260 if (status < 0) {
261 errno = -status;
262 return -1;
263 }
264
265 return status;
266 }
267
zpacket_sendmsg_ctx(struct net_context * ctx,const struct msghdr * msg,int flags)268 ssize_t zpacket_sendmsg_ctx(struct net_context *ctx, const struct msghdr *msg,
269 int flags)
270 {
271 k_timeout_t timeout = K_FOREVER;
272 int status;
273
274 if ((flags & ZSOCK_MSG_DONTWAIT) || sock_is_nonblock(ctx)) {
275 timeout = K_NO_WAIT;
276 } else {
277 net_context_get_option(ctx, NET_OPT_SNDTIMEO, &timeout, NULL);
278 }
279
280 status = net_context_sendmsg(ctx, msg, flags, NULL, timeout, NULL);
281 if (status < 0) {
282 errno = -status;
283 return -1;
284 }
285
286 return status;
287 }
288
zpacket_recvfrom_ctx(struct net_context * ctx,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)289 ssize_t zpacket_recvfrom_ctx(struct net_context *ctx, void *buf, size_t max_len,
290 int flags, struct sockaddr *src_addr,
291 socklen_t *addrlen)
292 {
293 size_t recv_len = 0;
294 k_timeout_t timeout = K_FOREVER;
295 struct net_pkt *pkt;
296
297 if ((flags & ZSOCK_MSG_DONTWAIT) || sock_is_nonblock(ctx)) {
298 timeout = K_NO_WAIT;
299 } else {
300 net_context_get_option(ctx, NET_OPT_RCVTIMEO, &timeout, NULL);
301 }
302
303 if (flags & ZSOCK_MSG_PEEK) {
304 int res;
305
306 res = k_fifo_wait_non_empty(&ctx->recv_q, timeout);
307 /* EAGAIN when timeout expired, EINTR when cancelled */
308 if (res && res != -EAGAIN && res != -EINTR) {
309 errno = -res;
310 return -1;
311 }
312
313 pkt = k_fifo_peek_head(&ctx->recv_q);
314 } else {
315 pkt = k_fifo_get(&ctx->recv_q, timeout);
316 }
317
318 if (!pkt) {
319 errno = EAGAIN;
320 return -1;
321 }
322
323 /* We do not handle any headers here,
324 * just pass the whole packet to caller.
325 */
326 recv_len = net_pkt_get_len(pkt);
327 if (recv_len > max_len) {
328 recv_len = max_len;
329 }
330
331 if (net_pkt_read(pkt, buf, recv_len)) {
332 errno = ENOBUFS;
333 return -1;
334 }
335
336 if (src_addr && addrlen) {
337 zpacket_set_source_addr(ctx, pkt, src_addr, addrlen);
338 }
339
340 if (IS_ENABLED(CONFIG_NET_PKT_RXTIME_STATS) &&
341 !(flags & ZSOCK_MSG_PEEK)) {
342 net_socket_update_tc_rx_time(pkt, k_cycle_get_32());
343 }
344
345 if (!(flags & ZSOCK_MSG_PEEK)) {
346 net_pkt_unref(pkt);
347 } else {
348 net_pkt_cursor_init(pkt);
349 }
350
351 return recv_len;
352 }
353
zpacket_getsockopt_ctx(struct net_context * ctx,int level,int optname,void * optval,socklen_t * optlen)354 int zpacket_getsockopt_ctx(struct net_context *ctx, int level, int optname,
355 void *optval, socklen_t *optlen)
356 {
357 if (!optval || !optlen) {
358 errno = EINVAL;
359 return -1;
360 }
361
362 return sock_fd_op_vtable.getsockopt(ctx, level, optname,
363 optval, optlen);
364 }
365
zpacket_setsockopt_ctx(struct net_context * ctx,int level,int optname,const void * optval,socklen_t optlen)366 int zpacket_setsockopt_ctx(struct net_context *ctx, int level, int optname,
367 const void *optval, socklen_t optlen)
368 {
369 return sock_fd_op_vtable.setsockopt(ctx, level, optname,
370 optval, optlen);
371 }
372
packet_sock_read_vmeth(void * obj,void * buffer,size_t count)373 static ssize_t packet_sock_read_vmeth(void *obj, void *buffer, size_t count)
374 {
375 return zpacket_recvfrom_ctx(obj, buffer, count, 0, NULL, 0);
376 }
377
packet_sock_write_vmeth(void * obj,const void * buffer,size_t count)378 static ssize_t packet_sock_write_vmeth(void *obj, const void *buffer,
379 size_t count)
380 {
381 return zpacket_sendto_ctx(obj, buffer, count, 0, NULL, 0);
382 }
383
packet_sock_ioctl_vmeth(void * obj,unsigned int request,va_list args)384 static int packet_sock_ioctl_vmeth(void *obj, unsigned int request,
385 va_list args)
386 {
387 return sock_fd_op_vtable.fd_vtable.ioctl(obj, request, args);
388 }
389
390 /*
391 * TODO: A packet socket can be bound to a network device using SO_BINDTODEVICE.
392 */
packet_sock_bind_vmeth(void * obj,const struct sockaddr * addr,socklen_t addrlen)393 static int packet_sock_bind_vmeth(void *obj, const struct sockaddr *addr,
394 socklen_t addrlen)
395 {
396 return zpacket_bind_ctx(obj, addr, addrlen);
397 }
398
399 /* The connect() function is no longer necessary. */
packet_sock_connect_vmeth(void * obj,const struct sockaddr * addr,socklen_t addrlen)400 static int packet_sock_connect_vmeth(void *obj, const struct sockaddr *addr,
401 socklen_t addrlen)
402 {
403 return -EOPNOTSUPP;
404 }
405
406 /*
407 * The listen() and accept() functions are without any functionality,
408 * since the client-Server-Semantic is no longer present.
409 * When we use packet sockets we are sending unconnected packets.
410 */
packet_sock_listen_vmeth(void * obj,int backlog)411 static int packet_sock_listen_vmeth(void *obj, int backlog)
412 {
413 return -EOPNOTSUPP;
414 }
415
packet_sock_accept_vmeth(void * obj,struct sockaddr * addr,socklen_t * addrlen)416 static int packet_sock_accept_vmeth(void *obj, struct sockaddr *addr,
417 socklen_t *addrlen)
418 {
419 return -EOPNOTSUPP;
420 }
421
packet_sock_sendto_vmeth(void * obj,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)422 static ssize_t packet_sock_sendto_vmeth(void *obj, const void *buf, size_t len,
423 int flags,
424 const struct sockaddr *dest_addr,
425 socklen_t addrlen)
426 {
427 return zpacket_sendto_ctx(obj, buf, len, flags, dest_addr, addrlen);
428 }
429
packet_sock_sendmsg_vmeth(void * obj,const struct msghdr * msg,int flags)430 static ssize_t packet_sock_sendmsg_vmeth(void *obj, const struct msghdr *msg,
431 int flags)
432 {
433 return zpacket_sendmsg_ctx(obj, msg, flags);
434 }
435
packet_sock_recvfrom_vmeth(void * obj,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)436 static ssize_t packet_sock_recvfrom_vmeth(void *obj, void *buf, size_t max_len,
437 int flags, struct sockaddr *src_addr,
438 socklen_t *addrlen)
439 {
440 return zpacket_recvfrom_ctx(obj, buf, max_len, flags,
441 src_addr, addrlen);
442 }
443
packet_sock_getsockopt_vmeth(void * obj,int level,int optname,void * optval,socklen_t * optlen)444 static int packet_sock_getsockopt_vmeth(void *obj, int level, int optname,
445 void *optval, socklen_t *optlen)
446 {
447 return zpacket_getsockopt_ctx(obj, level, optname, optval, optlen);
448 }
449
packet_sock_setsockopt_vmeth(void * obj,int level,int optname,const void * optval,socklen_t optlen)450 static int packet_sock_setsockopt_vmeth(void *obj, int level, int optname,
451 const void *optval, socklen_t optlen)
452 {
453 return zpacket_setsockopt_ctx(obj, level, optname, optval, optlen);
454 }
455
packet_sock_close_vmeth(void * obj)456 static int packet_sock_close_vmeth(void *obj)
457 {
458 return zsock_close_ctx(obj);
459 }
460
461 static const struct socket_op_vtable packet_sock_fd_op_vtable = {
462 .fd_vtable = {
463 .read = packet_sock_read_vmeth,
464 .write = packet_sock_write_vmeth,
465 .close = packet_sock_close_vmeth,
466 .ioctl = packet_sock_ioctl_vmeth,
467 },
468 .bind = packet_sock_bind_vmeth,
469 .connect = packet_sock_connect_vmeth,
470 .listen = packet_sock_listen_vmeth,
471 .accept = packet_sock_accept_vmeth,
472 .sendto = packet_sock_sendto_vmeth,
473 .sendmsg = packet_sock_sendmsg_vmeth,
474 .recvfrom = packet_sock_recvfrom_vmeth,
475 .getsockopt = packet_sock_getsockopt_vmeth,
476 .setsockopt = packet_sock_setsockopt_vmeth,
477 };
478
packet_is_supported(int family,int type,int proto)479 static bool packet_is_supported(int family, int type, int proto)
480 {
481 switch (type) {
482 case SOCK_RAW:
483 return proto == ETH_P_ALL
484 || proto == ETH_P_ECAT
485 || proto == ETH_P_IEEE802154
486 || proto == IPPROTO_RAW;
487
488 case SOCK_DGRAM:
489 return proto > 0;
490
491 default:
492 return false;
493 }
494 }
495
496 NET_SOCKET_REGISTER(af_packet, NET_SOCKET_DEFAULT_PRIO, AF_PACKET,
497 packet_is_supported, zpacket_socket);
498