1 /** @file
2 @brief Network stack private header
3
4 This is not to be included by the application.
5 */
6
7 /*
8 * Copyright (c) 2016 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12
13 #include <errno.h>
14 #include <zephyr/sys/printk.h>
15 #include <zephyr/net/net_context.h>
16 #include <zephyr/net/net_pkt.h>
17 #include <zephyr/net/icmp.h>
18
19 #ifdef CONFIG_NET_MGMT_EVENT_INFO
20
21 #include <zephyr/net/net_event.h>
22
23 #ifdef CONFIG_NET_L2_WIFI_MGMT
24 /* For struct wifi_scan_result */
25 #include <zephyr/net/wifi_mgmt.h>
26 #endif /* CONFIG_NET_L2_WIFI_MGMT */
27
28 #define DEFAULT_NET_EVENT_INFO_SIZE 32
29 /* NOTE: Update this union with all *big* event info structs */
30 union net_mgmt_events {
31 #if defined(CONFIG_NET_DHCPV4)
32 struct net_if_dhcpv4 dhcpv4;
33 #endif /* CONFIG_NET_DHCPV4 */
34 #if defined(CONFIG_NET_DHCPV6)
35 struct net_if_dhcpv6 dhcpv6;
36 #endif /* CONFIG_NET_DHCPV6 */
37 #if defined(CONFIG_NET_L2_WIFI_MGMT)
38 union wifi_mgmt_events wifi;
39 #endif /* CONFIG_NET_L2_WIFI_MGMT */
40 #if defined(CONFIG_NET_IPV6)
41 struct net_event_ipv6_prefix ipv6_prefix;
42 #if defined(CONFIG_NET_IPV6_MLD)
43 struct net_event_ipv6_route ipv6_route;
44 #endif /* CONFIG_NET_IPV6_MLD */
45 #endif /* CONFIG_NET_IPV6 */
46 #if defined(CONFIG_NET_HOSTNAME_ENABLE)
47 struct net_event_l4_hostname hostname;
48 #endif /* CONFIG_NET_HOSTNAME_ENABLE */
49 char default_event[DEFAULT_NET_EVENT_INFO_SIZE];
50 };
51
52 #define NET_EVENT_INFO_MAX_SIZE sizeof(union net_mgmt_events)
53
54 #endif
55
56 #include "connection.h"
57
58 extern void net_if_init(void);
59 extern void net_if_post_init(void);
60 extern void net_if_stats_reset(struct net_if *iface);
61 extern void net_if_stats_reset_all(void);
62 extern void net_process_rx_packet(struct net_pkt *pkt);
63 extern void net_process_tx_packet(struct net_pkt *pkt);
64
65 extern struct net_if_addr *net_if_ipv4_addr_get_first_by_index(int ifindex);
66
67 extern int net_icmp_call_ipv4_handlers(struct net_pkt *pkt,
68 struct net_ipv4_hdr *ipv4_hdr,
69 struct net_icmp_hdr *icmp_hdr);
70 extern int net_icmp_call_ipv6_handlers(struct net_pkt *pkt,
71 struct net_ipv6_hdr *ipv6_hdr,
72 struct net_icmp_hdr *icmp_hdr);
73
74 extern struct net_if *net_ipip_get_virtual_interface(struct net_if *input_iface);
75
76 #if defined(CONFIG_NET_STATISTICS_VIA_PROMETHEUS)
77 extern void net_stats_prometheus_init(struct net_if *iface);
78 #else
net_stats_prometheus_init(struct net_if * iface)79 static inline void net_stats_prometheus_init(struct net_if *iface)
80 {
81 ARG_UNUSED(iface);
82 }
83 #endif /* CONFIG_NET_STATISTICS_VIA_PROMETHEUS */
84
85 #if defined(CONFIG_NET_SOCKETS_SERVICE)
86 extern void socket_service_init(void);
87 #else
socket_service_init(void)88 static inline void socket_service_init(void) { }
89 #endif
90
91 #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD)
92 extern void net_context_init(void);
93 extern const char *net_context_state(struct net_context *context);
94 extern bool net_context_is_reuseaddr_set(struct net_context *context);
95 extern bool net_context_is_reuseport_set(struct net_context *context);
96 extern bool net_context_is_v6only_set(struct net_context *context);
97 extern bool net_context_is_recv_pktinfo_set(struct net_context *context);
98 extern bool net_context_is_timestamping_set(struct net_context *context);
99 extern void net_pkt_init(void);
100 int net_context_get_local_addr(struct net_context *context,
101 struct sockaddr *addr,
102 socklen_t *addrlen);
103 #else
net_context_init(void)104 static inline void net_context_init(void) { }
net_pkt_init(void)105 static inline void net_pkt_init(void) { }
net_context_state(struct net_context * context)106 static inline const char *net_context_state(struct net_context *context)
107 {
108 ARG_UNUSED(context);
109 return NULL;
110 }
net_context_is_reuseaddr_set(struct net_context * context)111 static inline bool net_context_is_reuseaddr_set(struct net_context *context)
112 {
113 ARG_UNUSED(context);
114 return false;
115 }
net_context_is_reuseport_set(struct net_context * context)116 static inline bool net_context_is_reuseport_set(struct net_context *context)
117 {
118 ARG_UNUSED(context);
119 return false;
120 }
net_context_is_recv_pktinfo_set(struct net_context * context)121 static inline bool net_context_is_recv_pktinfo_set(struct net_context *context)
122 {
123 ARG_UNUSED(context);
124 return false;
125 }
net_context_is_timestamping_set(struct net_context * context)126 static inline bool net_context_is_timestamping_set(struct net_context *context)
127 {
128 ARG_UNUSED(context);
129 return false;
130 }
131
net_context_get_local_addr(struct net_context * context,struct sockaddr * addr,socklen_t * addrlen)132 static inline int net_context_get_local_addr(struct net_context *context,
133 struct sockaddr *addr,
134 socklen_t *addrlen)
135 {
136 ARG_UNUSED(context);
137 ARG_UNUSED(addr);
138 ARG_UNUSED(addrlen);
139
140 return -ENOTSUP;
141 }
142 #endif
143
144 #if defined(CONFIG_DNS_SOCKET_DISPATCHER)
145 extern void dns_dispatcher_init(void);
146 #else
dns_dispatcher_init(void)147 static inline void dns_dispatcher_init(void) { }
148 #endif
149
150 #if defined(CONFIG_MDNS_RESPONDER)
151 extern void mdns_init_responder(void);
152 #else
mdns_init_responder(void)153 static inline void mdns_init_responder(void) { }
154 #endif /* CONFIG_MDNS_RESPONDER */
155
156 #if defined(CONFIG_NET_TEST)
157 extern void loopback_enable_address_swap(bool swap_addresses);
158 #endif /* CONFIG_NET_TEST */
159
160 #if defined(CONFIG_NET_NATIVE)
161 enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback);
162 enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback);
163 extern void net_tc_tx_init(void);
164 extern void net_tc_rx_init(void);
165 #else
net_ipv4_input(struct net_pkt * pkt,bool is_loopback)166 static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt,
167 bool is_loopback)
168 {
169 ARG_UNUSED(pkt);
170 ARG_UNUSED(is_loopback);
171
172 return NET_CONTINUE;
173 }
174
net_ipv6_input(struct net_pkt * pkt,bool is_loopback)175 static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt,
176 bool is_loopback)
177 {
178 ARG_UNUSED(pkt);
179 ARG_UNUSED(is_loopback);
180
181 return NET_CONTINUE;
182 }
183
net_tc_tx_init(void)184 static inline void net_tc_tx_init(void) { }
net_tc_rx_init(void)185 static inline void net_tc_rx_init(void) { }
186 #endif
187 extern bool net_tc_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt);
188 extern void net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
189 extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
190
191 char *net_sprint_addr(sa_family_t af, const void *addr);
192
193 #define net_sprint_ipv4_addr(_addr) net_sprint_addr(AF_INET, _addr)
194
195 #define net_sprint_ipv6_addr(_addr) net_sprint_addr(AF_INET6, _addr)
196
197 #if defined(CONFIG_COAP)
198 /**
199 * @brief CoAP init function declaration. It belongs here because we don't want
200 * to expose it as a public API -- it should only be called once, and only by
201 * net_core.
202 */
203 extern void net_coap_init(void);
204 #else
net_coap_init(void)205 static inline void net_coap_init(void)
206 {
207 return;
208 }
209 #endif
210
211 #if defined(CONFIG_NET_SOCKETS_OBJ_CORE)
212 struct sock_obj_type_raw_stats {
213 uint64_t sent;
214 uint64_t received;
215 };
216
217 struct sock_obj {
218 struct net_socket_register *reg;
219 uint64_t create_time; /* in ticks */
220 k_tid_t creator;
221 int fd;
222 int socket_family;
223 int socket_type;
224 int socket_proto;
225 bool init_done;
226 struct k_obj_core obj_core;
227 struct sock_obj_type_raw_stats stats;
228 };
229 #endif /* CONFIG_NET_SOCKETS_OBJ_CORE */
230
231 #if defined(CONFIG_NET_IPV6_PE)
232 /* This is needed by ipv6_pe.c when privacy extension support is enabled */
233 void net_if_ipv6_start_dad(struct net_if *iface,
234 struct net_if_addr *ifaddr);
235 #endif
236
237 #if defined(CONFIG_NET_GPTP)
238 /**
239 * @brief Initialize Precision Time Protocol Layer.
240 */
241 void net_gptp_init(void);
242
243 /**
244 * @brief Process a ptp message.
245 *
246 * @param buf Buffer with a valid PTP Ethernet type.
247 *
248 * @return Return the policy for network buffer.
249 */
250 enum net_verdict net_gptp_recv(struct net_if *iface, struct net_pkt *pkt);
251 #else
252 #define net_gptp_init()
253 #define net_gptp_recv(iface, pkt) NET_DROP
254 #endif /* CONFIG_NET_GPTP */
255
256 #if defined(CONFIG_NET_IPV4_FRAGMENT)
257 int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
258 uint16_t pkt_len, uint16_t mtu);
259 #endif
260
261 #if defined(CONFIG_NET_IPV6_FRAGMENT)
262 int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
263 uint16_t pkt_len, uint16_t mtu);
264 #endif
265
266 extern const char *net_verdict2str(enum net_verdict verdict);
267 extern const char *net_proto2str(int family, int proto);
268 extern char *net_byte_to_hex(char *ptr, uint8_t byte, char base, bool pad);
269 extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len,
270 char *buf, int buflen);
271 extern uint16_t calc_chksum(uint16_t sum_in, const uint8_t *data, size_t len);
272 extern uint16_t net_calc_chksum(struct net_pkt *pkt, uint8_t proto);
273
274 /**
275 * @brief Deliver the incoming packet through the recv_cb of the net_context
276 * to the upper layers
277 *
278 * @param conn Network connection
279 * @param pkt Network packet
280 * @param ip_hdr Pointer to IP header, optional
281 * @param proto_hdr Pointer to transport layer protocol header, optional
282 * @param user_data User data passed as an argument
283 *
284 * @return NET_OK if the packet is consumed through the recv_cb
285 * NET_DROP if the recv_cb isn't set
286 */
287 enum net_verdict net_context_packet_received(struct net_conn *conn,
288 struct net_pkt *pkt,
289 union net_ip_header *ip_hdr,
290 union net_proto_header *proto_hdr,
291 void *user_data);
292
293 #if defined(CONFIG_NET_IPV4)
294 extern uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt);
295 #endif /* CONFIG_NET_IPV4 */
296
297 #if defined(CONFIG_NET_IPV4_IGMP)
298 /**
299 * @brief Initialise the IGMP module for a given interface
300 *
301 * @param iface Interface to init IGMP
302 */
303 void net_ipv4_igmp_init(struct net_if *iface);
304 #endif /* CONFIG_NET_IPV4_IGMP */
305
306 #if defined(CONFIG_NET_IPV4_IGMP)
307 uint16_t net_calc_chksum_igmp(struct net_pkt *pkt);
308 enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
309 struct net_ipv4_hdr *ip_hdr);
310 #else
311 #define net_ipv4_igmp_input(...)
312 #define net_calc_chksum_igmp(pkt) 0U
313 #endif /* CONFIG_NET_IPV4_IGMP */
314
net_calc_chksum_icmpv6(struct net_pkt * pkt)315 static inline uint16_t net_calc_chksum_icmpv6(struct net_pkt *pkt)
316 {
317 return net_calc_chksum(pkt, IPPROTO_ICMPV6);
318 }
319
net_calc_chksum_icmpv4(struct net_pkt * pkt)320 static inline uint16_t net_calc_chksum_icmpv4(struct net_pkt *pkt)
321 {
322 return net_calc_chksum(pkt, IPPROTO_ICMP);
323 }
324
net_calc_chksum_udp(struct net_pkt * pkt)325 static inline uint16_t net_calc_chksum_udp(struct net_pkt *pkt)
326 {
327 uint16_t chksum = net_calc_chksum(pkt, IPPROTO_UDP);
328
329 return chksum == 0U ? 0xffff : chksum;
330 }
331
net_calc_verify_chksum_udp(struct net_pkt * pkt)332 static inline uint16_t net_calc_verify_chksum_udp(struct net_pkt *pkt)
333 {
334 return net_calc_chksum(pkt, IPPROTO_UDP);
335 }
336
net_calc_chksum_tcp(struct net_pkt * pkt)337 static inline uint16_t net_calc_chksum_tcp(struct net_pkt *pkt)
338 {
339 return net_calc_chksum(pkt, IPPROTO_TCP);
340 }
341
net_sprint_ll_addr(const uint8_t * ll,uint8_t ll_len)342 static inline char *net_sprint_ll_addr(const uint8_t *ll, uint8_t ll_len)
343 {
344 static char buf[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
345
346 return net_sprint_ll_addr_buf(ll, ll_len, (char *)buf, sizeof(buf));
347 }
348
net_hexdump(const char * str,const uint8_t * packet,size_t length)349 static inline void net_hexdump(const char *str,
350 const uint8_t *packet, size_t length)
351 {
352 if (!length) {
353 LOG_DBG("%s zero-length packet", str);
354 return;
355 }
356
357 LOG_HEXDUMP_DBG(packet, length, str);
358 }
359
360
361 /* Hexdump from all fragments */
net_pkt_hexdump(struct net_pkt * pkt,const char * str)362 static inline void net_pkt_hexdump(struct net_pkt *pkt, const char *str)
363 {
364 struct net_buf *buf = pkt->buffer;
365 char pkt_str[sizeof("0x") + sizeof(intptr_t) * 2];
366
367 if (str && str[0]) {
368 LOG_DBG("%s", str);
369 }
370
371 snprintk(pkt_str, sizeof(pkt_str), "%p", pkt);
372
373 while (buf) {
374 LOG_HEXDUMP_DBG(buf->data, buf->len, pkt_str);
375 buf = buf->frags;
376 }
377 }
378
net_pkt_print_buffer_info(struct net_pkt * pkt,const char * str)379 static inline void net_pkt_print_buffer_info(struct net_pkt *pkt, const char *str)
380 {
381 struct net_buf *buf = pkt->buffer;
382
383 if (str) {
384 printk("%s", str);
385 }
386
387 printk("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref));
388
389 if (buf) {
390 printk("->");
391 }
392
393 while (buf) {
394 printk("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref),
395 buf->len, net_buf_max_len(buf), buf->size);
396
397 buf = buf->frags;
398 if (buf) {
399 printk("->");
400 }
401 }
402
403 printk("\n");
404 }
405