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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ip6.c Source File

ip6.c

00001 #include <stdint.h>
00002 #include <stdbool.h>
00003 
00004 #include     "log.h"
00005 #include     "net.h"
00006 #include  "action.h"
00007 #include   "icmp6.h"
00008 #include "udptcp6.h"
00009 #include     "ar6.h"
00010 #include      "nr.h"
00011 #include   "slaac.h"
00012 #include     "eth.h"
00013 #include      "ip.h"
00014 #include "ip6addr.h"
00015 #include  "ip6hdr.h"
00016 #include     "ndp.h"
00017 #include     "ntp.h"
00018 #include     "mac.h"
00019 #include    "http.h"
00020 
00021 bool Ip6Trace = true;
00022 
00023 static void logHeader(char* pPacket)
00024 {
00025     if (NetTraceVerbose)
00026     {
00027         Log("IP6 header\r\n");
00028         LogF("  Version           %d\r\n",          Ip6HdrGetVersion   (pPacket));
00029         LogF("  Payload length    %d\r\n",          Ip6HdrGetPayloadLen(pPacket));
00030         LogF("  Hop limit         %d\r\n",          Ip6HdrGetHopLimit  (pPacket));
00031         LogF("  Protocol          "); IpProtocolLog(Ip6HdrGetProtocol  (pPacket)); Log("\r\n");
00032         Log ("  Source IP         "); Ip6AddrLog   (Ip6HdrPtrSrc       (pPacket)); Log("\r\n");
00033         Log ("  Destination IP    "); Ip6AddrLog   (Ip6HdrPtrDst       (pPacket)); Log("\r\n");
00034     }
00035     else
00036     {
00037         Log("IP6   header ");
00038         IpProtocolLog(Ip6HdrGetProtocol(pPacket));
00039         Log(" ");
00040         Ip6AddrLog   (Ip6HdrPtrSrc     (pPacket));
00041         Log(" >>> ");
00042         Ip6AddrLog   (Ip6HdrPtrDst     (pPacket));
00043         Log("\r\n");
00044     }
00045 }
00046 static char* pTracePacket;
00047 static void (*pTraceBack)(void);
00048 static void trace()
00049 {
00050     pTraceBack();
00051     logHeader(pTracePacket);
00052 }
00053 int Ip6HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* macRemote)
00054 {    
00055     pTracePacket = pPacketRx;
00056     pTraceBack   = traceback;
00057     
00058     char* pDataRx = pPacketRx + IP6_HEADER_LENGTH;
00059     char* pDataTx = pPacketTx + IP6_HEADER_LENGTH;
00060     
00061     int protocol        = Ip6HdrGetProtocol  (pPacketRx);
00062     int payloadLengthRx = Ip6HdrGetPayloadLen(pPacketRx);
00063     
00064     static char srcIp[16];
00065     static char dstIp[16];
00066     Ip6AddrCopy(srcIp, Ip6HdrPtrSrc (pPacketRx));
00067     Ip6AddrCopy(dstIp, Ip6HdrPtrDst (pPacketRx));
00068     
00069     int dataLengthRx = sizeRx - IP6_HEADER_LENGTH;
00070     if (dataLengthRx > payloadLengthRx) dataLengthRx = payloadLengthRx; //Choose the lesser of the data length and the payload length
00071     int dataLengthTx = *pSizeTx - IP6_HEADER_LENGTH;
00072     
00073     int  scope       = SlaacScope(dstIp);
00074     bool isMe        = scope != SCOPE_NONE;
00075     bool isMulticast = Ip6AddrIsMulticast(dstIp);
00076     bool isSolicited = Ip6AddrIsSolicited(dstIp);
00077     bool isGroup     = Ip6AddrIsSameGroup(dstIp, SlaacLinkLocalIp);
00078     
00079     bool doIt = isMe || (isMulticast && !isSolicited) || (isGroup && isSolicited);
00080     
00081     if (!doIt)
00082     {
00083         if (Ip6Trace)
00084         {
00085             LogTime("IP6 filtered out ip ");
00086             Ip6AddrLog(dstIp);
00087             LogF(" from ");
00088             Ip6AddrLog(srcIp);
00089             Log("\r\n");
00090         }
00091         return DO_NOTHING;
00092     }
00093     
00094     NetTraceHostCheckIp6(srcIp);
00095     
00096     int remArIndex = Ar6AddIpRecord(trace, macRemote, srcIp);
00097     NrMakeRequestForNameFromAddress6(srcIp);
00098 
00099     int action = DO_NOTHING;
00100     switch (protocol)
00101     {
00102         case HOPOPT: action = DO_NOTHING;                                                                                           break;
00103         case ICMP6:  action = Icmp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp); break;
00104         case UDP:    action =  Udp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp); break;
00105         case TCP:    action =  Tcp6HandleReceivedPacket(trace, scope, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, srcIp, dstIp, remArIndex); break;        
00106         default:
00107             LogTimeF("IP6 protocol %d unhandled\r\n", protocol);
00108             return DO_NOTHING;
00109     }
00110     if (!action) return DO_NOTHING;
00111     
00112     int hoplimit;
00113     if (Ip6AddrIsExternal(dstIp))
00114     {
00115         MacCopy(macRemote, NdpRouterMac); //Send to the router MAC
00116         hoplimit = NdpHopLimit;
00117     }
00118     else
00119     {
00120         hoplimit = 255;
00121     }
00122     
00123     Ip6HdrSetVersion   (pPacketTx, 6           );
00124     Ip6HdrSetPayloadLen(pPacketTx, dataLengthTx);
00125     Ip6HdrSetProtocol  (pPacketTx, protocol    );
00126     Ip6HdrSetHopLimit  (pPacketTx, hoplimit    );
00127     
00128     Ip6AddrCopy(Ip6HdrPtrSrc(pPacketTx), srcIp);
00129     Ip6AddrCopy(Ip6HdrPtrDst(pPacketTx), dstIp);
00130       
00131     *pSizeTx = IP6_HEADER_LENGTH + dataLengthTx;
00132     
00133     if (ActionGetTracePart(action)) logHeader(pPacketTx);
00134 
00135     return action;
00136 }
00137 int Ip6PollForPacketToSend(char* pPacket, int* pSize, char* pDstMac)
00138 {    
00139     static char srcIp[16];
00140     static char dstIp[16];
00141     
00142     char* pData    = pPacket + IP6_HEADER_LENGTH;
00143     int dataLength = *pSize  - IP6_HEADER_LENGTH;
00144     
00145     int protocol = 0;
00146     int action = DO_NOTHING;
00147     if (!action) { action = Icmp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = ICMP6; }
00148     if (!action) { action =  Udp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = UDP;   }
00149     if (!action) { action =  Tcp6PollForPacketToSend(pData, &dataLength, srcIp, dstIp); protocol = TCP;   }
00150     if (!action) return DO_NOTHING;
00151     
00152     int hoplimit = 0;
00153     int dest = ActionGetDestPart(action);
00154     switch (dest)
00155     {
00156         case UNICAST:
00157         case UNICAST_DNS:
00158         case UNICAST_DHCP:
00159         case UNICAST_NTP:
00160         case UNICAST_TFTP:
00161             if (Ip6AddrIsExternal(dstIp))
00162             {
00163                 MacCopy(pDstMac, NdpRouterMac); //Send to the router MAC
00164                 hoplimit = NdpHopLimit;
00165             }
00166             else
00167             {
00168                 Ar6IpToMac(dstIp, pDstMac); //Make the remote MAC from NP
00169                 hoplimit = 255;
00170             }
00171             break;
00172         case MULTICAST_NODE:
00173         case MULTICAST_ROUTER:
00174         case MULTICAST_MDNS:
00175         case MULTICAST_LLMNR:
00176         case MULTICAST_NTP:
00177         case SOLICITED_NODE:
00178             hoplimit = 255;
00179             break;
00180         default:
00181             LogTimeF("Ip6PollForPacketToSend - undefined destination %d\r\n", dest);
00182             return DO_NOTHING;
00183     }
00184 
00185     Ip6HdrSetVersion   (pPacket, 6         );
00186     Ip6HdrSetPayloadLen(pPacket, dataLength);
00187     Ip6HdrSetProtocol  (pPacket, protocol  );
00188     Ip6HdrSetHopLimit  (pPacket, hoplimit  );
00189     Ip6AddrCopy(Ip6HdrPtrSrc(pPacket), srcIp);
00190     Ip6AddrCopy(Ip6HdrPtrDst(pPacket), dstIp);
00191 
00192     *pSize = IP6_HEADER_LENGTH + dataLength;
00193     
00194     if (ActionGetTracePart(action)) logHeader(pPacket);
00195 
00196     return action;
00197 }