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 /**   Reverse Address Resolution Protocol (RARP)                          */
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_rarp.h"
30 #include "nx_packet.h"
31 
32 #ifndef NX_DISABLE_IPV4
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _nx_rarp_packet_send                                PORTABLE C      */
38 /*                                                           6.1          */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Yuxin Zhou, Microsoft Corporation                                   */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function builds an RARP packet and calls the associated driver */
46 /*    to send it out on the network.                                      */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    ip_ptr                                Pointer to IP instance        */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    None                                                                */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _nx_packet_allocate                   Allocate a packet for the     */
59 /*                                            RARP request                */
60 /*    (ip_link_driver)                      User supplied link driver     */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    NetX Source 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_rarp_packet_send(NX_IP * ip_ptr)75 VOID  _nx_rarp_packet_send(NX_IP *ip_ptr)
76 {
77 
78 NX_PACKET   *request_ptr;
79 ULONG       *message_ptr;
80 NX_IP_DRIVER driver_request;
81 ULONG        i;
82 
83 
84     /* Determine which interfaces to send RARP packets out from (e.g. do not have IP addresses). */
85     for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
86     {
87 
88         /* Skip this interface if it is not initialized yet. */
89         if (ip_ptr -> nx_ip_interface[i].nx_interface_valid == 0)
90         {
91             continue;
92         }
93 
94         /* If the interface has a valid address, skip it. */
95         if (ip_ptr -> nx_ip_interface[i].nx_interface_ip_address != 0)
96         {
97             continue;
98         }
99 
100 
101         /* Skip this interface if mapping is not required, i.e. the driver is not Ethernet-like. */
102         /*lint -e{539} suppress positive indentation.  */
103         if (ip_ptr -> nx_ip_interface[i].nx_interface_address_mapping_needed == 0)
104         {
105             continue;
106         }
107 
108         /* Allocate a packet to build the RARP message in.  */
109 #ifdef NX_ENABLE_DUAL_PACKET_POOL
110         /* Allocate from auxiliary packet pool first. */
111         if (_nx_packet_allocate(ip_ptr -> nx_ip_auxiliary_packet_pool, &request_ptr, (NX_PHYSICAL_HEADER + NX_RARP_MESSAGE_SIZE), NX_NO_WAIT))
112         {
113             if (ip_ptr -> nx_ip_auxiliary_packet_pool != ip_ptr -> nx_ip_default_packet_pool)
114 #endif /* NX_ENABLE_DUAL_PACKET_POOL */
115             {
116                 if (_nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &request_ptr, (NX_PHYSICAL_HEADER + NX_RARP_MESSAGE_SIZE), NX_NO_WAIT))
117                 {
118 
119                     /* Error getting packet, so just get out!  */
120                     return;
121                 }
122             }
123 #ifdef NX_ENABLE_DUAL_PACKET_POOL
124             else
125             {
126 
127                 /* Error getting packet, so just get out!  */
128                 return;
129             }
130         }
131 #endif /* NX_ENABLE_DUAL_PACKET_POOL */
132 
133         /* Add debug information. */
134         NX_PACKET_DEBUG(__FILE__, __LINE__, request_ptr);
135 
136 #ifndef NX_DISABLE_RARP_INFO
137         /* Increment the RARP requests sent count.  */
138         ip_ptr -> nx_ip_rarp_requests_sent++;
139 #endif
140         /*lint -e{644} suppress variable might not be initialized, since "request_ptr" was initialized in _nx_packet_allocate. */
141         request_ptr -> nx_packet_address.nx_packet_interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
142         /* Build the RARP request packet.  */
143 
144         /* Setup the size of the RARP message.  */
145         request_ptr -> nx_packet_length =  NX_RARP_MESSAGE_SIZE;
146 
147         /* Setup the prepend pointer.  */
148         request_ptr -> nx_packet_prepend_ptr -= NX_RARP_MESSAGE_SIZE;
149 
150         /* Setup the pointer to the message area.  */
151         /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
152         message_ptr =  (ULONG *)request_ptr -> nx_packet_prepend_ptr;
153 
154         /* Write the Hardware type into the message.  */
155         *message_ptr =        (ULONG)(NX_RARP_HARDWARE_TYPE << 16) | (NX_RARP_PROTOCOL_TYPE);
156         *(message_ptr + 1) =  (ULONG)(NX_RARP_HARDWARE_SIZE << 24) | (NX_RARP_PROTOCOL_SIZE << 16) | NX_RARP_OPTION_REQUEST;
157         *(message_ptr + 2) =  (ULONG)(request_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_physical_address_msw << 16) |
158                                      (request_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_physical_address_lsw >> 16);
159         *(message_ptr + 3) =  (ULONG)(request_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_physical_address_lsw << 16);
160         *(message_ptr + 4) =  (ULONG)(request_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_physical_address_msw & NX_LOWER_16_MASK);
161         *(message_ptr + 5) =  (ULONG)(request_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_physical_address_lsw);
162         *(message_ptr + 6) =  (ULONG)0;
163 
164         /* If trace is enabled, insert this event into the trace buffer.  */
165         NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_RARP_SEND, ip_ptr, 0, request_ptr, *(message_ptr + 1), NX_TRACE_INTERNAL_EVENTS, 0, 0);
166 
167         /* Endian swapping logic.  If NX_LITTLE_ENDIAN is specified, these macros will
168            swap the endian of the RARP message.  */
169         NX_CHANGE_ULONG_ENDIAN(*(message_ptr));
170         NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 1));
171         NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2));
172         NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3));
173         NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 4));
174         NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 5));
175         NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 6));
176 
177         /* Send the RARP request to the driver.  */
178         driver_request.nx_ip_driver_ptr =                   ip_ptr;
179         driver_request.nx_ip_driver_command =               NX_LINK_RARP_SEND;
180         driver_request.nx_ip_driver_packet =                request_ptr;
181         driver_request.nx_ip_driver_physical_address_msw =  0xFFFFUL;
182         driver_request.nx_ip_driver_physical_address_lsw =  0xFFFFFFFFUL;
183         driver_request.nx_ip_driver_interface =             request_ptr -> nx_packet_address.nx_packet_interface_ptr;
184 
185         /* If trace is enabled, insert this event into the trace buffer.  */
186         NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_RARP_SEND, ip_ptr, request_ptr, request_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
187 
188         (request_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_link_driver_entry)(&driver_request);
189     }
190 
191     return;
192 }
193 #endif /* !NX_DISABLE_IPV4  */
194 
195