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