📄 dhcpcstate1.c
字号:
if ((dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), pParams) == OK) && /* Then check that the lease time is equal to or greater than * the minimum lease time. */ (pParams->server_id.s_addr != 0 && pParams->lease_duration >= dhcpcMinLease) && /* Finally, take any DHCP message over BOOTP, * or take any lease with a longer duration than * we requested. */ (pLeaseData->dhcpcParam->msgtype == DHCP_BOOTP || pParams->lease_duration > pLeaseData->dhcpcParam->lease_duration)) { pParams->lease_origin = pLeaseData->initEpoch; clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = pParams; } else { clean_param (pParams); free (pParams); } } return (OK); }/********************************************************************************* requesting - Lease request state of client finite state machine** This routine implements the third state of the client finite state machine.* It handles all processing until a response to a transmitted DHCP request* message is received from the selected DHCP server or the retransmission * limit is reached. The DHCP request is retransmitted if a timeout occurs. * If the request is acknowledged, processing will continue with the bound()* routine. If it is refused or the retransmission limit is reached, the * negotiation process will restart with the init() routine.* .IP* This routine is invoked by the event handler of the client monitor task,* and should only be called internally. Any user requests generated by* incorrect calls or delayed responses to the dhcpcBind() and dhcpcVerify()* routines are ignored.** RETURNS: OK (processing complete), DHCPC_DONE (remove lease),* DHCPC_MORE (continue), or ERROR.** ERRNO: N/A** NOMANUAL*/int requesting ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { int arpans = 0; char *option = NULL; char errmsg[255]; int timer = 0; int retry = 0; struct dhcp_param tmpparam; struct dhcp_reqspec tmp_reqspec; int status; int msgtype; LEASE_DATA * pLeaseData = NULL; char * pMsgData; int length;#ifdef DHCPC_DEBUG char newAddr [INET_ADDR_LEN]; logMsg ("dhcpc: Entering requesting state.\n", 0, 0, 0, 0, 0, 0);#endif /* * Use the cookie to access the lease-specific data structures. For now, * just typecast the cookie. This translation could be replaced with a more * sophisticated lookup at some point. */ pLeaseData = (LEASE_DATA *)pEvent->leaseId; /* * The DHCP_USER_RELEASE event occurs in response to the dhcpcRelease() * or dhcpcShutdown() call. Remove all data structures for this lease. */ if (pEvent->type == DHCP_USER_RELEASE) { dhcpcLeaseCleanup (pLeaseData); return (DHCPC_DONE); } /* * Ignore bind, verify and inform user events, * which are meaningless for this state. */ if (pEvent->source == DHCP_USER_EVENT) return (OK); bzero (errmsg, sizeof (errmsg)); bzero ( (char *)&tmp_reqspec, sizeof (tmp_reqspec)); if (pEvent->type == DHCP_TIMEOUT) {#ifdef DHCPC_DEBUG logMsg ("Retransmission from requesting state.\n", 0, 0, 0, 0, 0, 0);#endif /* Handle timeout - no DHCP reply received yet. */ retry = pLeaseData->numRetry; timer = pLeaseData->timeout; retry++; if (retry > REQUEST_RETRANS) /* Retransmission limit reached. */ {#ifdef DHCPC_DEBUG logMsg ("Client can't get ACK/NAK reply from server\n", 0, 0, 0, 0, 0, 0);#endif if (pLeaseData->prevState == INFORMING) { /* Unable to get additional parameters. */ return (ERROR); } pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } else { /* * Try to retransmit DHCP request or inform * message using the same transaction ID. */ if (pLeaseData->prevState == INFORMING) msgtype = INFORMING; else msgtype = REQUESTING; length = make_request (pLeaseData, msgtype, FALSE); if (length < 0) {#ifdef DHCPC_DEBUG logMsg ("Error making DHCP request. Can't continue.\n", 0, 0, 0, 0, 0, 0);#endif if (pLeaseData->prevState == INFORMING) { /* Unable to get additional parameters. */ return (ERROR); } pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } gen_retransmit (pLeaseData, length); } if (timer < MAXTIMER) { /* Double retransmission delay with each attempt. (RFC 1541). */ timer *= 2; } /* Set retransmission timer to randomized exponential backoff. */ wdStart (pLeaseData->timer, sysClkRateGet() * SLEEP_RANDOM (timer), (FUNCPTR)retrans_requesting, (int)pLeaseData); pLeaseData->timeout = timer; pLeaseData->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 = pLeaseData->msgBuffer; align_msg (&dhcpcMsgIn, pMsgData); /* Examine type of message. Accept DHCPACK or DHCPNAK replies. */ option = (char *)pickup_opt (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), _DHCP_MSGTYPE_TAG); if (option == NULL) { /* * Message type not found - discard untyped DHCP messages, and * any BOOTP replies. */ return (OK); } /* * Message type available. Ignore unexpected values. 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. */ msgtype = *OPTBODY (option); if (msgtype != DHCPACK && msgtype != DHCPNAK) { return (OK); } if (msgtype == DHCPNAK) {#ifdef DHCPC_DEBUG logMsg ("Got DHCPNAK from server\n", 0, 0, 0, 0, 0, 0); option = (char *)pickup_opt (dhcpcMsgIn.dhcp, DHCPLEN(dhcpcMsgIn.udp), _DHCP_ERRMSG_TAG); if (option != NULL && nvttostr (OPTBODY (option), errmsg, (int)DHCPOPTLEN (option)) == 0) logMsg ("DHCPNAK contains the error message \"%s\"\n", (int)errmsg, 0, 0, 0, 0, 0);#endif /* Ignore invalid responses to DHCP inform message. */ if (pLeaseData->prevState == INFORMING) return (OK); clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = NULL; pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* * Got acknowledgement: fill in host requirements defaults * and add any parameters from message options. */ dhcpcDefaultsSet (&tmpparam); if (dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), &tmpparam) == OK) { /* Options parsed successfully - test as needed. */ if (pLeaseData->prevState == INFORMING) { /* * Bypass ARP test and remaining steps after saving * additional parameters. */ merge_param (pLeaseData->dhcpcParam, &tmpparam); *(pLeaseData->dhcpcParam) = tmpparam; /* * If an event notification hook is present, send an * indication about the new set of parameters. */ if (pLeaseData->eventHookRtn != NULL) (* pLeaseData->eventHookRtn) (DHCPC_LEASE_NEW, pEvent->leaseId); /* * Signal the successful completion of the message * exchange if the dhcpcInformGet() call is executing * synchronously. */ if (pLeaseData->waitFlag) semGive (pLeaseData->leaseSem); return (OK); } if ( (arpans = arp_check (&tmpparam.yiaddr, &pLeaseData->ifData)) == OK) { merge_param (pLeaseData->dhcpcParam, &tmpparam); *(pLeaseData->dhcpcParam) = tmpparam; pLeaseData->dhcpcParam->lease_origin = pLeaseData->initEpoch;#ifdef DHCPC_DEBUG inet_ntoa_b (pLeaseData->dhcpcParam->yiaddr, newAddr); logMsg ("Got DHCPACK (IP = %s, duration = %d secs)\n", (int)newAddr, pLeaseData->dhcpcParam->lease_duration, 0, 0, 0, 0);#endif pLeaseData->prevState = REQUESTING; pLeaseData->currState = BOUND; /* Use retrieved configuration parameters. */ status = use_parameter (pLeaseData->dhcpcParam, pLeaseData); if (status != 0) {#ifdef DHCPC_DEBUG logMsg ("Error configuring network. Shutting down.\n", 0, 0, 0, 0, 0, 0);#endif release (pLeaseData, FALSE); semTake (dhcpcMutexSem, WAIT_FOREVER); pLeaseData->leaseGood = FALSE; semGive (dhcpcMutexSem); } else { semTake (dhcpcMutexSem, WAIT_FOREVER); pLeaseData->leaseGood = TRUE; semGive (dhcpcMutexSem); } if (status == 0) return (DHCPC_MORE); else return (ERROR); } } /* * Invalid parameters or (for a full lease negotiation) a * failed ARP probe (address in use). Ignore invalid parameters * for DHCP inform messages. */ if (pLeaseData->prevState == INFORMING) return (OK); /* * For the full lease negotiation, send the DHCPDECLINE which * is now required when an ARP probe fails: RFC 2131, section 3.1.5. */ set_declinfo (&tmp_reqspec, pLeaseData, errmsg, arpans); dhcp_decline (&tmp_reqspec, &pLeaseData->ifData); clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = NULL;#ifdef DHCPC_DEBUG logMsg ("Received unacceptable DHCPACK. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* End of DHCP message processing. */ return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -