/*@!Encoding:1252*/
variables
{
  //
  // Constants
  //
  enum AF_FAMILY
  {
    AF_INET = 2,
    AF_INET6 = 23    
  };

  // Ethernt Type
  const WORD kEthernetTypeIPv4  = 0x0800;
  const WORD kEthernetTypeARP   = 0x0806;

  // IPv4 protocols
  const BYTE kIPv4_Protocol_UDP = 0x11;

  //
  // Structure for MAC ID
  //
  _align(1) struct EthMacId
  {
    BYTE part[6]; // part of MAC ID
  };

  struct EthMacId kBroadcastMacId = { part = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } };
  struct EthMacId kEmptyMacId     = { part = { 0x00,0x00,0x00,0x00,0x00,0x00 } };

  //
  // Structure for Ethernet Header
  //
  _align(1) struct EthHeader 
  {
    struct EthMacId ethDest;   // Destination MAC ID
    struct EthMacId ethSource; // Source MAC ID
    WORD            ethType;   // Ethernet Type
  };

  //
  // Structure for IPv4 Address
  //
  _align(1) struct IPv4Address
  {
    BYTE part[4]; // part of
  };

  struct IPv4Address kBroadcastIPv4 = { part = { 0xFF,0xFF,0xFF,0xFF } };
}

int EthGetMacIdFromString( struct EthMacId retMacId, char macId[] )
{
  char str[10] = "0x00";

  // part1 of MAC ID
  retMacId.part[0] = UtilGetHexNum( macId, 0 );

  // part2 of MAC ID
  retMacId.part[1] =  UtilGetHexNum( macId, 3 );

  // part3 of MAC ID
  retMacId.part[2] =  UtilGetHexNum( macId, 6 );

  // part4 of MAC ID
  retMacId.part[3] =  UtilGetHexNum( macId, 9 );

  // part5 of MAC ID
  retMacId.part[4] =  UtilGetHexNum( macId, 12 );

  // part6 of MAC ID
  retMacId.part[5] =  UtilGetHexNum( macId, 15 );

  return 0;
}

