A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
Diff: ip4/ip4.cpp
- Revision:
- 11:c051adb70c5a
- Parent:
- 10:f0854784e960
- Child:
- 14:e75a59c1123d
--- a/ip4/ip4.cpp Sun Apr 16 14:21:55 2017 +0000 +++ b/ip4/ip4.cpp Tue Apr 18 19:07:05 2017 +0000 @@ -10,6 +10,30 @@ #define DEBUG false +#define IP4_BROADCAST_ADDRESS 0xFFFFFFFF +#define IP4_MULTICAST_ALL_HOSTS 0x010000E0 +#define IP4_MULTICAST_ALL_ROUTERS 0x020000E0 +#define IP4_MULTICAST_DNS_ADDRESS 0xFB0000E0 +#define IP4_MULTICAST_LLMNR_ADDRESS 0xFC0000E0 + +void Ip4DestIpFromAction(int action, uint32_t* pDstIp) +{ + switch (action) + { + case UNICAST: break; + case UNICAST_DNS: *pDstIp = DhcpDnsServer; break; + case UNICAST_DHCP: *pDstIp = DhcpServer; break; + case MULTICAST_NODE: *pDstIp = IP4_MULTICAST_ALL_HOSTS; break; + case MULTICAST_ROUTER: *pDstIp = IP4_MULTICAST_ALL_ROUTERS; break; + case MULTICAST_MDNS: *pDstIp = IP4_MULTICAST_DNS_ADDRESS; break; + case MULTICAST_LLMNR: *pDstIp = IP4_MULTICAST_LLMNR_ADDRESS; break; + case BROADCAST: *pDstIp = IP4_BROADCAST_ADDRESS; break; + default: + LogTimeF("Ip4 DestIpFromAction unknown action %d\r\n", action); + break; + } +} + #define HEADER_LENGTH 20 __packed struct header @@ -43,41 +67,6 @@ static void* pData; static int dataLength; -static void protocolToString(uint16_t protocol, int size, char* text) -{ - switch (protocol) - { - case ICMP: strncpy (text, "ICMP", size); break; - case TCP: strncpy (text, "TCP" , size); break; - case UDP: strncpy (text, "UDP" , size); break; - default: snprintf(text, size, "%d", protocol); break; - } -} - -void logHeader(char* title) -{ - char text[30]; - LogTimeF("%s\r\n", title); - LogF(" Version %d\r\n", version); - LogF(" Header length %d\r\n", headerLength); - LogF(" Type of service %d\r\n", tos); - LogF(" Data length %d\r\n", dataLength); - LogF(" Identification %d\r\n", id); - if (dontFragment) LogF(" Don't fragment\r\n"); - else LogF(" Do fragment\r\n"); - if (moreFragments) LogF(" More fragments\r\n"); - else LogF(" No more fragments\r\n"); - LogF(" Offset %d\r\n", offset); - LogF(" Time to live %d\r\n", ttl); - protocolToString(protocol, sizeof(text), text); - LogF(" Protocol %s\r\n", text); - LogF(" Checksum (hex) %04hX\r\n", checksum); - LogF(" Calculated (hex) %04hX\r\n", calcsum); - NetIp4AddressToString(srcIp, sizeof(text), text); - LogF(" Source IP %s\r\n", text); - NetIp4AddressToString(dstIp, sizeof(text), text); - LogF(" Destination IP %s\r\n", text); -} void readHeader(struct header * pHeader) { version = pHeader->versionIhl >> 4; @@ -120,6 +109,31 @@ pHeader->checksum = NetCheckSum(headerLength, pHeader); calcsum = 0; } + +static void logHeader(char* title) +{ + char text[30]; + LogTimeF("%s\r\n", title); + LogF(" Version %d\r\n", version); + LogF(" Header length %d\r\n", headerLength); + LogF(" Type of service %d\r\n", tos); + LogF(" Data length %d\r\n", dataLength); + LogF(" Identification %d\r\n", id); + if (dontFragment) LogF(" Don't fragment\r\n"); + else LogF(" Do fragment\r\n"); + if (moreFragments) LogF(" More fragments\r\n"); + else LogF(" No more fragments\r\n"); + LogF(" Offset %d\r\n", offset); + LogF(" Time to live %d\r\n", ttl); + NetProtocolToString(protocol, sizeof(text), text); + LogF(" Protocol %s\r\n", text); + LogF(" Checksum (hex) %04hX\r\n", checksum); + LogF(" Calculated (hex) %04hX\r\n", calcsum); + NetIp4AddressToString(srcIp, sizeof(text), text); + LogF(" Source IP %s\r\n", text); + NetIp4AddressToString(dstIp, sizeof(text), text); + LogF(" Destination IP %s\r\n", text); +} int Ip4HandleReceivedPacket(char* pSrcMac, void* pPacket, int* pSize, char* pDstMac) { struct header * pHeader = (header*)pPacket; @@ -139,33 +153,17 @@ switch (protocol) { case ICMP: action = IcmpHandleReceivedPacket(&srcIp, &dstIp, &dataLength, pData); break; + case IGMP: return DO_NOTHING; case UDP: action = Udp4HandleReceivedPacket(&srcIp, &dstIp, &dataLength, pData); break; case TCP: action = Tcp4HandleReceivedPacket(&srcIp, &dstIp, &dataLength, pData); break; default: logHeader("IP4 packet unhandled"); return DO_NOTHING; } + if (!action) return DO_NOTHING; - switch (action) - { - case DO_NOTHING: - return DO_NOTHING; - case UNICAST: - case UNICAST_DNS: - case UNICAST_DHCP: - memcpy(pDstMac, pSrcMac, 6); - break; - case MULTICAST_NODE: - case MULTICAST_ROUTER: - case MULTICAST_MDNS: - case MULTICAST_LLMNR: - case BROADCAST: - break; - default: - LogTimeF("Ip4HandleReceivedPacket unknown action %d\r\n", action); - return DO_NOTHING; - } - + memcpy(pDstMac, pSrcMac, 6); + if (DEBUG) logHeader("IP4 packet replied to"); writeHeader(pHeader); @@ -176,36 +174,9 @@ } int Ip4PollForPacketToSend(void* pPacket, int* pSize, char* pDstMac) { - struct header * pHeader = (header*)pPacket; - - headerLength = HEADER_LENGTH; - pData = (char*)pPacket + headerLength; - - srcIp = 0; - dstIp = 0; - - dataLength = 0; - int action = DO_NOTHING; - if (!action) action = Udp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); - - switch (action) - { - case DO_NOTHING: - return DO_NOTHING; - case UNICAST: - case UNICAST_DNS: - case UNICAST_DHCP: - ArRev4(dstIp, pDstMac); //Make the remote MAC from ARP - break; - case MULTICAST_MDNS: - case MULTICAST_LLMNR: - case BROADCAST: - break; - default: - LogTimeF("Ip4PollForPacketToSend unknown action %d\r\n", action); - return DO_NOTHING; - } - + headerLength = HEADER_LENGTH; + pData = (char*)pPacket + headerLength; + dataLength = 0; version = 4; tos = 0; id = 0; @@ -215,9 +186,22 @@ ttl = 255; protocol = UDP; - if (DEBUG) logHeader("IP4 packet replied to"); + int action = DO_NOTHING; + if (!action) action = Udp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); + if (!action) return DO_NOTHING; + switch (action) + { + case UNICAST: + case UNICAST_DNS: + case UNICAST_DHCP: + ArRev4(dstIp, pDstMac); //Make the remote MAC from ARP + break; + } - writeHeader(pHeader); + + if (DEBUG) logHeader("IP4 polled packet sent"); + + writeHeader((header*)pPacket); *pSize = headerLength + dataLength;