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 #include "nx_ip.h"
30 #include "nx_packet.h"
31 
32 #ifndef NX_DISABLE_IPV4
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _nx_arp_queue_send                                  PORTABLE C      */
38 /*                                                           6.1          */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Yuxin Zhou, Microsoft Corporation                                   */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function sends packets from the ARP queue.                     */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    ip_ptr                                Pointer to IP instance        */
50 /*    arp_ptr                               Pointer to ARP entry          */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    None                                                                */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _nx_packet_transmit_release           Release ARP queued packet     */
59 /*    (nx_ip_fragment_processing)           Fragment processing           */
60 /*    (ip_interface_link_driver_entry)      User supplied link driver     */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    _nx_arp_static_entry_create           Create static entry           */
65 /*    _nx_arp_dynamic_entry_set             Set dynamic entry             */
66 /*    _nx_arp_packet_receive                Process the ARP packet        */
67 /*                                                                        */
68 /*  RELEASE HISTORY                                                       */
69 /*                                                                        */
70 /*    DATE              NAME                      DESCRIPTION             */
71 /*                                                                        */
72 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
73 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
74 /*                                            resulting in version 6.1    */
75 /*                                                                        */
76 /**************************************************************************/
_nx_arp_queue_send(NX_IP * ip_ptr,NX_ARP * arp_ptr)77 VOID  _nx_arp_queue_send(NX_IP *ip_ptr, NX_ARP *arp_ptr)
78 {
79 
80 TX_INTERRUPT_SAVE_AREA
81 NX_PACKET   *queued_list_head;
82 NX_PACKET   *packet_ptr;
83 NX_IP_DRIVER driver_request;
84 
85     /* Initialize the queued list head to NULL.  */
86     queued_list_head =  NX_NULL;
87 
88     /* Determine if this ARP entry has a packet queued up for sending.  */
89 
90     /* Disable interrupts before checking.  */
91     TX_DISABLE
92 
93     /* Look at the ARP packet queue pointer.  */
94     if (arp_ptr -> nx_arp_packets_waiting)
95     {
96 
97         /* Pickup the packet pointer and clear the ARP queue pointer.  */
98         queued_list_head =  arp_ptr -> nx_arp_packets_waiting;
99         arp_ptr -> nx_arp_packets_waiting =  NX_NULL;
100     }
101 
102     /* Restore previous interrupt posture.  */
103     TX_RESTORE
104 
105     /* Are there any packets queued to send?  */
106     while (queued_list_head)
107     {
108 
109         /* Pickup the first entry on the list.  */
110         packet_ptr =  queued_list_head;
111 
112         /* Move to the next entry on the ARP packet queue.  */
113         queued_list_head =  queued_list_head -> nx_packet_queue_next;
114 
115         /* Clear the packet's queue next pointer.  */
116         packet_ptr -> nx_packet_queue_next =  NX_NULL;
117 
118         packet_ptr -> nx_packet_address.nx_packet_interface_ptr = arp_ptr -> nx_arp_ip_interface;
119 
120         /* Build the driver request packet.  */
121         driver_request.nx_ip_driver_physical_address_msw =  arp_ptr -> nx_arp_physical_address_msw;
122         driver_request.nx_ip_driver_physical_address_lsw =  arp_ptr -> nx_arp_physical_address_lsw;
123         driver_request.nx_ip_driver_ptr                  =  ip_ptr;
124         driver_request.nx_ip_driver_command              =  NX_LINK_PACKET_SEND;
125         driver_request.nx_ip_driver_packet               =  packet_ptr;
126         driver_request.nx_ip_driver_interface            =  packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
127 
128         /* Determine if fragmentation is needed.  */
129         if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_mtu_size)
130         {
131 
132 #ifndef NX_DISABLE_FRAGMENTATION
133             /* Fragmentation is needed, call the fragment routine if available. */
134             if (ip_ptr -> nx_ip_fragment_processing)
135             {
136 
137                 /* Call the IP fragment processing routine.  */
138                 (ip_ptr -> nx_ip_fragment_processing)(&driver_request);
139             }
140             else
141             {
142 #endif /* NX_DISABLE_FRAGMENTATION */
143 
144 #ifndef NX_DISABLE_IP_INFO
145 
146                 /* Increment the IP send packets dropped count.  */
147                 ip_ptr -> nx_ip_send_packets_dropped++;
148 #endif
149 
150                 /* Just release the packet.  */
151                 _nx_packet_transmit_release(packet_ptr);
152 #ifndef NX_DISABLE_FRAGMENTATION
153             }
154 #endif /* NX_DISABLE_FRAGMENTATION */
155         }
156         else
157         {
158 
159 #ifndef NX_DISABLE_IP_INFO
160 
161             /* Increment the IP packet sent count.  */
162             ip_ptr -> nx_ip_total_packets_sent++;
163 
164             /* Increment the IP bytes sent count.  */
165             ip_ptr -> nx_ip_total_bytes_sent +=  packet_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV4_HEADER);
166 #endif
167 
168             /* If trace is enabled, insert this event into the trace buffer.  */
169             NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
170 
171             /* Send the queued IP packet out on the network via the attached driver.  */
172             (packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_link_driver_entry)(&driver_request);
173         }
174     }
175 }
176 #endif /* !NX_DISABLE_IPV4  */
177 
178