+++ /dev/null
-/*\r
- * FreeRTOS Kernel V10.2.1\r
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
- * this software and associated documentation files (the "Software"), to deal in\r
- * the Software without restriction, including without limitation the rights to\r
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
- * the Software, and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be included in all\r
- * copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- * http://www.FreeRTOS.org\r
- * http://aws.amazon.com/freertos\r
- *\r
- * 1 tab == 4 spaces!\r
- */\r
-\r
-/* WinPCap includes. */\r
-#include "pcap.h"\r
-#include "remote-ext.h"\r
-\r
-/* uIP includes. */\r
-#include "net/uip.h"\r
-#include "net/uip_arp.h"\r
-#include "net/clock-arch.h"\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "queue.h"\r
-\r
-/*\r
- * Query the computer the simulation is being executed on to find the network\r
- * interfaces it has installed.\r
- */\r
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );\r
-\r
-/*\r
- * Open the network interface. The number of the interface to be opened is set\r
- * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.\r
- */\r
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );\r
-\r
-/*\r
- * Configure the capture filter to allow blocking reads, and to filter out\r
- * packets that are not of interest to this demo.\r
- */\r
-static void prvConfigureCaptureBehaviour( void );\r
-\r
-pcap_t *pxOpenedInterfaceHandle = NULL;\r
-LARGE_INTEGER freq, sys_start_time;\r
-\r
-#define archNUM_BUFFERS 5\r
-#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 )\r
-\r
-static void prvInterruptSimulator( void *pvParameters );\r
-\r
-static unsigned char ucEthernetBuffer[ archNUM_BUFFERS ][ UIP_CONF_BUFFER_SIZE ];\r
-static unsigned char *pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ];\r
-\r
-static long lLengthOfDataInBuffer[ archNUM_BUFFER_POINTERS ] = { 0 };\r
-static unsigned char ucNextBufferToFill = 0U, ucNextBufferToProcess = 0U;\r
-\r
-unsigned char *uip_buf = NULL;\r
-char cErrorBuffer[PCAP_ERRBUF_SIZE];\r
-\r
-void vNetifTx( void )\r
-{\r
- pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len );\r
- pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-UBaseType_t uxNetifRx( void )\r
-{\r
-UBaseType_t xDataLen;\r
-unsigned char *pucTemp;\r
-\r
- /* Check there is really data available. */\r
- xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ];\r
- if( xDataLen != 0L )\r
- {\r
-\r
- /* The buffer pointed to by uip_buf is going to change. Remember which\r
- buffer uip_buf is currently pointing to. */\r
- pucTemp = uip_buf;\r
-\r
- /* Point uip_buf at the next buffer that contains data. */\r
- uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ];\r
-\r
- /* The buffer pointed to by \r
- pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by\r
- uip_buf, but the buffer uip_buf was pointing to on entry to this\r
- function is free. Set \r
- pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free \r
- buffer. */\r
- pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp;\r
- lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L;\r
-\r
- ucNextBufferToProcess++;\r
- if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS )\r
- {\r
- ucNextBufferToProcess = 0L;\r
- }\r
- }\r
-\r
- return xDataLen;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-BaseType_t xNetifInit( void )\r
-{\r
-BaseType_t x;\r
-pcap_if_t *pxAllNetworkInterfaces;\r
-\r
- /* Allocate a free buffer to each buffer pointer. */\r
- for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ )\r
- {\r
- pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] );\r
- }\r
-\r
- /* Start with uip_buf pointing to a buffer that is not referenced from the\r
- pucEthernetBufferPointers[] array. */\r
- uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] );\r
-\r
- /* Query the computer the simulation is being executed on to find the \r
- network interfaces it has installed. */\r
- pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();\r
- \r
- /* Open the network interface. The number of the interface to be opened is \r
- set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.\r
- Calling this function will set the pxOpenedInterfaceHandle variable. If,\r
- after calling this function, pxOpenedInterfaceHandle is equal to NULL, then\r
- the interface could not be opened. */\r
- if( pxAllNetworkInterfaces != NULL )\r
- {\r
- prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );\r
- }\r
- \r
-\r
- return x;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )\r
-{ \r
-pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;\r
-long lInterfaceNumber = 1;\r
-\r
- if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )\r
- {\r
- printf( "\r\nCould not obtain a list of network interfaces\r\n%s\r\n", cErrorBuffer );\r
- pxAllNetworkInterfaces = NULL;\r
- }\r
-\r
- if( pxAllNetworkInterfaces != NULL )\r
- {\r
- /* Print out the list of network interfaces. The first in the list\r
- is interface '1', not interface '0'. */\r
- for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )\r
- {\r
- printf( "%d. %s", lInterfaceNumber, xInterface->name );\r
- \r
- if( xInterface->description != NULL )\r
- {\r
- printf( " (%s)\r\n", xInterface->description );\r
- }\r
- else\r
- {\r
- printf( " (No description available)\r\n") ;\r
- }\r
- \r
- lInterfaceNumber++;\r
- }\r
- }\r
-\r
- if( lInterfaceNumber == 1 )\r
- {\r
- /* The interface number was never incremented, so the above for() loop\r
- did not execute meaning no interfaces were found. */\r
- printf( " \r\nNo network interfaces were found.\r\n" );\r
- pxAllNetworkInterfaces = NULL;\r
- }\r
-\r
- printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" );\r
- printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE );\r
- \r
- if( ( configNETWORK_INTERFACE_TO_USE < 1L ) || ( configNETWORK_INTERFACE_TO_USE > lInterfaceNumber ) )\r
- {\r
- printf("\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" );\r
- \r
- if( pxAllNetworkInterfaces != NULL )\r
- {\r
- /* Free the device list, as no devices are going to be opened. */\r
- pcap_freealldevs( pxAllNetworkInterfaces );\r
- pxAllNetworkInterfaces = NULL;\r
- }\r
- }\r
-\r
- return pxAllNetworkInterfaces;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )\r
-{\r
-pcap_if_t *xInterface;\r
-long x;\r
-\r
- /* Walk the list of devices until the selected device is located. */\r
- xInterface = pxAllNetworkInterfaces;\r
- for( x = 0L; x < ( configNETWORK_INTERFACE_TO_USE - 1L ); x++ )\r
- {\r
- xInterface = xInterface->next;\r
- }\r
-\r
- /* Open the selected interface. */\r
- pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */\r
- UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */\r
- PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and \r
- IP address is going to be "simulated", and \r
- not be the real MAC and IP address. This allows\r
- trafic to the simulated IP address to be routed\r
- to uIP, and trafic to the real IP address to be\r
- routed to the Windows TCP/IP stack. */\r
- 0xfffffffL, /* The read time out. This is going to block\r
- until data is available. */\r
- NULL, /* No authentication is required as this is\r
- not a remote capture session. */\r
- cErrorBuffer \r
- );\r
- \r
- if ( pxOpenedInterfaceHandle == NULL )\r
- {\r
- printf( "\r\n%s is not supported by WinPcap and cannot be opened\r\n", xInterface->name );\r
- }\r
- else\r
- {\r
- /* Configure the capture filter to allow blocking reads, and to filter \r
- out packets that are not of interest to this demo. */\r
- prvConfigureCaptureBehaviour();\r
- }\r
-\r
- /* The device list is no longer required. */\r
- pcap_freealldevs( pxAllNetworkInterfaces );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvConfigureCaptureBehaviour( void )\r
-{\r
-struct bpf_program xFilterCode;\r
-const long lMinBytesToCopy = 10L, lBlocking = 0L;\r
-unsigned long ulNetMask;\r
-\r
- /* Unblock a read as soon as anything is received. */\r
- pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy );\r
-\r
- /* Allow blocking. */\r
- pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer );\r
-\r
- /* Set up a filter so only the packets of interest are passed to the uIP\r
- stack. cErrorBuffer is used for convenience to create the string. Don't\r
- confuse this with an error message. */\r
- sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );\r
-\r
- ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;\r
-\r
- if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )\r
- {\r
- printf("\r\nThe packet filter string is invalid\r\n" );\r
- }\r
- else\r
- { \r
- if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )\r
- {\r
- printf( "\r\nAn error occurred setting the packet filter.\r\n" );\r
- }\r
- }\r
-\r
- /* Create a task that simulates an interrupt in a real system. This will\r
- block waiting for packets, then send a message to the uIP task when data\r
- is available. */\r
- xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( configuIP_TASK_PRIORITY - 1 ), NULL );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvInterruptSimulator( void *pvParameters )\r
-{\r
-static struct pcap_pkthdr *pxHeader;\r
-const unsigned char *pucPacketData;\r
-extern QueueHandle_t xEMACEventQueue;\r
-const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;\r
-long lResult;\r
-\r
- /* Just to kill the compiler warning. */\r
- ( void ) pvParameters;\r
-\r
- for( ;; )\r
- {\r
- /* Get the next packet. */\r
- lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData );\r
- if( lResult )\r
- {\r
- /* Is the next buffer into which data should be placed free? */\r
- if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L )\r
- {\r
- /* Copy the data from the captured packet into the buffer. */\r
- memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len );\r
-\r
- /* Note the amount of data that was copied. */\r
- lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len;\r
-\r
- /* Move onto the next buffer, wrapping around if necessary. */\r
- ucNextBufferToFill++;\r
- if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS )\r
- {\r
- ucNextBufferToFill = 0U;\r
- }\r
-\r
- /* Data was received and stored. Send a message to the uIP task\r
- to let it know. */\r
- xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY );\r
- }\r
- }\r
- }\r
-}\r
-\r