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 26 09:56:31 2011 +0000
Revision:
7:8e12f7357b9f
Parent:
5:3cd83fcb1467
Added IPv4 global broadcast address to processed frames inside IPv4 layer.

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 7:8e12f7357b9f 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 7:8e12f7357b9f 86 int32_t protocolIndex,
Benoit 7:8e12f7357b9f 87 payloadOffset;
Benoit 7:8e12f7357b9f 88 Protocol_Number_t protocolNumber;
Benoit 7:8e12f7357b9f 89 Protocol_Handler_t *protocolHandler;
Benoit 7:8e12f7357b9f 90 IPv4_Header_t *ipv4Packet;
Benoit 7:8e12f7357b9f 91
Benoit 7:8e12f7357b9f 92
Benoit 7:8e12f7357b9f 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 7:8e12f7357b9f 98 if ( (ipv4Packet->dest.addr == netIF->ipv4Address.addr) ||
Benoit 7:8e12f7357b9f 99 (ipv4Packet->dest.addr == netIF->ipv4Broadcast.addr) ||
Benoit 7:8e12f7357b9f 100 (ipv4Packet->dest.addr == ipv4_Addr_Broadcast.addr) )
Benoit 1:f4040665bc61 101 {
Benoit 7:8e12f7357b9f 102 for (protocolIndex = 0; protocolIndex < protocolHandlerCount; protocolIndex++)
Benoit 7:8e12f7357b9f 103 {
Benoit 7:8e12f7357b9f 104 protocolHandler = protocolHandlerTable[protocolIndex];
Benoit 7:8e12f7357b9f 105 if (protocolHandler->protocolNumber == protocolNumber)
Benoit 7:8e12f7357b9f 106 {
Benoit 7:8e12f7357b9f 107 NetIF_ProtoPush(packet, payloadOffset, Protocol_ID_IPv4);
Benoit 7:8e12f7357b9f 108 protocolHandler->HandlePacket(netIF, packet);
Benoit 7:8e12f7357b9f 109 break;
Benoit 7:8e12f7357b9f 110 }
Benoit 7:8e12f7357b9f 111 }
Benoit 1:f4040665bc61 112 }
Benoit 1:f4040665bc61 113
Benoit 1:f4040665bc61 114 return;
Benoit 1:f4040665bc61 115 }
Benoit 1:f4040665bc61 116
Benoit 1:f4040665bc61 117
Benoit 1:f4040665bc61 118 void IPv4_DumpIPv4Header(const char *prefix, IPv4_Header_t *ipv4Packet)
Benoit 1:f4040665bc61 119 {
Benoit 1:f4040665bc61 120 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 121 prefix != NULL ? prefix : "",
Benoit 1:f4040665bc61 122 ipv4Packet->source.IP0,
Benoit 1:f4040665bc61 123 ipv4Packet->source.IP1,
Benoit 1:f4040665bc61 124 ipv4Packet->source.IP2,
Benoit 1:f4040665bc61 125 ipv4Packet->source.IP3,
Benoit 1:f4040665bc61 126 ipv4Packet->dest.IP0,
Benoit 1:f4040665bc61 127 ipv4Packet->dest.IP1,
Benoit 1:f4040665bc61 128 ipv4Packet->dest.IP2,
Benoit 1:f4040665bc61 129 ipv4Packet->dest.IP3,
Benoit 1:f4040665bc61 130 ipv4Packet->version,
Benoit 1:f4040665bc61 131 ipv4Packet->ihl,
Benoit 1:f4040665bc61 132 ipv4Packet->tos,
Benoit 1:f4040665bc61 133 ntohs(ipv4Packet->totalLength),
Benoit 1:f4040665bc61 134 ntohs(ipv4Packet->id),
Benoit 1:f4040665bc61 135 (ntohs(ipv4Packet->fragmentFlags) & 0x1FFF) >> 13,
Benoit 1:f4040665bc61 136 ntohs(ipv4Packet->fragmentFlags),
Benoit 1:f4040665bc61 137 ipv4Packet->ttl,
Benoit 1:f4040665bc61 138 ipv4Packet->protocol,
Benoit 1:f4040665bc61 139 ntohs(ipv4Packet->crc)
Benoit 1:f4040665bc61 140 ));
Benoit 1:f4040665bc61 141 }
Benoit 1:f4040665bc61 142
Benoit 1:f4040665bc61 143
Benoit 1:f4040665bc61 144 uint16_t IPv4_ComputeCRC(IPv4_Header_t *ipv4Header)
Benoit 1:f4040665bc61 145 {
Benoit 1:f4040665bc61 146 uint32_t crc = 0,
Benoit 1:f4040665bc61 147 length;
Benoit 1:f4040665bc61 148 uint16_t *data;
Benoit 1:f4040665bc61 149
Benoit 1:f4040665bc61 150 data = (uint16_t *)ipv4Header;
Benoit 1:f4040665bc61 151 length = ipv4Header->ihl * 4;
Benoit 1:f4040665bc61 152
Benoit 1:f4040665bc61 153 while(length > 1)
Benoit 1:f4040665bc61 154 {
Benoit 1:f4040665bc61 155 crc += *data;
Benoit 1:f4040665bc61 156 data++;
Benoit 1:f4040665bc61 157 length -= 2;
Benoit 1:f4040665bc61 158 }
Benoit 1:f4040665bc61 159 if (length)
Benoit 1:f4040665bc61 160 {
Benoit 1:f4040665bc61 161 crc += *(uint8_t *)(data);
Benoit 1:f4040665bc61 162 }
Benoit 1:f4040665bc61 163
Benoit 1:f4040665bc61 164 crc = (crc >> 16) + (crc & 0xFFFF);
Benoit 1:f4040665bc61 165 crc = crc + (crc >> 16);
Benoit 1:f4040665bc61 166
Benoit 1:f4040665bc61 167 return (uint16_t)(~crc);
Benoit 1:f4040665bc61 168 }