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

📄 dhcpcboot.c

📁 VxWorks下DHCP的源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
            /*             * No response to new DHCP message format, which can be ignored             * by older DHCP servers as too short. Try the earlier format,             * which padded the options field to a minimum length. If             * successful, all subsequent messages will add that padding.             * The initialization guarantees that the transmit buffer can             * store the padded message.             */            if (!dhcpcOldFlag && dhcpcMsgLength < (DFLTDHCPLEN + UDPHL + IPHL)) {                dhcpcOldFlag = TRUE;                dhcpcMsgLength = make_discover ();                timer = FIRSTTIMER / 2; /* Counteract later doubling. */                retry = 0;            } else                return (ERROR);        }        /* Retransmission required - return after sending message. */        switch (gen_retransmit ()) {        case 0:                /* Transmission successful. */#ifdef DHCPC_DEBUG            logMsg ("retransmit DHCPDISCOVER\n", 0, 0, 0, 0, 0, 0);#endif            break;        case -1:               /* Couldn't update timing data */#ifdef DHCPC_DEBUG            logMsg ("time() error retransmitting DHCPDISCOVER\n", 0, 0, 0, 0, 0, 0);#endif            break;        case -2:               /* Transmission error in output routine */#ifdef DHCPC_DEBUG            logMsg ("Can't retransmit DHCPDISCOVER\n", 0, 0, 0, 0, 0, 0);#endif            break;        }        if (timer < MAXTIMER) {            /* Double retransmission delay with each attempt. (RFC 1541). */            timer *= 2;        }        /* Set retransmission timer to randomized exponential backoff. */        wdStart (dhcpcBootLeaseData.timer, sysClkRateGet () *                 SLEEP_RANDOM (timer), (FUNCPTR) retrans_wait_offer, 0);        dhcpcBootLeaseData.timeout = timer;        dhcpcBootLeaseData.numRetry = retry;    } else {        /*         * Process DHCP message stored in receive buffer by monitor task.         * The 4-byte alignment of the IP header needed by Sun BSP's is         * guaranteed by the Berkeley Packet Filter during input.         */        pMsgData = msgEvent.pMsg;        msgAlign (&dhcpcMsgIn, pMsgData);        /* Examine type of message. Accept DHCP offers or BOOTP replies. */        pOption = (char *) pickup_opt (dhcpcMsgIn.dhcp,                                       DHCPLEN (dhcpcMsgIn.udp), _DHCP_MSGTYPE_TAG);        if (pOption == NULL) {            /*              * Message type not found - check message length. Ignore             * untyped DHCP messages, but accept (shorter) BOOTP replies.             * This test might still treat (illegal) untyped DHCP messages             * like BOOTP messages if they are short enough, but that case             * can't be avoided. Mark the message buffer available after             * handling the last DHCP message.             */            if (DHCPLEN (dhcpcMsgIn.udp) > DFLTBOOTPLEN) {                if (msgEvent.lastFlag)                    dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;                return (WAIT_OFFER);            }        } else {            if (*OPTBODY (pOption) != DHCPOFFER) {                /*                 * Ignore messages with unexpected types. Mark the message                 * buffer available after handling the last DHCP message.                 */                if (msgEvent.lastFlag)                    dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;                return (WAIT_OFFER);            }        }        /* Allocate memory for configuration parameters. */        pParams = (struct dhcp_param *) calloc (1, sizeof (struct dhcp_param));        if (pParams == NULL) {            /*             * Memory for configuration parameters is unavailable. Remain             * in current state. Mark the message buffer available after             * handling the last DHCP message.             */            if (msgEvent.lastFlag)                dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;            return (WAIT_OFFER);        }        /* Fill in host requirements defaults. */        dhcpcDefaultsSet (pParams);        /* Check offered parameters. Copy to parameter list if acceptable. */        if (dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), pParams) == OK) {            /*             * Accept static BOOTP address or verify that the             * address offered by the DHCP server is available             * and check offered lease length against minimum value.             */            if ((pParams->msgtype == DHCP_BOOTP ||                 pParams->server_id.s_addr != 0) &&                (arpans = arp_check (&pParams->yiaddr, &dhcpcIntface)) == OK &&                pParams->lease_duration >= dhcpcMinLease) {                /*                 * Initial offer accepted. Set client session                 * to execute next routine and start timer.                 */                pParams->lease_origin = dhcpcBootLeaseData.initEpoch;                dhcpcBootParam = pParams;                /*                 * Reset timer from retransmission interval                 * to limit for collecting replies.                 */                wdCancel (dhcpcBootLeaseData.timer);                wdStart (dhcpcBootLeaseData.timer, sysClkRateGet () *                         dhcpcBootLeaseData.leaseReqSpec.waitsecs, (FUNCPTR) alarm_selecting, 0);                /*                 * Mark the message buffer available after handling the                 * last DHCP message.                 */                if (msgEvent.lastFlag)                    dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;                return (SELECTING); /* Next state is SELECTING */            } else {                /*                 * Offer is insufficient. Remove stored parameters                 * and remain in current state.                 */                clean_param (pParams);                free (pParams);            }        } else {            /* Conversion unsuccessful - remove any stored parameters. */            clean_param (pParams);            free (pParams);        }    }    /*     * No valid offer received yet. Next state is (still) WAIT_OFFER. Mark     * the message buffer available after handling the last DHCP message.     */    if (msgEvent.type == DHCP_MSG_ARRIVED && msgEvent.lastFlag)        dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;    return (WAIT_OFFER);}/********************************************************************************* dhcpcBootSelecting - Second offering state of client finite state machine** This routine continues the second state of the finite state machine. * It compares additional offers received from DHCP servers to the current* offer, and selects the offer which provides the lognest lease. When* the time limit specified by the DHCPC_OFFER_TIMEOUT definition passes, * processing of the selected DHCP offer will continue with the requesting() * routine. If no DHCP offers were received, the BOOTP reply selected by the * wait_offer() routine will be used by the bootstrap loader.** RETURNS: Next state of state machine, or -1 if error.** ERRNO: N/A** NOMANUAL*/LOCAL int dhcpcBootSelecting (void){    int arpans = 0;    struct dhcp_param *pParams = NULL;    char *pMsgData;    char *pOption;    EVENT_DATA msgEvent;    int status;    struct sockaddr_in dest;#ifdef DHCPC_DEBUG    logMsg ("dhcp: Entered SELECTING state.\n", 0, 0, 0, 0, 0, 0);#endif    /* Wait for message or timer expiration. */    semTake (dhcpcEventSem, WAIT_FOREVER);    status = rngBufGet (dhcpcEventRing, (char *) &msgEvent, sizeof (msgEvent));    if (status != sizeof (msgEvent)) {        /* Expected event missing or incomplete - remain in current state. */        return (SELECTING);    }    if (msgEvent.type == DHCP_TIMEOUT) {        /*         * Collection time expired -         *     parameters structure holds chosen offer.         */        /* No response is needed if a BOOTP reply is chosen. */        if (dhcpcBootParam->msgtype == DHCP_BOOTP) {            dhcpcBindType = DHCP_BOOTP;            return (BOUND);        }        dhcpcMsgLength = make_request (dhcpcBootParam, REQUESTING);        if (dhcpcMsgLength < 0) {#ifdef DHCPC_DEBUG            logMsg ("Error making DHCP request. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif            return (INIT);        }        dhcpcMsgOut.udp->uh_sum = 0;        dhcpcMsgOut.udp->uh_sum = udp_cksum (&spudph, (char *) dhcpcMsgOut.udp,                                             ntohs (spudph.ulen));        /*         * Retransmit the message using a link-level broadcast address,         * which prevents ARP messages if using Ethernet devices and allows         * transmission from interfaces without assigned IP addresses.         */        bzero ((char *) &dest, sizeof (struct sockaddr_in));        dest.sin_len = sizeof (struct sockaddr_in);        dest.sin_family = AF_INET;        dest.sin_addr.s_addr = dhcpcMsgOut.ip->ip_dst.s_addr;        if (dhcpSend (dhcpcIntface.iface, &dest, sbuf.buf, dhcpcMsgLength, TRUE) == ERROR) {#ifdef DHCPC_DEBUG            logMsg ("Can't send DHCPREQUEST\n", 0, 0, 0, 0, 0, 0);#endif            return (INIT);        }        /*         * DHCP request sent. Set client session to execute next state and         * start the retransmission timer.         */        dhcpcBootLeaseData.timeout = FIRSTTIMER;        dhcpcBootLeaseData.numRetry = 0;        wdStart (dhcpcBootLeaseData.timer, sysClkRateGet () *                 SLEEP_RANDOM (dhcpcBootLeaseData.timeout), (FUNCPTR) retrans_requesting, 0);        return (REQUESTING);    } else {        /*         * Process DHCP message stored in receive buffer by monitor task.          * The 4-byte alignment of the IP header needed by Sun BSP's is         * guaranteed by the Berkeley Packet Filter during input.         */        pMsgData = msgEvent.pMsg;        msgAlign (&dhcpcMsgIn, pMsgData);        /* Examine type of message. Only accept DHCP offers. */        pOption = (char *) pickup_opt (dhcpcMsgIn.dhcp,                                       DHCPLEN (dhcpcMsgIn.udp), _DHCP_MSGTYPE_TAG);        if (pOption == NULL) {            /*             * Message type not found - discard untyped DHCP messages, and             * any BOOTP replies. Mark the message buffer available after             * handling the last DHCP message.             */            if (msgEvent.lastFlag)                dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;            return (SELECTING);        } else {            if (*OPTBODY (pOption) != DHCPOFFER) {                /*                 * Ignore messages with unexpected types. Mark the message                 * buffer available after handling the last DHCP message.                 */                if (msgEvent.lastFlag)                    dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;                return (SELECTING);            }        }        /* Allocate memory for configuration parameters. */        pParams = (struct dhcp_param *) calloc (1, sizeof (struct dhcp_param));        if (pParams == NULL) {            /*             * Memory for configuration parameters is unavailable. Remain             * in current state. Mark the message buffer available after             * handling the last DHCP message.             */            if (msgEvent.lastFlag)                dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;            return (SELECTING);        }        /* Fill in host requirements defaults. */        dhcpcDefaultsSet (pParams);        /* Switch to offered parameters if they provide a longer DHCP lease. */        if (dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), pParams) == OK) {            if (pParams->server_id.s_addr != 0 &&                (arpans = arp_check (&pParams->yiaddr, &dhcpcIntface)) == OK &&                pParams->lease_duration >= dhcpcMinLease) {                /* Take any DHCP message over BOOTP, or take a longer lease. */                if (dhcpcBootParam->msgtype == DHCP_BOOTP ||                    pParams->lease_duration > dhcpcBootParam->lease_duration) {                    pParams->lease_origin = dhcpcBootLeaseData.initEpoch;                    clean_param (dhcpcBootParam);                    free (dhcpcBootParam);                    dhcpcBootParam = pParams;                }            } else {                /*                 * Offer is insufficient. Remove stored parameters                 * and remain in current state.                 */                clean_param (pParams);                free (pParams);            }        } else {            /* Conversion unsuccessful - remove any stored parameters. */            clean_param (pParams);            free (pParams);        }    }    /*     * Processed new offer before timer expired. Next state is (still)     * SELECTING. Mark the message buffer available after handling the     * last DHCP message.     */    if (msgEvent.lastFlag)        dhcpcMessageList[msgEvent.slot].writeFlag = TRUE;    return (SELECTING);}/********************************************************************************* dhcpcBootRequesting - Lease request state of client finite state machine** This routine implements the third state of the client finite state machine.* It sends a lease request to the DHCP server whose offer was selected,

⌨️ 快捷键说明

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