/** * * This function will send a Echo request packet. * * @param InstancePtr is a pointer to the instance of the EmacLite. * * @return None. * * @note None. * ******************************************************************************/ static void SendEchoReqFrame(XEmacLite *InstancePtr) { u16 *TempPtr; u16 *TxFramePtr; u16 *RxFramePtr; u16 CheckSum; u32 NextTxBuffBaseAddr; int Index; TxFramePtr = (u16 *)TxFrame; RxFramePtr = (u16 *)RxFrame; /* * Determine the next expected transmit buffer base address. */ NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr); /* * Add Destination MAC Address. */ Index = MAC_ADDR_LEN; while (Index--) { *(TxFramePtr + Index) = *(DestMacAddr + Index); } /* * Add Source MAC Address. */ Index = MAC_ADDR_LEN; TempPtr = (u16 *)LocalMacAddr; while (Index--) { *(TxFramePtr + (Index + SRC_MAC_ADDR_LOC )) = *(TempPtr + Index); } /* * Add IP header information. */ Index = IP_START_LOC; while (Index--) { *(TxFramePtr + (Index + ETHER_PROTO_TYPE_LOC )) = Xil_Htons(*(IpHeaderInfo + Index)); } /* * Add Source IP address. */ Index = IP_ADDR_LEN; TempPtr = (u16 *)LocalIpAddress; while (Index--) { *(TxFramePtr + (Index + IP_REQ_SRC_IP_LOC )) = *(TempPtr + Index); } /* * Add Destination IP address. */ Index = IP_ADDR_LEN; TempPtr = (u16 *)DestIpAddress; while (Index--) { *(TxFramePtr + (Index + IP_REQ_DEST_IP_LOC )) = *(TempPtr + Index); } /* * Checksum is calculated for IP field and added in the frame. */ CheckSum = CheckSumCalculation((u16 *)TxFrame, IP_START_LOC, IP_HEADER_LEN); CheckSum = ~CheckSum; *(TxFramePtr + IP_CHECKSUM_LOC) = Xil_Htons(CheckSum); /* * Add echo field information. */ *(TxFramePtr + ICMP_ECHO_FIELD_LOC) = Xil_Htons(XEL_ETHER_PROTO_TYPE_IP); /* * Checksum value is initialized to zeros. */ *(TxFramePtr + ICMP_DATA_LEN) = 0x0000; /* * Add identifier and sequence number to the frame. */ *(TxFramePtr + ICMP_IDEN_FIELD_LOC) = (IDEN_NUM); *(TxFramePtr + (ICMP_IDEN_FIELD_LOC + 1)) = Xil_Htons((u16)(++SeqNum)); /* * Add known data to the frame. */ Index = ICMP_KNOWN_DATA_LEN; while (Index--) { *(TxFramePtr + (Index + ICMP_KNOWN_DATA_LOC)) = Xil_Htons(*(IcmpData + Index)); } /* * Checksum is calculated for Data Field and added in the frame. */ CheckSum = CheckSumCalculation((u16 *)TxFrame, ICMP_DATA_START_LOC, ICMP_DATA_FIELD_LEN ); CheckSum = ~CheckSum; *(TxFramePtr + ICMP_DATA_CHECKSUM_LOC) = Xil_Htons(CheckSum); /* * Transmit the Frame. */ XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ICMP_PKT_SIZE); }
/** * * This function processes the received packet and generates the corresponding * reply packets. * * @param InstancePtr is a pointer to the instance of the EmacLite. * * @return None. * * @note This function assumes MAC does not strip padding or CRC. * ******************************************************************************/ static void ProcessRecvFrame(XEmacLite *InstancePtr) { u16 *RxFramePtr; u16 *TxFramePtr; u16 *TempPtr; u16 CheckSum; u32 NextTxBuffBaseAddr; int Index; int PacketType = 0; TxFramePtr = (u16 *)TxFrame; RxFramePtr = (u16 *)RxFrame; /* * Determine the next expected Tx buffer address. */ NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr); /* * Check the packet type. */ Index = MAC_ADDR_LEN; TempPtr = (u16 *)LocalMacAddr; while (Index--) { if (Xil_Ntohs((*(RxFramePtr + Index)) == BROADCAST_ADDR) && (PacketType != MAC_MATCHED_PACKET)) { PacketType = BROADCAST_PACKET; } else if (Xil_Ntohs((*(RxFramePtr + Index)) == *(TempPtr + Index)) && (PacketType != BROADCAST_PACKET)) { PacketType = MAC_MATCHED_PACKET; } else { PacketType = 0; break; } } /* * Process broadcast packet. */ if (PacketType == BROADCAST_PACKET) { /* * Check for an ARP Packet if so generate a reply. */ if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) == XEL_ETHER_PROTO_TYPE_ARP) { /* * IP address of the local machine. */ TempPtr = (u16 *)LocalIpAddr; /* * Check destination IP address of the packet with * local IP address. */ if ( ((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_1)) == *TempPtr++) && ((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_2)) == *TempPtr++)) { /* * Check ARP packet type(request/reply). */ if (Xil_Ntohs(*(RxFramePtr + ARP_REQ_STATUS_LOC)) == ARP_REQUEST) { /* * Add destination MAC address * to the reply packet (i.e) source * address of the received packet. */ Index = SRC_MAC_ADDR_LOC; while (Index < (SRC_MAC_ADDR_LOC + MAC_ADDR_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Add source (local) MAC address * to the reply packet. */ Index = 0; TempPtr = (u16 *)LocalMacAddr; while (Index < MAC_ADDR_LEN) { *TxFramePtr++ = *TempPtr++; Index++; } /* * Add Ethernet proto type H/W * type(10/3MBps),H/W address length and * protocol address len (i.e)same as in * the received packet */ Index = ETHER_PROTO_TYPE_LOC; while (Index < (ETHER_PROTO_TYPE_LOC + ETHER_PROTO_TYPE_LEN + ARP_HW_TYPE_LEN + ARP_HW_ADD_LEN + ARP_PROTO_ADD_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Add ARP reply status to the reply * packet. */ *TxFramePtr++ = Xil_Htons(ARP_REPLY); /* * Add local MAC Address * to the reply packet. */ TempPtr = (u16 *)LocalMacAddr; Index = 0; while (Index < MAC_ADDR_LEN) { *TxFramePtr++ = *TempPtr++; Index++; } /* * Add local IP Address * to the reply packet. */ TempPtr = (u16 *)LocalIpAddr; Index = 0; while (Index < IP_ADDR_LEN) { *TxFramePtr++ = *TempPtr++ ; Index++; } /* * Add Destination MAC Address * to the reply packet from the received * packet. */ Index = SRC_MAC_ADDR_LOC; while (Index < (SRC_MAC_ADDR_LOC + MAC_ADDR_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Add Destination IP Address * to the reply packet. */ Index = ARP_REQ_SRC_IP_LOC; while (Index < (ARP_REQ_SRC_IP_LOC + IP_ADDR_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Fill zeros as per protocol. */ Index = 0; while (Index < ARP_ZEROS_LEN) { *TxFramePtr++ = 0x0000; Index++; } /* * Transmit the Reply Packet. */ XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ARP_PACKET_SIZE); } } } } /* * Process packets whose MAC address is matched. */ if (PacketType == MAC_MATCHED_PACKET) { /* * Check ICMP packet. */ if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) == XEL_ETHER_PROTO_TYPE_IP) { /* * Check the IP header checksum. */ CheckSum = CheckSumCalculation(RxFramePtr, IP_HDR_START_LOC, IP_HDR_LEN); /* * Check the Data field checksum. */ if (CheckSum == CORRECT_CKSUM_VALUE) { CheckSum = CheckSumCalculation(RxFramePtr, ICMP_DATA_START_LOC, ICMP_DATA_FIELD_LEN); if (CheckSum == CORRECT_CKSUM_VALUE) { /* * Add destination address * to the reply packet (i.e)source * address of the received packet. */ Index = SRC_MAC_ADDR_LOC; while (Index < (SRC_MAC_ADDR_LOC + MAC_ADDR_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Add local MAC address * to the reply packet. */ Index = 0; TempPtr = (u16 *)LocalMacAddr; while (Index < MAC_ADDR_LEN) { *TxFramePtr++ = *TempPtr++; Index++; } /* * Add protocol type * header length and, packet * length(60 Bytes) to the reply packet. */ Index = ETHER_PROTO_TYPE_LOC; while (Index < (ETHER_PROTO_TYPE_LOC + ETHER_PROTO_TYPE_LEN + IP_VERSION_LEN + IP_PACKET_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Identification field a random number * which is set to IDENT_FIELD_VALUE. */ *TxFramePtr++ = IDENT_FIELD_VALUE; /* * Add fragment type, time to live and * ICM field. It is same as in the * received packet. */ Index = IP_FRAG_FIELD_LOC; while (Index < (IP_FRAG_FIELD_LOC + IP_TTL_ICM_LEN + IP_FRAG_FIELD_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Checksum first set to 0 and * added in this field later. */ *TxFramePtr++ = 0x0000; /* * Add Source IP address */ Index = 0; TempPtr = (u16 *)LocalIpAddr; while (Index < IP_ADDR_LEN) { *TxFramePtr++ = *TempPtr++; Index++; } /* * Add Destination IP address. */ Index = ICMP_REQ_SRC_IP_LOC; while (Index < (ICMP_REQ_SRC_IP_LOC + IP_ADDR_LEN)) { *TxFramePtr++ = *(RxFramePtr + Index); Index++; } /* * Calculate checksum, and * add it in the appropriate field. */ CheckSum = CheckSumCalculation( (u16 *)TxFrame, IP_HDR_START_LOC, IP_HDR_LEN); CheckSum = ~CheckSum; *(TxFramePtr - IP_CSUM_LOC_BACK) = Xil_Htons(CheckSum); /* * Echo reply status & checksum. */ Index = ICMP_ECHO_FIELD_LOC; while (Index < (ICMP_ECHO_FIELD_LOC + ICMP_ECHO_FIELD_LEN)) { *TxFramePtr++ = 0x0000; Index++; } /* * Add data to buffer which was * received from the packet. */ Index = ICMP_DATA_LOC; while (Index < (ICMP_DATA_LOC + ICMP_DATA_LEN)) { *TxFramePtr++ = (*(RxFramePtr + Index)); Index++; } /* * Generate checksum for the data and * add it in the appropriate field. */ CheckSum = CheckSumCalculation( (u16 *)TxFrame, ICMP_DATA_START_LOC, ICMP_DATA_FIELD_LEN); CheckSum = ~CheckSum; *(TxFramePtr - ICMP_DATA_CSUM_LOC_BACK) = Xil_Htons(CheckSum); /* * Transmit the frame. */ XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ICMP_PACKET_SIZE); /* * Increment the number of * Ping replies sent. */ NumOfPingReplies++; } } } } }
/** * * This function will send a ARP request packet. * * @param InstancePtr is a pointer to the instance of the EmacLite. * * @return None. * * @note None. * ******************************************************************************/ static void SendArpReqFrame(XEmacLite *InstancePtr) { u16 *TempPtr; u16 *TxFramePtr; u32 NextTxBuffBaseAddr; int Index; TxFramePtr = (u16 *)TxFrame; /* * Determine the next expected transmit buffer base address. */ NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr); /* * Add broadcast address. */ Index = MAC_ADDR_LEN; while (Index--) { *TxFramePtr++ = BROADCAST_ADDR; } /* * Add local MAC address. */ Index = 0; TempPtr = (u16 *)LocalMacAddr; while (Index < MAC_ADDR_LEN) { *TxFramePtr++ = *(TempPtr + Index); Index++; } /* * Add * - Ethernet proto type. * - Hardware Type * - Protocol IP Type * - IP version (IPv6/IPv4) * - ARP Request */ *TxFramePtr++ = Xil_Htons(XEL_ETHER_PROTO_TYPE_ARP); *TxFramePtr++ = Xil_Htons(HW_TYPE); *TxFramePtr++ = Xil_Htons(XEL_ETHER_PROTO_TYPE_IP); *TxFramePtr++ = Xil_Htons(IP_VERSION); *TxFramePtr++ = Xil_Htons(ARP_REQUEST); /* * Add local MAC address. */ Index = 0; TempPtr = (u16 *)LocalMacAddr; while (Index < MAC_ADDR_LEN) { *TxFramePtr++ = *(TempPtr + Index); Index++; } /* * Add local IP address. */ Index = 0; TempPtr = (u16 *)LocalIpAddress; while (Index < IP_ADDR_LEN) { *TxFramePtr++ = *(TempPtr + Index); Index++; } /* * Fills 6 bytes of information with zeros as per protocol. */ Index = 0; while (Index < 3) { *TxFramePtr++ = 0x0000; Index++; } /* * Add Destination IP address. */ Index = 0; TempPtr = (u16 *)DestIpAddress; while (Index < IP_ADDR_LEN) { *TxFramePtr++ = *(TempPtr + Index); Index++; } /* * Transmit the Frame. */ XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ARP_REQ_PKT_SIZE); }