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.

Committer:
Benoit
Date:
Sun Jun 12 11:23:03 2011 +0000
Revision:
0:19f5f51584de
Initial release (alpha quality)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Benoit 0:19f5f51584de 1 /*
Benoit 0:19f5f51584de 2 * $Id: IPv4.c 29 2011-06-11 14:53:08Z benoit $
Benoit 0:19f5f51584de 3 * $Author: benoit $
Benoit 0:19f5f51584de 4 * $Date: 2011-06-11 16:53:08 +0200 (sam., 11 juin 2011) $
Benoit 0:19f5f51584de 5 * $Rev: 29 $
Benoit 0:19f5f51584de 6 *
Benoit 0:19f5f51584de 7 *
Benoit 0:19f5f51584de 8 *
Benoit 0:19f5f51584de 9 *
Benoit 0:19f5f51584de 10 *
Benoit 0:19f5f51584de 11 */
Benoit 0:19f5f51584de 12
Benoit 0:19f5f51584de 13 #include "IPv4.h"
Benoit 0:19f5f51584de 14 #include "Ethernet.h"
Benoit 0:19f5f51584de 15 #include "Debug.h"
Benoit 0:19f5f51584de 16 #include <string.h>
Benoit 0:19f5f51584de 17
Benoit 0:19f5f51584de 18
Benoit 0:19f5f51584de 19 #define DEBUG_CURRENT_MODULE_NAME "IPv4"
Benoit 0:19f5f51584de 20 #define DEBUG_CURRENT_MODULE_ID DEBUG_MODULE_IPV4
Benoit 0:19f5f51584de 21
Benoit 0:19f5f51584de 22
Benoit 0:19f5f51584de 23 static void Init(void);
Benoit 0:19f5f51584de 24 static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler);
Benoit 0:19f5f51584de 25 static void Handler(NetIF_t *netIF, Packet_t *packet);
Benoit 0:19f5f51584de 26
Benoit 0:19f5f51584de 27
Benoit 0:19f5f51584de 28 static Protocol_Handler_t *protocolHandlerTable[IPV4_PROTOCOL_MAX_COUNT];
Benoit 0:19f5f51584de 29 static int32_t protocolHandlerCount = 0;
Benoit 0:19f5f51584de 30
Benoit 0:19f5f51584de 31
Benoit 0:19f5f51584de 32 const IPv4_Addr_t ipv4_Addr_Broadcast = { 255, 255, 255, 255 };
Benoit 0:19f5f51584de 33 const IPv4_Addr_t ipv4_Addr_Any = { 0, 0, 0, 0};
Benoit 0:19f5f51584de 34
Benoit 0:19f5f51584de 35
Benoit 0:19f5f51584de 36 Protocol_Handler_t ipv4 =
Benoit 0:19f5f51584de 37 {
Benoit 0:19f5f51584de 38 PROTOCOL_INDEX_NOT_INITIALIZED, /* Always PROTOCOL_INDEX_NOT_INITIALIZED at initialization */
Benoit 0:19f5f51584de 39 Protocol_ID_IPv4, /* Protocol ID */
Benoit 0:19f5f51584de 40 htons(ETHERNET_PROTO_IPV4), /* Protocol number */
Benoit 0:19f5f51584de 41 Init, /* Protocol initialisation function */
Benoit 0:19f5f51584de 42 Handler, /* Protocol handler */
Benoit 0:19f5f51584de 43 RegisterProtocol, /* Protocol registration function */
Benoit 0:19f5f51584de 44 NULL, /* API registration function */
Benoit 0:19f5f51584de 45 };
Benoit 0:19f5f51584de 46
Benoit 0:19f5f51584de 47
Benoit 0:19f5f51584de 48 static void Init(void)
Benoit 0:19f5f51584de 49 {
Benoit 0:19f5f51584de 50 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing IPv4 layer"));
Benoit 0:19f5f51584de 51 protocolHandlerCount = 0;
Benoit 0:19f5f51584de 52 memset(protocolHandlerTable, 0, sizeof(protocolHandlerTable));
Benoit 0:19f5f51584de 53 }
Benoit 0:19f5f51584de 54
Benoit 0:19f5f51584de 55
Benoit 0:19f5f51584de 56 static int32_t RegisterProtocol(Protocol_Handler_t *protocolHandler)
Benoit 0:19f5f51584de 57 {
Benoit 0:19f5f51584de 58 int32_t result = 0;
Benoit 0:19f5f51584de 59
Benoit 0:19f5f51584de 60 if (protocolHandlerCount >= IPV4_PROTOCOL_MAX_COUNT)
Benoit 0:19f5f51584de 61 {
Benoit 0:19f5f51584de 62 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Too many protocols"));
Benoit 0:19f5f51584de 63 result = -1;
Benoit 0:19f5f51584de 64 mbedNet_LastError = mbedNetResult_TooManyRegisteredProtocols;
Benoit 0:19f5f51584de 65 goto Exit;
Benoit 0:19f5f51584de 66 }
Benoit 0:19f5f51584de 67
Benoit 0:19f5f51584de 68 protocolHandlerTable[protocolHandlerCount] = protocolHandler;
Benoit 0:19f5f51584de 69 protocolHandler->index = protocolHandlerCount;
Benoit 0:19f5f51584de 70 protocolHandler->Init();
Benoit 0:19f5f51584de 71
Benoit 0:19f5f51584de 72 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Registered protocol %2d ipv4/%s",
Benoit 0:19f5f51584de 73 protocolHandler->protocolNumber,
Benoit 0:19f5f51584de 74 protocol_IDNames[protocolHandler->protocolID]
Benoit 0:19f5f51584de 75 ));
Benoit 0:19f5f51584de 76
Benoit 0:19f5f51584de 77 protocolHandlerCount++;
Benoit 0:19f5f51584de 78
Benoit 0:19f5f51584de 79 Exit:
Benoit 0:19f5f51584de 80 return result;
Benoit 0:19f5f51584de 81 }
Benoit 0:19f5f51584de 82
Benoit 0:19f5f51584de 83
Benoit 0:19f5f51584de 84 static void Handler(NetIF_t *netIF, Packet_t *packet)
Benoit 0:19f5f51584de 85 {
Benoit 0:19f5f51584de 86 int32_t protocolIndex,
Benoit 0:19f5f51584de 87 payloadOffset;
Benoit 0:19f5f51584de 88 Protocol_Number_t protocolNumber;
Benoit 0:19f5f51584de 89 Protocol_Handler_t *protocolHandler;
Benoit 0:19f5f51584de 90 IPv4_Header_t *ipv4Packet = (IPv4_Header_t *)packet->data;
Benoit 0:19f5f51584de 91
Benoit 0:19f5f51584de 92 protocolNumber = ipv4Packet->protocol;
Benoit 0:19f5f51584de 93 payloadOffset = ipv4Packet->ihl << 2;
Benoit 0:19f5f51584de 94
Benoit 0:19f5f51584de 95 if ((ipv4Packet->dest.addr != netIF->ipv4Address.addr) && (ipv4Packet->dest.addr != netIF->ipv4Broadcast.addr))
Benoit 0:19f5f51584de 96 {
Benoit 0:19f5f51584de 97 #if DEBUG_IPV4
Benoit 0:19f5f51584de 98 IPV4_DumpIPv4Header("Not for us ", ipv4Packet);
Benoit 0:19f5f51584de 99 #endif /* DEBUG_IPV4 */
Benoit 0:19f5f51584de 100 goto Exit;
Benoit 0:19f5f51584de 101 }
Benoit 0:19f5f51584de 102
Benoit 0:19f5f51584de 103 #if DEBUG_IPV4
Benoit 0:19f5f51584de 104 IPv4_DumpIPv4Header("processing ", ipv4Packet);
Benoit 0:19f5f51584de 105 #endif /* DEBUG_IPV4 */
Benoit 0:19f5f51584de 106
Benoit 0:19f5f51584de 107 //Debug_DumpBufferHex(packet, length);
Benoit 0:19f5f51584de 108 for (protocolIndex = 0; protocolIndex < protocolHandlerCount; protocolIndex++)
Benoit 0:19f5f51584de 109 {
Benoit 0:19f5f51584de 110 protocolHandler = protocolHandlerTable[protocolIndex];
Benoit 0:19f5f51584de 111 if (protocolHandler->protocolNumber == protocolNumber)
Benoit 0:19f5f51584de 112 {
Benoit 0:19f5f51584de 113 NetIF_ProtoPush(packet, payloadOffset, Protocol_ID_IPv4);
Benoit 0:19f5f51584de 114 protocolHandler->HandlePacket(netIF, packet);
Benoit 0:19f5f51584de 115 goto Exit;
Benoit 0:19f5f51584de 116 }
Benoit 0:19f5f51584de 117 }
Benoit 0:19f5f51584de 118
Benoit 0:19f5f51584de 119 #if DEBUG_IPV4
Benoit 0:19f5f51584de 120 IPV4_DumpIPv4Header("Not handled ", ipv4Packet);
Benoit 0:19f5f51584de 121 #endif /* DEBUG_IPV4 */
Benoit 0:19f5f51584de 122
Benoit 0:19f5f51584de 123
Benoit 0:19f5f51584de 124 Exit:
Benoit 0:19f5f51584de 125 return;
Benoit 0:19f5f51584de 126 }
Benoit 0:19f5f51584de 127
Benoit 0:19f5f51584de 128
Benoit 0:19f5f51584de 129 void IPv4_DumpIPv4Header(const char *prefix, IPv4_Header_t *ipv4Packet)
Benoit 0:19f5f51584de 130 {
Benoit 0:19f5f51584de 131 DEBUG_RAW(("%sIPv4 %d.%d.%d.%d --> %d.%d.%d.%d ver:%01X ihl:%01X tos:%03d totlen:%04d id:%04X flags:%1d frag:%05d ttl:%3d proto:%03d crc:%04X" ,
Benoit 0:19f5f51584de 132 prefix != NULL ? prefix : "",
Benoit 0:19f5f51584de 133 ipv4Packet->source.IP0,
Benoit 0:19f5f51584de 134 ipv4Packet->source.IP1,
Benoit 0:19f5f51584de 135 ipv4Packet->source.IP2,
Benoit 0:19f5f51584de 136 ipv4Packet->source.IP3,
Benoit 0:19f5f51584de 137 ipv4Packet->dest.IP0,
Benoit 0:19f5f51584de 138 ipv4Packet->dest.IP1,
Benoit 0:19f5f51584de 139 ipv4Packet->dest.IP2,
Benoit 0:19f5f51584de 140 ipv4Packet->dest.IP3,
Benoit 0:19f5f51584de 141 ipv4Packet->version,
Benoit 0:19f5f51584de 142 ipv4Packet->ihl,
Benoit 0:19f5f51584de 143 ipv4Packet->tos,
Benoit 0:19f5f51584de 144 ntohs(ipv4Packet->totalLength),
Benoit 0:19f5f51584de 145 ntohs(ipv4Packet->id),
Benoit 0:19f5f51584de 146 (ntohs(ipv4Packet->fragmentFlags) & 0x1FFF) >> 13,
Benoit 0:19f5f51584de 147 ntohs(ipv4Packet->fragmentFlags),
Benoit 0:19f5f51584de 148 ipv4Packet->ttl,
Benoit 0:19f5f51584de 149 ipv4Packet->protocol,
Benoit 0:19f5f51584de 150 ntohs(ipv4Packet->crc)
Benoit 0:19f5f51584de 151 ));
Benoit 0:19f5f51584de 152 }
Benoit 0:19f5f51584de 153
Benoit 0:19f5f51584de 154
Benoit 0:19f5f51584de 155 uint16_t IPv4_ComputeCRC(IPv4_Header_t *ipv4Header)
Benoit 0:19f5f51584de 156 {
Benoit 0:19f5f51584de 157 uint32_t crc = 0,
Benoit 0:19f5f51584de 158 length;
Benoit 0:19f5f51584de 159 uint16_t *data;
Benoit 0:19f5f51584de 160
Benoit 0:19f5f51584de 161 data = (uint16_t *)ipv4Header;
Benoit 0:19f5f51584de 162 length = ipv4Header->ihl * 4;
Benoit 0:19f5f51584de 163
Benoit 0:19f5f51584de 164 while(length > 1)
Benoit 0:19f5f51584de 165 {
Benoit 0:19f5f51584de 166 crc += *data;
Benoit 0:19f5f51584de 167 data++;
Benoit 0:19f5f51584de 168 length -= 2;
Benoit 0:19f5f51584de 169 }
Benoit 0:19f5f51584de 170 if (length)
Benoit 0:19f5f51584de 171 {
Benoit 0:19f5f51584de 172 crc += *(uint8_t *)(data);
Benoit 0:19f5f51584de 173 }
Benoit 0:19f5f51584de 174
Benoit 0:19f5f51584de 175 crc = (crc >> 16) + (crc & 0xFFFF);
Benoit 0:19f5f51584de 176 crc = crc + (crc >> 16);
Benoit 0:19f5f51584de 177
Benoit 0:19f5f51584de 178 return (uint16_t)(~crc);
Benoit 0:19f5f51584de 179 }