/* flaneth - flash and ethernet
   Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info>
   Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
   a BlinkenArea project - http://www.blinkenarea.org/ */

#include "arp.h"
#include "config.h"
#include "debug.h"
#include "ethernet.h"
#include "ip.h"
#include "macros.h"
#include "nethelp.h"
#include "rtl8019.h"

// process a received ethernet packet
void EthernetRecv(unsigned char *pData, unsigned short Length)  // (extern)
{
  struct EthernetPacket *pEthPack;

  // packet too short
  if (Length < sizeof(struct EthernetPacket))
    return;

  // convert pointer to ethernet packet
  // (this saves us from always casting pData)
  pEthPack = (struct EthernetPacket *)pData;

  debug_ether_printf
      ("recv len=%u type=0x%04X src=%02X:%02X:%02X:%02X:%02X:%02X", Length,
       ntohs(pEthPack->EthHdr.Type), pEthPack->EthHdr.Src[0],
       pEthPack->EthHdr.Src[1], pEthPack->EthHdr.Src[2],
       pEthPack->EthHdr.Src[3], pEthPack->EthHdr.Src[4],
       pEthPack->EthHdr.Src[5]);

  // branch according to packet type
  switch (pEthPack->EthHdr.Type) {
    // ARP
  case htons(0x0806):
    ArpRecv(pData, Length);
    break;
    // IP
  case htons(0x0800):
    IpRecv(pData, Length);
    break;
  }
}

// send an ethernet packet
// pData must point to a struct EthernetPacket with EthHdr.Dest and
// EthHdr.Type already initialized
void EthernetSend(unsigned char *pData, unsigned short Length)  // (extern)
{
  struct EthernetPacket *pEthPack;

  // packet too short
  if (Length < sizeof(struct EthernetPacket))
    return;

  // convert pointer to ethernet packet
  // (this saves us from always casting pData)
  pEthPack = (struct EthernetPacket *)pData;

  debug_ether_printf
      ("send len=%u type=0x%04X dest=%02X:%02X:%02X:%02X:%02X:%02X", Length,
       ntohs(pEthPack->EthHdr.Type), pEthPack->EthHdr.Dest[0],
       pEthPack->EthHdr.Dest[1], pEthPack->EthHdr.Dest[2],
       pEthPack->EthHdr.Dest[3], pEthPack->EthHdr.Dest[4],
       pEthPack->EthHdr.Dest[5]);

  // fill in source address
  mac_cpy(pEthPack->EthHdr.Src, ConfigMac);

  // send packet
  RtlWriteFrame((unsigned char *)pData, Length);
}
