Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
/*********************************************************************
 * Function:        void ARPPut(NODE_INFO* more, BYTE opCode)
 *
 * PreCondition:    None
 *
 * Input:           remote  - Remote node info
 *                  opCode  - ARP op code to send
 *
 * Output:          TRUE - The ARP packet was generated properly
 *					FALSE - Unable to allocate a TX buffer
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
BOOL ARPPut(NODE_INFO *remote, BYTE opCode)
{
    ARP_PACKET packet;

	BUFFER MyTxBuffer;
	MyTxBuffer = MACGetTxBuffer(TRUE);
	
	// Do not respond if there is no room to generate the ARP reply
	if(MyTxBuffer == INVALID_BUFFER)
		return FALSE;

	MACSetTxBuffer(MyTxBuffer, 0);
	
	
    packet.HardwareType             = HW_ETHERNET;
    packet.Protocol                 = ARP_IP;
    packet.MACAddrLen               = sizeof(MAC_ADDR);
    packet.ProtocolLen              = sizeof(IP_ADDR);

    if ( opCode == ARP_REQUEST )
    {
        packet.Operation            = ARP_OPERATION_REQ;
        packet.TargetMACAddr.v[0]   = 0xff;
        packet.TargetMACAddr.v[1]   = 0xff;
        packet.TargetMACAddr.v[2]   = 0xff;
        packet.TargetMACAddr.v[3]   = 0xff;
        packet.TargetMACAddr.v[4]   = 0xff;
        packet.TargetMACAddr.v[5]   = 0xff;
    }
    else
    {
        packet.Operation            = ARP_OPERATION_RESP;
        packet.TargetMACAddr        = remote->MACAddr;
    }

    packet.SenderMACAddr = AppConfig.MyMACAddr;
    packet.SenderIPAddr  = AppConfig.MyIPAddr;


    // Check to see if target is on same subnet, if not, find Gateway MAC.
    // Once we get Gateway MAC, all access to remote host will go through Gateway.
    if((packet.SenderIPAddr.Val ^ remote->IPAddr.Val) & AppConfig.MyMask.Val)
    {
		packet.TargetIPAddr = AppConfig.MyGateway;
    }
    else
        packet.TargetIPAddr             = remote->IPAddr;

    SwapARPPacket(&packet);

    MACPutHeader(&packet.TargetMACAddr, MAC_ARP, sizeof(packet));

    //MACPutArray((int8*)&packet, sizeof(packet));
    MACPutArray(&packet, sizeof(ARP_PACKET));

    MACFlush();
	
	return TRUE;
}
Exemplo n.º 4
0
/*********************************************************************
 * Function:        BOOL ARPGet(NODE_INFO* remote, BYTE* opCode)
 *
 * PreCondition:    ARP packet is ready in MAC buffer.
 *
 * Input:           remote  - Remote node info
 *                  opCode  - Buffer to hold ARP op code.
 *
 * Output:          TRUE if a valid ARP packet was received.
 *                  FALSE otherwise.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
int1 ARPGet(NODE_INFO *remote, int8 *opCode)
{
    ARP_PACKET packet;

    //MACGetArray((int8*)&packet, sizeof(packet));
    MACGetArray(&packet, sizeof(ARP_PACKET));

    MACDiscardRx();

    SwapARPPacket(&packet);

   debug_arp("\r\nARP: HW:%LX PR:%LX ML:%U PL:%U O:%LX TI:%U.%U.%U.%U FI:%U.%U.%U.%U",
      packet.HardwareType, packet.Protocol, packet.MACAddrLen, packet.ProtocolLen,
      packet.Operation, packet.TargetIPAddr.v[0],packet.TargetIPAddr.v[1],
      packet.TargetIPAddr.v[2],packet.TargetIPAddr.v[3],
      packet.SenderIPAddr.v[0],packet.SenderIPAddr.v[1],packet.SenderIPAddr.v[2],packet.SenderIPAddr.v[3]);

    if ( packet.HardwareType != HW_ETHERNET     ||
         packet.MACAddrLen != sizeof(MAC_ADDR)  ||
         packet.ProtocolLen != sizeof(IP_ADDR) )
         return FALSE;

    if ( packet.Operation == ARP_OPERATION_RESP )
        *opCode = ARP_REPLY;
    else if ( packet.Operation == ARP_OPERATION_REQ )
        *opCode = ARP_REQUEST;
    else
    {
        *opCode = ARP_UNKNOWN;
        return FALSE;
    }

    if(packet.TargetIPAddr.Val == AppConfig.MyIPAddr.Val)
    {
        remote->MACAddr     = packet.SenderMACAddr;
        remote->IPAddr      = packet.SenderIPAddr;
        return TRUE;
    }
    else
        return FALSE;
}
Exemplo n.º 5
0
/*********************************************************************
 * Function:        BOOL ARPGet(NODE_INFO* remote, BYTE* opCode)
 *
 * PreCondition:    ARP packet is ready in MAC buffer.
 *
 * Input:           remote  - Remote node info
 *                  opCode  - Buffer to hold ARP op code.
 *
 * Output:          TRUE if a valid ARP packet was received.
 *                  FALSE otherwise.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
BOOL ARPGet(NODE_INFO *remote, BYTE *opCode)
{
    ARP_PACKET packet;

    MACGetArray((BYTE*)&packet, sizeof(packet));

    MACDiscardRx();

    SwapARPPacket(&packet);

    if ( packet.HardwareType != HW_ETHERNET     ||
         packet.MACAddrLen != sizeof(MAC_ADDR)  ||
         packet.ProtocolLen != sizeof(IP_ADDR) )
    {
         return FALSE;
    }

    if ( packet.Operation == ARP_OPERATION_RESP )
    {   
        *opCode = ARP_REPLY;
    }
    else if ( packet.Operation == ARP_OPERATION_REQ )
        *opCode = ARP_REQUEST;
    else
    {
        *opCode = ARP_UNKNOWN;
        return FALSE;
    }

    if(packet.TargetIPAddr.Val == AppConfig.MyIPAddr.Val)
    {
        remote->MACAddr     = packet.SenderMACAddr;
        remote->IPAddr      = packet.SenderIPAddr;
        return TRUE;
    }
    else
        return FALSE;
}
Exemplo n.º 6
0
/*****************************************************************************
  Function:
    bool ARPProcess(void)

  Summary:
    Processes an incoming ARP packet.

  Description:
    Retrieves an ARP packet from the MAC buffer and determines if it is a
    response to our request (in which case the ARP is resolved) or if it
    is a request requiring our response (in which case we transmit one.)

  Precondition:
    ARP packet is ready in the MAC buffer.

  Parameters:
    None

  Return Values:
    true - All processing of this ARP packet is complete.  Do not call
            again until a new ARP packet is waiting in the RX buffer.
    false - This function must be called again.  More time is needed to
            send an ARP response.
  ***************************************************************************/
