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

📄 udp.c

📁 Xcale270Bsp包,wince平台
💻 C
📖 第 1 页 / 共 2 页
字号:
	pIPHeader->cwTotalLength = htons(sizeof(IPHeaderFormat) + sizeof(UDPHeaderFormat) + cwLength);
										// Unique packet identification
	pIPHeader->wIdentification = wIndentification++;
	pIPHeader->wFragment = 0;			// No fragmentation
	pIPHeader->bTimeToLive = (char)64;	// We can go through 64 routers
	pIPHeader->bProtocol = (char)17;	// Specify the UDP protocol
	pIPHeader->wCRC = 0;				// Set the CRC to 0 while it is being computed
	pIPHeader->dwSrcIP = pSrcAddr->dwIP;
	pIPHeader->dwDestIP = pDestAddr->dwIP;

	// Compute the CRC and we're done with the IP header
	pIPHeader->wCRC = CRC( (UINT16 *)pIPHeader, sizeof(IPHeaderFormat), NULL, 0);

	// The field information comes from page 145 of TCP/IP Illustrated by W. Richard Stevens
	// Construct the UDP pseudo header
	UDPPseudoHeader.dwSrcIP = pSrcAddr->dwIP;
	UDPPseudoHeader.dwDestIP = pDestAddr->dwIP;
	UDPPseudoHeader.bZero = 0;
	UDPPseudoHeader.bProtocol = 17;		// This is the code for the UDP protocol
	UDPPseudoHeader.cwTotalUDPLength = htons(sizeof(UDPHeaderFormat) + cwLength);

	// Construct the real UDP header
	pUDPHeader = (UDPHeaderFormat *)((BYTE *)pIPHeader + sizeof(IPHeaderFormat));
	pUDPHeader->wSrcPort = pSrcAddr->wPort;
	pUDPHeader->wDestPort = pDestAddr->wPort;
											// The total length of the UDP datagram
	pUDPHeader->cwTotalUDPLength = UDPPseudoHeader.cwTotalUDPLength;
	pUDPHeader->wCRC = 0;					// Set the CRC to 0 while it is being computed

    // Copy user data if necessary
    if ((pUDPData - pFrameBuffer) != UDP_DATA_FRAME_OFFSET)
        memcpy((BYTE *)pUDPHeader + sizeof(UDPHeaderFormat), pUDPData, cwLength);
    
	// Compute the CRC for the UDP datagram.  The pad 0 will automatically be added if there are an odd number of bytes
	pUDPHeader->wCRC = CRC( (UINT16 *)(&UDPPseudoHeader), sizeof(UDPPseudoHeader), (UINT16 *)pUDPHeader, ntohs(pUDPHeader->cwTotalUDPLength) );
	if (pUDPHeader->wCRC == 0)
		pUDPHeader->wCRC = ~(pUDPHeader->wCRC);

    return OEMEthSendFrame(pFrameBuffer,sizeof(EthernetFrameHeader) + ntohs(pIPHeader->cwTotalLength));
}



// These routines set/clear the fPromiscuousIP global flag that is used to indicate when the CheckUDP()
//  routine should allow any IP packet through the filtering system (set), or only allow packets that
//  have our destination IP address in them (clear).  These are used with the DHCP protocol.
void SetPromiscuousIP( void ) {

	fPromiscuousIP = 1;

}
void ClearPromiscuousIP( void ) {

	fPromiscuousIP = 0;

}



// This routine will check a UDP frame that has been received.  It will make sure that it
//  was for our IP address and that the checksums are right and that it's a UDP packet.  If something is
//  wrong, the packet will be discarded and the routine will return non-zero.  If everything is right,
//  then all the port and IP information will be filled out and the routine will return 0.
// Note that if we are doing the DHCP process, the DHCP server will send the OFFER packet to the IP
//  address that it would like to give us.  We have to have be able to accept a packet for any IP
//  address in that case.  This condition is signaled to the routine by fPromiscuousIP == 1, which is
//  set using SetPromiscuousIP()
UINT16 EbootCheckUDP( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer, UINT16 *wDestPort, UINT16 *wSrcPort, UINT16 **pwData, UINT16 *cwLength ) {

	IPHeaderFormat *pIPHeader;
	UDPPseudoHeaderFormat UDPPseudoHeader;
	UDPHeaderFormat *pUDPHeader;

	// Note that I don't do any checking that depends on a length field in the packet until after the CRC
	//  is verified for that data.  This prevents the code from running past the end of buffers, etc. when
	//  a bad packet is received.

	pIPHeader = (IPHeaderFormat *)(pFrameBuffer + sizeof(EthernetFrameHeader));
	// Make sure that it was for our IP address, unless we're doing DHCP (indicated by fPromiscuousIP == 1)
	if (!fPromiscuousIP && pIPHeader->dwDestIP != pMyAddr->dwIP) {
//        EdbgOutputDebugString("!CheckUDP: Not our IP (0x%X)\n",pIPHeader->dwDestIP);
		return 1;
    }
	// Make sure that it is a UDP packet
	if (pIPHeader->bProtocol != 17) {
        EdbgOutputDebugString("!CheckUDP: Not UDP (proto = 0x%X)\n",pIPHeader->bProtocol);
		return 2;
    }

	// Check the IP header checksum
	if (CRC( (UINT16 *)pIPHeader, sizeof(IPHeaderFormat), NULL, 0 ) != 0) {
        EdbgOutputDebugString("!CheckUDP: IP header checksum failure\n");
		return 3;
    }

	// Build the UDP Pseudo Header
	UDPPseudoHeader.dwSrcIP = pIPHeader->dwSrcIP;
	UDPPseudoHeader.dwDestIP = pIPHeader->dwDestIP;
	UDPPseudoHeader.bZero = 0;
	UDPPseudoHeader.bProtocol = 17;			// This is the code for the UDP protocol
	UDPPseudoHeader.cwTotalUDPLength = htons(htons(pIPHeader->cwTotalLength) - sizeof(IPHeaderFormat));

	// Check the UDP checksum, I'm using the cwTotalUDPLength calculated from the IP header info because
	//  we know that it's not corrupted and won't give an outrageous length for the packet
	pUDPHeader = (UDPHeaderFormat *)((BYTE *)pIPHeader + sizeof(IPHeaderFormat));
	if (CRC( (UINT16 *)(&UDPPseudoHeader), sizeof(UDPPseudoHeader), (UINT16 *)pUDPHeader, ntohs(UDPPseudoHeader.cwTotalUDPLength) ) != 0) {
        EdbgOutputDebugString("!CheckUDP: UDP header checksum failure\n");
		return 4;
    }
    
	// Now we know we have a good packet, fill out the fields
	*wDestPort = pUDPHeader->wDestPort;
	*wSrcPort = pUDPHeader->wSrcPort;
	*pwData = (UINT16 *)((BYTE *)pUDPHeader + sizeof(UDPHeaderFormat));
	*cwLength = htons(pUDPHeader->cwTotalUDPLength) - sizeof(UDPHeaderFormat);

	return 0;
}


