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_ip_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 hardware address in the */
44 /* ARP lists. If found, the associated IP address is returned. */
45 /* */
46 /* INPUT */
47 /* */
48 /* ip_ptr IP instance pointer */
49 /* ip_address IP Address return pointer */
50 /* physical_msw Physical address MSW */
51 /* physical_lsw Physical address LSW */
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_ip_address_find(NX_IP * ip_ptr,ULONG * ip_address,ULONG physical_msw,ULONG physical_lsw)75 UINT _nx_arp_ip_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_IP_ADDRESS_FIND, ip_ptr, 0, physical_msw, physical_lsw, 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 matching hardware mapping. */
97 arp_entry = ip_ptr -> nx_ip_arp_static_list;
98 while (arp_entry)
99 {
100
101 /* Determine if we have a hardware address match. */
102 if ((arp_entry -> nx_arp_physical_address_msw == physical_msw) &&
103 (arp_entry -> nx_arp_physical_address_lsw == physical_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 IP address in the return field. */
136 *ip_address = arp_entry -> nx_arp_ip_address;
137
138 /* Update the trace event with the status. */
139 NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_IP_ADDRESS_FIND, 0, *ip_address, 0, 0);
140
141 /* Release the protection on the ARP list. */
142 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
143
144 /* Return status to the caller. */
145 return(NX_SUCCESS);
146 }
147
148 /* Otherwise, we need to search the ARP dynamic list for a match. */
149 arp_entry = ip_ptr -> nx_ip_arp_dynamic_list;
150 count = 1;
151 while (arp_entry)
152 {
153
154 /* Determine if we have a hardware address match. */
155 if ((arp_entry -> nx_arp_physical_address_msw == physical_msw) &&
156 (arp_entry -> nx_arp_physical_address_lsw == physical_lsw))
157 {
158
159 /* Yes, we have found the ARP entry we are looking for. */
160 break;
161 }
162 else
163 {
164
165 /* Determine if we are at the end of the list of active ARP entries. */
166 if (count >= ip_ptr -> nx_ip_arp_dynamic_active_count)
167 {
168
169 /* Set the arp_entry to NULL to signify nothing was found and get
170 out of the search loop. */
171 arp_entry = NX_NULL;
172 break;
173 }
174 else
175 {
176
177 /* Just move to the next ARP entry on the dynamic list. */
178 arp_entry = arp_entry -> nx_arp_pool_next;
179
180 /* Increment the active count. */
181 count++;
182 }
183 }
184 }
185
186 /* Determine if an entry has been found. If so, we are finished and it needs to be
187 returned to the caller. */
188 if (arp_entry)
189 {
190
191 /* Store the IP address in the return fields. */
192 *ip_address = arp_entry -> nx_arp_ip_address;
193
194 /* Update the trace event with the status. */
195 NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_IP_ADDRESS_FIND, 0, *ip_address, 0, 0);
196
197 /* Release the protection on the ARP list. */
198 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
199
200 /* Return status to the caller. */
201 return(NX_SUCCESS);
202 }
203 else
204 {
205
206 /* Release the protection on the ARP list. */
207 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
208
209 /* Return status to the caller. */
210 return(NX_ENTRY_NOT_FOUND);
211 }
212 #else /* NX_DISABLE_IPV4 */
213 NX_PARAMETER_NOT_USED(ip_ptr);
214 NX_PARAMETER_NOT_USED(ip_address);
215 NX_PARAMETER_NOT_USED(physical_msw);
216 NX_PARAMETER_NOT_USED(physical_lsw);
217
218 return(NX_NOT_SUPPORTED);
219 #endif /* !NX_DISABLE_IPV4 */
220 }
221
222