bool ARPProcess(void)
{
    ARP_PACKET packet;
    static NODE_INFO Target;
    #if defined(STACK_USE_AUTO_IP)
        uint8_t i;
    #endif
    static enum
    {
        SM_ARP_IDLE = 0,
        SM_ARP_REPLY
    } smARP = SM_ARP_IDLE;

    switch(smARP)
    {
        case SM_ARP_IDLE:
            // Obtain the incoming ARP packet
            MACGetArray((uint8_t*)&packet, sizeof(packet));
            MACDiscardRx();
            SwapARPPacket(&packet);

            // Validate the ARP packet
            if ( packet.HardwareType != HW_ETHERNET     ||
                 packet.MACAddrLen != sizeof(MAC_ADDR)  ||
                 packet.ProtocolLen != sizeof(IP_ADDR) )
            {
                 return true;
            }
#ifdef STACK_USE_ZEROCONF_LINK_LOCAL
            ARPProcessRxPkt(&packet);
#endif

#ifdef STACK_USE_AUTO_IP
            if (packet.SenderIPAddr.Val == AppConfig.MyIPAddr.Val)
            {
                AutoIPConflict(0);
                return true;
            }
#endif

            // Handle incoming ARP responses
#ifdef STACK_CLIENT_MODE
            if(packet.Operation == ARP_OPERATION_RESP)
            {
/*                #if defined(STACK_USE_AUTO_IP)
                for (i = 0; i < NETWORK_INTERFACES; i++)
                    if (AutoIPConfigIsInProgress(i))
                        AutoIPConflict(i);
                #endif*/
                Cache.MACAddr = packet.SenderMACAddr;
                Cache.IPAddr = packet.SenderIPAddr;

                //putsUART("ARPProcess: SM_ARP_IDLE: ARP_OPERATION_RESP  \r\n");
                return true;
            }
#endif

            // Handle incoming ARP requests for our MAC address
            if(packet.Operation == ARP_OPERATION_REQ)
            {
                if(packet.TargetIPAddr.Val != AppConfig.MyIPAddr.Val)
                {
                    return true;
                }
#ifdef STACK_USE_ZEROCONF_LINK_LOCAL
                               /* Fix for Loop-Back suppression:
                                * For ZCLL-Claim packets, host should not respond.
                                * Check Sender's MAC-address with own MAC-address and
                                * if it is matched, response will not be sent back. This
                                * was leading to flooding of ARP-answeres */
                                if(!memcmp (&packet.SenderMACAddr, &AppConfig.MyMACAddr, 6))
                                {
                                     putsUART("Loopback answer suppressed \r\n");
                                     return true;
                                }
#endif
                #if defined(STACK_USE_AUTO_IP)
                for (i = 0; i < NETWORK_INTERFACES; i++)
                    if (AutoIPConfigIsInProgress(i))
                    {
                        AutoIPConflict(i);
                        return true;
                    }
                #endif
                Target.IPAddr = packet.SenderIPAddr;
                Target.MACAddr = packet.SenderMACAddr;

                //putsUART("ARPProcess: SM_ARP_IDLE: ARP_OPERATION_REQ  \r\n");

                smARP = SM_ARP_REPLY;
            }
            // Do not break.  If we get down here, we need to send a reply.

        case SM_ARP_REPLY:
            packet.Operation        = ARP_OPERATION_RESP;
            #if defined(STACK_USE_AUTO_IP)
            if (AutoIPIsConfigured(0))
            {
                packet.TargetMACAddr.v[0] = 0xFF;
                packet.TargetMACAddr.v[1] = 0xFF;
                packet.TargetMACAddr.v[2] = 0xFF;
                packet.TargetMACAddr.v[3] = 0xFF;
                packet.TargetMACAddr.v[4] = 0xFF;
                packet.TargetMACAddr.v[5] = 0xFF;
            }
            else
            #endif
                packet.TargetMACAddr    = Target.MACAddr;
            packet.TargetIPAddr     = Target.IPAddr;
#ifdef STACK_USE_ZEROCONF_LINK_LOCAL
            packet.SenderIPAddr     = AppConfig.MyIPAddr;
#endif
            //putsUART("ARPProcess: SM_ARP_REPLY  \r\n");

            // Send an ARP response to a previously received request
            if(!ARPPut(&packet))
            {
               return false;
            }

            // Begin listening for ARP requests again
            smARP = SM_ARP_IDLE;
            break;
    }

    return true;
}
Exemplo n.º 7
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;
        }
    }
}
Exemplo n.º 8
0
/*********************************************************************
 * Function:        void ARPPut(NODE_INFO* more, BYTE opCode)
 *
 * PreCondition:    MACIsTxReady() == TRUE
 *
 * Input:           remote  - Remote node info
 *                  opCode  - ARP op code to send
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void ARPPut(NODE_INFO *remote,
            BYTE opCode)
{
    ARP_PACKET packet;

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

    if ( opCode == ARP_REQUEST )
    {
        packet.Operation            = ARP_OPERATION_REQ;
        packet.TargetMACAddr.v[0]   = 0xff;
        packet.TargetMACAddr.v[1]   = 0xff;
        packet.TargetMACAddr.v[2]   = 0xff;
        packet.TargetMACAddr.v[3]   = 0xff;
        packet.TargetMACAddr.v[4]   = 0xff;
        packet.TargetMACAddr.v[5]   = 0xff;
    }
    else
    {
        packet.Operation            = ARP_OPERATION_RESP;
        packet.TargetMACAddr        = remote->MACAddr;
    }

    packet.SenderMACAddr.v[0]       = MY_MAC_BYTE1;
    packet.SenderMACAddr.v[1]       = MY_MAC_BYTE2;
    packet.SenderMACAddr.v[2]       = MY_MAC_BYTE3;
    packet.SenderMACAddr.v[3]       = MY_MAC_BYTE4;
    packet.SenderMACAddr.v[4]       = MY_MAC_BYTE5;
    packet.SenderMACAddr.v[5]       = MY_MAC_BYTE6;

    packet.SenderIPAddr.v[0]        = MY_IP_BYTE1;
    packet.SenderIPAddr.v[1]        = MY_IP_BYTE2;
    packet.SenderIPAddr.v[2]        = MY_IP_BYTE3;
    packet.SenderIPAddr.v[3]        = MY_IP_BYTE4;


    /*
     * Check to see if target is on same subnet, if not, find
     * Gateway MAC.
     * Once we get Gateway MAC, all access to remote host will
     * go through Gateway.
     */
    if (((packet.SenderIPAddr.v[0] ^ remote->IPAddr.v[0]) &
                                                MY_MASK_BYTE1) ||
        ((packet.SenderIPAddr.v[1] ^ remote->IPAddr.v[1]) &
                                                MY_MASK_BYTE2) ||
        ((packet.SenderIPAddr.v[2] ^ remote->IPAddr.v[2]) &
                                                MY_MASK_BYTE3) ||
        ((packet.SenderIPAddr.v[3] ^ remote->IPAddr.v[3]) &
                                                MY_MASK_BYTE4) )
    {
        packet.TargetIPAddr.v[0] = MY_GATE_BYTE1;
        packet.TargetIPAddr.v[1] = MY_GATE_BYTE2;
        packet.TargetIPAddr.v[2] = MY_GATE_BYTE3;
        packet.TargetIPAddr.v[3] = MY_GATE_BYTE4;
    }
    else
        packet.TargetIPAddr             = remote->IPAddr;

    SwapARPPacket(&packet);

    MACPutHeader(&packet.TargetMACAddr, MAC_ARP, sizeof(packet));

    MACPutArray((BYTE*)&packet, sizeof(packet));

    MACFlush();
}
Exemplo n.º 9
0
/*****************************************************************************
  Function:
    ARP_RESULT ARPProcess(NET_CONFIG* pIf)

  Summary:
    Processes an incoming ARP packet.

  Description:
    Retrieves an ARP packet from the MAC buffer and determines if it is a
    response to our request (in which case the ARP is resolved) or if it
    is a request requiring our response (in which case we transmit one.)

  Precondition:
    ARP packet is ready in the MAC buffer.

  Parameters:
    None

  Return Values:
    ARP_RES_OK      - processing OK.
    ARP_RES_error   - some error occurred
  ***************************************************************************/
