xref: /FreeRTOS-Plus-TCP-v4.0.0/source/portable/NetworkInterface/WinPCap/FaultInjection.c (revision a4124602cc584fa0658448c229f48a459a84fbb1)
1 #define xBUFFER_CACHE_SIZE           10
2 #define xMAX_FAULT_INJECTION_RATE    15
3 #define xMIN_FAULT_INJECTION_RATE    3
4 #define xNUM_FAULT_TYPES             1
5 
6 static NetworkBufferDescriptor_t * xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
7 
8 #define xFAULT_LOG_SIZE    2048
9 uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
10 uint32_t ulFaultLogIndex = 0;
11 
prvCachePacket(NetworkBufferDescriptor_t * pxNetworkBufferIn)12 static BaseType_t prvCachePacket( NetworkBufferDescriptor_t * pxNetworkBufferIn )
13 {
14     BaseType_t x, xReturn = pdFALSE;
15 
16     for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
17     {
18         if( xNetworkBufferCache[ x ] == NULL )
19         {
20             xNetworkBufferCache[ x ] = pxNetworkBufferIn;
21             xReturn = pdTRUE;
22             break;
23         }
24     }
25 
26     return xReturn;
27 }
28 /*-----------------------------------------------------------*/
29 
prvGetCachedPacket(void)30 static NetworkBufferDescriptor_t * prvGetCachedPacket( void )
31 {
32     BaseType_t x;
33     NetworkBufferDescriptor_t * pxReturn = NULL;
34 
35     for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
36     {
37         if( xNetworkBufferCache[ x ] != NULL )
38         {
39             pxReturn = xNetworkBufferCache[ x ];
40             xNetworkBufferCache[ x ] = NULL;
41             break;
42         }
43     }
44 
45     return pxReturn;
46 }
47 /*-----------------------------------------------------------*/
48 
prvDuplicatePacket(NetworkBufferDescriptor_t * pxOriginalPacket,const uint8_t * pucPacketData)49 static NetworkBufferDescriptor_t * prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket,
50                                                        const uint8_t * pucPacketData )
51 {
52     NetworkBufferDescriptor_t * pxReturn;
53 
54     /* Obtain a new descriptor. */
55     pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
56 
57     if( pxReturn != NULL )
58     {
59         /* Copy in the packet data. */
60         pxReturn->xDataLength = pxOriginalPacket->xDataLength;
61         memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
62     }
63 
64     return pxReturn;
65 }
66 /*-----------------------------------------------------------*/
67 
prvRxFaultInjection(NetworkBufferDescriptor_t * pxNetworkBufferIn,const uint8_t * pucPacketData)68 static NetworkBufferDescriptor_t * prvRxFaultInjection( NetworkBufferDescriptor_t * pxNetworkBufferIn,
69                                                         const uint8_t * pucPacketData )
70 {
71     static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
72     NetworkBufferDescriptor_t * pxReturn = pxNetworkBufferIn;
73     IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
74     uint32_t ulFault;
75 
76     return pxNetworkBufferIn;
77 
78     ulCallCount++;
79 
80     if( ulCallCount > ulNextFaultCallCount )
81     {
82         xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
83         ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
84 
85         if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
86         {
87             ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
88         }
89 
90         ulCallCount = 0;
91 
92         xApplicationGetRandomNumber( &( ulFault ) );
93         ulFault = ulFault % xNUM_FAULT_TYPES;
94 
95         if( ulFaultLogIndex < xFAULT_LOG_SIZE )
96         {
97             ulInjectedFault[ ulFaultLogIndex ] = ulFault;
98             ulFaultLogIndex++;
99         }
100 
101         switch( ulFault )
102         {
103             case 0:
104                 /* Just drop the packet. */
105                 vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
106                 pxReturn = NULL;
107                 break;
108 
109             case 1:
110 
111                 /* Store the packet in the cache for later. */
112                 if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
113                 {
114                     /* The packet may get sent later, it is not being sent
115                      * now. */
116                     pxReturn = NULL;
117                 }
118 
119                 break;
120 
121             case 2:
122                 /* Send a cached packet. */
123                 pxReturn = prvGetCachedPacket();
124 
125                 if( pxReturn != NULL )
126                 {
127                     /* A cached packet was obtained so drop the original
128                      * packet. */
129                     vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
130                 }
131                 else
132                 {
133                     /* Could not obtain a packet from the cache so just return
134                      * the packet that was passed in. */
135                     pxReturn = pxNetworkBufferIn;
136                 }
137 
138                 break;
139 
140             case 4:
141 
142                 /* Send a duplicate of the packet right away. */
143                 pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
144 
145                 /* Send the original packet to the stack. */
146                 xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
147 
148                 if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
149                 {
150                     vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
151                 }
152 
153                 break;
154 
155             case 5:
156 
157                 /* Send both a cached packet and the current packet. */
158                 xRxEvent.pvData = ( void * ) prvGetCachedPacket();
159 
160                 if( xRxEvent.pvData != NULL )
161                 {
162                     if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
163                     {
164                         vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
165                     }
166                 }
167 
168                 break;
169 
170             case 6:
171             case 7:
172             case 8:
173 
174                 /* Store the packet in the cache for later. */
175                 if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
176                 {
177                     /* The packet may get sent later, it is not being sent
178                      * now. */
179                     pxReturn = NULL;
180                 }
181 
182                 break;
183         }
184     }
185 
186     return pxReturn;
187 }
188 /*-----------------------------------------------------------*/
189