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

📄 udp.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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.

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);

⌨️ 快捷键说明

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