ARP_RESULT ARPProcess(NET_CONFIG* pIf)
{
    ARP_PACKET      packet;
    MAC_ADDR        *dstMAC;
    OA_HASH_ENTRY   *hE;
    ARP_CACHE_DCPT  *pArpDcpt;
    int              netIx;
    TCPIP_MAC_HANDLE hMac;
    ARP_RESULT       arpReqRes;

    netIx = _TCPIPStackNetIx(pIf);
    pArpDcpt = arpCache + netIx;
    hMac = _TCPIPStackNetToMac(pIf);

    // Obtain the incoming ARP packet and process
    MACGetArray(hMac, (uint8_t*)&packet, sizeof(packet));
    MACDiscardRx(hMac);
    SwapARPPacket(&packet);

    // Validate the ARP packet
    if ( packet.HardwareType != HW_ETHERNET     ||
            packet.MACAddrLen != sizeof(MAC_ADDR)  ||
            packet.ProtocolLen != sizeof(IP_ADDR) )
    {
        return ARP_RES_OK;
    }
#ifdef TCPIP_STACK_USE_ZEROCONF_LINK_LOCAL
    ARPProcessRxPkt(pIf, &packet);
#endif

    arpReqRes = ARP_RES_OK;
    // Handle incoming ARP packet
    hE = OAHashLookUp(pArpDcpt->cacheDcpt, &packet.SenderIPAddr.Val);
    if(hE != 0)
    {   // we already have this sender and we should update it
        _ARPUpdateEntry(pIf, (ARP_HASH_ENTRY*)hE, &packet.SenderMACAddr);
    }

    while(packet.TargetIPAddr.Val == pIf->MyIPAddr.Val)
    {   // we are the target and we should add to cache anyway
        if(hE == 0)
        {   // not there yet
            arpReqRes = _ARPAddCompleteEntry(pIf, &packet.SenderIPAddr, &packet.SenderMACAddr);
        }

        // Handle incoming ARP operation
        if(packet.Operation == ARP_OPERATION_REQ)
        {
            // ARP packet asking for this host IP address
#ifdef TCPIP_STACK_USE_ZEROCONF_LINK_LOCAL
            /* Fix for Loop-Back suppression:
             * For ZCLL-Claim packets, host should not respond.
             * Check Sender's MAC-address with own MAC-address and
             * if it is matched, response will not be sent back. This
             * was leading to flooding of ARP-answeres */
            if(!memcmp (&packet.SenderMACAddr, &pIf->MyMACAddr, 6))
            {
                SYS_CONSOLE_MESSAGE("Loopback answer suppressed \r\n");
                break;
            }
#endif
#if defined(TCPIP_STACK_USE_AUTO_IP)
            if ((packet.SenderIPAddr.Val == pIf->MyIPAddr.Val) || AutoIPConfigIsInProgress(pIf))
            {
                AutoIPConflict(pIf);
                break;
            }
#endif

            // Need to send a reply to the requestor
#if defined(TCPIP_STACK_USE_AUTO_IP)
            if (AutoIPIsConfigured(pIf))
            {
                dstMAC = &arpBcastAdd;
            }
            else
#endif
            {
                dstMAC = &packet.SenderMACAddr;
            }
            // Send an ARP response to the received request
            if(!ARP_SendIfPkt(pIf, ARP_OPERATION_RESP, (uint32_t)pIf->MyIPAddr.Val, (uint32_t)packet.SenderIPAddr.Val, dstMAC))
            {
                arpReqRes =  ARP_RES_TX_FAILED;
            }
        }
        break;
    }

    return arpReqRes;
}
Exemplo n.º 10
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;
        }
    }
}