xref: /FreeRTOS-Plus-TCP-v4.0.0/source/include/FreeRTOS_ARP.h (revision df5aed9e58a72e2489b6c1936788885672c62981)
1 /*
2  * FreeRTOS+TCP <DEVELOPMENT BRANCH>
3  * Copyright (C) 2022 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * http://aws.amazon.com/freertos
25  * http://www.FreeRTOS.org
26  */
27 
28 #ifndef FREERTOS_ARP_H
29 #define FREERTOS_ARP_H
30 
31 /* Application level configuration options. */
32 #include "FreeRTOSIPConfig.h"
33 #include "FreeRTOSIPConfigDefaults.h"
34 #include "IPTraceMacroDefaults.h"
35 
36 #include "FreeRTOS_IP.h"
37 
38 /* *INDENT-OFF* */
39 #ifdef __cplusplus
40     extern "C" {
41 #endif
42 /* *INDENT-ON* */
43 
44 /*-----------------------------------------------------------*/
45 /* Miscellaneous structure and definitions. */
46 /*-----------------------------------------------------------*/
47 
48 /* A forward declaration of 'xNetworkInterface' which is
49  * declared in FreeRTOS_Routing.h */
50 struct xNetworkInterface;
51 struct xNetworkEndPoint;
52 
53 /**
54  * Structure for one row in the ARP cache table.
55  */
56 typedef struct xARP_CACHE_TABLE_ROW
57 {
58     uint32_t ulIPAddress;     /**< The IP address of an ARP cache entry. */
59     MACAddress_t xMACAddress; /**< The MAC address of an ARP cache entry. */
60     uint8_t ucAge;            /**< A value that is periodically decremented but can also be refreshed by active communication.  The ARP cache entry is removed if the value reaches zero. */
61     uint8_t ucValid;          /**< pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
62     struct xNetworkEndPoint
63     * pxEndPoint;             /**< The end-point on which the MAC address was last seen. */
64 } ARPCacheRow_t;
65 
66 typedef enum
67 {
68     eARPCacheMiss = 0, /* 0 An ARP table lookup did not find a valid entry. */
69     eARPCacheHit,      /* 1 An ARP table lookup found a valid entry. */
70     eCantSendPacket    /* 2 There is no IP address, or an ARP is still in progress, so the packet cannot be sent. */
71 } eARPLookupResult_t;
72 
73 /** @brief A structure used internally in FreeRTOS_ARP.c.
74  * It is used as a parameter for the function prvFindCacheEntry().*/
75 typedef struct xCacheLocation
76 {
77     BaseType_t xIpEntry;  /**< The index of the matching IP-address. */
78     BaseType_t xMacEntry; /**< The index of the matching MAC-address. */
79     BaseType_t xUseEntry; /**< The index of the first free location. */
80 } CacheLocation_t;
81 
82 /**
83  * Look for an IP-MAC couple in ARP cache and reset the 'age' field. If no match
84  * is found then no action will be taken.
85  */
86 void vARPRefreshCacheEntryAge( const MACAddress_t * pxMACAddress,
87                                const uint32_t ulIPAddress );
88 
89 /*
90  * If ulIPAddress is already in the ARP cache table then reset the age of the
91  * entry back to its maximum value.  If ulIPAddress is not already in the ARP
92  * cache table then add it - replacing the oldest current entry if there is not
93  * a free space available.
94  */
95 /*void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, */
96 /*                            const uint32_t ulIPAddress ); */
97 
98 void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
99                             const uint32_t ulIPAddress,
100                             struct xNetworkEndPoint * pxEndPoint );
101 
102 #if ( ipconfigARP_USE_CLASH_DETECTION != 0 )
103     /* Becomes non-zero if another device responded to a gratuitous ARP message. */
104     extern BaseType_t xARPHadIPClash;
105     /* MAC-address of the other device containing the same IP-address. */
106     extern MACAddress_t xARPClashMacAddress;
107 #endif /* ipconfigARP_USE_CLASH_DETECTION */
108 
109 #if ( ipconfigUSE_ARP_REMOVE_ENTRY != 0 )
110 
111 /*
112  * In some rare cases, it might be useful to remove a ARP cache entry of a
113  * known MAC address to make sure it gets refreshed.
114  */
115     uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress );
116 
117 #endif /* ipconfigUSE_ARP_REMOVE_ENTRY != 0 */
118 
119 
120 BaseType_t xIsIPInARPCache( uint32_t ulAddressToLookup );
121 
122 BaseType_t xCheckRequiresARPResolution( const NetworkBufferDescriptor_t * pxNetworkBuffer );
123 
124 /*
125  * Look for ulIPAddress in the ARP cache.  If the IP address exists, copy the
126  * associated MAC address into pxMACAddress, refresh the ARP cache entry's
127  * age, and return eARPCacheHit.  If the IP address does not exist in the ARP
128  * cache return eARPCacheMiss.  If the packet cannot be sent for any reason
129  * (maybe DHCP is still in process, or the addressing needs a gateway but there
130  * isn't a gateway defined) then return eCantSendPacket.
131  */
132 eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress,
133                                       MACAddress_t * const pxMACAddress,
134                                       struct xNetworkEndPoint ** ppxEndPoint );
135 
136 #if ( ipconfigUSE_ARP_REVERSED_LOOKUP != 0 )
137 
138 /* Lookup an IP-address if only the MAC-address is known */
139     eARPLookupResult_t eARPGetCacheEntryByMac( const MACAddress_t * const pxMACAddress,
140                                                uint32_t * pulIPAddress,
141                                                struct xNetworkInterface ** ppxInterface );
142 
143 #endif
144 
145 /*
146  * Reduce the age count in each entry within the ARP cache.  An entry is no
147  * longer considered valid and is deleted if its age reaches zero.
148  */
149 void vARPAgeCache( void );
150 
151 /*
152  * Send out an ARP request for the IP address contained in pxNetworkBuffer, and
153  * add an entry into the ARP table that indicates that an ARP reply is
154  * outstanding so re-transmissions can be generated.
155  */
156 void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
157 
158 /*
159  * After DHCP is ready and when changing IP address, force a quick send of our new IP
160  * address
161  */
162 void vARPSendGratuitous( void );
163 
164 /* This function will check if the target IP-address belongs to this device.
165  * If so, the packet will be passed to the IP-stack, who will answer it.
166  * The function is to be called within the function xNetworkInterfaceOutput()
167  * in NetworkInterface.c as follows:
168  *
169  *   if( xCheckLoopback( pxDescriptor, bReleaseAfterSend ) != 0 )
170  *   {
171  *      / * The packet has been sent back to the IP-task.
172  *        * The IP-task will further handle it.
173  *        * Do not release the descriptor.
174  *        * /
175  *       return pdTRUE;
176  *   }
177  *   / * Send the packet as usual. * /
178  */
179 BaseType_t xCheckLoopback( NetworkBufferDescriptor_t * const pxDescriptor,
180                            BaseType_t bReleaseAfterSend );
181 
182 void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress );
183 
184 /* Clear all entries in the ARp cache. */
185 void FreeRTOS_ClearARP( const struct xNetworkEndPoint * pxEndPoint );
186 
187 /* *INDENT-OFF* */
188 #ifdef __cplusplus
189     } /* extern "C" */
190 #endif
191 /* *INDENT-ON* */
192 
193 #endif /* FREERTOS_ARP_H */
194