1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Component */
17 /** */
18 /** Internet Control Message Protocol (ICMP) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "nx_api.h"
29 #include "nx_ip.h"
30 #include "nx_icmp.h"
31 #include "nx_packet.h"
32 #include "tx_thread.h"
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _nx_icmp_packet_receive PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* Yuxin Zhou, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function receives an ICMP packet from the IP receive */
47 /* processing. If this routine is called from an ISR, it simply */
48 /* places the new message on the ICMP message queue, and wakes up the */
49 /* IP processing thread. If this routine is called from the IP helper */
50 /* thread, then the ICMP message is processed directly. */
51 /* */
52 /* INPUT */
53 /* */
54 /* ip_ptr Pointer to IP control block */
55 /* packet_ptr Pointer to packet to send */
56 /* */
57 /* OUTPUT */
58 /* */
59 /* None */
60 /* */
61 /* CALLS */
62 /* */
63 /* _nx_icmp_packet_process Process ICMP packet */
64 /* tx_event_flags_set Set event flags for IP helper */
65 /* thread */
66 /* */
67 /* CALLED BY */
68 /* */
69 /* _nx_ip_packet_receive Dispatch received IP packets */
70 /* */
71 /* RELEASE HISTORY */
72 /* */
73 /* DATE NAME DESCRIPTION */
74 /* */
75 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
76 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
77 /* resulting in version 6.1 */
78 /* */
79 /**************************************************************************/
_nx_icmp_packet_receive(NX_IP * ip_ptr,NX_PACKET * packet_ptr)80 VOID _nx_icmp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
81 {
82 #ifndef NX_DISABLE_IPV4
83
84 TX_INTERRUPT_SAVE_AREA
85
86 #ifdef NX_ENABLE_ICMP_ADDRESS_CHECK
87 NX_IPV4_HEADER *ip_header_ptr;
88 NX_INTERFACE *interface_ptr;
89 #endif /* NX_ENABLE_ICMP_ADDRESS_CHECK */
90
91
92 /* Add debug information. */
93 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
94
95 #ifndef NX_DISABLE_ICMP_INFO
96
97 /* Increment the ICMP total messages received counter. */
98 ip_ptr -> nx_ip_icmp_total_messages_received++;
99 #endif
100
101 #ifndef NX_DISABLE_RX_SIZE_CHECKING
102
103 /* Check for valid packet length. */
104 if (packet_ptr -> nx_packet_length < sizeof(NX_ICMP_HEADER))
105 {
106
107 #ifndef NX_DISABLE_ICMP_INFO
108
109 /* Increment the ICMP invalid packet error. */
110 ip_ptr -> nx_ip_icmp_invalid_packets++;
111 #endif
112
113 /* Invalid packet length, just release it. */
114 _nx_packet_release(packet_ptr);
115
116 /* The function is complete, just return! */
117 return;
118 }
119 #endif
120
121 #ifdef NX_ENABLE_ICMP_ADDRESS_CHECK
122
123 /* An ICMP Echo Request destined to an IP broadcast or IP multicast address
124 MAY be silently discarded.
125 RFC 1122, Section 3.2.2.6, Page42. */
126
127 /* Pickup the IP header and interface. */
128 ip_header_ptr = (NX_IPV4_HEADER *)(packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IPV4_HEADER));
129 interface_ptr = packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
130
131 if (
132 /* Check for Multicast address */
133 ((ip_header_ptr -> nx_ip_header_destination_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE) ||
134 /* Check for subnet-directed broadcast */
135 (((ip_header_ptr -> nx_ip_header_destination_ip & interface_ptr -> nx_interface_ip_network_mask) == interface_ptr -> nx_interface_ip_network) &&
136 ((ip_header_ptr -> nx_ip_header_destination_ip & ~(interface_ptr -> nx_interface_ip_network_mask)) == ~(interface_ptr -> nx_interface_ip_network_mask))) ||
137 /* Check for local subnet address */
138 (ip_header_ptr -> nx_ip_header_destination_ip == interface_ptr -> nx_interface_ip_network) ||
139 /* Check for limited broadcast */
140 (ip_header_ptr -> nx_ip_header_destination_ip == NX_IP_LIMITED_BROADCAST)
141 )
142 {
143
144 #ifndef NX_DISABLE_ICMP_INFO
145
146 /* Increment the ICMP invalid packet error. */
147 ip_ptr -> nx_ip_icmp_invalid_packets++;
148 #endif
149
150 /* Invalid packet length, just release it. */
151 _nx_packet_release(packet_ptr);
152
153 /* The function is complete, just return! */
154 return;
155 }
156 #endif /* NX_ENABLE_ICMP_ADDRESS_CHECK */
157
158 /* Determine if this routine is being called from an ISR. */
159 if ((TX_THREAD_GET_SYSTEM_STATE()) || (&(ip_ptr -> nx_ip_thread) != _tx_thread_current_ptr))
160 {
161
162 /* If system state is non-zero, we are in an ISR. If the current thread is not the IP thread,
163 we need to prevent unnecessary recursion in loopback. Just place the message at the
164 end of the ICMP message queue and wakeup the IP helper thread. */
165
166 /* Disable interrupts. */
167 TX_DISABLE
168
169 /* Add the packet to the ICMP message queue. */
170 if (ip_ptr -> nx_ip_icmp_queue_head)
171 {
172
173 /* Link the current packet to the list head. */
174 packet_ptr -> nx_packet_queue_next = ip_ptr -> nx_ip_icmp_queue_head;
175 }
176 else
177 {
178
179 /* Empty queue, add to the head of the ICMP message queue. */
180 packet_ptr -> nx_packet_queue_next = NX_NULL;
181 }
182
183 /* Update the queue head pointer. */
184 ip_ptr -> nx_ip_icmp_queue_head = packet_ptr;
185
186 /* Restore interrupts. */
187 TX_RESTORE
188
189 /* Wakeup IP thread for processing one or more messages in the ICMP queue. */
190 tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_ICMP_EVENT, TX_OR);
191 }
192 else
193 {
194
195 /* The IP message was deferred, so this routine is called from the IP helper
196 thread and thus may call the ICMP processing directly. */
197 _nx_icmp_packet_process(ip_ptr, packet_ptr);
198 }
199 #else
200 NX_PARAMETER_NOT_USED(ip_ptr);
201 NX_PARAMETER_NOT_USED(packet_ptr);
202 #endif /* NX_DISABLE_IPV4 */
203 }
204
205