Rewrite from scratch a TCP/IP stack for mbed. So far the following parts are usable: Drivers: - EMAC driver (from CMSIS 2.0) Protocols: - Ethernet protocol - ARP over ethernet for IPv4 - IPv4 over Ethernet - ICMPv4 over IPv4 - UDPv4 over IPv4 APIs: - Sockets for UDPv4 The structure of this stack is designed to be very modular. Each protocol can register one or more protocol to handle its payload, and in each protocol, an API can be hooked (like Sockets for example). This is an early release.
NetIF.cpp
00001 /* 00002 * $Id: NetIF.c 29 2011-06-11 14:53:08Z benoit $ 00003 * $Author: benoit $ 00004 * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $ 00005 * $Rev: 29 $ 00006 * 00007 * 00008 * 00009 * 00010 * 00011 */ 00012 00013 #include "NetIF.h" 00014 #include "Ethernet.h" 00015 #include "ARP.h" 00016 #include "Debug.h" 00017 #include <string.h> 00018 00019 00020 #define DEBUG_CURRENT_MODULE_NAME "NetIF" 00021 #define DEBUG_CURRENT_MODULE_ID DEBUG_MODULE_NETIF 00022 00023 00024 struct PeriodicFunctionTimer 00025 { 00026 char *name; 00027 PeriodicFunction_t function; 00028 FunctionPeriod_t period; 00029 int32_t age; 00030 }; 00031 typedef struct PeriodicFunctionTimer PeriodicFunctionTimer_t; 00032 00033 00034 static NetIF_t netIF_Table[NETIF_MAX_COUNT]; 00035 static int32_t netIF_Count = 0; 00036 static RTOS_Mutex_t netIF_TableMutex; 00037 00038 static PeriodicFunctionTimer_t netIF_PeriodicFunctionTable[NET_PERIODIC_FUNCTION_MAX_COUNT]; 00039 static int32_t netIF_PeriodicFunctionCount = 0; 00040 static RTOS_Mutex_t netIF_PeriodicFunctionTableMutex; 00041 00042 static Bool_t netIFLayerInitialized = False; 00043 static NetPacket_t rxPacket, 00044 txPacket; 00045 static int32_t gatewayNetIFIndex = -1; 00046 00047 00048 static void NetIF_Init(void); 00049 00050 00051 mbedNetResult_t mbedNet_LastError; 00052 const char *protocol_IDNames[Protocol_ID_Count] = 00053 { 00054 "Ethernet", 00055 "ARP", 00056 "IPv4", 00057 "ICMPv4", 00058 "UDPv4", 00059 "TCPv4", 00060 }; 00061 00062 00063 const char *api_IDNames[API_ID_Count] = 00064 { 00065 "sockets" 00066 }; 00067 00068 00069 static void NetIF_Init(void) 00070 { 00071 mbedNet_LastError = mbedNetResult_Success; 00072 00073 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing NetIF layer")); 00074 00075 netIF_Count = 0; 00076 memset(netIF_Table, 0, sizeof(netIF_Table)); 00077 netIF_TableMutex = RTOS_MUTEX_CREATE(); 00078 00079 netIF_PeriodicFunctionCount = 0; 00080 memset(netIF_PeriodicFunctionTable, 0, sizeof(netIF_PeriodicFunctionTable)); 00081 netIF_PeriodicFunctionTableMutex = RTOS_MUTEX_CREATE(); 00082 00083 memset(&rxPacket, 0, sizeof(rxPacket)); 00084 memset(&txPacket, 0, sizeof(txPacket)); 00085 00086 gatewayNetIFIndex = -1; 00087 00088 netIFLayerInitialized = True; 00089 } 00090 00091 00092 NetIF_t *NetIF_RegisterInterface(IPv4_Addr_t *address, IPv4_Addr_t *netmask, IPv4_Addr_t *gateway, NetIF_Driver_t *driver , void *driverParameter) 00093 { 00094 NetIF_t *netIF = NULL; 00095 00096 if (netIFLayerInitialized == False) 00097 { 00098 NetIF_Init(); 00099 } 00100 00101 if (netIF_Count >= NETIF_MAX_COUNT) 00102 { 00103 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many interfaces registered")); 00104 mbedNet_LastError = mbedNetResult_TooManyInterfaces; 00105 goto Exit; 00106 } 00107 00108 if (driver == NULL) 00109 { 00110 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Invalid driver specified")); 00111 mbedNet_LastError = mbedNetResult_InvalidDriver; 00112 goto Exit; 00113 } 00114 00115 RTOS_MUTEX_LOCK(netIF_TableMutex); 00116 netIF = netIF_Table + netIF_Count; 00117 netIF->index = netIF_Count; 00118 netIF->name = "en"; 00119 netIF->ipv4Address = *address; 00120 netIF->ipv4Netmask = *netmask; 00121 netIF->ipv4Network.addr = address->addr & netmask->addr; 00122 netIF->ipv4Gateway = *gateway; 00123 netIF->ipv4Broadcast.addr = (address->addr & netmask->addr) | (~netmask->addr); 00124 netIF->driverParameter = driverParameter; 00125 netIF->driver = driver; 00126 netIF->driver->Init(netIF); 00127 netIF->driver->protocolHandler->Init(); 00128 00129 if (gateway != NULL) 00130 { 00131 gatewayNetIFIndex = netIF_Count; 00132 } 00133 00134 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Interface '%s%d' registered (%d.%d.%d.%d/%d.%d.%d.%d gw %d.%d.%d.%d) using driver '%s'", 00135 netIF->name, 00136 netIF_Count, 00137 netIF->ipv4Address.IP0, netIF->ipv4Address.IP1, netIF->ipv4Address.IP2, netIF->ipv4Address.IP3, 00138 netIF->ipv4Netmask.IP0, netIF->ipv4Netmask.IP1, netIF->ipv4Netmask.IP2, netIF->ipv4Netmask.IP3, 00139 netIF->ipv4Gateway.IP0, netIF->ipv4Gateway.IP1, netIF->ipv4Gateway.IP2, netIF->ipv4Gateway.IP3, 00140 netIF->driver->name 00141 )); 00142 00143 netIF_Count++; 00144 RTOS_MUTEX_UNLOCK(netIF_TableMutex); 00145 00146 Exit: 00147 return netIF; 00148 } 00149 00150 00151 /* 00152 int32_t NetIF_ProcessFrames(void) 00153 { 00154 NetIF_Index_t netIFIndex; 00155 NetIF_t *netIF; 00156 int32_t result = 0, 00157 readResult; 00158 00159 DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("enter")); 00160 RTOS_MUTEX_LOCK(netIF_TableMutex); 00161 for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++) 00162 { 00163 netIF = netIF_Table + netIFIndex; 00164 readResult = netIF->driver->Read(&rxPacket.data, &rxPacket.length); 00165 if (readResult == 0) 00166 { 00167 rxPacket.depth = -1; 00168 netIF->driver->protocolHandler->HandlePacket(netIF, &rxPacket); 00169 } 00170 } 00171 RTOS_MUTEX_UNLOCK(netIF_TableMutex); 00172 00173 DEBUG_SOURCE(DEBUG_LEVEL_VERBOSE2, ("leave")); 00174 return result; 00175 } 00176 */ 00177 00178 00179 int32_t NetIF_RegisterPeriodicFunction(char *name, PeriodicFunction_t function, FunctionPeriod_t period) 00180 { 00181 int32_t result = 0; 00182 PeriodicFunctionTimer_t *timerEntry; 00183 00184 if (netIF_PeriodicFunctionCount >= NET_PERIODIC_FUNCTION_MAX_COUNT) 00185 { 00186 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many periodic functions registered")); 00187 mbedNet_LastError = mbedNetResult_TooManyPeriodicFunctions; 00188 goto Exit; 00189 } 00190 00191 RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex); 00192 timerEntry = netIF_PeriodicFunctionTable + netIF_PeriodicFunctionCount; 00193 timerEntry->name = name; 00194 timerEntry->function = function; 00195 timerEntry->period = period; 00196 timerEntry->age = 0; 00197 00198 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered periodic function '%s' with period %d seconds", 00199 name, 00200 period 00201 )); 00202 00203 netIF_PeriodicFunctionCount++; 00204 RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex); 00205 00206 Exit: 00207 return result; 00208 } 00209 00210 00211 int32_t NetIF_ProcessTimers(int32_t elapsedTime) 00212 { 00213 int32_t result = 0, 00214 timerIndex; 00215 PeriodicFunctionTimer_t *timerEntry; 00216 static int64_t seconds = 0; 00217 00218 seconds++; 00219 00220 RTOS_MUTEX_LOCK(netIF_PeriodicFunctionTableMutex); 00221 for (timerIndex = 0; timerIndex < netIF_PeriodicFunctionCount; timerIndex++) 00222 { 00223 timerEntry = netIF_PeriodicFunctionTable + timerIndex; 00224 if (elapsedTime == 0) 00225 { 00226 timerEntry->age = 0; 00227 continue; 00228 } 00229 00230 timerEntry->age += elapsedTime; 00231 if (timerEntry->age >= timerEntry->period) 00232 { 00233 timerEntry->age = 0; 00234 timerEntry->function(); 00235 } 00236 } 00237 RTOS_MUTEX_UNLOCK(netIF_PeriodicFunctionTableMutex); 00238 00239 return result; 00240 } 00241 00242 00243 int32_t NetIF_SendIPv4Packet(IPv4_Header_t *ipv4Header) 00244 { 00245 int32_t result = -1, 00246 mtu, 00247 lengthToSend; 00248 NetIF_Index_t netIFIndex; 00249 NetIF_t *netIF = NULL; 00250 Ethernet_Header_t *ethernetHeader; 00251 Bool_t useGateway = False; 00252 00253 RTOS_MUTEX_LOCK(netIF_TableMutex); 00254 00255 /* Look for netif having same network */ 00256 for (netIFIndex = 0; netIFIndex < netIF_Count; netIFIndex++) 00257 { 00258 netIF = netIF_Table + netIFIndex; 00259 if ( (netIF->up) && ((netIF->ipv4Netmask.addr & ipv4Header->dest.addr) == netIF->ipv4Network.addr)) break; 00260 netIF = NULL; 00261 } 00262 00263 /* if not found, use gateway netif */ 00264 if ((netIF == NULL) && (gatewayNetIFIndex >= 0)) 00265 { 00266 netIF = netIF_Table + gatewayNetIFIndex; 00267 if (netIF->up) 00268 { 00269 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("using gateway %d.%d.%d.%d to talk to %d.%d.%d.%d", 00270 netIF->ipv4Gateway.IP0, 00271 netIF->ipv4Gateway.IP1, 00272 netIF->ipv4Gateway.IP2, 00273 netIF->ipv4Gateway.IP3, 00274 00275 ipv4Header->dest.IP0, 00276 ipv4Header->dest.IP1, 00277 ipv4Header->dest.IP2, 00278 ipv4Header->dest.IP3 00279 )); 00280 useGateway = True; 00281 } 00282 } 00283 00284 /* Still no interface able to send, then return error */ 00285 if (netIF == NULL) 00286 { 00287 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("No route to host")); 00288 mbedNet_LastError = mbedNetResult_NoRouteToHost; 00289 goto Exit; 00290 } 00291 00292 /* Prepare to send the IPv4 packet */ 00293 mtu = netIF->driver->mtu; 00294 00295 lengthToSend = (sizeof(Ethernet_Header_t) + ntohs(ipv4Header->totalLength)); 00296 /* Check that total length doesn't exceed MTU */ 00297 if (lengthToSend > mtu) 00298 { 00299 DEBUG_MODULE(DEBUG_LEVEL_ERROR, ("Too much data: %d bytes", lengthToSend)); 00300 mbedNet_LastError = mbedNetResult_TooMuchData; 00301 goto Exit; 00302 } 00303 00304 /* Set source address and compute checksum of IPv4 header */ 00305 ipv4Header->source.addr = netIF->ipv4Address.addr; 00306 ipv4Header->crc = 0; 00307 ipv4Header->crc = IPv4_ComputeCRC(ipv4Header); 00308 00309 /* Prepare packet with ethernet data */ 00310 txPacket.depth = -1; 00311 txPacket.length = lengthToSend; 00312 txPacket.data = netIF->driver->GetTxBuffer(); 00313 ethernetHeader = (Ethernet_Header_t *)txPacket.data; 00314 00315 /* Copy destination MAC address */ 00316 if (useGateway) 00317 { 00318 while (ARP_ResolveIPv4Address(netIF, netIF->ipv4Gateway, ðernetHeader->destination) == -1) 00319 { 00320 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache", 00321 netIF->ipv4Gateway.IP0, 00322 netIF->ipv4Gateway.IP1, 00323 netIF->ipv4Gateway.IP2, 00324 netIF->ipv4Gateway.IP3 00325 )); 00326 } 00327 } 00328 else 00329 { 00330 while (ARP_ResolveIPv4Address(netIF, ipv4Header->dest, ðernetHeader->destination) == -1) 00331 { 00332 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("%d.%d.%d.%d not in ARP cache", 00333 ipv4Header->dest.IP0, 00334 ipv4Header->dest.IP1, 00335 ipv4Header->dest.IP2, 00336 ipv4Header->dest.IP3 00337 )); 00338 } 00339 } 00340 00341 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE0, ("IPv4 sending %d bytes %d.%d.%d.%d --> %d.%d.%d.%d using %s%d", 00342 ntohs(ipv4Header->totalLength), 00343 00344 ipv4Header->source.IP0, 00345 ipv4Header->source.IP1, 00346 ipv4Header->source.IP2, 00347 ipv4Header->source.IP3, 00348 00349 ipv4Header->dest.IP0, 00350 ipv4Header->dest.IP1, 00351 ipv4Header->dest.IP2, 00352 ipv4Header->dest.IP3, 00353 00354 netIF->name, 00355 netIF->index 00356 )); 00357 00358 /* Copy source MAC address */ 00359 memcpy(ðernetHeader->source, (uint8_t *)netIF->driverParameter, 6); 00360 ethernetHeader->protocol = htons(ETHERNET_PROTO_IPV4); 00361 NetIF_ProtoPush(&txPacket, sizeof(Ethernet_Header_t), Protocol_ID_Ethernet); 00362 00363 /* Copy ethernet payload */ 00364 //ipv4Header = (IPv4_Header_t *)txPacket.data; 00365 memcpy(txPacket.data, ipv4Header, ntohs(ipv4Header->totalLength)); 00366 NetIF_ProtoPop(&txPacket); 00367 00368 /* Send packet */ 00369 result = netIF->driver->Write(txPacket.data, txPacket.length); 00370 00371 Exit: 00372 RTOS_MUTEX_UNLOCK(netIF_TableMutex); 00373 return result; 00374 } 00375 00376 00377 int32_t NetIF_Up(NetIF_t *netIF) 00378 { 00379 int32_t result = 0; 00380 00381 if (netIF->up) 00382 { 00383 result = -1; 00384 mbedNet_LastError = mbedNetResult_InterfaceAlreadyUp; 00385 goto Exit; 00386 } 00387 00388 netIF->driver->Enable(); 00389 netIF->up = True; 00390 00391 Exit: 00392 return result; 00393 } 00394 00395 00396 int32_t NetIF_Down(NetIF_t *netIF) 00397 { 00398 int32_t result = 0; 00399 00400 if (!netIF->up) 00401 { 00402 result = -1; 00403 mbedNet_LastError = mbedNetResult_InterfaceAlreadyDown; 00404 goto Exit; 00405 } 00406 00407 netIF->driver->Disable(); 00408 netIF->up = False; 00409 00410 Exit: 00411 return result; 00412 } 00413 00414 00415 void NetIF_ProtoPop(NetPacket_t *packet) 00416 { 00417 static int32_t depth, headerSize, index; 00418 00419 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); 00420 if (packet->depth >= 0) 00421 { 00422 depth = packet->depth; 00423 headerSize = packet->headerLenTable[depth]; 00424 00425 packet->data -= headerSize; 00426 packet->length += headerSize; 00427 00428 packet->depth--; 00429 } 00430 00431 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > Decapsulate: ")); 00432 DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1) 00433 { 00434 for (index = 0; index <= packet->depth; index++) 00435 { 00436 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index])); 00437 } 00438 } 00439 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); 00440 } 00441 00442 00443 void NetIF_ProtoPush(NetPacket_t *packet, int32_t headerSize, Protocol_ID_t protocol) 00444 { 00445 static int32_t depth, index; 00446 00447 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); 00448 00449 packet->depth++; 00450 depth = packet->depth; 00451 00452 packet->headerPtrTable[depth] = packet->data; 00453 packet->headerLenTable[depth] = headerSize; 00454 packet->protocolTable[depth] = protocol; 00455 packet->data += headerSize; 00456 packet->length -= headerSize; 00457 00458 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > Encapsulate: ")); 00459 DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE1) 00460 { 00461 for (index = 0; index <= depth; index++) 00462 { 00463 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (" > %d %s header:%d bytes", index, protocol_IDNames[packet->protocolTable[index]], packet->headerLenTable[index])); 00464 } 00465 } 00466 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, (">>> Packet depth %d with %d bytes", packet->depth, packet->length)); 00467 } 00468
Generated on Wed Jul 13 2022 06:09:33 by 1.7.2