Beispiel #1
0
/*****************************************************************************
  Function:
    static bool ARPPut(ARP_PACKET* packet)

  Description:
    Writes an ARP packet to the MAC.

  Precondition:
    None

  Parameters:
    packet - A pointer to an ARP_PACKET structure with correct operation
                and target preconfigured.

  Return Values:
    true - The ARP packet was generated properly
    false - Not a possible return value
  ***************************************************************************/
static bool ARPPut(ARP_PACKET* packet)
{
    while(!MACIsTxReady());
    MACSetWritePtr(BASE_TX_ADDR);


    packet->HardwareType  = HW_ETHERNET;
    packet->Protocol      = ARP_IP;
    packet->MACAddrLen    = sizeof(MAC_ADDR);
    packet->ProtocolLen   = sizeof(IP_ADDR);
//    packet->SenderMACAddr = AppConfig.MyMACAddr;  // HI-TECH PICC-18 compiler can't handle this statement, use memcpy() as a workaround
    memcpy(&packet->SenderMACAddr, (void*)&AppConfig.MyMACAddr, sizeof(packet->SenderMACAddr));
#ifdef STACK_USE_ZEROCONF_LINK_LOCAL
    //packet->SenderIPAddr  = AppConfig.MyIPAddr; /* Removed for ZCLL, SenderIPAddr should be filled in */
#else
    packet->SenderIPAddr  = AppConfig.MyIPAddr;
#endif

    SwapARPPacket(packet);

    MACPutHeader(&packet->TargetMACAddr, MAC_ARP, sizeof(*packet));
    MACPutArray((uint8_t*)packet, sizeof(*packet));
    MACFlush();

    return true;
}
Beispiel #2
0
/*****************************************************************************
  Function:
    static bool ARP_SendIfPkt(NET_CONFIG* pIf, uint16_t oper, uint32_t srcIP, uint32_t dstIP, MAC_ADDR* dstMAC)

  Description:
    Writes an ARP packet to the MAC using the interface pointer for src IP and MAC address.

  Precondition:
    None

  Parameters:

  Return Values:
    true - The ARP packet was generated properly
    false - otherwise


  ***************************************************************************/
static bool ARP_SendIfPkt(NET_CONFIG* pIf, uint16_t oper, uint32_t srcIP, uint32_t dstIP, MAC_ADDR* dstMAC)
{
    ARP_PACKET       packet;
    TCPIP_MAC_HANDLE hMac;


    packet.HardwareType  = HW_ETHERNET;
    packet.Protocol      = ARP_IP;
    packet.MACAddrLen    = sizeof(MAC_ADDR);
    packet.ProtocolLen   = sizeof(IP_ADDR);
    packet.Operation = oper;

    packet.SenderMACAddr = pIf->MyMACAddr;
    packet.SenderIPAddr.Val  = srcIP;
    packet.TargetMACAddr = *dstMAC;
    packet.TargetIPAddr.Val  = dstIP;

    SwapARPPacket(&packet);


    hMac = _TCPIPStackNetToMac(pIf);
    if(!MACIsTxReady(hMac))
    {
        return false;
    }

    MACSetWritePtr(hMac, MACGetTxBaseAddr(hMac));
    MACPutHeader(hMac, &packet.TargetMACAddr, ETHERTYPE_ARP, sizeof(packet));
    MACPutArray(hMac, (uint8_t*)&packet, sizeof(packet));
    MACFlush(hMac);

    return true;
}
Beispiel #3
0
/**
 * Checks if there is a transmit buffer ready for accepting data, and that the given socket
 * is valid (not equal to INVALID_UDP_SOCKET for example).
 *
 * Side Effects:    Given socket is set as the active UDP Socket. <br>
 *
 * Note: This function automatically sets supplied socket as the active
 * socket. All subsequent calls will us this socket as the active socket.
 *
 * @param s         Socket that is to be loaded and made an active UDP socket.
 *
 * @return          TRUE if at least one UDP buffer is ready to transmit, and given socket is valid<br>
 *                  FALSE if not
 */
