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
net.cpp@9:91dae5300a4d, 2017-04-04 (annotated)
- Committer:
- andrewboyson
- Date:
- Tue Apr 04 10:41:25 2017 +0000
- Revision:
- 9:91dae5300a4d
- Parent:
- 7:b794780e33b4
- Child:
- 10:f0854784e960
IP6 NDP is working for neighbour and router adverts and solicitations.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 7:b794780e33b4 | 1 | #include "mbed.h" |
andrewboyson | 7:b794780e33b4 | 2 | #include "phy.h" |
andrewboyson | 7:b794780e33b4 | 3 | #include "net.h" |
andrewboyson | 7:b794780e33b4 | 4 | #include "tcp.h" |
andrewboyson | 7:b794780e33b4 | 5 | #include "dhcp.h" |
andrewboyson | 9:91dae5300a4d | 6 | #include "ar.h" |
andrewboyson | 7:b794780e33b4 | 7 | #include "dns.h" |
andrewboyson | 7:b794780e33b4 | 8 | #include "slaac.h" |
andrewboyson | 9:91dae5300a4d | 9 | #include "ndp.h" |
andrewboyson | 2:849103b5a16d | 10 | |
andrewboyson | 7:b794780e33b4 | 11 | static void addHexNibble(bool* pAdded, int number, int index, char** pp) |
andrewboyson | 7:b794780e33b4 | 12 | { |
andrewboyson | 7:b794780e33b4 | 13 | int nibble = number; |
andrewboyson | 7:b794780e33b4 | 14 | if (index) nibble >>= 4; |
andrewboyson | 7:b794780e33b4 | 15 | nibble &= 0xF; |
andrewboyson | 7:b794780e33b4 | 16 | |
andrewboyson | 7:b794780e33b4 | 17 | if (nibble || *pAdded) |
andrewboyson | 7:b794780e33b4 | 18 | { |
andrewboyson | 7:b794780e33b4 | 19 | **pp = nibble < 10 ? nibble + '0' : nibble - 10 + 'a'; |
andrewboyson | 7:b794780e33b4 | 20 | *pp += 1; |
andrewboyson | 7:b794780e33b4 | 21 | *pAdded = true; |
andrewboyson | 7:b794780e33b4 | 22 | } |
andrewboyson | 7:b794780e33b4 | 23 | } |
andrewboyson | 7:b794780e33b4 | 24 | int NetIp6AddressToString(char* pIp, int size, char* pText) |
andrewboyson | 7:b794780e33b4 | 25 | { |
andrewboyson | 7:b794780e33b4 | 26 | char* pIpE = pIp + 16; |
andrewboyson | 7:b794780e33b4 | 27 | char* p = pText; |
andrewboyson | 7:b794780e33b4 | 28 | while (true) |
andrewboyson | 7:b794780e33b4 | 29 | { |
andrewboyson | 7:b794780e33b4 | 30 | bool added = false; |
andrewboyson | 7:b794780e33b4 | 31 | if (*pIp || *(pIp + 1)) |
andrewboyson | 7:b794780e33b4 | 32 | { |
andrewboyson | 7:b794780e33b4 | 33 | if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 1, &p); |
andrewboyson | 7:b794780e33b4 | 34 | if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 0), 0, &p); |
andrewboyson | 7:b794780e33b4 | 35 | if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 1, &p); |
andrewboyson | 7:b794780e33b4 | 36 | if (p > pText + size - 2) break; addHexNibble(&added, *(pIp + 1), 0, &p); |
andrewboyson | 7:b794780e33b4 | 37 | } |
andrewboyson | 7:b794780e33b4 | 38 | |
andrewboyson | 7:b794780e33b4 | 39 | pIp += 2; |
andrewboyson | 7:b794780e33b4 | 40 | if (pIp >= pIpE) break; |
andrewboyson | 7:b794780e33b4 | 41 | |
andrewboyson | 7:b794780e33b4 | 42 | if (p > pText + size - 2) break; *p++ = ':'; |
andrewboyson | 7:b794780e33b4 | 43 | } |
andrewboyson | 7:b794780e33b4 | 44 | *p = 0; |
andrewboyson | 7:b794780e33b4 | 45 | return p - pText; |
andrewboyson | 7:b794780e33b4 | 46 | } |
andrewboyson | 7:b794780e33b4 | 47 | int NetIp4AddressToString(uint32_t ip, int size, char* text) |
andrewboyson | 2:849103b5a16d | 48 | { |
andrewboyson | 2:849103b5a16d | 49 | int a0 = (ip & 0xFF000000) >> 24; |
andrewboyson | 2:849103b5a16d | 50 | int a1 = (ip & 0x00FF0000) >> 16; |
andrewboyson | 2:849103b5a16d | 51 | int a2 = (ip & 0x0000FF00) >> 8; |
andrewboyson | 2:849103b5a16d | 52 | int a3 = (ip & 0x000000FF); |
andrewboyson | 7:b794780e33b4 | 53 | return snprintf(text, size, "%d.%d.%d.%d", a3, a2, a1, a0); |
andrewboyson | 7:b794780e33b4 | 54 | } |
andrewboyson | 7:b794780e33b4 | 55 | int NetMacToString(char* mac, int size, char* text) |
andrewboyson | 7:b794780e33b4 | 56 | { |
andrewboyson | 9:91dae5300a4d | 57 | return snprintf(text, size, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
andrewboyson | 2:849103b5a16d | 58 | } |
andrewboyson | 9:91dae5300a4d | 59 | void NetProtocolToString(uint8_t protocol, int size, char* text) |
andrewboyson | 2:849103b5a16d | 60 | { |
andrewboyson | 7:b794780e33b4 | 61 | switch (protocol) |
andrewboyson | 7:b794780e33b4 | 62 | { |
andrewboyson | 9:91dae5300a4d | 63 | case ICMP: strncpy (text, "ICMP4", size); break; |
andrewboyson | 9:91dae5300a4d | 64 | case ICMP6: strncpy (text, "ICMP6", size); break; |
andrewboyson | 9:91dae5300a4d | 65 | case TCP: strncpy (text, "TCP" , size); break; |
andrewboyson | 9:91dae5300a4d | 66 | case UDP: strncpy (text, "UDP" , size); break; |
andrewboyson | 9:91dae5300a4d | 67 | default: snprintf(text, size, "%d", protocol); break; |
andrewboyson | 7:b794780e33b4 | 68 | } |
andrewboyson | 2:849103b5a16d | 69 | } |
andrewboyson | 0:faa09bd4e6bf | 70 | |
andrewboyson | 0:faa09bd4e6bf | 71 | int16_t NetToHost16(int16_t n) |
andrewboyson | 0:faa09bd4e6bf | 72 | { |
andrewboyson | 0:faa09bd4e6bf | 73 | int16_t h; |
andrewboyson | 0:faa09bd4e6bf | 74 | |
andrewboyson | 0:faa09bd4e6bf | 75 | char* pn = (char*)&n; |
andrewboyson | 0:faa09bd4e6bf | 76 | char* ph = (char*)&h + 1; |
andrewboyson | 0:faa09bd4e6bf | 77 | |
andrewboyson | 0:faa09bd4e6bf | 78 | *ph = *pn; ph--; pn++; // 1<-0 |
andrewboyson | 0:faa09bd4e6bf | 79 | *ph = *pn; // 0<-1 |
andrewboyson | 0:faa09bd4e6bf | 80 | |
andrewboyson | 0:faa09bd4e6bf | 81 | return h; |
andrewboyson | 0:faa09bd4e6bf | 82 | } |
andrewboyson | 0:faa09bd4e6bf | 83 | |
andrewboyson | 0:faa09bd4e6bf | 84 | int32_t NetToHost32(int32_t n) |
andrewboyson | 0:faa09bd4e6bf | 85 | { |
andrewboyson | 0:faa09bd4e6bf | 86 | int32_t h; |
andrewboyson | 0:faa09bd4e6bf | 87 | |
andrewboyson | 0:faa09bd4e6bf | 88 | char* pn = (char*)&n; |
andrewboyson | 0:faa09bd4e6bf | 89 | char* ph = (char*)&h + 3; |
andrewboyson | 0:faa09bd4e6bf | 90 | |
andrewboyson | 0:faa09bd4e6bf | 91 | *ph = *pn; ph--; pn++; // 3<-0 |
andrewboyson | 0:faa09bd4e6bf | 92 | *ph = *pn; ph--; pn++; // 2<-1 |
andrewboyson | 0:faa09bd4e6bf | 93 | *ph = *pn; ph--; pn++; // 1<-2 |
andrewboyson | 0:faa09bd4e6bf | 94 | *ph = *pn; // 0<-3 |
andrewboyson | 0:faa09bd4e6bf | 95 | |
andrewboyson | 0:faa09bd4e6bf | 96 | return h; |
andrewboyson | 0:faa09bd4e6bf | 97 | } |
andrewboyson | 0:faa09bd4e6bf | 98 | int64_t NetToHost64(int64_t n) |
andrewboyson | 0:faa09bd4e6bf | 99 | { |
andrewboyson | 0:faa09bd4e6bf | 100 | int64_t h; |
andrewboyson | 0:faa09bd4e6bf | 101 | |
andrewboyson | 0:faa09bd4e6bf | 102 | char* pn = (char*)&n; |
andrewboyson | 0:faa09bd4e6bf | 103 | char* ph = (char*)&h + 7; |
andrewboyson | 0:faa09bd4e6bf | 104 | |
andrewboyson | 0:faa09bd4e6bf | 105 | *ph = *pn; ph--; pn++; // 7<-0 |
andrewboyson | 0:faa09bd4e6bf | 106 | *ph = *pn; ph--; pn++; // 6<-1 |
andrewboyson | 0:faa09bd4e6bf | 107 | *ph = *pn; ph--; pn++; // 5<-2 |
andrewboyson | 0:faa09bd4e6bf | 108 | *ph = *pn; ph--; pn++; // 4<-3 |
andrewboyson | 0:faa09bd4e6bf | 109 | *ph = *pn; ph--; pn++; // 3<-4 |
andrewboyson | 0:faa09bd4e6bf | 110 | *ph = *pn; ph--; pn++; // 2<-5 |
andrewboyson | 0:faa09bd4e6bf | 111 | *ph = *pn; ph--; pn++; // 1<-6 |
andrewboyson | 0:faa09bd4e6bf | 112 | *ph = *pn; // 0<-7 |
andrewboyson | 0:faa09bd4e6bf | 113 | |
andrewboyson | 0:faa09bd4e6bf | 114 | return h; |
andrewboyson | 0:faa09bd4e6bf | 115 | } |
andrewboyson | 0:faa09bd4e6bf | 116 | uint16_t onesComplement(uint16_t start, int count, void* pData) |
andrewboyson | 0:faa09bd4e6bf | 117 | { |
andrewboyson | 0:faa09bd4e6bf | 118 | uint32_t sum = start; //Initialise the 32 bit accumulator with the last sum |
andrewboyson | 0:faa09bd4e6bf | 119 | uint16_t* p = (uint16_t*)pData; //Set up a 16 bit pointer for the data |
andrewboyson | 0:faa09bd4e6bf | 120 | |
andrewboyson | 0:faa09bd4e6bf | 121 | while(count > 1) |
andrewboyson | 0:faa09bd4e6bf | 122 | { |
andrewboyson | 0:faa09bd4e6bf | 123 | sum += *p++; // Add each pair of bytes into 32 bit accumulator |
andrewboyson | 0:faa09bd4e6bf | 124 | count -= 2; |
andrewboyson | 0:faa09bd4e6bf | 125 | } |
andrewboyson | 0:faa09bd4e6bf | 126 | if(count) sum += * (uint8_t*) p; // Add left-over byte, if any |
andrewboyson | 0:faa09bd4e6bf | 127 | while (sum>>16) sum = (sum & 0xffff) + (sum >> 16); // Add any carries from the sum back into the sum to make it ones complement |
andrewboyson | 0:faa09bd4e6bf | 128 | return sum; |
andrewboyson | 0:faa09bd4e6bf | 129 | } |
andrewboyson | 0:faa09bd4e6bf | 130 | uint16_t NetCheckSumTwo(int count1, void* pData1, int count2, void* pData2) |
andrewboyson | 0:faa09bd4e6bf | 131 | { |
andrewboyson | 0:faa09bd4e6bf | 132 | uint16_t sum = onesComplement(0, count1, pData1); |
andrewboyson | 0:faa09bd4e6bf | 133 | return ~onesComplement(sum, count2, pData2); |
andrewboyson | 0:faa09bd4e6bf | 134 | } |
andrewboyson | 0:faa09bd4e6bf | 135 | uint16_t NetCheckSum(int count, void* pData) |
andrewboyson | 0:faa09bd4e6bf | 136 | { |
andrewboyson | 0:faa09bd4e6bf | 137 | return ~onesComplement(0, count, pData); |
andrewboyson | 0:faa09bd4e6bf | 138 | } |
andrewboyson | 2:849103b5a16d | 139 | |
andrewboyson | 2:849103b5a16d | 140 | static bool ticked() |
andrewboyson | 2:849103b5a16d | 141 | { |
andrewboyson | 2:849103b5a16d | 142 | static time_t lastT = 0; |
andrewboyson | 2:849103b5a16d | 143 | time_t thisT = time(NULL); |
andrewboyson | 2:849103b5a16d | 144 | bool oneshot = lastT != thisT; |
andrewboyson | 2:849103b5a16d | 145 | lastT = thisT; |
andrewboyson | 2:849103b5a16d | 146 | return oneshot; |
andrewboyson | 2:849103b5a16d | 147 | } |
andrewboyson | 2:849103b5a16d | 148 | |
andrewboyson | 2:849103b5a16d | 149 | int NetInit() |
andrewboyson | 2:849103b5a16d | 150 | { |
andrewboyson | 2:849103b5a16d | 151 | PhyInit(); |
andrewboyson | 2:849103b5a16d | 152 | TcpInit(); |
andrewboyson | 9:91dae5300a4d | 153 | ArInit(); |
andrewboyson | 7:b794780e33b4 | 154 | SlaacInit(); |
andrewboyson | 2:849103b5a16d | 155 | return 0; |
andrewboyson | 2:849103b5a16d | 156 | } |
andrewboyson | 2:849103b5a16d | 157 | int NetMain() |
andrewboyson | 2:849103b5a16d | 158 | { |
andrewboyson | 2:849103b5a16d | 159 | PhyMain(); |
andrewboyson | 9:91dae5300a4d | 160 | ArMain(); |
andrewboyson | 2:849103b5a16d | 161 | if (ticked()) |
andrewboyson | 2:849103b5a16d | 162 | { |
andrewboyson | 2:849103b5a16d | 163 | DhcpTick(); |
andrewboyson | 9:91dae5300a4d | 164 | ArTick(); |
andrewboyson | 7:b794780e33b4 | 165 | DnsTick(); |
andrewboyson | 9:91dae5300a4d | 166 | NdpTick(); |
andrewboyson | 2:849103b5a16d | 167 | } |
andrewboyson | 2:849103b5a16d | 168 | return 0; |
andrewboyson | 2:849103b5a16d | 169 | } |