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

📄 dhcp.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
            return pbParse;
    }
    if (fUseSname)
        pbParse = EdbgDHCPParseField (DHCPOption, pDHCPMsg->szSNAME);

    return pbParse;

} // EdbgDHCPFindOption()


// This routine generates a pseudo random sequence using a 16-bit LFSR.  These are used as source ports
//  for the TFTP protocol.  Note that because XOR was used, 0 is a dead value and will never be
//  returned.  The value of all 1's can be made the dead value if XNOR is used.
static UINT16 EdbgGenerateSrcPort (void) {

    static UINT16 wLastValue = 1;
    UINT16 wTempValue;

    // Loop here until we get a value that isn't in use
    do {
        // For a 16-bit LFSR shifting to the left, I'll take bits 15,14,12,3
        wTempValue = 0xD008 & wLastValue;
        // Now XOR those bits together to get the bit shifted in on the right
        wTempValue ^= (wTempValue >> 12);
        wTempValue ^= (wTempValue >> 2);
        wTempValue ^= (wTempValue >> 1);

        // Shift it and OR in the new bit
        wLastValue = (wLastValue << 1) | (wTempValue & 0x0001);

    }
    while(wLastValue < htons(1024));    // Stay out of well-known port range

    return wLastValue;
}


// This routine will form the DHCP messages that we have to send and send them out.
static BOOL EdbgSendDHCPRenew (EDBG_ADDR *pMyAddr, DWORD *dwXID)
{
    UCHAR FrameBuf[UDP_DATA_FRAME_OFFSET + sizeof(DHCPMsgFormat)];
    DHCPMsgFormat *pDHCPMsg = (DHCPMsgFormat *)(FrameBuf + UDP_DATA_FRAME_OFFSET);
    WORD wOpOff;

    // Start out by zeroing out the whole thing because most of it is supposed to be zero anyway
    memset(pDHCPMsg, 0, sizeof(DHCPMsgFormat));

    pDHCPMsg->bOperation = 1;               // Client to Server messages are BOOTREQUEST
    pDHCPMsg->bHardwareAddrType = 1;        // Hardware type is 10Mbps Ethernet
    pDHCPMsg->bHardwareAddrLen = 6;         // Hardware address length
    // Fill in our MAC address
    pDHCPMsg->wCHADDR[0] = pMyAddr->wMAC[0];
    pDHCPMsg->wCHADDR[1] = pMyAddr->wMAC[1];
    pDHCPMsg->wCHADDR[2] = pMyAddr->wMAC[2];
    pDHCPMsg->wSecs = (WORD) OEMKitlGetSecs ();      // Number of seconds elapsed since last reset

    // The flags field is zero.  Note that since the broadcast bit isn't set
    //  here, we must accept packets using our new IP address before we
    //  do the final confirmation.

    // Now fill in the option fields
    wOpOff = 0;

    // Fill in the "Magic Cookie"
    pDHCPMsg->bOptions[wOpOff++] = 99;      pDHCPMsg->bOptions[wOpOff++] = 130;
    pDHCPMsg->bOptions[wOpOff++] = 83;      pDHCPMsg->bOptions[wOpOff++] = 99;

    // Put in the message type field
    pDHCPMsg->bOptions[wOpOff++] = DHCP_MSGTYPE;    // This is the DHCP message type field
    pDHCPMsg->bOptions[wOpOff++] = 1;               // Length of 1 byte
    pDHCPMsg->bOptions[wOpOff++] = DHCP_REQUEST;    // Set the message type

    EdbgDHCPBuildOps (DHCP_HOSTNAME, pDHCPMsg, &wOpOff, (DWORD)pMyAddr->wMAC);
    // Request the old IP address
    EdbgDHCPBuildOps (DHCP_IP_ADDR_REQ, pDHCPMsg, &wOpOff, pMyAddr->dwIP);
    *dwXID = pDHCPMsg->dwXID = (((DWORD)pDHCPMsg->wCHADDR[2]) << 16) | EdbgGenerateSrcPort();
    pDHCPMsg->dwCIADDR = pMyAddr->dwIP;
    EdbgDHCPBuildOps (DHCP_CLIENT_ID, pDHCPMsg, &wOpOff, (DWORD)pMyAddr->wMAC);
    // Indicate end of options
    EdbgDHCPBuildOps (DHCP_END, pDHCPMsg, &wOpOff, 0);

    // We need to broadcast these messages to all the DHCP servers.
    if (!EncodeUDP (FrameBuf, sizeof(DHCPMsgFormat), pMyAddr, &BroadCastAddr))
        return FALSE;

    return KitlSendRawData (FrameBuf, sizeof (FrameBuf));

} // SendDHCPRenew()


static BYTE HexToChar(BYTE hex)
{
    switch (hex) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
        return '0' + hex;

    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
        return 'A' + hex - 10;
    }
    return 'X';
}


