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

📄 dhcpcboot.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        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,* and waits up to the current timeout value to receive a reply from that* server. If a timeout occurs, the DHCP request message is retransmitted.* If the request is refused or the retransmission limit is reached, the lease* negotiation process will restart or the inform process will exit. If the* request is acknowledged, the corresponding parameters will be used by the* bootstrap loader to configure the boot device and fetch the runtime image.** RETURNS: Next state of state machine, or -1 if error.** ERRNO: N/A** NOMANUAL*/LOCAL int dhcpcBootRequesting    (    void    )    {    STATUS result = OK;    char *pOption = NULL;    char errmsg[255];    int timer = 0;    int retry = 0;    struct dhcp_param tmpparam;    struct dhcp_reqspec tmp_reqspec;    EVENT_DATA 		newEvent;    char * pMsgData;    int status;    int msgtype;#ifdef DHCPC_DEBUG    char newAddr [INET_ADDR_LEN];    logMsg ("dhcpc: Entering requesting state.\n", 0, 0, 0, 0, 0, 0);#endif     bzero (errmsg, sizeof (errmsg));    bzero ( (char *)&tmp_reqspec, sizeof (tmp_reqspec));    /* Wait for message or retransmission. */    semTake (dhcpcEventSem, WAIT_FOREVER);    status = rngBufGet (dhcpcEventRing, (char *)&newEvent, sizeof (newEvent));    if (status != sizeof (newEvent))        {        /* Expected event missing or incomplete - remain in current state. */        return (REQUESTING);        }    if (newEvent.type == DHCP_TIMEOUT)        {        /* Handle timeout - no DHCP reply received yet. */        retry = dhcpcBootLeaseData.numRetry;        timer = dhcpcBootLeaseData.timeout;        retry++;        if (retry > REQUEST_RETRANS)             {#ifdef DHCPC_DEBUG            logMsg ("Client can't get ACK/NAK reply from server\n",                      0, 0, 0, 0, 0, 0);#endif          /* Exit if unable to get additional parameters for known address. */            if (dhcpcPrevState == INFORMING)                return (BOUND);            return (INIT);           /* Next state is INIT */            }        /* Retransmission required - return after sending message. */        switch (gen_retransmit ())            {            case 0:         /* Transmission successful. */#ifdef DHCPC_DEBUG                logMsg ("retransmit DHCPREQUEST\n", 0, 0, 0, 0, 0, 0);#endif                break;            case -1:        /* Couldn't update timing data */#ifdef DHCPC_DEBUG                logMsg ("time() error retransmitting DHCPREQUEST\n",                         0, 0, 0, 0, 0, 0);#endif                break;            case -2:        /* Transmission error in output routine */#ifdef DHCPC_DEBUG                logMsg ("Can't retransmit DHCPREQUEST\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_requesting, 0);        dhcpcBootLeaseData.timeout = timer;        dhcpcBootLeaseData.numRetry = retry;        }    else        {        bzero ( (char *)&tmpparam, sizeof (tmpparam));        /*         * 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 = newEvent.pMsg;        msgAlign (&dhcpcMsgIn, pMsgData);        pOption = (char *) pickup_opt (dhcpcMsgIn.dhcp,                                       DHCPLEN (dhcpcMsgIn.udp),                                       _DHCP_MSGTYPE_TAG);        if (pOption != NULL)             {            msgtype =*OPTBODY (pOption);            /*             * Ignore unknown message types. If the client does not receive             * a valid response within the expected interval, it will             * timeout and retransmit the request - RFC 2131, section 3.1.5.             */            if (msgtype != DHCPACK && msgtype != DHCPNAK)                {                /*                 * Mark the message buffer available after                 * handling the last DHCP message.                 */                if (newEvent.lastFlag)                    dhcpcMessageList [newEvent.slot].writeFlag = TRUE;                return (REQUESTING);                }	    if (msgtype == DHCPNAK)                 {#ifdef DHCPC_DEBUG	        logMsg ("Got DHCPNAK from server\n", 0, 0, 0, 0, 0, 0);                pOption = (char *)pickup_opt (dhcpcMsgIn.dhcp,                                               DHCPLEN(dhcpcMsgIn.udp),                                               _DHCP_ERRMSG_TAG);                if (pOption != NULL &&                    nvttostr (OPTBODY (pOption), errmsg,                               (int)DHCPOPTLEN (pOption)) == 0)	            logMsg ("DHCPNAK contains the error message \"%s\"\n",                              (int)errmsg, 0, 0, 0, 0, 0);#endif                /*                 * Mark the message buffer available after handling the                 * last DHCP message.                 */                if (newEvent.lastFlag)                    dhcpcMessageList [newEvent.slot].writeFlag = TRUE;                /* Ignore invalid responses to DHCP inform message. */                if (dhcpcPrevState == INFORMING)                    return (REQUESTING);                clean_param (dhcpcBootParam);                free (dhcpcBootParam);                dhcpcBootParam = NULL;                return (INIT);               /* Next state is INIT */	        }            /*             * Got acknowledgement: fill in host requirements defaults and             * add any parameters from message options.             */            dhcpcDefaultsSet (&tmpparam);               result = dhcp_msgtoparam (dhcpcMsgIn.dhcp,                                      DHCPLEN (dhcpcMsgIn.udp), &tmpparam);            /*             * Mark the message buffer available after             * handling the last DHCP message.             */            if (newEvent.lastFlag)                dhcpcMessageList [newEvent.slot].writeFlag = TRUE;            if (result == OK)                 {                /* Options parsed successfully - test as needed. */                if (dhcpcPrevState == INFORMING)                    dhcpcBindType = DHCP_MANUAL;     /* Not a lease. */                else                    {                    /* Full lease negotiation - send ARP probe. */                    result = arp_check (&tmpparam.yiaddr, &dhcpcIntface);                    if (result == OK)                        { #ifdef DHCPC_DEBUG                        inet_ntoa_b (dhcpcBootParam->yiaddr, newAddr);                        logMsg ("Got DHCPACK (IP = %s, duration = %d secs)\n",                                (int)newAddr, dhcpcBootParam->lease_duration,                                 0, 0, 0, 0);#endif                        dhcpcBindType = DHCP_NATIVE;                        }                    }                /* Save additional parameters if address is available. */                if (result == OK)                    {                    merge_param (dhcpcBootParam, &tmpparam);                    *dhcpcBootParam = tmpparam;                    if (dhcpcBindType == DHCP_NATIVE)                        {                        /* Save the lease start time. */                        dhcpcBootParam->lease_origin =                                                dhcpcBootLeaseData.initEpoch;                        }                    return (BOUND);    /* Address is available. */                    }                }            /*             * Invalid parameters or (for a full lease negotiation) a             * failed ARP probe (address in use). For the full lease             * negotiation, send the DHCPDECLINE message which is now             * required when an ARP probe fails: RFC 2131, section 3.1.5.             */            if (dhcpcPrevState != INFORMING)                {                set_declinfo (&tmp_reqspec, errmsg);                dhcp_decline (&tmp_reqspec);                clean_param (dhcpcBootParam);                free (dhcpcBootParam);                dhcpcBootParam = NULL;#ifdef DHCPC_DEBUG                logMsg ("Received unacceptable ACK. Entering INIT state.\n",                        0, 0, 0, 0, 0, 0);#endif                return (INIT);                }            /* Ignore invalid parameters for DHCP inform messages. */            return (REQUESTING);            }        /*         * Message type unavailable - remain in current state. Mark         * the message buffer available after handling the last DHCP         * message.         */        if (newEvent.lastFlag)            dhcpcMessageList [newEvent.slot].writeFlag = TRUE;        }    /* Timeout occurred - remain in current state. */    return (REQUESTING);    }/********************************************************************************* generate_xid - generate a transaction identifier ** This routine forms a transaction identifier for outgoing messages from the* DHCP client. It is called from multiple locations after the initialization * routines have retrieved the network interface hardware address.** RETURNS: 32-bit transaction identifier in host byte order. ** ERRNO: N/A** NOMANUAL*/LOCAL long generate_xid    (    void    )    {    time_t current = 0;    u_short result1 = 0;    u_short result2 = 0;    u_short tmp[6];     bcopy (dhcpcIntface.haddr.haddr, (char *)tmp, 6);    dhcpTime (&current);    result1 = checksum (tmp, 6);    result2 = checksum ( (u_short *)&current, 2);    return ( (result1 << 16) + result2);    }/********************************************************************************* msgAlign - set the buffer pointers to access message components** This routine sets the pointers in the given message descriptor* structure to access the various components of a received DHCP* message. It is used internally by the state machine routines.** RETURNS: N/A** ERRNO:   N/A** NOMANUAL*/LOCAL void msgAlign    (    struct msg *rmsg, 	/* Components of received message */    char *rbuf 		/* Received Ethernet packet */    )    {    rmsg->ip = (struct ip *) rbuf;    if ( (ntohs (rmsg->ip->ip_off) & 0x1fff) == 0 &&        ntohs (rmsg->ip->ip_len) >= (DFLTDHCPLEN - DFLTOPTLEN + 4) + 				    UDPHL + IPHL)        {#if BSD<44        rmsg->udp = (struct udphdr *)&rbuf [(rmsg->ip->ip_v_hl & 0xf) * WORD];        rmsg->dhcp = (struct dhcp *)&rbuf [(rmsg->ip->ip_v_hl & 0xf) * WORD +                                           UDPHL];#else        rmsg->udp = (struct udphdr *) &rbuf [rmsg->ip->ip_hl * WORD];        rmsg->dhcp = (struct dhcp *) &rbuf [rmsg->ip->ip_hl * WORD +                                            UDPHL];#endif        }    else        {        rmsg->udp = NULL;        rmsg->dhcp = NULL;        }    return;    }/********************************************************************************* arp_check - use ARP to check if given address is in use** This routine broadcasts an ARP request and waits for a reply to determine if* an IP address offered by a DHCP server is already in use.** RETURNS: ERROR if ARP indicates client in use, or OK otherwise.** ERRNO: N/A** NOMANUAL*/int arp_check    (    struct in_addr *target,    struct if_info *pIfData     /* interface used by lease */    )    {    int i = 0;    int tmp;    char inbuf [MAX_ARPLEN];    char *pField1;    char *pField2;    struct arphdr * pArpHdr = NULL;

⌨️ 快捷键说明

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