Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
ip6/icmp/ns.cpp
- Committer:
- andrewboyson
- Date:
- 2017-10-19
- Revision:
- 43:bc028d5a6424
File content as of revision 43:bc028d5a6424:
#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"
bool NsTraceRecvSol = false;
bool NsTraceRecvAdv = false;
bool NsTraceSendSol = false;
static char srcMAC[6];
static char tgtMAC[6];
char NsAddressToResolve[16];
bool NsResolveRequestFlag = false;
static int logOptions(char* p)
{
int type = *p++;
int size = *p++;
char text[100];
switch (type)
{
case 1:
MacToString(p, sizeof(text), text);
LogF(" Src MAC %s\r\n", text);
break;
case 2:
MacToString(p, sizeof(text), text);
LogF(" Tgt MAC %s\r\n", text);
break;
default:
LogF(" Unknown option %d\r\n", type);
break;
}
return size * 8;
}
void logHeader(void* pPacket, int* pSize)
{
__packed struct header
{
uint32_t reserved;
char target[16];
};
struct header* pHeader = (header*)pPacket;
char* pData = (char*)pHeader + sizeof(struct header);
int dataLength = *pSize - sizeof(struct header);
Log("NDP header\r\n");
LogF(" Size %d\r\n", *pSize);
char text[100];
Ip6AddressToString(pHeader->target, sizeof(text), text);
LogF(" Target %s\r\n", text);
char* p = pData;
char* pE = pData + dataLength;
while(p < pE) p += logOptions(p);
}
static int decodeOptions(char* p)
{
int type = *p++;
int size = *p++;
switch (type)
{
case 1:
memcpy(srcMAC, p, 6);
break;
case 2:
memcpy(tgtMAC, p, 6);
break;
default:
LogF(" Unknown option %d\r\n", type);
break;
}
return size * 8;
}
int NsHandleReceivedSolicitation(void (*traceback)(void), void* pPacket, int* pSize, uint8_t* pType, uint8_t* pCode)
{
__packed struct header
{
uint32_t reserved;
char target[16];
};
struct header* pHeader = (header*)pPacket;
char* pData = (char*)pHeader + sizeof(struct header);
int dataLength = *pSize - sizeof(struct header);
//Check it is us
if (!SlaacIsMe(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);
}
char* p = pData;
char* pE = pData + dataLength;
while(p < pE) p += decodeOptions(p);
//Send advertisement
*pType = 136;
*pCode = 0;
pHeader->reserved = 0x00000060; //R=0 (not a router); S=1 (solicited); O=1 (override)
//pHeader->target is unchanged
p = pData;
*p++ = 2; //Target MAC option
*p++ = 1; //8 bytes
memcpy(p, MacLocal, 6);
p += 6;
*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)
{
__packed struct header
{
uint32_t reserved;
char target[16];
};
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* p = pData;
char* pE = pData + dataLength;
while(p < pE) p += decodeOptions(p);
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;
__packed struct header
{
uint32_t reserved;
char target[16];
};
struct header* pHeader = (header*)pPacket;
pHeader->reserved = 0;
memcpy(pHeader->target, NsAddressToResolve, 16);
*pSize = sizeof(struct header);
*pType = 135; //Neighbour solicitation
*pCode = 0;
char* pData = (char*)pHeader + sizeof(struct header);
char* p = pData;
*p++ = 1; //Source MAC option
*p++ = 1; //8 bytes
memcpy(p, MacLocal, 6);
p += 6;
*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);
}