⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp.c

📁 Xcale270Bsp包,wince平台
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

Module Name:  

Abstract:  

Functions:


Notes: 

--*/

/*********************************************************************
*
*	Module Name: udp.c
*
*	Abstract:
*		This contains the UDP/IP and ARP routines for the bootloader.
*	This module operates on top of the pktdrv.c module.
*
*	History:
*
*	Note:
*
********************************************************************/
#include <windows.h>
#include "udp.h"


BYTE fPromiscuousIP;

void EbootIPWarning(DWORD dwIP, BYTE * chMAC);
BOOL EbootDHCPDecline( EDBG_ADDR *pMyAddr); // dhcp.c

// This routine will set an EDBG_ADDR to point to the source of this IP frame
void SrcAddrFromFrame( EDBG_ADDR *pAddr, BYTE *pFrameBuffer ) {
	EthernetFrameHeader *pFrameHeader;
	IPHeaderFormat *pIPHeader;
	UDPHeaderFormat *pUDPHeader;

	// Replace the old host information
	pFrameHeader = (EthernetFrameHeader *)pFrameBuffer;
	pAddr->wMAC[0] = pFrameHeader->wSrcMAC[0];
	pAddr->wMAC[1] = pFrameHeader->wSrcMAC[1];
	pAddr->wMAC[2] = pFrameHeader->wSrcMAC[2];
	pIPHeader = (IPHeaderFormat *)(pFrameBuffer + sizeof(EthernetFrameHeader));
	pAddr->dwIP = pIPHeader->dwSrcIP;
	pUDPHeader = (UDPHeaderFormat *)((BYTE *)pIPHeader + sizeof(IPHeaderFormat));
	pAddr->wPort = pUDPHeader->wSrcPort;

}



// This routine will calculation the complemented 16-bit 1's complement sum required to compute
//  network CRCs.  The CRC can be calculated over two different memory regions.  If only one
//  region is desired, then the other's length can be set to 0.  Also, if an odd number of bytes
//  are specified, the routine will add a 0 to the end of the data before doing the CRC and will
//  include that 0 in the calculation.
static UINT16 CRC( UINT16 *pwRegion1, UINT16 wLength1, UINT16 *pwRegion2, UINT16 wLength2 ) {

	DWORD dwSum, dwCarryOut;
	UINT16 wCRC;
	UINT16 i;

	// There is no need to swap for network ordering during calculation because of the end around
	//  carry used in 1's complement addition
	dwSum = 0;
	if (wLength1 & 1) {
		*((BYTE *)pwRegion1 + wLength1) = 0;
		wLength1++;
	}
	wLength1 >>= 1;
	for( i = 0; i < wLength1; i++ )
		dwSum += *pwRegion1++;

	if (wLength2 & 1) {
		*((BYTE *)pwRegion2 + wLength2) = 0;
		wLength2++;
	}
	wLength2 >>= 1;
	for( i = 0; i < wLength2; i++ )
		dwSum += *pwRegion2++;

	// Now, we have to add back in all the carry out's from the lower 16 bits
	//  because this is 1's complement
	while( dwSum & 0xFFFF0000UL ) {
		dwCarryOut = dwSum >> 16;
		dwSum &= 0x0000FFFFUL;
		dwSum += dwCarryOut;
	}

	wCRC = (UINT16)dwSum;

	// There is no need to flip for network byte order because we did all the sums backwards
	//  already.
	wCRC = ~wCRC;

	return wCRC;

}


// This routine is called in response to receiving an ARP packet.  If a request is received, we send back
//  a response and update the HostAddress to point to the machine that requested it.
// If a response is received, then most likely some other station thinks it owns our IP address.
// CAUTION: This routine WILL reformat the original frame into the format of the ARP response
UINT16 EbootProcessARP( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer ) {

	EthernetFrameHeader *pFrameHeader;
	ARPPacketFormat *pARP;

	pARP = (ARPPacketFormat *)(pFrameBuffer + sizeof(EthernetFrameHeader));

    // Check to see that they were requesting the ARP response from us
	if (pARP->dwDestIP != pMyAddr->dwIP)
		return PROCESS_ARP_IGNORE;

	// Make sure this is an ARP request
	switch (htons(pARP->wOperation)) {
    case 1: // ARP request
        break;

    case 2: // ARP response
        // Any ARP response destined for our station is NOT expected.
        // We expect to have a unique IP. We now need to reissue a DHCP request
        EbootIPWarning(pARP->dwSrcIP, (char *)pARP->wSrcMAC);
        EbootDHCPDecline(pMyAddr);
        return PROCESS_ARP_RESPONSE;

    case 3: // RARP request
    case 4: // RARP response
    default:
		return PROCESS_ARP_IGNORE;
    }

	// Fill in destination and source MAC addresses and the ARP frame type
	pFrameHeader = (EthernetFrameHeader *)pFrameBuffer;
	pFrameHeader->wDestMAC[0] = pARP->wSrcMAC[0];
	pFrameHeader->wDestMAC[1] = pARP->wSrcMAC[1];
	pFrameHeader->wDestMAC[2] = pARP->wSrcMAC[2];
	pFrameHeader->wSrcMAC[0] = pMyAddr->wMAC[0];
	pFrameHeader->wSrcMAC[1] = pMyAddr->wMAC[1];
	pFrameHeader->wSrcMAC[2] = pMyAddr->wMAC[2];
	pFrameHeader->wFrameType = htons(0x0806);

	// The field information comes from page 57 of TCP/IP Illustrated by W. Richard Stevens
	pARP->wHardwareType = htons(1);			// Specifies Ethernet
	pARP->wProtocolType = htons(0x0800);	// Specifies that IP addresses are being mapped
	pARP->bHardwareAddrSize = 6;			// Ethernet MAC addresses are 6 bytes long
	pARP->bProtocolAddrSize = 4;			// IP addresses are 4 bytes long
	pARP->wOperation = htons(2);			// Specify an ARP reply

	// Fill in the destination information
	pARP->wDestMAC[0] = pARP->wSrcMAC[0];
	pARP->wDestMAC[1] = pARP->wSrcMAC[1];
	pARP->wDestMAC[2] = pARP->wSrcMAC[2];
	pARP->dwDestIP = pARP->dwSrcIP;
	// Fill in the source side information
	pARP->dwSrcIP = pMyAddr->dwIP;
	pARP->wSrcMAC[0] = pMyAddr->wMAC[0];
	pARP->wSrcMAC[1] = pMyAddr->wMAC[1];
	pARP->wSrcMAC[2] = pMyAddr->wMAC[2];

	if (OEMEthSendFrame( pFrameBuffer, sizeof(EthernetFrameHeader) + sizeof(ARPPacketFormat)))
        return PROCESS_ARP_REQUEST;
    else
        return PROCESS_ARP_REQUEST_ERR;
}


