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
ip6/ip6.c@151:bde6f7da1755, 2019-07-19 (annotated)
- Committer:
- andrewboyson
- Date:
- Fri Jul 19 17:48:06 2019 +0000
- Revision:
- 151:bde6f7da1755
- Parent:
- 136:8a65abb0dc63
- Child:
- 172:9bc3c7b2cca1
Removed private key and certificate from semihost storage as found to be unreliable (though secure) and moved it into flash storage (reliable, simple, but visible on mbed.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 61:aad055f1b0d1 | 1 | #include <stdint.h> |
andrewboyson | 61:aad055f1b0d1 | 2 | #include <stdbool.h> |
andrewboyson | 61:aad055f1b0d1 | 3 | |
andrewboyson | 52:fbc5a46b5e16 | 4 | #include "log.h" |
andrewboyson | 49:1a6336f2b3f9 | 5 | #include "net.h" |
andrewboyson | 49:1a6336f2b3f9 | 6 | #include "action.h" |
andrewboyson | 49:1a6336f2b3f9 | 7 | #include "icmp6.h" |
andrewboyson | 49:1a6336f2b3f9 | 8 | #include "udptcp6.h" |
andrewboyson | 49:1a6336f2b3f9 | 9 | #include "ar6.h" |
andrewboyson | 50:492f2d2954e4 | 10 | #include "nr6.h" |
andrewboyson | 49:1a6336f2b3f9 | 11 | #include "slaac.h" |
andrewboyson | 49:1a6336f2b3f9 | 12 | #include "eth.h" |
andrewboyson | 49:1a6336f2b3f9 | 13 | #include "ip.h" |
andrewboyson | 49:1a6336f2b3f9 | 14 | #include "ip6addr.h" |
andrewboyson | 136:8a65abb0dc63 | 15 | #include "ip6hdr.h" |
andrewboyson | 49:1a6336f2b3f9 | 16 | #include "ndp.h" |
andrewboyson | 49:1a6336f2b3f9 | 17 | #include "ntp.h" |
andrewboyson | 49:1a6336f2b3f9 | 18 | #include "mac.h" |
andrewboyson | 49:1a6336f2b3f9 | 19 | #include "http.h" |
andrewboyson | 11:c051adb70c5a | 20 | |
andrewboyson | 48:952dddb74b8b | 21 | bool Ip6Trace = true; |
andrewboyson | 11:c051adb70c5a | 22 | |
andrewboyson | 136:8a65abb0dc63 | 23 | static void logHeader(char* pPacket) |
andrewboyson | 11:c051adb70c5a | 24 | { |
andrewboyson | 43:bc028d5a6424 | 25 | if (NetTraceVerbose) |
andrewboyson | 43:bc028d5a6424 | 26 | { |
andrewboyson | 43:bc028d5a6424 | 27 | Log("IP6 header\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 28 | LogF(" Version %d\r\n", Ip6HdrGetVersion (pPacket)); |
andrewboyson | 136:8a65abb0dc63 | 29 | LogF(" Payload length %d\r\n", Ip6HdrGetPayloadLen(pPacket)); |
andrewboyson | 136:8a65abb0dc63 | 30 | LogF(" Hop limit %d\r\n", Ip6HdrGetHopLimit (pPacket)); |
andrewboyson | 136:8a65abb0dc63 | 31 | LogF(" Protocol "); IpProtocolLog(Ip6HdrGetProtocol (pPacket)); Log("\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 32 | Log (" Source IP "); Ip6AddressLog(Ip6HdrPtrSrc (pPacket)); Log("\r\n"); |
andrewboyson | 136:8a65abb0dc63 | 33 | Log (" Destination IP "); Ip6AddressLog(Ip6HdrPtrDst (pPacket)); Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 34 | } |
andrewboyson | 43:bc028d5a6424 | 35 | else |
andrewboyson | 43:bc028d5a6424 | 36 | { |
andrewboyson | 44:83ce5ace337b | 37 | Log("IP6 header "); |
andrewboyson | 136:8a65abb0dc63 | 38 | IpProtocolLog(Ip6HdrGetProtocol(pPacket)); |
andrewboyson | 43:bc028d5a6424 | 39 | Log(" "); |
andrewboyson | 136:8a65abb0dc63 | 40 | Ip6AddressLog(Ip6HdrPtrSrc (pPacket)); |
andrewboyson | 43:bc028d5a6424 | 41 | Log(" >>> "); |
andrewboyson | 136:8a65abb0dc63 | 42 | Ip6AddressLog(Ip6HdrPtrDst (pPacket)); |
andrewboyson | 43:bc028d5a6424 | 43 | Log("\r\n"); |
andrewboyson | 43:bc028d5a6424 | 44 | } |
andrewboyson | 11:c051adb70c5a | 45 | } |
andrewboyson | 136:8a65abb0dc63 | 46 | static char* pTracePacket; |
andrewboyson | 37:793b39683406 | 47 | static void (*pTraceBack)(void); |
andrewboyson | 37:793b39683406 | 48 | static void trace() |
andrewboyson | 10:f0854784e960 | 49 | { |
andrewboyson | 37:793b39683406 | 50 | pTraceBack(); |
andrewboyson | 136:8a65abb0dc63 | 51 | logHeader(pTracePacket); |
andrewboyson | 37:793b39683406 | 52 | } |
andrewboyson | 136:8a65abb0dc63 | 53 | int Ip6HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* macRemote) |
andrewboyson | 136:8a65abb0dc63 | 54 | { |
andrewboyson | 136:8a65abb0dc63 | 55 | pTracePacket = pPacketRx; |
andrewboyson | 136:8a65abb0dc63 | 56 | pTraceBack = traceback; |
andrewboyson | 37:793b39683406 | 57 | |
andrewboyson | 136:8a65abb0dc63 | 58 | char* pDataRx = pPacketRx + IP6_HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 59 | char* pDataTx = pPacketTx + IP6_HEADER_LENGTH; |
andrewboyson | 59:e0e556c8bd46 | 60 | |
andrewboyson | 136:8a65abb0dc63 | 61 | int protocol = Ip6HdrGetProtocol (pPacketRx); |
andrewboyson | 136:8a65abb0dc63 | 62 | int payloadLengthRx = Ip6HdrGetPayloadLen(pPacketRx); |
andrewboyson | 59:e0e556c8bd46 | 63 | |
andrewboyson | 136:8a65abb0dc63 | 64 | static char srcIp[16]; |
andrewboyson | 136:8a65abb0dc63 | 65 | static char dstIp[16]; |
andrewboyson | 136:8a65abb0dc63 | 66 | Ip6AddressCopy(srcIp, Ip6HdrPtrSrc (pPacketRx)); |
andrewboyson | 136:8a65abb0dc63 | 67 | Ip6AddressCopy(dstIp, Ip6HdrPtrDst (pPacketRx)); |
andrewboyson | 59:e0e556c8bd46 | 68 | |
andrewboyson | 136:8a65abb0dc63 | 69 | int dataLengthRx = sizeRx - IP6_HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 70 | if (dataLengthRx > payloadLengthRx) dataLengthRx = payloadLengthRx; //Choose the lesser of the data length and the payload length |
andrewboyson | 136:8a65abb0dc63 | 71 | int dataLengthTx = *pSizeTx - IP6_HEADER_LENGTH; |
andrewboyson | 10:f0854784e960 | 72 | |
andrewboyson | 44:83ce5ace337b | 73 | int scope = SlaacScope(dstIp); |
andrewboyson | 61:aad055f1b0d1 | 74 | bool isMe = scope != SCOPE_NONE; |
andrewboyson | 136:8a65abb0dc63 | 75 | bool isMulticast = Ip6AddrIsMulticast(dstIp); |
andrewboyson | 136:8a65abb0dc63 | 76 | bool isSolicited = Ip6AddrIsSolicited(dstIp); |
andrewboyson | 136:8a65abb0dc63 | 77 | bool isGroup = Ip6AddrIsSameGroup(dstIp, SlaacLinkLocalIp); |
andrewboyson | 10:f0854784e960 | 78 | |
andrewboyson | 61:aad055f1b0d1 | 79 | bool doIt = isMe || (isMulticast && !isSolicited) || (isGroup && isSolicited); |
andrewboyson | 10:f0854784e960 | 80 | |
andrewboyson | 14:e75a59c1123d | 81 | if (!doIt) |
andrewboyson | 14:e75a59c1123d | 82 | { |
andrewboyson | 48:952dddb74b8b | 83 | if (Ip6Trace) |
andrewboyson | 15:6ca6778168b1 | 84 | { |
andrewboyson | 47:73af5c0b0dc2 | 85 | LogTime("IP6 filtered out ip "); |
andrewboyson | 47:73af5c0b0dc2 | 86 | Ip6AddressLog(dstIp); |
andrewboyson | 47:73af5c0b0dc2 | 87 | LogF(" from "); |
andrewboyson | 47:73af5c0b0dc2 | 88 | Ip6AddressLog(srcIp); |
andrewboyson | 47:73af5c0b0dc2 | 89 | Log("\r\n"); |
andrewboyson | 15:6ca6778168b1 | 90 | } |
andrewboyson | 14:e75a59c1123d | 91 | return DO_NOTHING; |
andrewboyson | 14:e75a59c1123d | 92 | } |
andrewboyson | 10:f0854784e960 | 93 | |
andrewboyson | 57:e0fb648acf48 | 94 | NetTraceHostCheckIp6(srcIp); |
andrewboyson | 57:e0fb648acf48 | 95 | |
andrewboyson | 74:c3756bfa960e | 96 | int remArIndex = Ar6AddIpRecord(trace, macRemote, srcIp); |
andrewboyson | 50:492f2d2954e4 | 97 | Nr6MakeRequestForNameFromIp(srcIp); |
andrewboyson | 11:c051adb70c5a | 98 | |
andrewboyson | 10:f0854784e960 | 99 | int action = DO_NOTHING; |
andrewboyson | 10:f0854784e960 | 100 | switch (protocol) |
andrewboyson | 10:f0854784e960 | 101 | { |
andrewboyson | 61:aad055f1b0d1 | 102 | case HOPOPT: action = DO_NOTHING; break; |
andrewboyson | 59:e0e556c8bd46 | 103 | case ICMP6: action = Icmp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp); break; |
andrewboyson | 59:e0e556c8bd46 | 104 | case UDP: action = Udp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp); break; |
andrewboyson | 74:c3756bfa960e | 105 | case TCP: action = Tcp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp, remArIndex); break; |
andrewboyson | 10:f0854784e960 | 106 | default: |
andrewboyson | 37:793b39683406 | 107 | LogTimeF("IP6 protocol %d unhandled\r\n", protocol); |
andrewboyson | 10:f0854784e960 | 108 | return DO_NOTHING; |
andrewboyson | 10:f0854784e960 | 109 | } |
andrewboyson | 11:c051adb70c5a | 110 | if (!action) return DO_NOTHING; |
andrewboyson | 11:c051adb70c5a | 111 | |
andrewboyson | 136:8a65abb0dc63 | 112 | int hoplimit; |
andrewboyson | 53:77f8a49adf89 | 113 | if (NdpIpNeedsToBeRouted(dstIp)) |
andrewboyson | 53:77f8a49adf89 | 114 | { |
andrewboyson | 59:e0e556c8bd46 | 115 | MacCopy(macRemote, NdpRouterMac); //Send to the router MAC |
andrewboyson | 53:77f8a49adf89 | 116 | hoplimit = NdpHopLimit; |
andrewboyson | 53:77f8a49adf89 | 117 | } |
andrewboyson | 53:77f8a49adf89 | 118 | else |
andrewboyson | 53:77f8a49adf89 | 119 | { |
andrewboyson | 53:77f8a49adf89 | 120 | hoplimit = 255; |
andrewboyson | 53:77f8a49adf89 | 121 | } |
andrewboyson | 59:e0e556c8bd46 | 122 | |
andrewboyson | 136:8a65abb0dc63 | 123 | Ip6HdrSetVersion (pPacketTx, 6 ); |
andrewboyson | 136:8a65abb0dc63 | 124 | Ip6HdrSetPayloadLen(pPacketTx, dataLengthTx); |
andrewboyson | 136:8a65abb0dc63 | 125 | Ip6HdrSetProtocol (pPacketTx, protocol ); |
andrewboyson | 136:8a65abb0dc63 | 126 | Ip6HdrSetHopLimit (pPacketTx, hoplimit ); |
andrewboyson | 136:8a65abb0dc63 | 127 | |
andrewboyson | 136:8a65abb0dc63 | 128 | Ip6AddressCopy(Ip6HdrPtrSrc(pPacketTx), srcIp); |
andrewboyson | 136:8a65abb0dc63 | 129 | Ip6AddressCopy(Ip6HdrPtrDst(pPacketTx), dstIp); |
andrewboyson | 11:c051adb70c5a | 130 | |
andrewboyson | 136:8a65abb0dc63 | 131 | *pSizeTx = IP6_HEADER_LENGTH + dataLengthTx; |
andrewboyson | 10:f0854784e960 | 132 | |
andrewboyson | 136:8a65abb0dc63 | 133 | if (ActionGetTracePart(action)) logHeader(pPacketTx); |
andrewboyson | 37:793b39683406 | 134 | |
andrewboyson | 10:f0854784e960 | 135 | return action; |
andrewboyson | 10:f0854784e960 | 136 | } |
andrewboyson | 136:8a65abb0dc63 | 137 | int Ip6PollForPacketToSend(char* pPacket, int* pSize, char* pDstMac) |
andrewboyson | 10:f0854784e960 | 138 | { |
andrewboyson | 136:8a65abb0dc63 | 139 | static char srcIp[16]; |
andrewboyson | 136:8a65abb0dc63 | 140 | static char dstIp[16]; |
andrewboyson | 10:f0854784e960 | 141 | |
andrewboyson | 136:8a65abb0dc63 | 142 | char* pData = pPacket + IP6_HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 143 | int dataLength = *pSize - IP6_HEADER_LENGTH; |
andrewboyson | 136:8a65abb0dc63 | 144 | |
andrewboyson | 136:8a65abb0dc63 | 145 | int protocol = 0; |
andrewboyson | 10:f0854784e960 | 146 | int action = DO_NOTHING; |
andrewboyson | 71:736a5747ade1 | 147 | if (!action) { action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = ICMP6; } |
andrewboyson | 71:736a5747ade1 | 148 | if (!action) { action = Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = UDP; } |
andrewboyson | 71:736a5747ade1 | 149 | if (!action) { action = Tcp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = TCP; } |
andrewboyson | 11:c051adb70c5a | 150 | if (!action) return DO_NOTHING; |
andrewboyson | 37:793b39683406 | 151 | |
andrewboyson | 136:8a65abb0dc63 | 152 | int hoplimit = 0; |
andrewboyson | 37:793b39683406 | 153 | int dest = ActionGetDestPart(action); |
andrewboyson | 37:793b39683406 | 154 | switch (dest) |
andrewboyson | 11:c051adb70c5a | 155 | { |
andrewboyson | 11:c051adb70c5a | 156 | case UNICAST: |
andrewboyson | 11:c051adb70c5a | 157 | case UNICAST_DNS: |
andrewboyson | 11:c051adb70c5a | 158 | case UNICAST_DHCP: |
andrewboyson | 22:914b970356f0 | 159 | case UNICAST_NTP: |
andrewboyson | 57:e0fb648acf48 | 160 | case UNICAST_TFTP: |
andrewboyson | 53:77f8a49adf89 | 161 | if (NdpIpNeedsToBeRouted(dstIp)) |
andrewboyson | 53:77f8a49adf89 | 162 | { |
andrewboyson | 53:77f8a49adf89 | 163 | MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC |
andrewboyson | 53:77f8a49adf89 | 164 | hoplimit = NdpHopLimit; |
andrewboyson | 53:77f8a49adf89 | 165 | } |
andrewboyson | 53:77f8a49adf89 | 166 | else |
andrewboyson | 53:77f8a49adf89 | 167 | { |
andrewboyson | 53:77f8a49adf89 | 168 | Ar6IpToMac(dstIp, pDstMac); //Make the remote MAC from NP |
andrewboyson | 53:77f8a49adf89 | 169 | hoplimit = 255; |
andrewboyson | 53:77f8a49adf89 | 170 | } |
andrewboyson | 11:c051adb70c5a | 171 | break; |
andrewboyson | 22:914b970356f0 | 172 | case MULTICAST_NODE: |
andrewboyson | 22:914b970356f0 | 173 | case MULTICAST_ROUTER: |
andrewboyson | 22:914b970356f0 | 174 | case MULTICAST_MDNS: |
andrewboyson | 22:914b970356f0 | 175 | case MULTICAST_LLMNR: |
andrewboyson | 112:f8694d0b8858 | 176 | case MULTICAST_NTP: |
andrewboyson | 22:914b970356f0 | 177 | case SOLICITED_NODE: |
andrewboyson | 53:77f8a49adf89 | 178 | hoplimit = 255; |
andrewboyson | 22:914b970356f0 | 179 | break; |
andrewboyson | 22:914b970356f0 | 180 | default: |
andrewboyson | 37:793b39683406 | 181 | LogTimeF("Ip6PollForPacketToSend - undefined destination %d\r\n", dest); |
andrewboyson | 53:77f8a49adf89 | 182 | return DO_NOTHING; |
andrewboyson | 11:c051adb70c5a | 183 | } |
andrewboyson | 10:f0854784e960 | 184 | |
andrewboyson | 136:8a65abb0dc63 | 185 | Ip6HdrSetVersion (pPacket, 6 ); |
andrewboyson | 136:8a65abb0dc63 | 186 | Ip6HdrSetPayloadLen(pPacket, dataLength); |
andrewboyson | 136:8a65abb0dc63 | 187 | Ip6HdrSetProtocol (pPacket, protocol ); |
andrewboyson | 136:8a65abb0dc63 | 188 | Ip6HdrSetHopLimit (pPacket, hoplimit ); |
andrewboyson | 136:8a65abb0dc63 | 189 | Ip6AddressCopy(Ip6HdrPtrSrc(pPacket), srcIp); |
andrewboyson | 136:8a65abb0dc63 | 190 | Ip6AddressCopy(Ip6HdrPtrDst(pPacket), dstIp); |
andrewboyson | 11:c051adb70c5a | 191 | |
andrewboyson | 136:8a65abb0dc63 | 192 | *pSize = IP6_HEADER_LENGTH + dataLength; |
andrewboyson | 10:f0854784e960 | 193 | |
andrewboyson | 136:8a65abb0dc63 | 194 | if (ActionGetTracePart(action)) logHeader(pPacket); |
andrewboyson | 37:793b39683406 | 195 | |
andrewboyson | 10:f0854784e960 | 196 | return action; |
andrewboyson | 10:f0854784e960 | 197 | } |