Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Revision:
61:aad055f1b0d1
Parent:
59:e0e556c8bd46
Child:
136:8a65abb0dc63
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ip6/icmp/ndp/ns.c	Thu Jan 11 17:38:21 2018 +0000
@@ -0,0 +1,145 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+#include    "log.h"
+#include    "net.h"
+#include "action.h"
+#include "ip6addr.h"
+#include    "mac.h"
+#include    "nr6.h"
+#include    "ar6.h"
+#include    "ip6.h"
+#include  "slaac.h"
+#include    "ndp.h"
+
+bool NsTraceRecvSol = false;
+bool NsTraceRecvAdv = false;
+bool NsTraceSendSol = false;
+
+char NsAddressToResolve[16];
+bool NsResolveRequestFlag = false;
+
+__packed struct header
+{
+    uint32_t  reserved;
+    char      target[16];
+};
+
+static void logHeader(struct header* pHeader, int size)
+{
+    char* pData = (char*)pHeader + sizeof(struct header);
+    int dataLength = size - sizeof(struct header);
+    
+    if (NetTraceVerbose)
+    {
+        Log("NS header\r\n");
+        LogF("  Size        %d\r\n", size);
+        LogF("  Target      "); Ip6AddressLog(pHeader->target); Log("\r\n");
+        NdpLogOptionsVerbose(pData, dataLength);
+    }
+    else
+    {
+        Log("NS    header ");
+        Ip6AddressLog(pHeader->target);
+        NdpLogOptionsQuiet(pData, dataLength); 
+        Log("\r\n");
+    }
+}
+static struct header * pTraceHeader;
+static int traceSize;
+static void (*pTraceBack)(void);
+static void trace()
+{
+    pTraceBack();
+    logHeader(pTraceHeader, traceSize);
+}
+int NsHandleReceivedSolicitation(void (*traceback)(void), uint8_t* pType, uint8_t* pCode, void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx)
+{
+    pTraceBack = traceback;
+    struct header* pHeaderRx = (struct header*)pPacketRx;
+    struct header* pHeaderTx = (struct header*)pPacketTx;
+    
+    pTraceHeader = pHeaderRx;
+    traceSize = sizeRx;
+    
+    //Check it is us
+    if (!SlaacScope(pHeaderRx->target)) return DO_NOTHING;
+
+    if (NsTraceRecvSol)
+    {
+        if (NetTraceNewLine) Log("\r\n");
+        LogTimeF("NDP received neighbour solicit\r\n");
+        if (NetTraceStack) traceback();
+        logHeader(pHeaderRx, sizeRx);
+    }
+    
+    //Send advertisement
+    *pType = 136;
+    *pCode = 0;
+    pHeaderTx->reserved = 0x00000060; //R=0 (not a router); S=1 (solicited); O=1 (override)
+    Ip6AddressCopy(pHeaderTx->target, pHeaderRx->target); //Target toes not change
+    
+    //Add target MAC
+    char* pDataTx = (char*)pHeaderTx + sizeof(struct header);
+    char* p = pDataTx;
+    p += NdpAddOptionTargetMac(p, MacLocal);
+    
+    *pSizeTx = sizeof(struct header) + p - pDataTx;
+    
+    if (NsTraceRecvSol) logHeader(pHeaderTx, *pSizeTx);
+    
+    return ActionMakeFromDestAndTrace(UNICAST, NsTraceRecvSol && NetTraceStack);
+
+}
+int NsHandleReceivedAdvertisement(void (*traceback)(void), void* pPacket, int* pSize)
+{
+    pTraceBack = traceback;
+    struct header* pHeader = (struct header*)pPacket;
+    char* pData = (char*)pHeader + sizeof(struct header);
+    int dataLength = *pSize - sizeof(struct header);
+    
+    if (NsTraceRecvAdv)
+    {
+        if (NetTraceNewLine) Log("\r\n");
+        LogTimeF("NDP received neighbour advertise\r\n");
+        if (NetTraceStack) traceback();
+        logHeader(pHeader, *pSize);
+    }
+    
+    char tgtMac[6];
+    NdpDecodeOptions(pData, dataLength, NULL, tgtMac);
+    
+    Ar6AddIpRecord(trace, tgtMac, pHeader->target);
+    Nr6MakeRequestForNameFromIp(pHeader->target);
+    
+    return DO_NOTHING;
+}
+
+int NsGetWaitingSolicitation(void* pPacket, int* pSize, uint8_t* pType, uint8_t* pCode)
+{    
+    if (!NsResolveRequestFlag) return DO_NOTHING;
+    NsResolveRequestFlag = false;
+
+    *pType = 135; //Neighbour solicitation
+    *pCode = 0;
+        
+    struct header* pHeader = (struct header*)pPacket;
+    pHeader->reserved = 0;
+    Ip6AddressCopy(pHeader->target, NsAddressToResolve);
+    
+    char* pData = (char*)pHeader + sizeof(struct header);
+    char* p = pData;
+    p += NdpAddOptionSourceMac(p, MacLocal);
+    
+    *pSize = sizeof(struct header) + p - pData;
+
+    if (NsTraceSendSol)
+    {
+        if (NetTraceNewLine) Log("\r\n");
+        LogTimeF("NDP sent neighbour solicit\r\n");
+        logHeader(pHeader, *pSize);
+    }
+    
+    return ActionMakeFromDestAndTrace(MULTICAST_NODE, NsTraceSendSol && NetTraceStack);
+    
+}