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

Committer:
andrewboyson
Date:
2019-07-19
Revision:
151:bde6f7da1755
Parent:
143:8cec8f08dc54
Child:
172:9bc3c7b2cca1

File content as of revision 151:bde6f7da1755:

#include <stdbool.h>
#include <string.h>
#include <stdio.h>

#include    "log.h"
#include    "net.h"
#include "action.h"
#include    "eth.h"
#include   "http.h"

char MacLocal[6];
void MacClear(char* mac)
{
    memset(mac, 0, 6);
}
void MacCopy(char* macTo, const char* macFrom)
{
    memcpy(macTo, macFrom, 6);
}
bool MacIsSame(const char* macA, const char* macB)
{
    return memcmp(macA, macB, 6) == 0;
}
bool MacIsEmpty(const char* mac)
{
           if (*mac) return false;
    mac++; if (*mac) return false;
    mac++; if (*mac) return false;
    mac++; if (*mac) return false;
    mac++; if (*mac) return false;
    mac++; if (*mac) return false;
    return true;
}

int MacToString(const char* mac, int size, char* text)
{
    return snprintf(text, size, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
int MacLog(const char* mac)
{
    return LogF("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
int MacHttp(const char* mac)
{
    return HttpAddF("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

int MacAccept(const char* p)
{
    switch (*p)
    {
        case 0xff: //Broadcast
        {
            p++; if (*p != 0xff) return DO_NOTHING;
            p++; if (*p != 0xff) return DO_NOTHING;
            p++; if (*p != 0xff) return DO_NOTHING;
            p++; if (*p != 0xff) return DO_NOTHING;
            p++; if (*p != 0xff) return DO_NOTHING;
            return BROADCAST;
        }
        case 0x01: //Multicast IP4
        {
            p++; if (*p != 0x00) return DO_NOTHING; //01 00
            p++; if (*p != 0x5e) return DO_NOTHING; //01 00 5E
            p++; if (*p != 0x00) return DO_NOTHING; //01 00 5E 00
            p++;
            switch (*p)
            {
                case 0x00: //01 00 5E 00 00
                    p++;
                    switch (*p) //01 00 5E 00 00 xx
                    {
                        case 0x01: return MULTICAST_NODE;
                        case 0x02: return MULTICAST_ROUTER;
                        case 0xfb: return MULTICAST_MDNS;
                        case 0xfc: return MULTICAST_LLMNR;
                        default:   return DO_NOTHING;
                    }
                case 0x01: //01 00 5E 00 01
                    p++;
                    switch (*p) //01 00 5E 00 01 xx
                    {
                        case 0x01: return MULTICAST_NTP;
                        default:   return DO_NOTHING;
                    }
                default: return DO_NOTHING;
            }
        }
        case 0x33: //Multicast IP6
        {
            p++; if (*p != 0x33) return DO_NOTHING;
            p++;
            switch (*p) //33 33
            {
                case 0x00: //33 33 00 Special address
                {
                    p++;
                    switch (*p)
                    {
                        case 0x00: //33 33 00 00
                        {
                            p++; 
                            switch (*p)
                            {
                                case 0x00:
                                    p++;
                                    switch (*p) //33 33 00 00 00 xx
                                    {
                                        case 0x01: return MULTICAST_NODE;
                                        case 0x02: return MULTICAST_ROUTER;
                                        case 0xfb: return MULTICAST_MDNS;
                                        default:   return DO_NOTHING;
                                    }
                                case 0x01:
                                    p++;
                                    switch (*p) //33 33 00 00 01 xx
                                    {
                                        case 0x01: return MULTICAST_NTP;
                                        default:   return DO_NOTHING;
                                    }
                                default: return DO_NOTHING;
                            }
                        }
                        case 0x01: //33 33 00 01
                        {
                            p++; if (*p != 0x00) return DO_NOTHING;
                            p++;
                            switch (*p) //33 33 00 01 00 xx
                            {
                                case 0x03: return MULTICAST_LLMNR;
                                default:   return DO_NOTHING;
                            }
                        }
                        default: return DO_NOTHING;
                    }
                }
                case 0xff: //33 33 FF LL LL LL Solicited address
                {
                    char* q = MacLocal + 3;
                    p++; if (*p != *q++) return DO_NOTHING;
                    p++; if (*p != *q++) return DO_NOTHING;
                    p++; if (*p != *q++) return DO_NOTHING;
                    return SOLICITED_NODE;
                }
                default: return DO_NOTHING;
            }
        }
        default: //Unicast to me
        {
            char* q = MacLocal;
                 if (*p != *q++) return DO_NOTHING;
            p++; if (*p != *q++) return DO_NOTHING;
            p++; if (*p != *q++) return DO_NOTHING;
            p++; if (*p != *q++) return DO_NOTHING;
            p++; if (*p != *q++) return DO_NOTHING;
            p++; if (*p != *q)   return DO_NOTHING;
            return UNICAST;
        }
    }
}

void MacMakeFromDest(int dest, int pro, char* p)
{
    if (dest == BROADCAST)       { *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p = 0xff; return; }
    
    if (pro == IPV4)
    {
        switch (dest)
        {
            case MULTICAST_NODE:   *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0x01; break;
            case MULTICAST_ROUTER: *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0x02; break;
            case MULTICAST_MDNS:   *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0xfb; break;
            case MULTICAST_LLMNR:  *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x00; *p = 0xfc; break;
            case MULTICAST_NTP:    *p++ = 0x01; *p++ = 0x00; *p++ = 0x5e; *p++ = 0x00; *p++ = 0x01; *p = 0x01; break;
        }
    }
    else
    {
        switch (dest)
        {
            case MULTICAST_NODE:   *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p = 0x01; break;
            case MULTICAST_ROUTER: *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p = 0x02; break;
            case MULTICAST_MDNS:   *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p = 0xfb; break;
            case MULTICAST_LLMNR:  *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x01; *p++ = 0x00; *p = 0x03; break;
            case MULTICAST_NTP:    *p++ = 0x33; *p++ = 0x33; *p++ = 0x00; *p++ = 0x00; *p++ = 0x01; *p = 0x01; break;
        }
    }
}