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 ns.c Source File

ns.c

00001 #include <stdint.h>
00002 #include <stdbool.h>
00003 
00004 #include     "log.h"
00005 #include     "net.h"
00006 #include  "action.h"
00007 #include "ip6addr.h"
00008 #include     "mac.h"
00009 #include      "nr.h"
00010 #include     "ar6.h"
00011 #include     "ip6.h"
00012 #include   "slaac.h"
00013 #include     "ndp.h"
00014 
00015 bool NsTraceRecvSol = false;
00016 bool NsTraceRecvAdv = false;
00017 bool NsTraceSendSol = false;
00018 
00019 char NsAddressToResolve[16];
00020 bool NsResolveRequestFlag = false;
00021 
00022 static char* hdrPtrReserved(char* pPacket) { return pPacket +  0; } // 4
00023 static char* hdrPtrTarget  (char* pPacket) { return pPacket +  4; } //16
00024 const int HEADER_LENGTH = 20;
00025 static void  hdrSetReserved(char* pPacket, uint32_t value) { NetInvert32(hdrPtrReserved(pPacket), &value); }
00026 
00027 static void logHeader(char* pPacket, int size)
00028 {
00029     char* pData = pPacket + HEADER_LENGTH;
00030     int dataLength = size - HEADER_LENGTH;
00031     
00032     if (NetTraceVerbose)
00033     {
00034         Log("NS header\r\n");
00035         LogF("  Size        %d\r\n", size);
00036         LogF("  Target      "); Ip6AddrLog(hdrPtrTarget(pPacket)); Log("\r\n");
00037         NdpLogOptionsVerbose(pData, dataLength);
00038     }
00039     else
00040     {
00041         Log("NS    header ");
00042         Ip6AddrLog(hdrPtrTarget(pPacket));
00043         NdpLogOptionsQuiet(pData, dataLength); 
00044         Log("\r\n");
00045     }
00046 }
00047 static char* pTraceHeader;
00048 static int traceSize;
00049 static void (*pTraceBack)(void);
00050 static void trace()
00051 {
00052     pTraceBack();
00053     logHeader(pTraceHeader, traceSize);
00054 }
00055 int NsHandleReceivedSolicitation(void (*traceback)(void), uint8_t* pType, uint8_t* pCode, char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx)
00056 {
00057     pTraceBack = traceback;
00058     
00059     pTraceHeader = pPacketRx;
00060     traceSize = sizeRx;
00061     
00062     //Check it is us
00063     if (!SlaacScope(hdrPtrTarget(pPacketRx))) return DO_NOTHING;
00064 
00065     if (NsTraceRecvSol)
00066     {
00067         if (NetTraceNewLine) Log("\r\n");
00068         LogTimeF("NDP received neighbour solicit\r\n");
00069         if (NetTraceStack) traceback();
00070         logHeader(pPacketRx, sizeRx);
00071     }
00072     
00073     //Send advertisement
00074     *pType = 136;
00075     *pCode = 0;
00076     hdrSetReserved(pPacketTx, 0x60000000); //R=0 (not a router); S=1 (solicited); O=1 (override)
00077     Ip6AddrCopy(hdrPtrTarget(pPacketTx), hdrPtrTarget(pPacketRx)); //Target does not change
00078     
00079     //Add target MAC
00080     char* pDataTx = pPacketTx + HEADER_LENGTH;
00081     char* p = pDataTx;
00082     p += NdpAddOptionTargetMac(p, MacLocal);
00083 
00084     *pSizeTx = HEADER_LENGTH + p - pDataTx;
00085     
00086     if (NsTraceRecvSol) logHeader(pPacketTx, *pSizeTx);
00087     
00088     return ActionMakeFromDestAndTrace(UNICAST, NsTraceRecvSol && NetTraceStack);
00089 }
00090 int NsHandleReceivedAdvertisement(void (*traceback)(void), char* pPacket, int* pSize)
00091 {
00092     pTraceBack = traceback;
00093     char* pData    = pPacket + HEADER_LENGTH;
00094     int dataLength = *pSize  - HEADER_LENGTH;
00095     
00096     if (NsTraceRecvAdv)
00097     {
00098         if (NetTraceNewLine) Log("\r\n");
00099         LogTimeF("NDP received neighbour advertise\r\n");
00100         if (NetTraceStack) traceback();
00101         logHeader(pPacket, *pSize);
00102     }
00103     
00104     char tgtMac[6];
00105     NdpDecodeOptions(pData, dataLength, NULL, tgtMac);
00106     
00107     Ar6AddIpRecord(trace, tgtMac, hdrPtrTarget(pPacket));
00108     NrMakeRequestForNameFromAddress6(hdrPtrTarget(pPacket));
00109     
00110     return DO_NOTHING;
00111 }
00112 
00113 int NsGetWaitingSolicitation(char* pPacket, int* pSize, uint8_t* pType, uint8_t* pCode)
00114 {  
00115     if (!NsResolveRequestFlag) return DO_NOTHING;
00116     NsResolveRequestFlag = false;
00117 
00118     *pType = 135; //Neighbour solicitation
00119     *pCode = 0;
00120         
00121     hdrSetReserved(pPacket, 0);
00122     Ip6AddrCopy(hdrPtrTarget(pPacket), NsAddressToResolve);
00123     
00124     char* pData = pPacket + HEADER_LENGTH;
00125     char* p = pData;
00126     p += NdpAddOptionSourceMac(p, MacLocal);
00127     
00128     *pSize = HEADER_LENGTH + p - pData;
00129 
00130     if (NsTraceSendSol)
00131     {
00132         if (NetTraceNewLine) Log("\r\n");
00133         LogTimeF("NDP sent neighbour solicit\r\n");
00134         logHeader(pPacket, *pSize);
00135     }
00136     
00137     return ActionMakeFromDestAndTrace(MULTICAST_NODE, NsTraceSendSol && NetTraceStack);
00138     
00139 }