1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** Address Resolution Protocol (ARP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "nx_arp.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _nx_arp_hardware_address_find PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Yuxin Zhou, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function searches for the specified IP address in the ARP */
44 /* lists. If found, the associated hardware address is returned. */
45 /* */
46 /* INPUT */
47 /* */
48 /* ip_ptr IP instance pointer */
49 /* ip_address IP Address to search for */
50 /* physical_msw Physical address MSW pointer */
51 /* physical_lsw Physical address LSW pointer */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* status Completion status */
56 /* */
57 /* CALLS */
58 /* */
59 /* tx_mutex_get Obtain protection mutex */
60 /* tx_mutex_put Release protection mutex */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Application Code */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
71 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_nx_arp_hardware_address_find(NX_IP * ip_ptr,ULONG ip_address,ULONG * physical_msw,ULONG * physical_lsw)75 UINT _nx_arp_hardware_address_find(NX_IP *ip_ptr, ULONG ip_address,
76 ULONG *physical_msw, ULONG *physical_lsw)
77 {
78
79 #ifndef NX_DISABLE_IPV4
80 NX_ARP *arp_entry;
81 ULONG count;
82
83 #ifdef TX_ENABLE_EVENT_TRACE
84 TX_TRACE_BUFFER_ENTRY *trace_event;
85 ULONG trace_timestamp;
86 #endif
87
88
89 /* If trace is enabled, insert this event into the trace buffer. */
90 NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_HARDWARE_ADDRESS_FIND, ip_ptr, ip_address, 0, 0, NX_TRACE_ARP_EVENTS, &trace_event, &trace_timestamp);
91
92 /* Obtain protection on this IP instance for access into the ARP static
93 list. */
94 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
95
96 /* Search the static list for a matching IP and hardware mapping. */
97 arp_entry = ip_ptr -> nx_ip_arp_static_list;
98 while (arp_entry)
99 {
100
101 /* Determine if we have a match. */
102 if ((arp_entry -> nx_arp_ip_address == ip_address) &&
103 (arp_entry -> nx_arp_physical_address_msw | arp_entry -> nx_arp_physical_address_lsw))
104 {
105
106 /* Yes, we have found the ARP entry we are looking for. */
107 break;
108 }
109 else
110 {
111
112 /* Determine if we are at the end of the list. */
113 if (arp_entry -> nx_arp_pool_next == ip_ptr -> nx_ip_arp_static_list)
114 {
115
116 /* Set the arp_entry to NULL to signify nothing was found and get
117 out of the search loop. */
118 arp_entry = NX_NULL;
119 break;
120 }
121 else
122 {
123
124 /* Just move to the next ARP entry on the static list. */
125 arp_entry = arp_entry -> nx_arp_pool_next;
126 }
127 }
128 }
129
130 /* Determine if an entry has been found. If so, we are finished and it needs to be
131 returned to the caller. */
132 if (arp_entry)
133 {
134
135 /* Store the hardware address in the return fields. */
136 *physical_msw = arp_entry -> nx_arp_physical_address_msw;
137 *physical_lsw = arp_entry -> nx_arp_physical_address_lsw;
138
139 /* Update the trace event with the status. */
140 NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_HARDWARE_ADDRESS_FIND, 0, 0, *physical_msw, *physical_lsw);
141
142 /* Release the protection on the ARP list. */
143 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
144
145 /* Return status to the caller. */
146 return(NX_SUCCESS);
147 }
148
149 /* Otherwise, we need to search the ARP dynamic list for a match. */
150 arp_entry = ip_ptr -> nx_ip_arp_dynamic_list;
151 count = 1;
152 while (arp_entry)
153 {
154
155 /* Determine if we have a match. */
156 if ((arp_entry -> nx_arp_ip_address == ip_address) &&
157 (arp_entry -> nx_arp_physical_address_msw | arp_entry -> nx_arp_physical_address_lsw))
158 {
159
160 /* Yes, we have found the ARP entry we are looking for. */
161 break;
162 }
163 else
164 {
165
166 /* Determine if we are at the end of the list of active ARP entries. */
167 if (count >= ip_ptr -> nx_ip_arp_dynamic_active_count)
168 {
169
170 /* Set the arp_entry to NULL to signify nothing was found and get
171 out of the search loop. */
172 arp_entry = NX_NULL;
173 break;
174 }
175 else
176 {
177
178 /* Just move to the next ARP entry on the dynamic list. */
179 arp_entry = arp_entry -> nx_arp_pool_next;
180
181 /* Increment the active count. */
182 count++;
183 }
184 }
185 }
186
187 /* Determine if an entry has been found. If so, we are finished and it needs to be
188 returned to the caller. */
189 if (arp_entry)
190 {
191
192 /* Store the hardware address in the return fields. */
193 *physical_msw = arp_entry -> nx_arp_physical_address_msw;
194 *physical_lsw = arp_entry -> nx_arp_physical_address_lsw;
195
196 /* Update the trace event with the status. */
197 NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_HARDWARE_ADDRESS_FIND, 0, 0, *physical_msw, *physical_lsw);
198
199 /* Release the protection on the ARP list. */
200 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
201
202 /* Return status to the caller. */
203 return(NX_SUCCESS);
204 }
205 else
206 {
207
208 /* Release the protection on the ARP list. */
209 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
210
211 /* Return status to the caller. */
212 return(NX_ENTRY_NOT_FOUND);
213 }
214 #else /* NX_DISABLE_IPV4 */
215 NX_PARAMETER_NOT_USED(ip_ptr);
216 NX_PARAMETER_NOT_USED(ip_address);
217 NX_PARAMETER_NOT_USED(physical_msw);
218 NX_PARAMETER_NOT_USED(physical_lsw);
219
220 return(NX_NOT_SUPPORTED);
221 #endif /* !NX_DISABLE_IPV4 */
222 }
223
224