1 /*
2  * FreeRTOS V202212.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26 
27 /* Standard includes. */
28 #include <stdio.h>
29 
30 /* FreeRTOS includes. */
31 #include "FreeRTOS.h"
32 #include "task.h"
33 
34 /* TCP/IP stack includes. */
35 #include "FreeRTOS_IP.h"
36 #include "FreeRTOS_Sockets.h"
37 
38 /* Function from freertos_hooks_winsim.c */
39 extern UBaseType_t uxRand( void );
40 /*-----------------------------------------------------------*/
41 
42 #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 )
43 
44 /* In case multiple interfaces are used, define them statically. */
45 
46 /* there is only 1 physical interface. */
47     static NetworkInterface_t xInterfaces[ 1 ];
48 
49 /* It will have several end-points. */
50     static NetworkEndPoint_t xEndPoints[ 4 ];
51 
52 #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */
53 
54 /*-----------------------------------------------------------*/
55 
56 extern UBaseType_t uxRand();
57 
58 /*-----------------------------------------------------------*/
59 
60 #if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
61 
pcApplicationHostnameHook(void)62     const char * pcApplicationHostnameHook( void )
63     {
64         /* Assign the name "FreeRTOS" to this network node.  This function will
65          * be called during the DHCP: the machine will be registered with an IP
66          * address plus this name. */
67         return "FreeRTOSWinSim";
68     }
69 
70 #endif
71 
72 /*-----------------------------------------------------------*/
73 
74 #if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )
75 
76     #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 )
xApplicationDNSQueryHook_Multi(struct xNetworkEndPoint * pxEndPoint,const char * pcName)77         BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint,
78                                                    const char * pcName )
79     #else
80         BaseType_t xApplicationDNSQueryHook( const char * pcName )
81     #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */
82     {
83         BaseType_t xReturn;
84 
85         /* Determine if a name lookup is for this node.  Two names are given
86          * to this node: that returned by pcApplicationHostnameHook() and that set
87          * by mainDEVICE_NICK_NAME. */
88         if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )
89         {
90             xReturn = pdPASS;
91         }
92         else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
93         {
94             xReturn = pdPASS;
95         }
96         else
97         {
98             xReturn = pdFAIL;
99         }
100 
101         return xReturn;
102     }
103 
104 #endif /* if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) */
105 
106 /*
107  * Set *pulNumber to a random number, and return pdTRUE. When the random number
108  * generator is broken, it shall return pdFALSE.
109  */
xApplicationGetRandomNumber(uint32_t * pulNumber)110 BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber )
111 {
112     *pulNumber = ( uint32_t ) uxRand();
113     return pdTRUE;
114 }
115 
116 /*-----------------------------------------------------------*/
117 
118 /*
119  * Callback that provides the inputs necessary to generate a randomized TCP
120  * Initial Sequence Number per RFC 6528.  THIS IS ONLY A DUMMY IMPLEMENTATION
121  * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION
122  * SYSTEMS.
123  */
ulApplicationGetNextSequenceNumber(uint32_t ulSourceAddress,uint16_t usSourcePort,uint32_t ulDestinationAddress,uint16_t usDestinationPort)124 uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
125                                              uint16_t usSourcePort,
126                                              uint32_t ulDestinationAddress,
127                                              uint16_t usDestinationPort )
128 {
129     ( void ) ulSourceAddress;
130     ( void ) usSourcePort;
131     ( void ) ulDestinationAddress;
132     ( void ) usDestinationPort;
133 
134     return ( uint32_t ) uxRand();
135 }
136 
137 /* Called by FreeRTOS+TCP when the network connects or disconnects.  Disconnect
138  * events are only received if implemented in the MAC driver. */
139 /* *INDENT-OFF* */
140 #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 )
vApplicationIPNetworkEventHook_Multi(eIPCallbackEvent_t eNetworkEvent,struct xNetworkEndPoint * pxEndPoint)141     void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent,
142                                                struct xNetworkEndPoint * pxEndPoint )
143 #else
144     void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
145 #endif
146 /* *INDENT-ON* */
147 {
148     uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
149     char cBuffer[ 16 ];
150     static BaseType_t xTasksAlreadyCreated = pdFALSE;
151 
152     /* If the network has just come up...*/
153     if( eNetworkEvent == eNetworkUp )
154     {
155         /* Print out the network configuration, which may have come from a DHCP
156          * server. */
157         #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 )
158             FreeRTOS_GetEndPointConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress, pxNetworkEndPoints );
159         #else
160             FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
161         #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */
162 
163         FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
164         FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );
165 
166         FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
167         FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );
168 
169         FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
170         FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );
171 
172         FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
173         FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );
174     }
175 }
176 
177 /*-----------------------------------------------------------*/
178 
vPlatformInitIpStack(void)179 void vPlatformInitIpStack( void )
180 {
181     BaseType_t xResult;
182     uint8_t ucIPAddress[ 4 ];
183     uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };
184     uint8_t ucMACAddress[ 6 ];
185     uint8_t ucDNSServerAddress[ 4 ];
186     uint8_t ucGatewayAddress[ 4 ];
187 
188     ucMACAddress[ 0 ] = configMAC_ADDR0;
189     ucMACAddress[ 1 ] = configMAC_ADDR1;
190     ucMACAddress[ 2 ] = configMAC_ADDR2;
191     ucMACAddress[ 3 ] = configMAC_ADDR3;
192     ucMACAddress[ 4 ] = configMAC_ADDR4;
193     ucMACAddress[ 5 ] = configMAC_ADDR5;
194 
195     ucIPAddress[ 0 ] = configIP_ADDR0;
196     ucIPAddress[ 1 ] = configIP_ADDR1;
197     ucIPAddress[ 2 ] = configIP_ADDR2;
198     ucIPAddress[ 3 ] = configIP_ADDR3;
199 
200     ucDNSServerAddress[ 0 ] = configDNS_SERVER_ADDR0;
201     ucDNSServerAddress[ 1 ] = configDNS_SERVER_ADDR1;
202     ucDNSServerAddress[ 2 ] = configDNS_SERVER_ADDR2;
203     ucDNSServerAddress[ 3 ] = configDNS_SERVER_ADDR3;
204 
205     ucGatewayAddress[ 0 ] = configGATEWAY_ADDR0;
206     ucGatewayAddress[ 1 ] = configGATEWAY_ADDR1;
207     ucGatewayAddress[ 2 ] = configGATEWAY_ADDR2;
208     ucGatewayAddress[ 3 ] = configGATEWAY_ADDR3;
209 
210     /* Initialise the network interface.*/
211     FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\r\n" ) );
212 
213     #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 )
214         /* Initialise the interface descriptor for WinPCap. */
215         #ifdef ipconfigUSE_LIBSLIRP
216             extern NetworkInterface_t * pxLibslirp_FillInterfaceDescriptor( BaseType_t xEMACIndex,
217                                                                             NetworkInterface_t * pxInterface );
218             pxLibslirp_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) );
219         #else
220             extern NetworkInterface_t * pxWinPcap_FillInterfaceDescriptor( BaseType_t xEMACIndex,
221                                                                            NetworkInterface_t * pxInterface );
222             pxWinPcap_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) );
223         #endif
224 
225         /* === End-point 0 === */
226         FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
227     #if ( ipconfigUSE_DHCP != 0 )
228         {
229             /* End-point 0 wants to use DHCPv4. */
230             xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE;
231         }
232         #endif /* ( ipconfigUSE_DHCP != 0 ) */
233 
234         xResult = FreeRTOS_IPInit_Multi();
235     #else /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */
236         /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */
237         xResult = FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
238     #endif /* defined( FREERTOS_PLUS_TCP_VERSION ) && ( FREERTOS_PLUS_TCP_VERSION >= 10 ) */
239 
240     configASSERT( xResult == pdTRUE );
241 }
242 
243 /*-----------------------------------------------------------*/
244 
xPlatformIsNetworkUp(void)245 BaseType_t xPlatformIsNetworkUp( void )
246 {
247     return FreeRTOS_IsNetworkUp();
248 }
249 
250 /*-----------------------------------------------------------*/
251 
252 #if ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_DHCP_HOOK != 0 ) )
253 
254     #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 )
xApplicationDHCPHook(eDHCPCallbackPhase_t eDHCPPhase,uint32_t ulIPAddress)255         eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
256                                                     uint32_t ulIPAddress )
257     #else /* ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) */
258         eDHCPCallbackAnswer_t xApplicationDHCPHook_Multi( eDHCPCallbackPhase_t eDHCPPhase,
259                                                           struct xNetworkEndPoint * pxEndPoint,
260                                                           IP_Address_t * pxIPAddress )
261     #endif /* ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) */
262     {
263         /* Provide a stub for this function. */
264         return eDHCPContinue;
265     }
266 
267 #endif /* if ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_DHCP_HOOK != 0 ) ) */
268 /*-----------------------------------------------------------*/
269