/** * ARP FSM is executed. * @preCondition ARP packet is ready in MAC buffer. * @return */ BOOL ARPProcess(void) { NODE_INFO remoteNode; BYTE opCode; //If a valid ARP packet addressed to us was received, true is returned and //opcode (ARP_REPLY or ARP_REQUEST) is writen to given opCode buffer. switch(smARP) { case SM_ARP_IDLE: if ( !ARPGet(&remoteNode, &opCode) ) break; if ( opCode == ARP_REPLY ) //We have received an ARP reply resolving a requested IP address's MAC address { #ifdef STACK_CLIENT_MODE Cache.MACAddr = remoteNode.MACAddr; Cache.IPAddr.Val = remoteNode.IPAddr.Val; #endif break; } else smARP = SM_ARP_REPLY; default: if(ARPPut(&remoteNode, ARP_REPLY)) { smARP = SM_ARP_IDLE; } else return FALSE; break; } return TRUE; }
/********************************************************************* * Function: BOOL ARPProcess(void) * * PreCondition: ARP packet is ready in MAC buffer. * * Input: None * * Output: ARP FSM is executed. * * Side Effects: None * * Overview: None * * Note: None ********************************************************************/ BOOL ARPProcess(void) { NODE_INFO remoteNode; BYTE opCode; switch(smARP) { case SM_ARP_IDLE: if ( !ARPGet(&remoteNode, &opCode) ) break; if ( opCode == ARP_REPLY ) { #ifdef STACK_CLIENT_MODE Cache.MACAddr = remoteNode.MACAddr; Cache.IPAddr.Val = remoteNode.IPAddr.Val; #endif break; } else smARP = SM_ARP_REPLY; default: if(ARPPut(&remoteNode, ARP_REPLY)) { smARP = SM_ARP_IDLE; } else return FALSE; break; } return TRUE; }
void ARPResolve(IP_ADDR *IPAddr) { NODE_INFO remoteNode; remoteNode.IPAddr = *IPAddr; ARPPut(&remoteNode, ARP_REQUEST); }
void ARPResolve(IP_ADDR* IPAddr) { ARP_PACKET packet; #ifdef STACK_USE_ZEROCONF_LINK_LOCAL #define KS_ARP_IP_MULTICAST_HACK y #ifdef KS_ARP_IP_MULTICAST_HACK if ((IPAddr->v[0] >= 224) &&(IPAddr->v[0] <= 239)) { // "Resolve" the IP to MAC address mapping for // IP multicast address range from 224.0.0.0 to 239.255.255.255 Cache.MACAddr.v[0] = 0x01; Cache.MACAddr.v[1] = 0x00; Cache.MACAddr.v[2] = 0x5E; Cache.MACAddr.v[3] = 0x7f & IPAddr->v[1]; Cache.MACAddr.v[4] = IPAddr->v[2]; Cache.MACAddr.v[5] = IPAddr->v[3]; Cache.IPAddr.Val = IPAddr->Val; return; } #endif #endif 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; //putsUART("ARPResolve() \r\n"); // ARP query either the IP address directly (on our subnet), or do an ARP query for our Gateway if off of our subnet packet.TargetIPAddr = ((AppConfig.MyIPAddr.Val ^ IPAddr->Val) & AppConfig.MyMask.Val) ? AppConfig.MyGateway : *IPAddr; #ifdef STACK_USE_ZEROCONF_LINK_LOCAL packet.SenderIPAddr = AppConfig.MyIPAddr; #endif ARPPut(&packet); }
/***************************************************************************** Function: void ARPSendPkt(IP_ADDR* SrcIPAddr, IP_ADDR* DestIPAddr, int op_req ) Summary: Transmits an ARP request/Reply initated by Application or external module. Description: This function transmits and ARP request/reply to determine the hardware address of a given IP address (or) Announce self-address to all nodes in network. Extended for zeroconf protocol. Precondition: ARP packet is ready in the MAC buffer. Parameters: SrcIPAddr - The Source IP-address DestIPAddr - The Destination IP-Address op_req - Operation Request (ARP_REQ/ARP_RESP) Returns: true - The ARP packet was generated properly false - Not possible return value Remarks: This API is to give control over AR-packet to external modules. ***************************************************************************/ bool ARPSendPkt(uint32_t SrcIPAddr, uint32_t DestIPAddr, uint8_t op_req ) { ARP_PACKET packet; #ifdef STACK_USE_ZEROCONF_LINK_LOCAL #define KS_ARP_IP_MULTICAST_HACK y #ifdef KS_ARP_IP_MULTICAST_HACK TCPIP_UINT32_VAL *DestAddr = (TCPIP_UINT32_VAL *)&DestIPAddr; if ((DestAddr->v[0] >= 224) &&(DestAddr->v[0] <= 239)) { // "Resolve" the IP to MAC address mapping for // IP multicast address range from 224.0.0.0 to 239.255.255.255 Cache.MACAddr.v[0] = 0x01; Cache.MACAddr.v[1] = 0x00; Cache.MACAddr.v[2] = 0x5E; Cache.MACAddr.v[3] = 0x7f & DestAddr->v[1]; Cache.MACAddr.v[4] = DestAddr->v[2]; Cache.MACAddr.v[5] = DestAddr->v[3]; Cache.IPAddr.Val = DestAddr->Val; return true; } #endif #endif packet.Operation = op_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; packet.TargetIPAddr.Val = DestIPAddr; packet.SenderIPAddr.Val = SrcIPAddr; return ( ARPPut(&packet) ); }
/***************************************************************************** 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; }