int IPv4AddressToStruct( struct IPv4Address retAddr, char ipAddr[] )
{
  char str[5];
  int  pos;

  // part1 of MAC ID
  pos = 0;
  substr_cpy( str, ipAddr, pos, 3, 4 );
  retAddr.part[0] = atol(str );

  // part2 of MAC ID
  pos = strstr_off( ipAddr, pos+1, "." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  retAddr.part[1] = atol(str );

  // part3 of MAC ID
  pos = strstr_off( ipAddr, pos+1,"." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  retAddr.part[2] = atol(str );

  // part4 of MAC ID
  pos = strstr_off( ipAddr, pos+1, "." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  retAddr.part[3] = atol(str );

  return 0;
}

LONG UtilGetHexNum( char text[], int offset )
{
  CHAR c1, c2;
  LONG digit1, digit2;

  if (offset+1 < strlen(text)) {
    c1 = text[offset];
    c2 = text[offset+1];

    // digit 1
    if ((c1 >= '0') && (c1 <= '9')) {
      digit1 = c1 - '0';
    }
    else if ((c1 >= 'A') && (c1 <= 'F')) {
      digit1 = c1 - 'A' + 10;
    }
    else if ((c1 >= 'a') && (c1 <= 'f')) {
      digit1 = c1 - 'a' + 10;
    }

    // digit 2
    if ((c2 >= '0') && (c2 <= '9')) {
      digit2 = c2 - '0';
    }
    else if ((c2 >= 'A') && (c2 <= 'F')) {
      digit2 = c2 - 'A' + 10;
    }
    else if ((c2 >= 'a') && (c2 <= 'f')) {
      digit2 = c2 - 'a' + 10;
    }

    return ((digit1 << 4) & 0xF0) | (digit2 & 0x0F);
  }
  else {
    return 0;
  }
}

int IPv4Address2Data( BYTE part[], DWORD offset, char ipAddr[] )
{
  char str[5];
  int  pos;

  // part1 of MAC ID
  pos = 0;
  substr_cpy( str, ipAddr, pos, 3, 4 );
  part[offset+0] = atol(str );

  // part2 of MAC ID
  pos = strstr_off( ipAddr, pos+1, "." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  part[offset+1] = atol(str );

  // part3 of MAC ID
  pos = strstr_off( ipAddr, pos+1,"." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  part[offset+2] = atol(str );

  // part4 of MAC ID
  pos = strstr_off( ipAddr, pos+1, "." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  part[offset+3] = atol(str );

  return 0;
}

int EthGetMacIdFromString( BYTE part[], DWORD offset, char macId[] )
{
  char str[10] = "0x00";

  // part1 of MAC ID
  part[offset+0] = UtilGetHexNum( macId, 0 );

  // part2 of MAC ID
  part[offset+1] =  UtilGetHexNum( macId, 3 );

  // part3 of MAC ID
  part[offset+2] =  UtilGetHexNum( macId, 6 );

  // part4 of MAC ID
  part[offset+3] =  UtilGetHexNum( macId, 9 );

  // part5 of MAC ID
  part[offset+4] =  UtilGetHexNum( macId, 12 );

  // part6 of MAC ID
  part[offset+5] =  UtilGetHexNum( macId, 15 );

  return 0;
}

int EthMacId2Str( BYTE part[], DWORD offset, char macId[] )
{
  snprintf( macId, elCount(macId), "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", part[offset+0], part[offset+1], part[offset+2], part[offset+3], part[offset+4], part[offset+5] );

  return 0;
}

int IPv4Address2Str( BYTE part[], DWORD offset, char ipAddr[] )
{
  snprintf( ipAddr, elCount(ipAddr), "%d.%.d.%d.%d", part[offset+0], part[offset+1], part[offset+2], part[offset+3] );

  return 0;
}

DWORD IPv4GetAddress( char ipAddr[] )
{
  char str[5];
  int  pos;
  DWORD addr;
  
  addr = 0;

  // part1 of MAC ID
  pos = 0;
  substr_cpy( str, ipAddr, pos, 3, 4 );
  addr = (addr & 0xFFFFFF00) | ((atol(str ) & 0xFF));

  // part2 of MAC ID
  pos = strstr_off( ipAddr, pos+1, "." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  addr = (addr & 0xFFFF00FF) | ((atol(str ) & 0xFF) << 8);

  // part3 of MAC ID
  pos = strstr_off( ipAddr, pos+1,"." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  addr = (addr & 0xFF00FFFF) | ((atol(str ) & 0xFF) << 16);

  // part4 of MAC ID
  pos = strstr_off( ipAddr, pos+1, "." );
  substr_cpy( str, ipAddr, pos+1, 3, 4 );
  addr = (addr & 0x00FFFFFF) | ((atol(str ) & 0xFF) << 24);

  return addr;
}

int IPv4Address2Str( DWORD address, char ipAddr[] )
{
  snprintf( ipAddr, elCount(ipAddr), "%d.%.d.%d.%d", (address & 0xFF), ((address >> 8) & 0xFF), ((address >> 16) & 0xFF), ((address >> 24) & 0xFF) );

  return 0;
}

DWORD htonl(DWORD hostlong)
{
  return ((hostlong & 0xff)<<24) | ((hostlong & 0xff00)<<8) | ((hostlong & 0xff0000)>>8) | ((hostlong & 0xff000000)>>24);
}

WORD htons(WORD hostshort)
{
  return ((hostshort & 0xff)<<8) | ((hostshort & 0xff00)>>8);
}

DWORD ntohl(DWORD netlong)
{
  return ((netlong & 0xff)<<24) | ((netlong & 0xff00)<<8) | ((netlong & 0xff0000)>>8) | ((netlong & 0xff000000)>>24);
}

WORD ntohs(WORD netshort)
{
  return ((netshort & 0xff)<<8) | ((netshort & 0xff00)>>8);
}