//
// Code and data to generate CE reference platform debug ethernet names
//

typedef struct vendorid {
    DWORD dwUpperMAC; // first 3 bytes of ethernet address
    char  *szAbbrev;
} VENDORID;


#define SMC_VENDOR_ID 0x00800F

static const VENDORID VendorIds[] = {
    {0x00006E, "AE" }, // Artisoft
    {0x000094, "AS" }, // ASANTE
    {0x0000E8, "AC" }, // Accton Technology
    {0x004005, "LS" }, // LinkSys
    {0x004033, "AD" }, // Addtron Technology
    {0x004092, "ASP"}, // ASP Computer Products
    {SMC_VENDOR_ID, "SMC"}, // SMC  (assume ODO platform)
    {0x008048, "CPX"}, // Compex
    {0x0080AD, "CN" }, // CNET Technologies
    {0x0080C8, "DL" }, // D-Link
    {0x00A0D2, "AT" }, // Allied TeleSyn
    {0x00C00D, "ALR"}, // Advanced Logic Research
    {0x00C06D, "BR" }, // Boca Research
    {0x00C0DF, "GE" }, // Kye International GENIUS GE2000 series
    {0x00C0F0, "KS" }, // Kingston
    {0x4854E8, "WB" }  // WinBond Electronics Corp
};

#define NUM_VENDORIDS (sizeof(VendorIds)/sizeof(VENDORID))

#define CEPC_PLATFORM_STRING "CEPC"
#define ODO_PLATFORM_STRING  "ODO"

static void
itoa10(
    int i,
    BYTE * a
    )
{
    BYTE * p = a;
    int c = 0;
    int n = i;
    BYTE swap;

    //
    // Build the ascii string in reverse digit order
    //
    while (n) {
        *p = (BYTE)(n % 10) + '0';
        n /= 10;
        p++;
        c++;
    }
    *p = 0;
    c--;

    //
    // Reverse the string in place to correct order
    //
    for (n = 0; n < c; n++, c--) {
        swap = a[n];
        a[n] = a[c];
        a[c] = swap;
    }
}

static DWORD
UpperDWFromMAC(BYTE * pAddr)
{
    DWORD ret;

    //
    // Given a hex ethernet address of 12 34 56 78 9a bc
    // the 4 byte return value should look like 0x00123456
    //
    ret  = (DWORD)pAddr[0];
    ret  <<= 8;
    ret |= (DWORD)pAddr[1];
    ret  <<= 8;
    ret |= (DWORD)pAddr[2];
    return ret;
}

static void
CreateDeviceName(BYTE * pAddr, BYTE * szBuf)
{
    int i;
    DWORD dwTmp = UpperDWFromMAC(pAddr);

    if (dwTmp == SMC_VENDOR_ID) {
        strcpy(szBuf, ODO_PLATFORM_STRING);
        szBuf += strlen(szBuf);
        dwTmp = (DWORD)pAddr[5];

    } else {
        strcpy(szBuf, CEPC_PLATFORM_STRING);
        szBuf += strlen(szBuf);
    
        for (i=0;i<NUM_VENDORIDS;i++) {
            if (dwTmp == VendorIds[i].dwUpperMAC) {
                strcat(szBuf,VendorIds[i].szAbbrev);
                szBuf += strlen(szBuf);
                break;
            }
        }

        dwTmp = (DWORD)pAddr[4];
        dwTmp <<= 8;
        dwTmp |= (DWORD)pAddr[5];
    }

    itoa10(dwTmp, szBuf);

}

//
// This function prints a warning when ProcessARP has detected an IP address collision.
//
void
EbootIPWarning(DWORD dwIP, BYTE * pchMAC)
{
    BYTE szSrcName[32];

    CreateDeviceName(pchMAC, szSrcName);

    EdbgOutputDebugString("EbootIPWarning: IP address %s is in use by station with ethernet address %B %B %B %B %B %B.\n",
        inet_ntoa(dwIP), pchMAC[0], pchMAC[1], pchMAC[2], pchMAC[3], pchMAC[4], pchMAC[5]);
    EdbgOutputDebugString("EbootIPWarning: If this is a CE reference platform, the device name is %s.\n", szSrcName);
    EdbgOutputDebugString("EbootIPWarning: Otherwise use \"ping -a %s\" to determine machine name.\n", inet_ntoa(dwIP));


}

⌨️ 快捷键说明

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