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@172:9bc3c7b2cca1, 2020-12-16 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Dec 16 17:33:22 2020 +0000
- Revision:
- 172:9bc3c7b2cca1
- Parent:
- 136:8a65abb0dc63
- Child:
- 187:122fc1996c86
Modified name resolution to work with both IPv4 and IPv6. Before there were two independent modules.
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 | 172:9bc3c7b2cca1 | 10 | #include "nr.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 | 172:9bc3c7b2cca1 | 32 | Log (" Source IP "); Ip6AddrLog (Ip6HdrPtrSrc (pPacket)); Log("\r\n"); |
andrewboyson | 172:9bc3c7b2cca1 | 33 | Log (" Destination IP "); Ip6AddrLog (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 | 172:9bc3c7b2cca1 | 40 | Ip6AddrLog (Ip6HdrPtrSrc (pPacket)); |
andrewboyson | 43:bc028d5a6424 | 41 | Log(" >>> "); |
andrewboyson | 172:9bc3c7b2cca1 | 42 | Ip6AddrLog (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 | 172:9bc3c7b2cca1 | 66 | Ip6AddrCopy(srcIp, Ip6HdrPtrSrc (pPacketRx)); |
andrewboyson | 172:9bc3c7b2cca1 | 67 | Ip6AddrCopy(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 | 172:9bc3c7b2cca1 | 86 | Ip6AddrLog(dstIp); |
andrewboyson | 47:73af5c0b0dc2 | 87 | LogF(" from "); |
andrewboyson | 172:9bc3c7b2cca1 | 88 | Ip6AddrLog(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 | 172:9bc3c7b2cca1 | 97 | NrMakeRequestForNameFromAddress6(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 | 172:9bc3c7b2cca1 | 128 | Ip6AddrCopy(Ip6HdrPtrSrc(pPacketTx), srcIp); |
andrewboyson | 172:9bc3c7b2cca1 | 129 | Ip6AddrCopy(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 | 172:9bc3c7b2cca1 | 189 | Ip6AddrCopy(Ip6HdrPtrSrc(pPacket), srcIp); |
andrewboyson | 172:9bc3c7b2cca1 | 190 | Ip6AddrCopy(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 | } |