Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

ip6/icmp/ndp/ns.cpp

Committer:
andrewboyson
Date:
2017-10-26
Revision:
47:73af5c0b0dc2
Parent:
46:40d33e9037e4
Child:
48:952dddb74b8b

File content as of revision 47:73af5c0b0dc2:

#include   "mbed.h"
#include    "log.h"
#include    "net.h"
#include "action.h"
#include    "ip6.h"
#include    "mac.h"
#include     "nr.h"
#include     "ar.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(void* pPacket, int size)
{
    struct header* pHeader = (header*)pPacket;
    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");
    }
}

int NsHandleReceivedSolicitation(void (*traceback)(void), void* pPacket, int* pSize, uint8_t* pType, uint8_t* pCode)
{
    struct header* pHeader = (header*)pPacket;
    char* pData = (char*)pHeader + sizeof(struct header);
    
    //Check it is us
    if (!SlaacScope(pHeader->target)) return DO_NOTHING;

    if (NsTraceRecvSol)
    {
        if (NetTraceNewLine) Log("\r\n");
        LogTimeF("NDP received neighbour solicit\r\n");
        if (NetTraceStack) traceback();
        logHeader(pPacket, *pSize);
    }
    
    //Send advertisement
    *pType = 136;
    *pCode = 0;
    pHeader->reserved = 0x00000060; //R=0 (not a router); S=1 (solicited); O=1 (override)
                                    //pHeader->target is unchanged
    
    //Add target MAC
    char* p = pData;
    p += NdpAddOptionTargetMac(p, MacLocal);
    
    *pSize = sizeof(struct header) + p - pData;
    
    if (NsTraceRecvSol) logHeader(pPacket, *pSize);
    
    return ActionMakeFromDestAndTrace(UNICAST, NsTraceRecvSol && NetTraceStack);

}
int NsHandleReceivedAdvertisement(void (*traceback)(void), void* pPacket, int* pSize)
{
    struct header* pHeader = (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(pPacket, *pSize);
    }
    
    char tgtMac[6];
    NdpDecodeOptions(pData, dataLength, NULL, tgtMac);
    
    ArAddIp6Record(tgtMac, pHeader->target);
    NrMakeRequestForNameFromIp6(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 = (header*)pPacket;
    pHeader->reserved = 0;
    Ip6Copy(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(pPacket, *pSize);
    }
    
    return ActionMakeFromDestAndTrace(MULTICAST_NODE, NsTraceSendSol && NetTraceStack);
    
}