BOOL UDPIsPutReady(UDP_SOCKET s)
{
    //Check if the given socket is valid
    if (s < MAX_UDP_SOCKETS) {
        activeUDPSocket = s;
    
        return MACIsTxReady(TRUE);
    }
    
    return FALSE;
}
Beispiel #4
0
/*****************************************************************************
  Function:
	WORD UDPIsPutReady(UDP_SOCKET s)

  Summary:
	Determines how many bytes can be written to the UDP socket.
	
  Description:
	This function determines if bytes can be written to the specified UDP
	socket.  It also prepares the UDP module for writing by setting the 
	indicated socket as the currently active connection.

  Precondition:
	UDPInit() must have been previously called.

  Parameters:
	s - The socket to be made active

  Returns:
  	The number of bytes that can be written to this socket.
  ***************************************************************************/
WORD UDPIsPutReady(UDP_SOCKET s)
{
	if(!MACIsTxReady())
		return 0;

	if(LastPutSocket != s)
	{
		LastPutSocket = s;
		UDPTxCount = 0;
		UDPSetTxBuffer(0);
	}

	activeUDPSocket = s;

	return MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) - UDPTxCount;
}
Beispiel #5
0
void AutoIPTasks(void)
{
    BYTE i;

    for (i = 0; i < NETWORK_INTERFACES; i++)
    {
        LoadState (i);
        AutoIPClient.flags.bits.bCurrentLinkState = MACIsLinked();
    	if(AutoIPClient.flags.bits.bCurrentLinkState != AutoIPClient.flags.bits.bLastLinkState)
    	{
    		AutoIPClient.flags.bits.bLastLinkState = AutoIPClient.flags.bits.bCurrentLinkState;
    		if(!AutoIPClient.flags.bits.bCurrentLinkState)
    		{
                AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
    			AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
    			AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
    		}
            else
            {
                AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
    	}
    
        #if defined (STACK_USE_DHCP_CLIENT)
        if (DHCPIsBound(i))
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
            AutoIPClient.flags.bits.bLastDHCPState = TRUE;
        }
        else
        {
            if (AutoIPClient.flags.bits.bLastDHCPState == TRUE)
            {
                if (AutoIPClient.flags.bits.bCurrentLinkState)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
            AutoIPClient.flags.bits.bLastDHCPState = FALSE;
        }
        #endif
    
    
        if (AutoIPClient.flags.bits.gDisableAutoIP == TRUE)
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
        }
    
    
        switch (AutoIPClient.smAUTOIPState)
        {
            // Default no-AutoIP case
        	case SM_AUTOIP_DISABLED:

                break;
    
            // Initializes the random number generator with a seed based on the MAC address
            case SM_AUTOIP_INIT_RNG:
                AutoIPRandSeed (((DWORD)AppConfig.MyMACAddr.v[0] + ((DWORD)AppConfig.MyMACAddr.v[1] << 8) + \
                        ((DWORD)AppConfig.MyMACAddr.v[2] << 16) + ((DWORD)AppConfig.MyMACAddr.v[3] << 24) + \
                        ((DWORD)AppConfig.MyMACAddr.v[4]) + ((DWORD)AppConfig.MyMACAddr.v[5] << 8)), i);
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
    
            // Check the address to see if it's in use before we write it into AppConfig
            case SM_AUTOIP_CHECK_ADDRESS:
    
                if (AutoIPClient.flags.bits.checkAddress == FALSE)
                {
                    AutoIPClient.flags.bits.checkAddress = TRUE;
    
                    AppConfig.MyMask.Val = 0x00000000;
    
                    // Generate a random IP address (based on the MAC address) to try and claim.
                    // Dynamic link-local addresses can fall within the range:
                    // 169.254.1.0 - 169.254.254.255
                    AutoIPClient.packet.TargetIPAddr.byte.MB = AutoIPRand(i) % 256;
                    AutoIPClient.packet.TargetIPAddr.byte.UB = (AutoIPRand(i) % 254) + 1;
                    AutoIPClient.packet.TargetIPAddr.word.LW = 0xFEA9;
    
                    ARPResolve (&AutoIPClient.packet.TargetIPAddr);
    
                    AutoIPClient.eventTime = TickGet();
                }
                
                if (!ARPIsResolved (&AutoIPClient.packet.TargetIPAddr, &AutoIPClient.packet.TargetMACAddr))
                {
                    if (TickGet() - AutoIPClient.eventTime > TICK_SECOND)
                    {
                        AutoIPClient.smAUTOIPState = SM_AUTOIP_SETUP_MESSAGE;
                    }
                }
                else
                {
                    AutoIPClient.flags.bits.checkAddress = FALSE;
                }
    
                break;
    
            // Set up an ARP packet
            case SM_AUTOIP_SETUP_MESSAGE:
    
                AutoIPClient.flags.bits.checkAddress = FALSE;
    
                // Set the bConfigureAutoIP flag- This flag will cause an AutoIP conflict
                // if a response packet is received from the address we're trying to claim.
                AutoIPClient.flags.bits.bConfigureAutoIP = TRUE;
    
                // Configure the fields for a gratuitous ARP packet
            	AutoIPClient.packet.Operation            = ARP_OPERATION_REQ;
            
            	AutoIPClient.packet.TargetMACAddr.v[0]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[1]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[2]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[3]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[4]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[5]   = 0xff;
    
                AppConfig.MyIPAddr = AutoIPClient.packet.TargetIPAddr;
                AppConfig.MyMask.Val = 0x0000FFFF;
            	memcpy(&AutoIPClient.packet.SenderMACAddr, (void*)&AppConfig.MyMACAddr, sizeof(AutoIPClient.packet.SenderMACAddr));
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
                AutoIPClient.packet.MACAddrLen    = sizeof(MAC_ADDR);
                AutoIPClient.packet.ProtocolLen   = sizeof(IP_ADDR);
                AutoIPClient.packet.SenderIPAddr.Val  = AutoIPClient.packet.TargetIPAddr.Val;
    
                SwapARPPacket(&AutoIPClient.packet);
    
                // Generate a random delay between 0 and 1 second
                AutoIPClient.randomDelay = ((rand() % 20) * TICK_SECOND) / 20;
                // Store the current time
                AutoIPClient.eventTime = TickGet();
    
                // Set the state to send the ARP packet
                AutoIPClient.smAUTOIPState = SM_AUTOIP_GRATUITOUS_ARP1;
    
                break;
    
            // Send a gratuitous ARP packet to try and claim our address
            case SM_AUTOIP_GRATUITOUS_ARP1:
            case SM_AUTOIP_GRATUITOUS_ARP2:
            case SM_AUTOIP_GRATUITOUS_ARP3:
                // Check to ensure we've passed the delay time
                if (TickGet() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                {
                    // Store the new event time
                    AutoIPClient.eventTime = TickGet();
                    // Generate a new random delay between 1 and 2 seconds
                    AutoIPClient.randomDelay = TICK_SECOND + (((rand() % 20) * TICK_SECOND) / 20);
    
                    // Transmit the packet
                	while(!MACIsTxReady());
                	MACSetWritePtr(BASE_TX_ADDR);
    
                    MACPutHeader(&AutoIPClient.packet.TargetMACAddr, MAC_ARP, sizeof(AutoIPClient.packet));
                    MACPutArray((BYTE*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                    MACFlush();
    
                    // Increment the probe iteration or increment to the delay state
                    AutoIPClient.smAUTOIPState++;
                }
                break;
    
            // Delay for 1-2 seconds after sending the third ARP request before
            // entering the configured state
            case SM_AUTOIP_DELAY:
                if (TickGet() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
    
            // Configure the module to limit the rate at which packets are sent
            case SM_AUTOIP_RATE_LIMIT_SET:
                AutoIPClient.eventTime = TickGet();
                AppConfig.MyIPAddr.v[0] = MY_DEFAULT_IP_ADDR_BYTE1;
                AppConfig.MyIPAddr.v[1] = MY_DEFAULT_IP_ADDR_BYTE2;
                AppConfig.MyIPAddr.v[2] = MY_DEFAULT_IP_ADDR_BYTE3;
                AppConfig.MyIPAddr.v[3] = MY_DEFAULT_IP_ADDR_BYTE4;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_RATE_LIMIT_WAIT;
                break;
    
            // Ensure that we don't try more than one address every 60 seconds
            case SM_AUTOIP_RATE_LIMIT_WAIT:
                if (TickGet() - AutoIPClient.eventTime > TICK_SECOND * 60)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
                break;
    
            // Configured state
            case SM_AUTOIP_CONFIGURED:
                AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
                break;
    
            // Address defense state
            case SM_AUTOIP_DEFEND:
                // Prepare and send an ARP response
                AutoIPClient.packet.Operation     = ARP_OPERATION_RESP;
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
    
                SwapARPPacket(&AutoIPClient.packet);
    
            	while(!MACIsTxReady());
            	MACSetWritePtr(BASE_TX_ADDR);
    
                MACPutHeader(&AutoIPClient.packet.TargetMACAddr, MAC_ARP, sizeof(AutoIPClient.packet));
                MACPutArray((BYTE*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                MACFlush();
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
        }
    }
}
Beispiel #6
0
void AutoIPTasks(NET_CONFIG* pConfig)
{
//    uint8_t i;
    TCPIP_MAC_HANDLE hMac;

//    for (i = 0; i < NETWORK_INTERFACES; i++)
    {
        LoadState(_TCPIPStackNetIx(pConfig));
        hMac = _TCPIPStackNetToMac(pConfig);
        AutoIPClient.flags.bits.bCurrentLinkState = MACIsLinked(hMac);
    	if(AutoIPClient.flags.bits.bCurrentLinkState != AutoIPClient.flags.bits.bLastLinkState)
    	{
    		AutoIPClient.flags.bits.bLastLinkState = AutoIPClient.flags.bits.bCurrentLinkState;
    		if(!AutoIPClient.flags.bits.bCurrentLinkState)
    		{
                AutoIPClient.flags.bits.bConfigureAutoIP = false;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
    			pConfig->MyIPAddr.Val = pConfig->DefaultIPAddr.Val;
    			pConfig->MyMask.Val = pConfig->DefaultMask.Val;
    		}
            else
            {
                AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
    	}
    
        #if defined (TCPIP_STACK_USE_DHCP_CLIENT)
        if (DHCPIsBound(pConfig))
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = false;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
            AutoIPClient.flags.bits.bLastDHCPState = true;
        }
        else
        {
            if (AutoIPClient.flags.bits.bLastDHCPState == true)
            {
                if (AutoIPClient.flags.bits.bCurrentLinkState)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
            AutoIPClient.flags.bits.bLastDHCPState = false;
        }
        #endif
    
    
        if (AutoIPClient.flags.bits.gDisableAutoIP == true)
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = false;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
        }
    
    
        switch (AutoIPClient.smAUTOIPState)
        {
            // Default no-AutoIP case
        	case SM_AUTOIP_DISABLED:

                break;
    
            // Initializes the random number generator with a seed based on the MAC address
            case SM_AUTOIP_INIT_RNG:
                AutoIPRandSeed (((uint32_t)pConfig->MyMACAddr.v[0] + ((uint32_t)pConfig->MyMACAddr.v[1] << 8) + \
                        ((uint32_t)pConfig->MyMACAddr.v[2] << 16) + ((uint32_t)pConfig->MyMACAddr.v[3] << 24) + \
                        ((uint32_t)pConfig->MyMACAddr.v[4]) + ((uint32_t)pConfig->MyMACAddr.v[5] << 8)), pConfig);
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
    
            // Check the address to see if it's in use before we write it into NetConfig
            case SM_AUTOIP_CHECK_ADDRESS:
    
                if (AutoIPClient.flags.bits.checkAddress == false)
                {
                    AutoIPClient.flags.bits.checkAddress = true;
    
                    pConfig->MyMask.Val = 0x00000000;
    
                    // Generate a random IP address (based on the MAC address) to try and claim.
                    // Dynamic link-local addresses can fall within the range:
                    // 169.254.1.0 - 169.254.254.255
                    AutoIPClient.packet.TargetIPAddr.byte.MB = AutoIPRand(pConfig) % 256;
                    AutoIPClient.packet.TargetIPAddr.byte.UB = (AutoIPRand(pConfig) % 254) + 1;
                    AutoIPClient.packet.TargetIPAddr.word.LW = 0xFEA9;
    
                    ARPResolve (pConfig, &AutoIPClient.packet.TargetIPAddr);
    
                    AutoIPClient.eventTime = SYS_TICK_Get();
                }
                
                if (!ARPIsResolved (pConfig, &AutoIPClient.packet.TargetIPAddr, &AutoIPClient.packet.TargetMACAddr))
                {
                    if (SYS_TICK_Get() - AutoIPClient.eventTime > SYS_TICK_TicksPerSecondGet())
                    {
                        AutoIPClient.smAUTOIPState = SM_AUTOIP_SETUP_MESSAGE;
                    }
                }
                else
                {
                    AutoIPClient.flags.bits.checkAddress = false;
                }
    
                break;
    
            // Set up an ARP packet
            case SM_AUTOIP_SETUP_MESSAGE:
    
                AutoIPClient.flags.bits.checkAddress = false;
    
                // Set the bConfigureAutoIP flag- This flag will cause an AutoIP conflict
                // if a response packet is received from the address we're trying to claim.
                AutoIPClient.flags.bits.bConfigureAutoIP = true;
    
                // Configure the fields for a gratuitous ARP packet
            	AutoIPClient.packet.Operation            = ARP_OPERATION_REQ;
            
            	AutoIPClient.packet.TargetMACAddr.v[0]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[1]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[2]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[3]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[4]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[5]   = 0xff;
    
                pConfig->MyIPAddr = AutoIPClient.packet.TargetIPAddr;
                pConfig->MyMask.Val = 0x0000FFFF;
            	memcpy(&AutoIPClient.packet.SenderMACAddr, (void*)&pConfig->MyMACAddr, sizeof(AutoIPClient.packet.SenderMACAddr));
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
                AutoIPClient.packet.MACAddrLen    = sizeof(MAC_ADDR);
                AutoIPClient.packet.ProtocolLen   = sizeof(IP_ADDR);
                AutoIPClient.packet.SenderIPAddr.Val  = AutoIPClient.packet.TargetIPAddr.Val;
    
                SwapARPPacket(&AutoIPClient.packet);
    
                // Generate a random delay between 0 and 1 second
                AutoIPClient.randomDelay = ((LFSRRand() % 20) * SYS_TICK_TicksPerSecondGet()) / 20;
                // Store the current time
                AutoIPClient.eventTime = SYS_TICK_Get();
    
                // Set the state to send the ARP packet
                AutoIPClient.smAUTOIPState = SM_AUTOIP_GRATUITOUS_ARP1;
    
                break;
    
            // Send a gratuitous ARP packet to try and claim our address
            case SM_AUTOIP_GRATUITOUS_ARP1:
            case SM_AUTOIP_GRATUITOUS_ARP2:
            case SM_AUTOIP_GRATUITOUS_ARP3:
                // Check to ensure we've passed the delay time
                if (SYS_TICK_Get() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                {
                	if(!MACIsTxReady(hMac))
                    {
                        break;
                    }
                    // Store the new event time
                    AutoIPClient.eventTime = SYS_TICK_Get();
                    // Generate a new random delay between 1 and 2 seconds
                    AutoIPClient.randomDelay = SYS_TICK_TicksPerSecondGet() + (((LFSRRand() % 20) * SYS_TICK_TicksPerSecondGet()) / 20);
    
                    // Transmit the packet
                	MACSetWritePtr(hMac, MACGetTxBaseAddr(hMac));
    
                    MACPutHeader(hMac, &AutoIPClient.packet.TargetMACAddr, ETHERTYPE_ARP, sizeof(AutoIPClient.packet));
                    MACPutArray(hMac, (uint8_t*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                    MACFlush(hMac);
    
                    // Increment the probe iteration or increment to the delay state
                    AutoIPClient.smAUTOIPState++;
                }
                break;
    
            // Delay for 1-2 seconds after sending the third ARP request before
            // entering the configured state
            case SM_AUTOIP_DELAY:
                if (SYS_TICK_Get() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
    
            // Configure the module to limit the rate at which packets are sent
            case SM_AUTOIP_RATE_LIMIT_SET:
                AutoIPClient.eventTime = SYS_TICK_Get();
                pConfig->MyIPAddr.Val = pConfig->DefaultIPAddr.Val;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_RATE_LIMIT_WAIT;
                break;
    
            // Ensure that we don't try more than one address every 60 seconds
            case SM_AUTOIP_RATE_LIMIT_WAIT:
                if (SYS_TICK_Get() - AutoIPClient.eventTime > SYS_TICK_TicksPerSecondGet() * 60)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
                break;
    
            // Configured state
            case SM_AUTOIP_CONFIGURED:
                AutoIPClient.flags.bits.bConfigureAutoIP = false;
                break;
    
            // Address defense state
            case SM_AUTOIP_DEFEND:
                // Prepare and send an ARP response
            	if(!MACIsTxReady(hMac))
                {
                    break;
                }
                AutoIPClient.packet.Operation     = ARP_OPERATION_RESP;
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
    
                SwapARPPacket(&AutoIPClient.packet);
    
            	MACSetWritePtr(hMac, MACGetTxBaseAddr(hMac));
    
                MACPutHeader(hMac, &AutoIPClient.packet.TargetMACAddr, ETHERTYPE_ARP, sizeof(AutoIPClient.packet));
                MACPutArray(hMac, (uint8_t*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                MACFlush(hMac);
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
        }
    }
}