/********************************************************************* * * ARP Module for Microchip TCP/IP Stack * ********************************************************************* * FileName: ARP.c * Dependencies: string.h * stacktsk.h * helpers.h * arp.h * mac.h * Processor: PIC18 * Complier: MCC18 v1.00.50 or higher * HITECH PICC-18 V8.10PL1 or higher * Company: Microchip Technology, Inc. * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the “Company”) for its PICmicro® Microcontroller is intended and * supplied to you, the Company’s customer, for use solely and * exclusively on Microchip PICmicro Microcontroller products. The * software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * HiTech PICC18 Compiler Options excluding device selection: * -FAKELOCAL -G -Zg -E -C * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Nilesh Rajbharti 5/1/01 Original (Rev 1.0) * Nilesh Rajbharti 2/9/02 Cleanup * Nilesh Rajbharti 5/22/02 Rev 2.0 (See version.log for detail) ********************************************************************/ #include #include "stacktsk.h" #include "helpers.h" #include "arp.h" #include "mac.h" /* * ARP Operation codes. */ #define ARP_OPERATION_REQ 0x01 #define ARP_OPERATION_RESP 0x02 /* * ETHERNET packet type as defined by IEEE 802.3 */ #define HW_ETHERNET (0x0001) #define ARP_IP (0x0800) /* * ARP packet */ typedef struct _ARP_PACKET { WORD HardwareType; WORD Protocol; BYTE MACAddrLen; BYTE ProtocolLen; WORD Operation; MAC_ADDR SenderMACAddr; IP_ADDR SenderIPAddr; MAC_ADDR TargetMACAddr; IP_ADDR TargetIPAddr; } ARP_PACKET; static void SwapARPPacket(ARP_PACKET *p); /********************************************************************* * 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.v[0] == MY_IP_BYTE1) && (packet.TargetIPAddr.v[1] == MY_IP_BYTE2) && (packet.TargetIPAddr.v[2] == MY_IP_BYTE3) && (packet.TargetIPAddr.v[3] == MY_IP_BYTE4) ) { remote->MACAddr = packet.SenderMACAddr; remote->IPAddr = packet.SenderIPAddr; return TRUE; } else return FALSE; } /********************************************************************* * 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(); } /********************************************************************* * Function: static void SwapARPPacket(ARP_PACKET* p) * * PreCondition: None * * Input: p - ARP packet to be swapped. * * Output: None * * Side Effects: None * * Overview: None * * Note: None ********************************************************************/ static void SwapARPPacket(ARP_PACKET *p) { p->HardwareType = swaps(p->HardwareType); p->Protocol = swaps(p->Protocol); p->Operation = swaps(p->Operation); }