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 int net_icmp_call_ipv4_handlers(struct net_pkt *pkt,
66 struct net_ipv4_hdr *ipv4_hdr,
67 struct net_icmp_hdr *icmp_hdr);
68 extern int net_icmp_call_ipv6_handlers(struct net_pkt *pkt,
69 struct net_ipv6_hdr *ipv6_hdr,
70 struct net_icmp_hdr *icmp_hdr);
71
72 #if defined(CONFIG_NET_NATIVE) || defined(CONFIG_NET_OFFLOAD)
73 extern void net_context_init(void);
74 extern const char *net_context_state(struct net_context *context);
75 extern bool net_context_is_reuseaddr_set(struct net_context *context);
76 extern bool net_context_is_reuseport_set(struct net_context *context);
77 extern bool net_context_is_v6only_set(struct net_context *context);
78 extern bool net_context_is_recv_pktinfo_set(struct net_context *context);
79 extern void net_pkt_init(void);
80 extern void net_tc_tx_init(void);
81 extern void net_tc_rx_init(void);
82 #else
net_context_init(void)83 static inline void net_context_init(void) { }
net_pkt_init(void)84 static inline void net_pkt_init(void) { }
net_tc_tx_init(void)85 static inline void net_tc_tx_init(void) { }
net_tc_rx_init(void)86 static inline void net_tc_rx_init(void) { }
net_context_state(struct net_context * context)87 static inline const char *net_context_state(struct net_context *context)
88 {
89 ARG_UNUSED(context);
90 return NULL;
91 }
net_context_is_reuseaddr_set(struct net_context * context)92 static inline bool net_context_is_reuseaddr_set(struct net_context *context)
93 {
94 ARG_UNUSED(context);
95 return false;
96 }
net_context_is_reuseport_set(struct net_context * context)97 static inline bool net_context_is_reuseport_set(struct net_context *context)
98 {
99 ARG_UNUSED(context);
100 return false;
101 }
net_context_is_recv_pktinfo_set(struct net_context * context)102 static inline bool net_context_is_recv_pktinfo_set(struct net_context *context)
103 {
104 ARG_UNUSED(context);
105 return false;
106 }
107 #endif
108
109 #if defined(CONFIG_NET_NATIVE)
110 enum net_verdict net_ipv4_input(struct net_pkt *pkt, bool is_loopback);
111 enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback);
112 #else
net_ipv4_input(struct net_pkt * pkt,bool is_loopback)113 static inline enum net_verdict net_ipv4_input(struct net_pkt *pkt,
114 bool is_loopback)
115 {
116 ARG_UNUSED(pkt);
117 ARG_UNUSED(is_loopback);
118
119 return NET_CONTINUE;
120 }
121
net_ipv6_input(struct net_pkt * pkt,bool is_loopback)122 static inline enum net_verdict net_ipv6_input(struct net_pkt *pkt,
123 bool is_loopback)
124 {
125 ARG_UNUSED(pkt);
126 ARG_UNUSED(is_loopback);
127
128 return NET_CONTINUE;
129 }
130 #endif
131 extern bool net_tc_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt);
132 extern void net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
133 extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
134
135 char *net_sprint_addr(sa_family_t af, const void *addr);
136
137 #define net_sprint_ipv4_addr(_addr) net_sprint_addr(AF_INET, _addr)
138
139 #define net_sprint_ipv6_addr(_addr) net_sprint_addr(AF_INET6, _addr)
140
141 #if defined(CONFIG_COAP)
142 /**
143 * @brief CoAP init function declaration. It belongs here because we don't want
144 * to expose it as a public API -- it should only be called once, and only by
145 * net_core.
146 */
147 extern void net_coap_init(void);
148 #else
net_coap_init(void)149 static inline void net_coap_init(void)
150 {
151 return;
152 }
153 #endif
154
155 #if defined(CONFIG_NET_SOCKETS_OBJ_CORE)
156 struct sock_obj_type_raw_stats {
157 uint64_t sent;
158 uint64_t received;
159 };
160
161 struct sock_obj {
162 struct net_socket_register *reg;
163 uint64_t create_time; /* in ticks */
164 k_tid_t creator;
165 int fd;
166 int socket_family;
167 int socket_type;
168 int socket_proto;
169 bool init_done;
170 struct k_obj_core obj_core;
171 struct sock_obj_type_raw_stats stats;
172 };
173 #endif /* CONFIG_NET_SOCKETS_OBJ_CORE */
174
175 #if defined(CONFIG_NET_GPTP)
176 /**
177 * @brief Initialize Precision Time Protocol Layer.
178 */
179 void net_gptp_init(void);
180
181 /**
182 * @brief Process a ptp message.
183 *
184 * @param buf Buffer with a valid PTP Ethernet type.
185 *
186 * @return Return the policy for network buffer.
187 */
188 enum net_verdict net_gptp_recv(struct net_if *iface, struct net_pkt *pkt);
189 #else
190 #define net_gptp_init()
191 #define net_gptp_recv(iface, pkt) NET_DROP
192 #endif /* CONFIG_NET_GPTP */
193
194 #if defined(CONFIG_NET_IPV4_FRAGMENT)
195 int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
196 uint16_t pkt_len, uint16_t mtu);
197 #endif
198
199 #if defined(CONFIG_NET_IPV6_FRAGMENT)
200 int net_ipv6_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
201 uint16_t pkt_len);
202 #endif
203
204 extern const char *net_proto2str(int family, int proto);
205 extern char *net_byte_to_hex(char *ptr, uint8_t byte, char base, bool pad);
206 extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len,
207 char *buf, int buflen);
208 extern uint16_t calc_chksum(uint16_t sum_in, const uint8_t *data, size_t len);
209 extern uint16_t net_calc_chksum(struct net_pkt *pkt, uint8_t proto);
210
211 /**
212 * @brief Deliver the incoming packet through the recv_cb of the net_context
213 * to the upper layers
214 *
215 * @param conn Network connection
216 * @param pkt Network packet
217 * @param ip_hdr Pointer to IP header, optional
218 * @param proto_hdr Pointer to transport layer protocol header, optional
219 * @param user_data User data passed as an argument
220 *
221 * @return NET_OK if the packet is consumed through the recv_cb
222 * NET_DROP if the recv_cb isn't set
223 */
224 enum net_verdict net_context_packet_received(struct net_conn *conn,
225 struct net_pkt *pkt,
226 union net_ip_header *ip_hdr,
227 union net_proto_header *proto_hdr,
228 void *user_data);
229
230 #if defined(CONFIG_NET_IPV4)
231 extern uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt);
232 #endif /* CONFIG_NET_IPV4 */
233
234 #if defined(CONFIG_NET_IPV4_IGMP)
235 /**
236 * @brief Initialise the IGMP module for a given interface
237 *
238 * @param iface Interface to init IGMP
239 */
240 void net_ipv4_igmp_init(struct net_if *iface);
241 #endif /* CONFIG_NET_IPV4_IGMP */
242
243 #if defined(CONFIG_NET_IPV4_IGMP)
244 uint16_t net_calc_chksum_igmp(struct net_pkt *pkt);
245 enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
246 struct net_ipv4_hdr *ip_hdr);
247 #else
248 #define net_ipv4_igmp_input(...)
249 #define net_calc_chksum_igmp(pkt) 0U
250 #endif /* CONFIG_NET_IPV4_IGMP */
251
net_calc_chksum_icmpv6(struct net_pkt * pkt)252 static inline uint16_t net_calc_chksum_icmpv6(struct net_pkt *pkt)
253 {
254 return net_calc_chksum(pkt, IPPROTO_ICMPV6);
255 }
256
net_calc_chksum_icmpv4(struct net_pkt * pkt)257 static inline uint16_t net_calc_chksum_icmpv4(struct net_pkt *pkt)
258 {
259 return net_calc_chksum(pkt, IPPROTO_ICMP);
260 }
261
net_calc_chksum_udp(struct net_pkt * pkt)262 static inline uint16_t net_calc_chksum_udp(struct net_pkt *pkt)
263 {
264 uint16_t chksum = net_calc_chksum(pkt, IPPROTO_UDP);
265
266 return chksum == 0U ? 0xffff : chksum;
267 }
268
net_calc_verify_chksum_udp(struct net_pkt * pkt)269 static inline uint16_t net_calc_verify_chksum_udp(struct net_pkt *pkt)
270 {
271 return net_calc_chksum(pkt, IPPROTO_UDP);
272 }
273
net_calc_chksum_tcp(struct net_pkt * pkt)274 static inline uint16_t net_calc_chksum_tcp(struct net_pkt *pkt)
275 {
276 return net_calc_chksum(pkt, IPPROTO_TCP);
277 }
278
net_sprint_ll_addr(const uint8_t * ll,uint8_t ll_len)279 static inline char *net_sprint_ll_addr(const uint8_t *ll, uint8_t ll_len)
280 {
281 static char buf[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
282
283 return net_sprint_ll_addr_buf(ll, ll_len, (char *)buf, sizeof(buf));
284 }
285
net_hexdump(const char * str,const uint8_t * packet,size_t length)286 static inline void net_hexdump(const char *str,
287 const uint8_t *packet, size_t length)
288 {
289 if (!length) {
290 LOG_DBG("%s zero-length packet", str);
291 return;
292 }
293
294 LOG_HEXDUMP_DBG(packet, length, str);
295 }
296
297
298 /* Hexdump from all fragments */
net_pkt_hexdump(struct net_pkt * pkt,const char * str)299 static inline void net_pkt_hexdump(struct net_pkt *pkt, const char *str)
300 {
301 struct net_buf *buf = pkt->buffer;
302 char pkt_str[sizeof("0x") + sizeof(intptr_t) * 2];
303
304 if (str && str[0]) {
305 LOG_DBG("%s", str);
306 }
307
308 snprintk(pkt_str, sizeof(pkt_str), "%p", pkt);
309
310 while (buf) {
311 LOG_HEXDUMP_DBG(buf->data, buf->len, pkt_str);
312 buf = buf->frags;
313 }
314 }
315
net_pkt_print_buffer_info(struct net_pkt * pkt,const char * str)316 static inline void net_pkt_print_buffer_info(struct net_pkt *pkt, const char *str)
317 {
318 struct net_buf *buf = pkt->buffer;
319
320 if (str) {
321 printk("%s", str);
322 }
323
324 printk("%p[%ld]", pkt, atomic_get(&pkt->atomic_ref));
325
326 if (buf) {
327 printk("->");
328 }
329
330 while (buf) {
331 printk("%p[%ld/%u (%u/%u)]", buf, atomic_get(&pkt->atomic_ref),
332 buf->len, net_buf_max_len(buf), buf->size);
333
334 buf = buf->frags;
335 if (buf) {
336 printk("->");
337 }
338 }
339
340 printk("\n");
341 }
342