1 /** @file
2  @brief IPv4 related functions
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 #ifndef __IPV4_H
14 #define __IPV4_H
15 
16 #include <zephyr/types.h>
17 
18 #include <net/net_ip.h>
19 #include <net/net_pkt.h>
20 #include <net/net_if.h>
21 #include <net/net_context.h>
22 
23 #define NET_IPV4_IHL_MASK 0x0F
24 
25 /* IPv4 Options */
26 #define NET_IPV4_OPTS_EO   0   /* End of Options */
27 #define NET_IPV4_OPTS_NOP  1   /* No operation */
28 #define NET_IPV4_OPTS_RR   7   /* Record Route */
29 #define NET_IPV4_OPTS_TS   68  /* Timestamp */
30 #define NET_IPV4_OPTS_RA   148 /* Router Alert */
31 
32 /* IPv4 Options Timestamp flags */
33 #define NET_IPV4_TS_OPT_TS_ONLY	0 /* Timestamp only */
34 #define NET_IPV4_TS_OPT_TS_ADDR	1 /* Timestamp and address */
35 #define NET_IPV4_TS_OPT_TS_PRES	3 /* Timestamp prespecified hops*/
36 
37 #define NET_IPV4_HDR_OPTNS_MAX_LEN 40
38 
39 /* Fragment bits */
40 #define NET_IPV4_MF BIT(0) /* More fragments  */
41 #define NET_IPV4_DF BIT(1) /* Do not fragment */
42 
43 #define NET_IPV4_IGMP_QUERY     0x11 /* Membership query     */
44 #define NET_IPV4_IGMP_REPORT_V1 0x12 /* v1 Membership report */
45 #define NET_IPV4_IGMP_REPORT_V2 0x16 /* v2 Membership report */
46 #define NET_IPV4_IGMP_LEAVE     0x17 /* v2 Leave group       */
47 #define NET_IPV4_IGMP_REPORT_V3 0x22 /* v3 Membership report */
48 
49 struct net_ipv4_igmp_v2_query {
50 	uint8_t type;
51 	uint8_t max_rsp;
52 	uint16_t chksum;
53 	struct in_addr address;
54 } __packed;
55 
56 struct net_ipv4_igmp_v2_report {
57 	uint8_t type;
58 	uint8_t max_rsp;
59 	uint16_t chksum;
60 	struct in_addr address;
61 } __packed;
62 
63 /**
64  * @brief Create IPv4 packet in provided net_pkt with option to set all the
65  *        caller settable values.
66  *
67  * @param pkt Network packet
68  * @param src Source IPv4 address
69  * @param dst Destination IPv4 address
70  * @param tos Type of service
71  * @param id Fragment id
72  * @param flags Fragmentation flags
73  * @param offset Fragment offset
74  * @param ttl Time-to-live value
75  *
76  * @return 0 on success, negative errno otherwise.
77  */
78 #if defined(CONFIG_NET_NATIVE_IPV4)
79 int net_ipv4_create_full(struct net_pkt *pkt,
80 			 const struct in_addr *src,
81 			 const struct in_addr *dst,
82 			 uint8_t tos,
83 			 uint16_t id,
84 			 uint8_t flags,
85 			 uint16_t offset,
86 			 uint8_t ttl);
87 #else
net_ipv4_create_full(struct net_pkt * pkt,const struct in_addr * src,const struct in_addr * dst,uint8_t tos,uint16_t id,uint8_t flags,uint16_t offset,uint8_t ttl)88 static inline int net_ipv4_create_full(struct net_pkt *pkt,
89 				       const struct in_addr *src,
90 				       const struct in_addr *dst,
91 				       uint8_t tos,
92 				       uint16_t id,
93 				       uint8_t flags,
94 				       uint16_t offset,
95 				       uint8_t ttl)
96 {
97 	ARG_UNUSED(pkt);
98 	ARG_UNUSED(src);
99 	ARG_UNUSED(dst);
100 	ARG_UNUSED(tos);
101 	ARG_UNUSED(id);
102 	ARG_UNUSED(flags);
103 	ARG_UNUSED(offset);
104 	ARG_UNUSED(ttl);
105 
106 	return -ENOTSUP;
107 }
108 #endif
109 
110 /**
111  * @brief Create IPv4 packet in provided net_pkt.
112  *
113  * @param pkt Network packet
114  * @param src Source IPv4 address
115  * @param dst Destination IPv4 address
116  *
117  * @return 0 on success, negative errno otherwise.
118  */
119 #if defined(CONFIG_NET_NATIVE_IPV4)
120 int net_ipv4_create(struct net_pkt *pkt,
121 		    const struct in_addr *src,
122 		    const struct in_addr *dst);
123 #else
net_ipv4_create(struct net_pkt * pkt,const struct in_addr * src,const struct in_addr * dst)124 static inline int net_ipv4_create(struct net_pkt *pkt,
125 				  const struct in_addr *src,
126 				  const struct in_addr *dst)
127 {
128 	ARG_UNUSED(pkt);
129 	ARG_UNUSED(src);
130 	ARG_UNUSED(dst);
131 
132 	return -ENOTSUP;
133 }
134 #endif
135 
136 /**
137  * @brief Finalize IPv4 packet. It should be called right before
138  * sending the packet and after all the data has been added into
139  * the packet. This function will set the length of the
140  * packet and calculate the higher protocol checksum if needed.
141  *
142  * @param pkt Network packet
143  * @param next_header_proto Protocol type of the next header after IPv4 header.
144  *
145  * @return 0 on success, negative errno otherwise.
146  */
147 #if defined(CONFIG_NET_NATIVE_IPV4)
148 int net_ipv4_finalize(struct net_pkt *pkt, uint8_t next_header_proto);
149 #else
net_ipv4_finalize(struct net_pkt * pkt,uint8_t next_header_proto)150 static inline int net_ipv4_finalize(struct net_pkt *pkt,
151 				    uint8_t next_header_proto)
152 {
153 	ARG_UNUSED(pkt);
154 	ARG_UNUSED(next_header_proto);
155 
156 	return -ENOTSUP;
157 }
158 #endif
159 
160 /**
161  * @typedef net_ipv4_parse_hdr_options_cb_t
162  * @brief IPv4 header options handle callback
163  *
164  * @details The callback is called when parser encounter
165  * supported options.
166  *
167  * @param opt_type Option type
168  * @param opt_data Option data
169  * @param opt_len Option length
170  * @param user_data Userdata given in net_ipv4_parse_hdr_options()
171  *
172  * @return 0 on success, negative otherwise.
173  */
174 typedef int (*net_ipv4_parse_hdr_options_cb_t)(uint8_t opt_type,
175 					       uint8_t *opt_data,
176 					       uint8_t opt_len,
177 					       void *user_data);
178 
179 /**
180  * @brief Parse IPv4 header options.
181  * Parse the IPv4 header options and call the callback with
182  * options type, data and length along with user_data.
183  *
184  * @param pkt Network packet
185  * @param cb callback to handle IPv4 header options
186  * @param user_data User data
187  *
188  * @return 0 on success, negative otherwise.
189  */
190 #if defined(CONFIG_NET_IPV4_HDR_OPTIONS)
191 int net_ipv4_parse_hdr_options(struct net_pkt *pkt,
192 			       net_ipv4_parse_hdr_options_cb_t cb,
193 			       void *user_data);
194 #else
net_ipv4_parse_hdr_options(struct net_pkt * pkt,net_ipv4_parse_hdr_options_cb_t cb,void * user_data)195 static inline int net_ipv4_parse_hdr_options(struct net_pkt *pkt,
196 					     net_ipv4_parse_hdr_options_cb_t cb,
197 					     void *user_data)
198 {
199 	ARG_UNUSED(pkt);
200 	ARG_UNUSED(cb);
201 	ARG_UNUSED(user_data);
202 
203 	return -ENOTSUP;
204 }
205 #endif
206 
207 #endif /* __IPV4_H */
208