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

📄 udp.c

📁 windows mobile 5 下的底层驱动包
💻 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:    udp.c

Abstract:       This contains the UDP/IP and ARP routines for the 
                bootloader.  This module operates on top of the 
                pktdrv.c module.

Functions:


Notes: 

--*/


// Include Files

#include <windows.h>
#include "udp.h"


// Local Variables

static  BYTE fPromiscuousIP;


// External Functions (header file?)

BOOL EbootDHCPDecline( EDBG_ADDR *pMyAddr); // dhcp.c


// Static Functions

static  void    DuplicateIPWarning( DWORD dwIP, BYTE * chMAC );
static  DWORD   UpperDWFromMAC( BYTE *pAddr );
static  UINT16  CRC( UINT16 *pwRegion1, 
                     UINT16  wLength1, 
                     UINT16 *pwRegion2, 
                     UINT16  wLength2 );

//------------------------------------------------------------------------------
//
//  Function Name:  SrcAddrFromFrame( EDBG_ADDR *pAddr, BYTE *pFrameBuffer ) 
//  Description..:  This routine will set an EDBG_ADDR to point to the source 
//                  of this IP frame
//  Inputs.......:  EDBG_ADDR       pntr to address
//                  BYTE *          pntr to frame buffer
//  Outputs......:  none
//
//------------------------------------------------------------------------------

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;
}

//------------------------------------------------------------------------------
//
//  Function Name:  EbootProcessARP( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer ) 
//  Description..:  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.
//
//  Inputs.......:  EDBG_ADDR *     pntr to address
//                  BYTE *          pntr to frame buffer
//  Outputs......:  ARP request status
//
//------------------------------------------------------------------------------

UINT16 EbootProcessARP( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer ) 
{
    EthernetFrameHeader *pFrameHeader;
    ARPPacketFormat     *pARP;

    // Access ARP packet

    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

        // An ARP response destined for our station is NOT expected.
        // We expect to have a unique IP and we now need to re-issue 
        // a DHCP request.

        DuplicateIPWarning( 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);         // Ethernet
    pARP->wProtocolType = htons(0x0800);    // IP addresses are being mapped
    pARP->bHardwareAddrSize = 6;            // 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];

    // Send the frame

    if( OEMEthSendFrame( pFrameBuffer, 
        sizeof(EthernetFrameHeader) + sizeof(ARPPacketFormat)) )
    {
        return PROCESS_ARP_REQUEST;
    }
    else
    {
        return PROCESS_ARP_REQUEST_ERR;
    }
}

//------------------------------------------------------------------------------
//
//  Function Name:  EbootGratuitousARP( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer ) 
//  Description..:  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.
//
//  Inputs.......:  EDBG_ADDR *     pntr to address
//                  BYTE *          pntr to frame buffer
//  Outputs......:  TRUE on success, else FALSE
//
//------------------------------------------------------------------------------

UINT16 EbootGratuitousARP( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer ) 
{
    EthernetFrameHeader *pFrameHeader;
    ARPPacketFormat *pARP;

    // Access the ARP packet

    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);         // Ethernet
    pARP->wProtocolType = htons(0x0800);    // IP addresses are being mapped
    pARP->bHardwareAddrSize = 6;            // 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];

    // Send the frame

    if( OEMEthSendFrame( pFrameBuffer, 
        sizeof(EthernetFrameHeader) + sizeof(ARPPacketFormat)) )
    {
        return( 0 );
    }
    else
    {
        return( 1 );
    }
}

//------------------------------------------------------------------------------
//
//  Function Name:  EbootSendUDP(...)
//  Description..:  Format Ethernet, IP, and UDP headers into supplied frame 
//                  buffer, and send to peer.  Pointer to frame buffer to hold 
//                  Ethernet frame must be at least 42 bytes + length of UDP 
//                  data. Pointer to UDP data. Can, but doesn't have to, be 
//                  within the frame buffer.
//  Inputs.......:  BYTE *          pntr to frame
//                  EDBG_ADDR       pntr to dst addr
//                  EDBG_ADDR       pntr to src addr
//                  BYTE *          pntr to UDP data
//                  UINT16          data length 
//  Outputs......:  TRUE on success, else FALSE
//
//------------------------------------------------------------------------------

BOOL EbootSendUDP( BYTE        *pFrameBuffer,    
                   EDBG_ADDR   *pDestAddr,          
                   EDBG_ADDR   *pSrcAddr,       
                   BYTE        *pUDPData,               
                   UINT16       cwLength )      
{
    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;   // IPv4, No options, 5 longs
    pIPHeader->bTypeOfService = 0;      // no special transport options

    // Total length of the IP datagram

    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;    // UDP protocol is 17

⌨️ 快捷键说明

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