// This routine is called to verify that the station's IP address is unique on the net.
// A gratuitous ARP is an ARP request for our own IP address. If there is a response, then
// some other station thinks it still owns our IP address. 
// CAUTION: This routine WILL reformat the original frame
UINT16 EbootGratuitousARP( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer ) {

	EthernetFrameHeader *pFrameHeader;
	ARPPacketFormat *pARP;

	pARP = (ARPPacketFormat *)(pFrameBuffer + sizeof(EthernetFrameHeader));

	// Fill in destination and source MAC addresses and the ARP frame type
	pFrameHeader = (EthernetFrameHeader *)pFrameBuffer;
	pFrameHeader->wDestMAC[0] = 0xFFFF;
	pFrameHeader->wDestMAC[1] = 0xFFFF;
	pFrameHeader->wDestMAC[2] = 0xFFFF;
	pFrameHeader->wSrcMAC[0] = pMyAddr->wMAC[0];
	pFrameHeader->wSrcMAC[1] = pMyAddr->wMAC[1];
	pFrameHeader->wSrcMAC[2] = pMyAddr->wMAC[2];
	pFrameHeader->wFrameType = htons(0x0806);

	// The field information comes from page 57 of TCP/IP Illustrated by W. Richard Stevens
	pARP->wHardwareType = htons(1);			// Specifies Ethernet
	pARP->wProtocolType = htons(0x0800);	// Specifies that IP addresses are being mapped
	pARP->bHardwareAddrSize = 6;			// Ethernet MAC addresses are 6 bytes long
	pARP->bProtocolAddrSize = 4;			// IP addresses are 4 bytes long
	pARP->wOperation = htons(1);			// Specify an ARP request

	// Fill in the destination information
	pARP->wDestMAC[0] = pMyAddr->wMAC[0];
	pARP->wDestMAC[1] = pMyAddr->wMAC[1];
	pARP->wDestMAC[2] = pMyAddr->wMAC[2];
	pARP->dwDestIP = pMyAddr->dwIP;
	// Fill in the source side information
	pARP->dwSrcIP = pMyAddr->dwIP;
	pARP->wSrcMAC[0] = pMyAddr->wMAC[0];
	pARP->wSrcMAC[1] = pMyAddr->wMAC[1];
	pARP->wSrcMAC[2] = pMyAddr->wMAC[2];

	if (OEMEthSendFrame( pFrameBuffer, sizeof(EthernetFrameHeader) + sizeof(ARPPacketFormat)))
        return 0;
    else
        return 1;
}



/* EbootSendUDP
 *
 *   Format Ethernet, IP, and UDP headers into supplied frame buffer, and send to peer.
 */
BOOL
EbootSendUDP(
    BYTE *pFrameBuffer,    // IN - Pointer to frame buffer to hold Ethernet frame. Must be at least 42 bytes + length of UDP data
    EDBG_ADDR *pDestAddr,  // IN - Destination address and port
    EDBG_ADDR *pSrcAddr,   // IN - Source address and port
    BYTE *pUDPData,        // IN - Pointer to UDP data. Can (but doesn't have to) be within the frame buffer
    UINT16 cwLength ) {    // IN - Length of UDP data.

	EthernetFrameHeader *pFrameHeader;
	IPHeaderFormat *pIPHeader;
	UDPPseudoHeaderFormat UDPPseudoHeader;
	UDPHeaderFormat *pUDPHeader;
	static UINT16 wIndentification = 0;
    
	// Fill in destination and source MAC addresses and the IP frame type
	pFrameHeader = (EthernetFrameHeader *)pFrameBuffer;
	pFrameHeader->wDestMAC[0] = pDestAddr->wMAC[0];
	pFrameHeader->wDestMAC[1] = pDestAddr->wMAC[1];
	pFrameHeader->wDestMAC[2] = pDestAddr->wMAC[2];
	pFrameHeader->wSrcMAC[0] = pSrcAddr->wMAC[0];
	pFrameHeader->wSrcMAC[1] = pSrcAddr->wMAC[1];
	pFrameHeader->wSrcMAC[2] = pSrcAddr->wMAC[2];
	pFrameHeader->wFrameType = htons(0x0800);

	// The field information comes from page 34 of TCP/IP Illustrated by W. Richard Stevens
	pIPHeader = (IPHeaderFormat *)(pFrameBuffer + sizeof(EthernetFrameHeader));
	pIPHeader->bVersionLength = 0x45;	// IP Version 4, No option IP header (5 32 bit words)
	pIPHeader->bTypeOfService = 0;		// No special transport options
										// Total length of the IP datagram

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -