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:
Mon Jun 13 13:13:59 2011 +0000
Revision:
5:3cd83fcb1467
Parent:
1:f4040665bc61
Child:
7:8e12f7357b9f
Renamed some types to avoid conflicts with other objects

Who changed what in which revision?

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