77
88#include "kernel.h"
99
10+ /**
11+ * @brief ICMP packet types
12+ */
1013enum icmp_type_t {
14+ /** Echo reply */
1115 ICMP_ECHO_REPLY = 0 ,
16+
17+ /** Destination unreachable */
1218 ICMP_DESTINATION_UNREACHABLE = 3 ,
19+
20+ /** Source quench, deprecated */
1321 ICMP_SOURCE_QUENCH = 4 ,
22+
23+ /** Redirect */
1424 ICMP_REDIRECT = 5 ,
25+
26+ /** Echo request */
1527 ICMP_ECHO = 8 ,
28+
29+ /** Time exceeded */
1630 ICMP_TIME_EXCEEDED = 11 ,
31+
32+ /** Parameter problem */
1733 ICMP_PARAMETER_PROBLEM = 12 ,
34+
35+ /** Timestamp request */
1836 ICMP_TIMESTAMP = 13 ,
37+
38+ /** Timestamp reply */
1939 ICMP_TIMESTAMP_REPLY = 14 ,
40+
41+ /** Information request */
2042 ICMP_INFORMATION_REQUEST = 15 ,
43+
44+ /** Information reply */
2145 ICMP_INFORMATION_REPLY = 16 ,
2246};
2347
48+ /**
49+ * @brief ICMP destination unreachable reason codes
50+ */
2451enum icmp_unreachable_code_t {
52+ /** Destination network is unreachable */
2553 ICMP_NET_UNREACHABLE = 0 ,
54+
55+ /** Destination host is unreachable */
2656 ICMP_HOST_UNREACHABLE = 1 ,
57+
58+ /** Destination protocol is unreachable */
2759 ICMP_PROTOCOL_UNREACHABLE = 2 ,
60+
61+ /** Destination port is unreachable */
2862 ICMP_PORT_UNREACHABLE = 3 ,
63+
64+ /** Fragmentation is required but the IPv4 DF bit was set */
2965 ICMP_FRAGMENTATION_NEEDED = 4 ,
66+
67+ /** Source route failed */
3068 ICMP_SOURCE_ROUTE_FAILED = 5 ,
3169};
3270
71+ /**
72+ * @brief ICMP time exceeded reason codes
73+ */
3374enum icmp_time_exceeded_code_t {
75+ /** Packet TTL expired in transit */
3476 ICMP_TTL_EXCEEDED = 0 ,
77+
78+ /** Fragment reassembly timeout expired */
3579 ICMP_FRAGMENT_REASSEMBLY_TIME_EXCEEDED = 1 ,
3680};
3781
82+ /**
83+ * @brief ICMP redirect reason codes
84+ */
3885enum icmp_redirect_code_t {
86+ /** Redirect traffic for a network */
3987 ICMP_REDIRECT_NETWORK = 0 ,
88+
89+ /** Redirect traffic for a host */
4090 ICMP_REDIRECT_HOST = 1 ,
91+
92+ /** Redirect traffic for a TOS/network combination */
4193 ICMP_REDIRECT_TOS_NETWORK = 2 ,
94+
95+ /** Redirect traffic for a TOS/host combination */
4296 ICMP_REDIRECT_TOS_HOST = 3 ,
4397};
4498
99+ /**
100+ * @brief Generic ICMP packet carrying a quoted IPv4 datagram
101+ *
102+ * Used for destination unreachable and time exceeded messages. For
103+ * fragmentation-needed messages, unused carries the next-hop MTU in network
104+ * byte order.
105+ */
45106typedef struct icmp_packet {
107+ /** ICMP packet type */
46108 uint8_t type ;
109+
110+ /** ICMP type-specific code */
47111 uint8_t code ;
112+
113+ /** Internet checksum of the ICMP packet */
48114 uint16_t checksum ;
115+
116+ /** Type-specific auxiliary field */
49117 uint32_t unused ;
118+
119+ /** Quoted IPv4 datagram that triggered the ICMP message */
50120 ip_packet_t original_datagram ;
51121} __attribute__((packed )) icmp_packet_t ;
52122
123+ /**
124+ * @brief ICMP redirect packet
125+ */
53126typedef struct icmp_redirect_packet {
127+ /** ICMP packet type */
54128 uint8_t type ;
129+
130+ /** ICMP redirect reason code */
55131 uint8_t code ;
132+
133+ /** Internet checksum of the ICMP packet */
56134 uint16_t checksum ;
135+
136+ /** Replacement gateway IPv4 address */
57137 uint32_t gateway ;
138+
139+ /** Quoted IPv4 datagram that triggered the redirect */
58140 ip_packet_t original_datagram ;
59141} __attribute__((packed )) icmp_redirect_packet_t ;
60142
143+ /**
144+ * @brief ICMP information request/reply packet
145+ */
61146typedef struct icmp_information {
147+ /** ICMP packet type */
62148 uint8_t type ;
149+
150+ /** ICMP type-specific code */
63151 uint8_t code ;
152+
153+ /** Internet checksum of the ICMP packet */
64154 uint16_t checksum ;
155+
156+ /** Request identifier */
65157 uint16_t id ;
158+
159+ /** Request sequence number */
66160 uint16_t seq ;
67161} __attribute__((packed )) icmp_information_t ;
68162
163+ /**
164+ * @brief ICMP parameter problem packet
165+ */
69166typedef struct icmp_parameter_problem_packet {
167+ /** ICMP packet type */
70168 uint8_t type ;
169+
170+ /** ICMP parameter problem code */
71171 uint8_t code ;
172+
173+ /** Internet checksum of the ICMP packet */
72174 uint16_t checksum ;
175+
176+ /** Offset of invalid byte within the IPv4 header */
73177 uint8_t problem_ptr ;
178+
179+ /** Reserved field */
74180 uint16_t unused1 ;
181+
182+ /** Reserved field */
75183 uint16_t unused2 ;
184+
185+ /** Quoted IPv4 datagram containing the invalid header */
76186 ip_packet_t original_datagram ;
77187} __attribute__((packed )) icmp_parameter_problem_packet_t ;
78188
189+ /**
190+ * @brief ICMP echo request/reply packet
191+ */
79192typedef struct icmp_echo_packet {
193+ /** ICMP packet type */
80194 uint8_t type ;
195+
196+ /** ICMP type-specific code */
81197 uint8_t code ;
198+
199+ /** Internet checksum of the ICMP packet */
82200 uint16_t checksum ;
201+
202+ /** Echo identifier */
83203 uint16_t id ;
204+
205+ /** Echo sequence number */
84206 uint16_t seq ;
85207} __attribute__((packed )) icmp_echo_packet_t ;
86208
209+ /**
210+ * @brief ICMP timestamp request/reply packet
211+ */
87212typedef struct icmp_timestamp_packet {
213+ /** ICMP packet type */
88214 uint8_t type ;
215+
216+ /** ICMP type-specific code */
89217 uint8_t code ;
218+
219+ /** Internet checksum of the ICMP packet */
90220 uint16_t checksum ;
221+
222+ /** Request identifier */
91223 uint16_t id ;
224+
225+ /** Request sequence number */
92226 uint16_t seq ;
227+
228+ /** Sender originate timestamp */
93229 uint32_t originate_timestamp ;
230+
231+ /** Receiver receive timestamp */
94232 uint32_t receive_timestamp ;
233+
234+ /** Sender transmit timestamp */
95235 uint32_t transmit_timestamp ;
96236} __attribute__((packed )) icmp_timestamp_packet_t ;
97237
98238/**
99- * @brief Handle ICMP packet from the IP driver
100- *
101- * @param ip Encapsulating IP packet
102- * @param packet raw ICMP packet
103- * @param length ICMP packet length
239+ * @brief Callback for protocol handlers interested in ICMP unreachable messages
240+ *
241+ * The quoted IPv4 datagram identifies the protocol endpoint that triggered the
242+ * ICMP error. The MTU value is only meaningful for ICMP_FRAGMENTATION_NEEDED.
243+ *
244+ * @param quoted_ip Quoted IPv4 datagram from the ICMP payload
245+ * @param code ICMP unreachable reason code
246+ * @param mtu Path MTU for ICMP_FRAGMENTATION_NEEDED, otherwise zero
247+ */
248+ typedef void (* icmp_unreachable_handler_t )(ip_packet_t * , uint8_t , uint16_t );
249+
250+ /**
251+ * @brief Register a handler for ICMP unreachable notifications
252+ *
253+ * @param protocol IP protocol number to register for
254+ * @param handler Callback function
104255 */
105- void icmp_handle_packet ([[ maybe_unused ]] ip_packet_t * encap_packet , icmp_packet_t * packet , size_t len );
256+ void icmp_register_unreachable_handler ( uint8_t protocol , icmp_unreachable_handler_t handler );
106257
258+ /**
259+ * @brief Send an ICMP echo request
260+ *
261+ * @param destination Destination IPv4 address
262+ * @param id Echo identifier
263+ * @param seq Echo sequence number
264+ */
107265void icmp_send_echo (uint8_t * destination , uint16_t id , uint16_t seq );
108266
267+ /**
268+ * @brief Send an ICMP time exceeded packet
269+ *
270+ * @param original_ip Original IPv4 packet that triggered the error
271+ * @param code ICMP time exceeded reason code
272+ */
109273void icmp_send_time_exceeded (ip_packet_t * original_ip , uint8_t code );
110274
275+ /**
276+ * @brief Send an ICMP destination unreachable packet
277+ *
278+ * @param original_ip Original IPv4 packet that triggered the error
279+ * @param code ICMP unreachable reason code
280+ */
111281void icmp_send_destination_unreachable (ip_packet_t * original_ip , uint8_t code );
112282
283+ /**
284+ * @brief Send an ICMP parameter problem packet
285+ *
286+ * @param original_ip Original IPv4 packet that triggered the error
287+ * @param pointer_offset Offset of invalid byte within the IPv4 header
288+ */
113289void icmp_send_parameter_problem (ip_packet_t * original_ip , uint8_t pointer_offset );
114290
291+ /**
292+ * @brief Send an ICMP redirect packet
293+ *
294+ * @param original_ip Original IPv4 packet that triggered the redirect
295+ * @param code ICMP redirect reason code
296+ * @param new_gateway_ip Replacement gateway IPv4 address
297+ */
115298void icmp_send_redirect (ip_packet_t * original_ip , uint8_t code , uint32_t new_gateway_ip );
116299
300+ /**
301+ * @brief Send an ICMP fragmentation needed packet
302+ *
303+ * @param original_ip Original IPv4 packet that could not be forwarded
304+ * @param mtu Path MTU required for successful forwarding
305+ */
117306void icmp_send_fragmentation_needed (ip_packet_t * original_ip , uint16_t mtu );
307+
308+ /**
309+ * @brief Initialise the ICMP subsystem
310+ */
311+ void icmp_init ();
0 commit comments