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
eth/mac.c@195:bd5b123143ca, 2021-04-18 (annotated)
- Committer:
- andrewboyson
- Date:
- Sun Apr 18 19:04:48 2021 +0000
- Revision:
- 195:bd5b123143ca
- Parent:
- 172:9bc3c7b2cca1
Added a user module to allow user defined UDPs port to be used - in this case for a WIZ module.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 61:aad055f1b0d1 | 1 | #include <stdbool.h> |
andrewboyson | 61:aad055f1b0d1 | 2 | #include <string.h> |
andrewboyson | 61:aad055f1b0d1 | 3 | #include <stdio.h> |
andrewboyson | 61:aad055f1b0d1 | 4 | |
andrewboyson | 60:1d8c7a1e7483 | 5 | #include "log.h" |
andrewboyson | 60:1d8c7a1e7483 | 6 | #include "net.h" |
andrewboyson | 60:1d8c7a1e7483 | 7 | #include "action.h" |
andrewboyson | 60:1d8c7a1e7483 | 8 | #include "eth.h" |
andrewboyson | 60:1d8c7a1e7483 | 9 | #include "http.h" |
andrewboyson | 60:1d8c7a1e7483 | 10 | |
andrewboyson | 60:1d8c7a1e7483 | 11 | char MacLocal[6]; |
andrewboyson | 60:1d8c7a1e7483 | 12 | void MacClear(char* mac) |
andrewboyson | 60:1d8c7a1e7483 | 13 | { |
andrewboyson | 60:1d8c7a1e7483 | 14 | memset(mac, 0, 6); |
andrewboyson | 60:1d8c7a1e7483 | 15 | } |
andrewboyson | 143:8cec8f08dc54 | 16 | void MacCopy(char* macTo, const char* macFrom) |
andrewboyson | 60:1d8c7a1e7483 | 17 | { |
andrewboyson | 60:1d8c7a1e7483 | 18 | memcpy(macTo, macFrom, 6); |
andrewboyson | 60:1d8c7a1e7483 | 19 | } |
andrewboyson | 143:8cec8f08dc54 | 20 | bool MacIsSame(const char* macA, const char* macB) |
andrewboyson | 60:1d8c7a1e7483 | 21 | { |
andrewboyson | 60:1d8c7a1e7483 | 22 | return memcmp(macA, macB, 6) == 0; |
andrewboyson | 60:1d8c7a1e7483 | 23 | } |
andrewboyson | 143:8cec8f08dc54 | 24 | bool MacIsEmpty(const char* mac) |
andrewboyson | 60:1d8c7a1e7483 | 25 | { |
andrewboyson | 60:1d8c7a1e7483 | 26 | if (*mac) return false; |
andrewboyson | 60:1d8c7a1e7483 | 27 | mac++; if (*mac) return false; |
andrewboyson | 60:1d8c7a1e7483 | 28 | mac++; if (*mac) return false; |
andrewboyson | 60:1d8c7a1e7483 | 29 | mac++; if (*mac) return false; |
andrewboyson | 60:1d8c7a1e7483 | 30 | mac++; if (*mac) return false; |
andrewboyson | 60:1d8c7a1e7483 | 31 | mac++; if (*mac) return false; |
andrewboyson | 60:1d8c7a1e7483 | 32 | return true; |
andrewboyson | 60:1d8c7a1e7483 | 33 | } |
andrewboyson | 60:1d8c7a1e7483 | 34 | |
andrewboyson | 195:bd5b123143ca | 35 | void MacParse(const char *text, char *mac) |
andrewboyson | 195:bd5b123143ca | 36 | { |
andrewboyson | 195:bd5b123143ca | 37 | MacClear(mac); |
andrewboyson | 195:bd5b123143ca | 38 | int field = 0; |
andrewboyson | 195:bd5b123143ca | 39 | int byte = 0; |
andrewboyson | 195:bd5b123143ca | 40 | while(true) |
andrewboyson | 195:bd5b123143ca | 41 | { |
andrewboyson | 195:bd5b123143ca | 42 | switch (*text) |
andrewboyson | 195:bd5b123143ca | 43 | { |
andrewboyson | 195:bd5b123143ca | 44 | case ':': |
andrewboyson | 195:bd5b123143ca | 45 | mac[field] = byte; |
andrewboyson | 195:bd5b123143ca | 46 | field++; |
andrewboyson | 195:bd5b123143ca | 47 | if (field > 6) return; |
andrewboyson | 195:bd5b123143ca | 48 | byte = 0; |
andrewboyson | 195:bd5b123143ca | 49 | break; |
andrewboyson | 195:bd5b123143ca | 50 | case '0': byte <<= 4; byte |= 0; break; |
andrewboyson | 195:bd5b123143ca | 51 | case '1': byte <<= 4; byte |= 1; break; |
andrewboyson | 195:bd5b123143ca | 52 | case '2': byte <<= 4; byte |= 2; break; |
andrewboyson | 195:bd5b123143ca | 53 | case '3': byte <<= 4; byte |= 3; break; |
andrewboyson | 195:bd5b123143ca | 54 | case '4': byte <<= 4; byte |= 4; break; |
andrewboyson | 195:bd5b123143ca | 55 | case '5': byte <<= 4; byte |= 5; break; |
andrewboyson | 195:bd5b123143ca | 56 | case '6': byte <<= 4; byte |= 6; break; |
andrewboyson | 195:bd5b123143ca | 57 | case '7': byte <<= 4; byte |= 7; break; |
andrewboyson | 195:bd5b123143ca | 58 | case '8': byte <<= 4; byte |= 8; break; |
andrewboyson | 195:bd5b123143ca | 59 | case '9': byte <<= 4; byte |= 9; break; |
andrewboyson | 195:bd5b123143ca | 60 | case 'a': |
andrewboyson | 195:bd5b123143ca | 61 | case 'A': byte <<= 4; byte |= 10; break; |
andrewboyson | 195:bd5b123143ca | 62 | case 'b': |
andrewboyson | 195:bd5b123143ca | 63 | case 'B': byte <<= 4; byte |= 11; break; |
andrewboyson | 195:bd5b123143ca | 64 | case 'c': |
andrewboyson | 195:bd5b123143ca | 65 | case 'C': byte <<= 4; byte |= 12; break; |
andrewboyson | 195:bd5b123143ca | 66 | case 'd': |
andrewboyson | 195:bd5b123143ca | 67 | case 'D': byte <<= 4; byte |= 13; break; |
andrewboyson | 195:bd5b123143ca | 68 | case 'e': |
andrewboyson | 195:bd5b123143ca | 69 | case 'E': byte <<= 4; byte |= 14; break; |
andrewboyson | 195:bd5b123143ca | 70 | case 'f': |
andrewboyson | 195:bd5b123143ca | 71 | case 'F': byte <<= 4; byte |= 15; break; |
andrewboyson | 195:bd5b123143ca | 72 | case 0: |
andrewboyson | 195:bd5b123143ca | 73 | mac[field] = byte; |
andrewboyson | 195:bd5b123143ca | 74 | return; |
andrewboyson | 195:bd5b123143ca | 75 | } |
andrewboyson | 195:bd5b123143ca | 76 | text++; |
andrewboyson | 195:bd5b123143ca | 77 | } |
andrewboyson | 195:bd5b123143ca | 78 | } |
andrewboyson | 143:8cec8f08dc54 | 79 | int MacToString(const char* mac, int size, char* text) |
andrewboyson | 60:1d8c7a1e7483 | 80 | { |
andrewboyson | 60:1d8c7a1e7483 | 81 | return snprintf(text, size, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
andrewboyson | 60:1d8c7a1e7483 | 82 | } |
andrewboyson | 143:8cec8f08dc54 | 83 | int MacLog(const char* mac) |
andrewboyson | 60:1d8c7a1e7483 | 84 | { |
andrewboyson | 60:1d8c7a1e7483 | 85 | return LogF("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
andrewboyson | 60:1d8c7a1e7483 | 86 | } |
andrewboyson | 143:8cec8f08dc54 | 87 | int MacHttp(const char* mac) |
andrewboyson | 60:1d8c7a1e7483 | 88 | { |
andrewboyson | 60:1d8c7a1e7483 | 89 | return HttpAddF("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
andrewboyson | 60:1d8c7a1e7483 | 90 | } |
andrewboyson | 60:1d8c7a1e7483 | 91 | |
andrewboyson | 143:8cec8f08dc54 | 92 | int MacAccept(const char* p) |
andrewboyson | 60:1d8c7a1e7483 | 93 | { |
andrewboyson | 60:1d8c7a1e7483 | 94 | switch (*p) |
andrewboyson | 60:1d8c7a1e7483 | 95 | { |
andrewboyson | 60:1d8c7a1e7483 | 96 | case 0xff: //Broadcast |
andrewboyson | 60:1d8c7a1e7483 | 97 | { |
andrewboyson | 60:1d8c7a1e7483 | 98 | p++; if (*p != 0xff) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 99 | p++; if (*p != 0xff) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 100 | p++; if (*p != 0xff) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 101 | p++; if (*p != 0xff) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 102 | p++; if (*p != 0xff) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 103 | return BROADCAST; |
andrewboyson | 60:1d8c7a1e7483 | 104 | } |
andrewboyson | 60:1d8c7a1e7483 | 105 | case 0x01: //Multicast IP4 |
andrewboyson | 60:1d8c7a1e7483 | 106 | { |
andrewboyson | 105:ef2dd21d808c | 107 | p++; if (*p != 0x00) return DO_NOTHING; //01 00 |
andrewboyson | 105:ef2dd21d808c | 108 | p++; if (*p != 0x5e) return DO_NOTHING; //01 00 5E |
andrewboyson | 105:ef2dd21d808c | 109 | p++; if (*p != 0x00) return DO_NOTHING; //01 00 5E 00 |
andrewboyson | 60:1d8c7a1e7483 | 110 | p++; |
andrewboyson | 105:ef2dd21d808c | 111 | switch (*p) |
andrewboyson | 60:1d8c7a1e7483 | 112 | { |
andrewboyson | 105:ef2dd21d808c | 113 | case 0x00: //01 00 5E 00 00 |
andrewboyson | 105:ef2dd21d808c | 114 | p++; |
andrewboyson | 105:ef2dd21d808c | 115 | switch (*p) //01 00 5E 00 00 xx |
andrewboyson | 105:ef2dd21d808c | 116 | { |
andrewboyson | 105:ef2dd21d808c | 117 | case 0x01: return MULTICAST_NODE; |
andrewboyson | 105:ef2dd21d808c | 118 | case 0x02: return MULTICAST_ROUTER; |
andrewboyson | 105:ef2dd21d808c | 119 | case 0xfb: return MULTICAST_MDNS; |
andrewboyson | 105:ef2dd21d808c | 120 | case 0xfc: return MULTICAST_LLMNR; |
andrewboyson | 105:ef2dd21d808c | 121 | default: return DO_NOTHING; |
andrewboyson | 105:ef2dd21d808c | 122 | } |
andrewboyson | 105:ef2dd21d808c | 123 | case 0x01: //01 00 5E 00 01 |
andrewboyson | 105:ef2dd21d808c | 124 | p++; |
andrewboyson | 105:ef2dd21d808c | 125 | switch (*p) //01 00 5E 00 01 xx |
andrewboyson | 105:ef2dd21d808c | 126 | { |
andrewboyson | 105:ef2dd21d808c | 127 | case 0x01: return MULTICAST_NTP; |
andrewboyson | 105:ef2dd21d808c | 128 | default: return DO_NOTHING; |
andrewboyson | 105:ef2dd21d808c | 129 | } |
andrewboyson | 105:ef2dd21d808c | 130 | default: return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 131 | } |
andrewboyson | 60:1d8c7a1e7483 | 132 | } |
andrewboyson | 60:1d8c7a1e7483 | 133 | case 0x33: //Multicast IP6 |
andrewboyson | 60:1d8c7a1e7483 | 134 | { |
andrewboyson | 60:1d8c7a1e7483 | 135 | p++; if (*p != 0x33) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 136 | p++; |
andrewboyson | 60:1d8c7a1e7483 | 137 | switch (*p) //33 33 |
andrewboyson | 60:1d8c7a1e7483 | 138 | { |
andrewboyson | 60:1d8c7a1e7483 | 139 | case 0x00: //33 33 00 Special address |
andrewboyson | 60:1d8c7a1e7483 | 140 | { |
andrewboyson | 60:1d8c7a1e7483 | 141 | p++; |
andrewboyson | 60:1d8c7a1e7483 | 142 | switch (*p) |
andrewboyson | 60:1d8c7a1e7483 | 143 | { |
andrewboyson | 60:1d8c7a1e7483 | 144 | case 0x00: //33 33 00 00 |
andrewboyson | 60:1d8c7a1e7483 | 145 | { |
andrewboyson | 105:ef2dd21d808c | 146 | p++; |
andrewboyson | 105:ef2dd21d808c | 147 | switch (*p) |
andrewboyson | 60:1d8c7a1e7483 | 148 | { |
andrewboyson | 105:ef2dd21d808c | 149 | case 0x00: |
andrewboyson | 105:ef2dd21d808c | 150 | p++; |
andrewboyson | 105:ef2dd21d808c | 151 | switch (*p) //33 33 00 00 00 xx |
andrewboyson | 105:ef2dd21d808c | 152 | { |
andrewboyson | 105:ef2dd21d808c | 153 | case 0x01: return MULTICAST_NODE; |
andrewboyson | 105:ef2dd21d808c | 154 | case 0x02: return MULTICAST_ROUTER; |
andrewboyson | 105:ef2dd21d808c | 155 | case 0xfb: return MULTICAST_MDNS; |
andrewboyson | 105:ef2dd21d808c | 156 | default: return DO_NOTHING; |
andrewboyson | 105:ef2dd21d808c | 157 | } |
andrewboyson | 105:ef2dd21d808c | 158 | case 0x01: |
andrewboyson | 105:ef2dd21d808c | 159 | p++; |
andrewboyson | 105:ef2dd21d808c | 160 | switch (*p) //33 33 00 00 01 xx |
andrewboyson | 105:ef2dd21d808c | 161 | { |
andrewboyson | 105:ef2dd21d808c | 162 | case 0x01: return MULTICAST_NTP; |
andrewboyson | 105:ef2dd21d808c | 163 | default: return DO_NOTHING; |
andrewboyson | 105:ef2dd21d808c | 164 | } |
andrewboyson | 105:ef2dd21d808c | 165 | default: return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 166 | } |
andrewboyson | 60:1d8c7a1e7483 | 167 | } |
andrewboyson | 60:1d8c7a1e7483 | 168 | case 0x01: //33 33 00 01 |
andrewboyson | 60:1d8c7a1e7483 | 169 | { |
andrewboyson | 60:1d8c7a1e7483 | 170 | p++; if (*p != 0x00) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 171 | p++; |
andrewboyson | 60:1d8c7a1e7483 | 172 | switch (*p) //33 33 00 01 00 xx |
andrewboyson | 60:1d8c7a1e7483 | 173 | { |
andrewboyson | 60:1d8c7a1e7483 | 174 | case 0x03: return MULTICAST_LLMNR; |
andrewboyson | 60:1d8c7a1e7483 | 175 | default: return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 176 | } |
andrewboyson | 60:1d8c7a1e7483 | 177 | } |
andrewboyson | 60:1d8c7a1e7483 | 178 | default: return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 179 | } |
andrewboyson | 60:1d8c7a1e7483 | 180 | } |
andrewboyson | 60:1d8c7a1e7483 | 181 | case 0xff: //33 33 FF LL LL LL Solicited address |
andrewboyson | 60:1d8c7a1e7483 | 182 | { |
andrewboyson | 60:1d8c7a1e7483 | 183 | char* q = MacLocal + 3; |
andrewboyson | 60:1d8c7a1e7483 | 184 | p++; if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 185 | p++; if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 186 | p++; if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 187 | return SOLICITED_NODE; |
andrewboyson | 60:1d8c7a1e7483 | 188 | } |
andrewboyson | 60:1d8c7a1e7483 | 189 | default: return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 190 | } |
andrewboyson | 60:1d8c7a1e7483 | 191 | } |
andrewboyson | 60:1d8c7a1e7483 | 192 | default: //Unicast to me |
andrewboyson | 60:1d8c7a1e7483 | 193 | { |
andrewboyson | 60:1d8c7a1e7483 | 194 | char* q = MacLocal; |
andrewboyson | 60:1d8c7a1e7483 | 195 | if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 196 | p++; if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 197 | p++; if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 198 | p++; if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 199 | p++; if (*p != *q++) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 200 | p++; if (*p != *q) return DO_NOTHING; |
andrewboyson | 60:1d8c7a1e7483 | 201 | return UNICAST; |
andrewboyson | 60:1d8c7a1e7483 | 202 | } |
andrewboyson | 60:1d8c7a1e7483 | 203 | } |
andrewboyson | 60:1d8c7a1e7483 | 204 | } |
andrewboyson | 60:1d8c7a1e7483 | 205 | |
andrewboyson | 60:1d8c7a1e7483 | 206 | void MacMakeFromDest(int dest, int pro, char* p) |
andrewboyson | 60:1d8c7a1e7483 | 207 | { |
andrewboyson | 60:1d8c7a1e7483 | 208 | if (dest == BROADCAST) { *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p = 0xff; return; } |
andrewboyson | 60:1d8c7a1e7483 | 209 | |
andrewboyson | 172:9bc3c7b2cca1 | 210 | if (pro == ETH_IPV4) |
andrewboyson | 60:1d8c7a1e7483 | 211 | { |
andrewboyson | 60:1d8c7a1e7483 | 212 | switch (dest) |
andrewboyson | 60:1d8c7a1e7483 | 213 | { |
andrewboyson | 60:1d8c7a1e7483 | 214 | case MULTICAST_NODE: *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0x01; break; |
andrewboyson | 60:1d8c7a1e7483 | 215 | case MULTICAST_ROUTER: *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0x02; break; |
andrewboyson | 60:1d8c7a1e7483 | 216 | case MULTICAST_MDNS: *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0xfb; break; |
andrewboyson | 60:1d8c7a1e7483 | 217 | case MULTICAST_LLMNR: *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0xfc; break; |
andrewboyson | 105:ef2dd21d808c | 218 | case MULTICAST_NTP: *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x01; *p = 0x01; break; |
andrewboyson | 60:1d8c7a1e7483 | 219 | } |
andrewboyson | 60:1d8c7a1e7483 | 220 | } |
andrewboyson | 60:1d8c7a1e7483 | 221 | else |
andrewboyson | 60:1d8c7a1e7483 | 222 | { |
andrewboyson | 60:1d8c7a1e7483 | 223 | switch (dest) |
andrewboyson | 60:1d8c7a1e7483 | 224 | { |
andrewboyson | 60:1d8c7a1e7483 | 225 | case MULTICAST_NODE: *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p = 0x01; break; |
andrewboyson | 60:1d8c7a1e7483 | 226 | case MULTICAST_ROUTER: *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p = 0x02; break; |
andrewboyson | 60:1d8c7a1e7483 | 227 | case MULTICAST_MDNS: *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p = 0xfb; break; |
andrewboyson | 60:1d8c7a1e7483 | 228 | case MULTICAST_LLMNR: *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x01; *p++ = 0x00; *p = 0x03; break; |
andrewboyson | 105:ef2dd21d808c | 229 | case MULTICAST_NTP: *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x01; *p = 0x01; break; |
andrewboyson | 60:1d8c7a1e7483 | 230 | } |
andrewboyson | 60:1d8c7a1e7483 | 231 | } |
andrewboyson | 60:1d8c7a1e7483 | 232 | } |