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 const char *net_if_oper_state2str(enum net_if_oper_state state);
63 extern void net_process_rx_packet(struct net_pkt *pkt);
64 extern void net_process_tx_packet(struct net_pkt *pkt);
65
66 extern struct net_if_addr *net_if_ipv4_addr_get_first_by_index(int ifindex);
67
68 extern int net_icmp_call_ipv4_handlers(struct net_pkt *pkt,
69 struct net_ipv4_hdr *ipv4_hdr,
70 struct net_icmp_hdr *icmp_hdr);
71 extern int net_icmp_call_ipv6_handlers(struct net_pkt *pkt,
72 struct net_ipv6_hdr *ipv6_hdr,
73 struct net_icmp_hdr *icmp_hdr);
74
75 extern struct net_if *net_ipip_get_virtual_interface(struct net_if *input_iface);
76
77 #if defined(CONFIG_NET_STATISTICS_VIA_PROMETHEUS)
78 extern void net_stats_prometheus_init(struct net_if *iface);
79 #else
net_stats_prometheus_init(struct net_if * iface)80 static inline void net_stats_prometheus_init(struct net_if *iface)
81 {
82 ARG_UNUSED(iface);
83 }
84 #endif /* CONFIG_NET_STATISTICS_VIA_PROMETHEUS */
85
86 #if defined(CONFIG_NET_SOCKETS_SERVICE)
87 extern void socket_service_init(void);
88 #else
socket_service_init(void)89 static inline void socket_service_init(void) { }
90 #endif
91
92 #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD)
93 extern void net_context_init(void);
94 extern const char *net_context_state(struct net_context *context);
95 extern bool net_context_is_reuseaddr_set(struct net_context *context);
96 extern bool net_context_is_reuseport_set(struct net_context *context);
97 extern bool net_context_is_v6only_set(struct net_context *context);
98 extern bool net_context_is_recv_pktinfo_set(struct net_context *context);
99 extern bool net_context_is_timestamping_set(struct net_context *context);
100 extern void net_pkt_init(void);
101 int net_context_get_local_addr(struct net_context *context,
102 struct sockaddr *addr,
103 socklen_t *addrlen);
104 #else
net_context_init(void)105 static inline void net_context_init(void) { }
net_pkt_init(void)106 static inline void net_pkt_init(void) { }
net_context_state(struct net_context * context)107 static inline const char *net_context_state(struct net_context *context)
108 {
109 ARG_UNUSED(context);
110 return NULL;
111 }
net_context_is_reuseaddr_set(struct net_context * context)112 static inline bool net_context_is_reuseaddr_set(struct net_context *context)
113 {
114 ARG_UNUSED(context);
115 return false;
116 }
net_context_is_reuseport_set(struct net_context * context)117 static inline bool net_context_is_reuseport_set(struct net_context *context)
118 {
119 ARG_UNUSED(context);
120 return false;
121 }
net_context_is_recv_pktinfo_set(struct net_context * context)122 static inline bool net_context_is_recv_pktinfo_set(struct net_context *context)
123 {
124 ARG_UNUSED(context);
125 return false;
126 }
net_context_is_timestamping_set(struct net_context * context)127 static inline bool net_context_is_timestamping_set(struct net_context *context)
128 {
129 ARG_UNUSED(context);
130 return false;
131 }
132
net_context_get_local_addr(struct net_context * context,struct sockaddr * addr,socklen_t * addrlen)133 static inline int net_context_get_local_addr(struct net_context *context,
134 struct sockaddr *addr,
135 socklen_t *addrlen)
136 {
137 ARG_UNUSED(context);
138 ARG_UNUSED(addr);
139 ARG_UNUSED(addrlen);
140
141 return -ENOTSUP;
142 }
143 #endif
144
145 #if defined(CONFIG_DNS_SOCKET_DISPATCHER)
146 extern void dns_dispatcher_init(void);
147 #else
dns_dispatcher_init(void)148 static inline void dns_dispatcher_init(void) { }
149 #endif
150
151 #if defined(CONFIG_MDNS_RESPONDER)
152 extern void mdns_init_responder(void);
153 #else
mdns_init_responder(void)154 static inline void mdns_init_responder(void) { }
155 #endif /* CONFIG_MDNS_RESPONDER */
156
157 #if defined(CONFIG_DNS_RESOLVER)
158 #include <zephyr/net/dns_resolve.h>
159 extern int dns_resolve_name_internal(struct dns_resolve_context *ctx,
160 const char *query,
161 enum dns_query_type type,
162 uint16_t *dns_id,
163 dns_resolve_cb_t cb,
164 void *user_data,
165 int32_t timeout,
166 bool use_cache);
167 #include <zephyr/net/socket_service.h>
168 extern int dns_resolve_init_with_svc(struct dns_resolve_context *ctx,
169 const char *servers[],
170 const struct sockaddr *servers_sa[],
171 const struct net_socket_service_desc *svc,
172 uint16_t port, int interfaces[]);
173 #endif /* CONFIG_DNS_RESOLVER */
174
175 #if defined(CONFIG_NET_TEST)
176 extern void loopback_enable_address_swap(bool swap_addresses);
177 #endif /* CONFIG_NET_TEST */
178
179 #if defined(CONFIG_NET_NATIVE)
180 enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback);
181 enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback);
182 extern void net_tc_tx_init(void);
183 extern void net_tc_rx_init(void);
184 #else
net_ipv4_input(struct net_pkt * pkt,bool is_loopback)185 static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt,
186 bool is_loopback)
187 {
188 ARG_UNUSED(pkt);
189 ARG_UNUSED(is_loopback);
190
191 return NET_CONTINUE;
192 }
193
net_ipv6_input(struct net_pkt * pkt,bool is_loopback)194 static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt,
195 bool is_loopback)
196 {
197 ARG_UNUSED(pkt);
198 ARG_UNUSED(is_loopback);
199
200 return NET_CONTINUE;
201 }
202
net_tc_tx_init(void)203 static inline void net_tc_tx_init(void) { }
net_tc_rx_init(void)204 static inline void net_tc_rx_init(void) { }
205 #endif
206 enum net_verdict net_tc_try_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt,
207 k_timeout_t timeout);
208 extern enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
209 extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
210
211 char *net_sprint_addr(sa_family_t af, const void *addr);
212
213 #define net_sprint_ipv4_addr(_addr) net_sprint_addr(AF_INET, _addr)
214
215 #define net_sprint_ipv6_addr(_addr) net_sprint_addr(AF_INET6, _addr)
216
217 #if defined(CONFIG_COAP)
218 /**
219 * @brief CoAP init function declaration. It belongs here because we don't want
220 * to expose it as a public API -- it should only be called once, and only by
221 * net_core.
222 */
223 extern void net_coap_init(void);
224 #else
net_coap_init(void)225 static inline void net_coap_init(void)
226 {
227 return;
228 }
229 #endif
230
231 #if defined(CONFIG_NET_SOCKETS_OBJ_CORE)
232 struct sock_obj_type_raw_stats {
233 uint64_t sent;
234 uint64_t received;
235 };
236
237 struct sock_obj {
238 struct net_socket_register *reg;
239 uint64_t create_time; /* in ticks */
240 k_tid_t creator;
241 int fd;
242 int socket_family;
243 int socket_type;
244 int socket_proto;
245 bool init_done;
246 struct k_obj_core obj_core;
247 struct sock_obj_type_raw_stats stats;
248 };
249 #endif /* CONFIG_NET_SOCKETS_OBJ_CORE */
250
251 #if defined(CONFIG_NET_IPV6_PE)
252 /* This is needed by ipv6_pe.c when privacy extension support is enabled */
253 void net_if_ipv6_start_dad(struct net_if *iface,
254 struct net_if_addr *ifaddr);
255 #endif
256
257 #if defined(CONFIG_NET_GPTP)
258 /**
259 * @brief Initialize Precision Time Protocol Layer.
260 */
261 void net_gptp_init(void);
262 #else
263 #define net_gptp_init()
264 #endif /* CONFIG_NET_GPTP */
265
266 #if defined(CONFIG_NET_IPV4_FRAGMENT)
267 int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
268 uint16_t pkt_len, uint16_t mtu);
269 #endif
270
271 #if defined(CONFIG_NET_IPV6_FRAGMENT)
272 int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
273 uint16_t pkt_len, uint16_t mtu);
274 #endif
275
276 extern const char *net_verdict2str(enum net_verdict verdict);
277 extern const char *net_proto2str(int family, int proto);
278 extern char *net_byte_to_hex(char *ptr, uint8_t byte, char base, bool pad);
279 extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len,
280 char *buf, int buflen);
281 extern uint16_t calc_chksum(uint16_t sum_in, const uint8_t *data, size_t len);
282 extern uint16_t net_calc_chksum(struct net_pkt *pkt, uint8_t proto);
283
284 /**
285 * @brief Deliver the incoming packet through the recv_cb of the net_context
286 * to the upper layers
287 *
288 * @param conn Network connection
289 * @param pkt Network packet
290 * @param ip_hdr Pointer to IP header, optional
291 * @param proto_hdr Pointer to transport layer protocol header, optional
292 * @param user_data User data passed as an argument
293 *
294 * @return NET_OK if the packet is consumed through the recv_cb
295 * NET_DROP if the recv_cb isn't set
296 */
297 enum net_verdict net_context_packet_received(struct net_conn *conn,
298 struct net_pkt *pkt,
299 union net_ip_header *ip_hdr,
300 union net_proto_header *proto_hdr,
301 void *user_data);
302
303 #if defined(CONFIG_NET_IPV4)
304 extern uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt);
305 #endif /* CONFIG_NET_IPV4 */
306
307 #if defined(CONFIG_NET_IPV4_IGMP)
308 /**
309 * @brief Initialise the IGMP module for a given interface
310 *
311 * @param iface Interface to init IGMP
312 */
313 void net_ipv4_igmp_init(struct net_if *iface);
314 #endif /* CONFIG_NET_IPV4_IGMP */
315
316 #if defined(CONFIG_NET_IPV4_IGMP)
317 uint16_t net_calc_chksum_igmp(struct net_pkt *pkt);
318 enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
319 struct net_ipv4_hdr *ip_hdr);
320 #else
321 #define net_ipv4_igmp_input(...)
322 #define net_calc_chksum_igmp(pkt) 0U
323 #endif /* CONFIG_NET_IPV4_IGMP */
324
net_calc_chksum_icmpv6(struct net_pkt * pkt)325 static inline uint16_t net_calc_chksum_icmpv6(struct net_pkt *pkt)
326 {
327 return net_calc_chksum(pkt, IPPROTO_ICMPV6);
328 }
329
net_calc_chksum_icmpv4(struct net_pkt * pkt)330 static inline uint16_t net_calc_chksum_icmpv4(struct net_pkt *pkt)
331 {
332 return net_calc_chksum(pkt, IPPROTO_ICMP);
333 }
334
net_calc_chksum_udp(struct net_pkt * pkt)335 static inline uint16_t net_calc_chksum_udp(struct net_pkt *pkt)
336 {
337 uint16_t chksum = net_calc_chksum(pkt, IPPROTO_UDP);
338
339 return chksum == 0U ? 0xffff : chksum;
340 }
341
net_calc_verify_chksum_udp(struct net_pkt * pkt)342 static inline uint16_t net_calc_verify_chksum_udp(struct net_pkt *pkt)
343 {
344 return net_calc_chksum(pkt, IPPROTO_UDP);
345 }
346
net_calc_chksum_tcp(struct net_pkt * pkt)347 static inline uint16_t net_calc_chksum_tcp(struct net_pkt *pkt)
348 {
349 return net_calc_chksum(pkt, IPPROTO_TCP);
350 }
351
net_sprint_ll_addr(const uint8_t * ll,uint8_t ll_len)352 static inline char *net_sprint_ll_addr(const uint8_t *ll, uint8_t ll_len)
353 {
354 static char buf[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
355
356 return net_sprint_ll_addr_buf(ll, ll_len, (char *)buf, sizeof(buf));
357 }
358
net_hexdump(const char * str,const uint8_t * packet,size_t length)359 static inline void net_hexdump(const char *str,
360 const uint8_t *packet, size_t length)
361 {
362 if (!length) {
363 LOG_DBG("%s zero-length packet", str);
364 return;
365 }
366
367 LOG_HEXDUMP_DBG(packet, length, str);
368 }
369
370
371 /* Hexdump from all fragments */
net_pkt_hexdump(struct net_pkt * pkt,const char * str)372 static inline void net_pkt_hexdump(struct net_pkt *pkt, const char *str)
373 {
374 struct net_buf *buf = pkt->buffer;
375 char pkt_str[sizeof("0x") + sizeof(intptr_t) * 2];
376
377 if (str && str[0]) {
378 LOG_DBG("%s", str);
379 }
380
381 snprintk(pkt_str, sizeof(pkt_str), "%p", pkt);
382
383 while (buf) {
384 LOG_HEXDUMP_DBG(buf->data, buf->len, pkt_str);
385 buf = buf->frags;
386 }
387 }
388
net_pkt_print_buffer_info(struct net_pkt * pkt,const char * str)389 static inline void net_pkt_print_buffer_info(struct net_pkt *pkt, const char *str)
390 {
391 struct net_buf *buf = pkt->buffer;
392
393 if (str) {
394 printk("%s", str);
395 }
396
397 printk("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref));
398
399 if (buf) {
400 printk("->");
401 }
402
403 while (buf) {
404 printk("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref),
405 buf->len, net_buf_max_len(buf), buf->size);
406
407 buf = buf->frags;
408 if (buf) {
409 printk("->");
410 }
411 }
412
413 printk("\n");
414 }
415