// Generate a string which is the concatenation of "CED" and the ethernet address
// ("CED" denotes the debug ethernet component of a CE device.)
static void FormatDHCPName(BYTE * pName, BYTE * pEthAddr)
{
    DWORD j;
    BYTE * pN;
    BYTE * pA;
    BYTE A;

    pName[0] = 'C';
    pName[1] = 'E';
    pName[2] = 'D';

    pN = pName + 3;
    pA = pEthAddr;

    for (j = 0; j < 6; j++, pA++, pN += 2) {
        A = *pA;
        pN[0] = HexToChar((BYTE)(A >> 4));
        pN[1] = HexToChar((BYTE)(A & 0x0f));
    }
    *pN = 0;
}   // FormatDHCPName


// This routine will add options to the DHCP Options field.  The option type is filled in
//  and the Option Offset (pwOpOff) is incremented to include the new option.  Some of the
//  options can be taken from the DHCP header itself, data for others is passed in through
//  the generic dwData.
static void EdbgDHCPBuildOps (DHCPOptions DHCPOption, DHCPMsgFormat *pDHCPMsg, WORD *pwOpOff, DWORD dwData)
{
    BYTE * pName;
    
    switch (DHCPOption) {
    case DHCP_SERVER_ID:
    case DHCP_IP_ADDR_REQ:
    case DHCP_HOSTNAME:
    case DHCP_CLIENT_ID:
    case DHCP_END:
        pDHCPMsg->bOptions[(*pwOpOff)++] = DHCPOption;
        break;
    } // switch

    switch (DHCPOption) {
    case DHCP_SERVER_ID:
    case DHCP_IP_ADDR_REQ:
        // There are 4 data bytes
        pDHCPMsg->bOptions[(*pwOpOff)++] = 4;
        // IP address that we'd like to have
        pDHCPMsg->bOptions[(*pwOpOff)++] = (BYTE)dwData;
        pDHCPMsg->bOptions[(*pwOpOff)++] = (BYTE)(dwData >> 8);
        pDHCPMsg->bOptions[(*pwOpOff)++] = (BYTE)(dwData >> 16);
        pDHCPMsg->bOptions[(*pwOpOff)++] = (BYTE)(dwData >> 24);
        break;

    case DHCP_HOSTNAME:
        // The ethernet address is passed in dwData
        pName = &(pDHCPMsg->bOptions[*pwOpOff+1]);
        FormatDHCPName(pName, (BYTE *)dwData);

        // Fill out the host name length
        (*pwOpOff) += pDHCPMsg->bOptions[*pwOpOff] = strlen(pName) + 1;
        (*pwOpOff)++;
        break;

    case DHCP_CLIENT_ID:
        pDHCPMsg->bOptions[(*pwOpOff)++] = 7;   // 1 byte of hw addr type and 6 bytes of ethernet addr
        pDHCPMsg->bOptions[(*pwOpOff)++] = 1;   // ethernet hw addr type
        memcpy(&(pDHCPMsg->bOptions[*pwOpOff]), (BYTE *) dwData, 6);  // ethernet addr
        *pwOpOff += 6;
        break;
    } // switch

} // DHCPBuildOps()

// 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. 
static BOOL SendGratuitousARP (EDBG_ADDR *pMyAddr)
{
    BYTE FrameBuffer[sizeof(EthernetFrameHeader) + sizeof(ARPPacketFormat)];
    EthernetFrameHeader *pFrameHeader;
    ARPPacketFormat *pARP;

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

    // Fill in destination and source MAC addresses and the ARP frame type
    pFrameHeader = (EthernetFrameHeader *)FrameBuffer;
    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(ARP_FRAME);

    // 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->wSrcMAC[0] = pMyAddr->wMAC[0];
    pARP->wSrcMAC[1] = pMyAddr->wMAC[1];
    pARP->wSrcMAC[2] = pMyAddr->wMAC[2];
    pARP->dwSrcIP = pMyAddr->dwIP;

    return KitlSendRawData (FrameBuffer, sizeof(EthernetFrameHeader) + sizeof(ARPPacketFormat));
}

// This function gets called when we can't get our original IP address back
// (either the DHCP server sent a NAK or some other station thinks it owns our IP
// address and has responded to our gratuitous ARP
static void EdbgDHCPError (void)
{
    // An ARP response means some other station thinks it owns our IP address
    // We cannot just restart the DHCP discovery/request process because the other
    // EDBG components (like on the desktop) are not able to switch IP addresses
    // on the fly.
    KITLOutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    KITLOutputDebugString("!!! Fatal error in debug Ethernet, another system using our IP address, SPIN FOREVER !!!\n");
    KITLOutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");

    while (1)
        ;
}

⌨️ 快捷键说明

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