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/ndp/ndp.cpp@46:40d33e9037e4, 2017-10-24 (annotated)
- Committer:
 - andrewboyson
 - Date:
 - Tue Oct 24 07:01:35 2017 +0000
 - Revision:
 - 46:40d33e9037e4
 - Child:
 - 47:73af5c0b0dc2
 
Tidied up the RA module
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| andrewboyson | 46:40d33e9037e4 | 1 | #include "mbed.h" | 
| andrewboyson | 46:40d33e9037e4 | 2 | #include "log.h" | 
| andrewboyson | 46:40d33e9037e4 | 3 | #include "mac.h" | 
| andrewboyson | 46:40d33e9037e4 | 4 | #include "ip6.h" | 
| andrewboyson | 46:40d33e9037e4 | 5 | #include "slaac.h" | 
| andrewboyson | 46:40d33e9037e4 | 6 | #include "clock.h" | 
| andrewboyson | 46:40d33e9037e4 | 7 | #include "rs.h" | 
| andrewboyson | 46:40d33e9037e4 | 8 | |
| andrewboyson | 46:40d33e9037e4 | 9 | int NdpHopLimit = 0; | 
| andrewboyson | 46:40d33e9037e4 | 10 | bool NdpManagedAddressConfiguration = false; | 
| andrewboyson | 46:40d33e9037e4 | 11 | bool NdpOtherConfiguration = false; | 
| andrewboyson | 46:40d33e9037e4 | 12 | int NdpLifetime = 0; | 
| andrewboyson | 46:40d33e9037e4 | 13 | |
| andrewboyson | 46:40d33e9037e4 | 14 | char NdpRouterMac[6]; | 
| andrewboyson | 46:40d33e9037e4 | 15 | |
| andrewboyson | 46:40d33e9037e4 | 16 | int NdpPrefixLength = 0; | 
| andrewboyson | 46:40d33e9037e4 | 17 | uint8_t NdpPrefixLA = 0; | 
| andrewboyson | 46:40d33e9037e4 | 18 | uint32_t NdpPrefixValidLifetime = 0; | 
| andrewboyson | 46:40d33e9037e4 | 19 | uint32_t NdpPrefixPreferredLifetime = 0; | 
| andrewboyson | 46:40d33e9037e4 | 20 | char NdpPrefix[16]; | 
| andrewboyson | 46:40d33e9037e4 | 21 | |
| andrewboyson | 46:40d33e9037e4 | 22 | uint32_t NdpDnsLifetime = 0; | 
| andrewboyson | 46:40d33e9037e4 | 23 | char NdpDnsServer[16]; | 
| andrewboyson | 46:40d33e9037e4 | 24 | |
| andrewboyson | 46:40d33e9037e4 | 25 | int NdpMtu = 0; | 
| andrewboyson | 46:40d33e9037e4 | 26 | |
| andrewboyson | 46:40d33e9037e4 | 27 | uint32_t NdpElapsedTime = 0; //Reset whenever an IP address request has been acknowledged | 
| andrewboyson | 46:40d33e9037e4 | 28 | |
| andrewboyson | 46:40d33e9037e4 | 29 | static char dstMAC[6]; | 
| andrewboyson | 46:40d33e9037e4 | 30 | |
| andrewboyson | 46:40d33e9037e4 | 31 | bool NdpIpNeedsToBeRouted(char* ip) | 
| andrewboyson | 46:40d33e9037e4 | 32 | { | 
| andrewboyson | 46:40d33e9037e4 | 33 | //Check address is assigned to internet | 
| andrewboyson | 46:40d33e9037e4 | 34 | if (*(ip + 0) != 0x20) return false; | 
| andrewboyson | 46:40d33e9037e4 | 35 | if (*(ip + 1) != 0x00) return false; | 
| andrewboyson | 46:40d33e9037e4 | 36 | |
| andrewboyson | 46:40d33e9037e4 | 37 | //Check it is not our own prefix | 
| andrewboyson | 46:40d33e9037e4 | 38 | if (memcmp(ip, NdpPrefix, 8) == 0) return false; | 
| andrewboyson | 46:40d33e9037e4 | 39 | |
| andrewboyson | 46:40d33e9037e4 | 40 | return true; | 
| andrewboyson | 46:40d33e9037e4 | 41 | } | 
| andrewboyson | 46:40d33e9037e4 | 42 | |
| andrewboyson | 46:40d33e9037e4 | 43 | static uint32_t decodeUint32(char* p) | 
| andrewboyson | 46:40d33e9037e4 | 44 | { | 
| andrewboyson | 46:40d33e9037e4 | 45 | uint32_t value = 0; | 
| andrewboyson | 46:40d33e9037e4 | 46 | value |= *p++ << 24; | 
| andrewboyson | 46:40d33e9037e4 | 47 | value |= *p++ << 12; | 
| andrewboyson | 46:40d33e9037e4 | 48 | value |= *p++ << 8; | 
| andrewboyson | 46:40d33e9037e4 | 49 | value |= *p++ << 0; | 
| andrewboyson | 46:40d33e9037e4 | 50 | return value; | 
| andrewboyson | 46:40d33e9037e4 | 51 | } | 
| andrewboyson | 46:40d33e9037e4 | 52 | static int decodeOption(char* p) | 
| andrewboyson | 46:40d33e9037e4 | 53 | { | 
| andrewboyson | 46:40d33e9037e4 | 54 | int type = *p++; | 
| andrewboyson | 46:40d33e9037e4 | 55 | int size = *p++; | 
| andrewboyson | 46:40d33e9037e4 | 56 | switch (type) | 
| andrewboyson | 46:40d33e9037e4 | 57 | { | 
| andrewboyson | 46:40d33e9037e4 | 58 | case 1: | 
| andrewboyson | 46:40d33e9037e4 | 59 | MacCopy(NdpRouterMac, p); | 
| andrewboyson | 46:40d33e9037e4 | 60 | break; | 
| andrewboyson | 46:40d33e9037e4 | 61 | case 2: | 
| andrewboyson | 46:40d33e9037e4 | 62 | MacCopy(dstMAC, p); | 
| andrewboyson | 46:40d33e9037e4 | 63 | break; | 
| andrewboyson | 46:40d33e9037e4 | 64 | case 3: | 
| andrewboyson | 46:40d33e9037e4 | 65 | NdpPrefixLength = *p++; | 
| andrewboyson | 46:40d33e9037e4 | 66 | NdpPrefixLA = *p++; | 
| andrewboyson | 46:40d33e9037e4 | 67 | NdpPrefixValidLifetime = decodeUint32(p); | 
| andrewboyson | 46:40d33e9037e4 | 68 | p += 4; | 
| andrewboyson | 46:40d33e9037e4 | 69 | NdpPrefixPreferredLifetime = decodeUint32(p); | 
| andrewboyson | 46:40d33e9037e4 | 70 | p += 4; | 
| andrewboyson | 46:40d33e9037e4 | 71 | p += 4; //Skip gracefully past the Reserved2 field | 
| andrewboyson | 46:40d33e9037e4 | 72 | Ip6Copy(NdpPrefix, p); | 
| andrewboyson | 46:40d33e9037e4 | 73 | SlaacMakeGlobal(NdpPrefix); | 
| andrewboyson | 46:40d33e9037e4 | 74 | break; | 
| andrewboyson | 46:40d33e9037e4 | 75 | case 5: | 
| andrewboyson | 46:40d33e9037e4 | 76 | p += 2; //Skip past the reserved field | 
| andrewboyson | 46:40d33e9037e4 | 77 | NdpMtu = decodeUint32(p); | 
| andrewboyson | 46:40d33e9037e4 | 78 | break; | 
| andrewboyson | 46:40d33e9037e4 | 79 | case 25: | 
| andrewboyson | 46:40d33e9037e4 | 80 | p += 2; //Skip past the reserved field | 
| andrewboyson | 46:40d33e9037e4 | 81 | NdpDnsLifetime = decodeUint32(p); | 
| andrewboyson | 46:40d33e9037e4 | 82 | p += 4; | 
| andrewboyson | 46:40d33e9037e4 | 83 | Ip6Copy(NdpDnsServer, p); | 
| andrewboyson | 46:40d33e9037e4 | 84 | break; | 
| andrewboyson | 46:40d33e9037e4 | 85 | default: | 
| andrewboyson | 46:40d33e9037e4 | 86 | LogF(" Unknown option %d\r\n", type); | 
| andrewboyson | 46:40d33e9037e4 | 87 | break; | 
| andrewboyson | 46:40d33e9037e4 | 88 | } | 
| andrewboyson | 46:40d33e9037e4 | 89 | return size * 8; | 
| andrewboyson | 46:40d33e9037e4 | 90 | } | 
| andrewboyson | 46:40d33e9037e4 | 91 | int NdpAddOptionSourceMac(char* p, char* pMac) | 
| andrewboyson | 46:40d33e9037e4 | 92 | { | 
| andrewboyson | 46:40d33e9037e4 | 93 | *p++ = 1; //Source MAC option | 
| andrewboyson | 46:40d33e9037e4 | 94 | *p++ = 1; //8 bytes | 
| andrewboyson | 46:40d33e9037e4 | 95 | MacCopy(p, pMac); | 
| andrewboyson | 46:40d33e9037e4 | 96 | return 8; | 
| andrewboyson | 46:40d33e9037e4 | 97 | } | 
| andrewboyson | 46:40d33e9037e4 | 98 | static int logOption(char* p) | 
| andrewboyson | 46:40d33e9037e4 | 99 | { | 
| andrewboyson | 46:40d33e9037e4 | 100 | char text[100]; | 
| andrewboyson | 46:40d33e9037e4 | 101 | uint32_t value; | 
| andrewboyson | 46:40d33e9037e4 | 102 | int type = *p++; | 
| andrewboyson | 46:40d33e9037e4 | 103 | int size = *p++; | 
| andrewboyson | 46:40d33e9037e4 | 104 | switch (type) | 
| andrewboyson | 46:40d33e9037e4 | 105 | { | 
| andrewboyson | 46:40d33e9037e4 | 106 | case 1: | 
| andrewboyson | 46:40d33e9037e4 | 107 | MacToString(p, sizeof(text), text); | 
| andrewboyson | 46:40d33e9037e4 | 108 | LogF(" Src MAC %s\r\n", text); | 
| andrewboyson | 46:40d33e9037e4 | 109 | break; | 
| andrewboyson | 46:40d33e9037e4 | 110 | case 2: | 
| andrewboyson | 46:40d33e9037e4 | 111 | MacToString(p, sizeof(text), text); | 
| andrewboyson | 46:40d33e9037e4 | 112 | LogF(" Dst MAC %s\r\n", text); | 
| andrewboyson | 46:40d33e9037e4 | 113 | break; | 
| andrewboyson | 46:40d33e9037e4 | 114 | case 3: | 
| andrewboyson | 46:40d33e9037e4 | 115 | LogF(" Prefix length %d\r\n", *p++); | 
| andrewboyson | 46:40d33e9037e4 | 116 | LogF(" Prefix LA %X\r\n", *p++); | 
| andrewboyson | 46:40d33e9037e4 | 117 | value = decodeUint32(p); p += 4; | 
| andrewboyson | 46:40d33e9037e4 | 118 | LogF(" Prefix valid %u seconds\r\n", value); | 
| andrewboyson | 46:40d33e9037e4 | 119 | value = decodeUint32(p); p += 4; | 
| andrewboyson | 46:40d33e9037e4 | 120 | LogF(" Prefix preferred %u seconds\r\n", value); | 
| andrewboyson | 46:40d33e9037e4 | 121 | p += 4; //Skip gracefully past the Reserved2 field | 
| andrewboyson | 46:40d33e9037e4 | 122 | Ip6AddressToString(p, sizeof(text), text); | 
| andrewboyson | 46:40d33e9037e4 | 123 | LogF(" Prefix %s\r\n", text); | 
| andrewboyson | 46:40d33e9037e4 | 124 | break; | 
| andrewboyson | 46:40d33e9037e4 | 125 | case 5: | 
| andrewboyson | 46:40d33e9037e4 | 126 | p += 2; //Skip past the reserved field | 
| andrewboyson | 46:40d33e9037e4 | 127 | value = decodeUint32(p); | 
| andrewboyson | 46:40d33e9037e4 | 128 | p += 4; | 
| andrewboyson | 46:40d33e9037e4 | 129 | LogF(" MTU %u\r\n", value); | 
| andrewboyson | 46:40d33e9037e4 | 130 | break; | 
| andrewboyson | 46:40d33e9037e4 | 131 | case 25: | 
| andrewboyson | 46:40d33e9037e4 | 132 | p += 2; //Skip past the reserved field | 
| andrewboyson | 46:40d33e9037e4 | 133 | value = decodeUint32(p); | 
| andrewboyson | 46:40d33e9037e4 | 134 | p += 4; | 
| andrewboyson | 46:40d33e9037e4 | 135 | LogF(" DNS lifetime %u\r\n", value); | 
| andrewboyson | 46:40d33e9037e4 | 136 | Ip6AddressToString(p, sizeof(text), text); | 
| andrewboyson | 46:40d33e9037e4 | 137 | LogF(" DNS Server %s\r\n", text); | 
| andrewboyson | 46:40d33e9037e4 | 138 | break; | 
| andrewboyson | 46:40d33e9037e4 | 139 | default: | 
| andrewboyson | 46:40d33e9037e4 | 140 | LogF(" Unknown option %d\r\n", type); | 
| andrewboyson | 46:40d33e9037e4 | 141 | break; | 
| andrewboyson | 46:40d33e9037e4 | 142 | } | 
| andrewboyson | 46:40d33e9037e4 | 143 | return size * 8; | 
| andrewboyson | 46:40d33e9037e4 | 144 | } | 
| andrewboyson | 46:40d33e9037e4 | 145 | void NdpDecodeOptions(char* pData, int dataLength) | 
| andrewboyson | 46:40d33e9037e4 | 146 | { | 
| andrewboyson | 46:40d33e9037e4 | 147 | char* p = pData; | 
| andrewboyson | 46:40d33e9037e4 | 148 | char* pE = pData + dataLength; | 
| andrewboyson | 46:40d33e9037e4 | 149 | while(p < pE) p += decodeOption(p); | 
| andrewboyson | 46:40d33e9037e4 | 150 | } | 
| andrewboyson | 46:40d33e9037e4 | 151 | void NdpLogOptions(char* pData, int dataLength) | 
| andrewboyson | 46:40d33e9037e4 | 152 | { | 
| andrewboyson | 46:40d33e9037e4 | 153 | char* p = pData; | 
| andrewboyson | 46:40d33e9037e4 | 154 | char* pE = pData + dataLength; | 
| andrewboyson | 46:40d33e9037e4 | 155 | while(p < pE) p += logOption(p); | 
| andrewboyson | 46:40d33e9037e4 | 156 | } |