📄 dhcpcstate1.c
字号:
LEASE_DATA * pLeaseData = NULL; STATUS result; bzero (sbuf.buf, sbuf.size + DHCPC_OFF);#ifdef DHCPC_DEBUG logMsg ("dhcpc: Entered INIT 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; wdCancel (pLeaseData->timer); /* Reset watchdog timer. */ /* * 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); } /* * Unrecoverable errors are only removed when the dhcpcBind() call sets * the state indicators to INIT_REBOOT. Ignore all other events until then. */ if (pLeaseData->prevState == DHCPC_ERROR) return (OK); semTake (dhcpcMutexSem, WAIT_FOREVER); /* Reset status indicator. */ pLeaseData->leaseGood = FALSE; semGive (dhcpcMutexSem); /* Create DHCP_DISCOVER message and assign new transaction ID. */ make_discover (pLeaseData, TRUE); /* * Random delay from one to ten seconds to avoid startup congestion. * (Delay length specified in RFC 1541). * */ taskDelay (sysClkRateGet () * (1 + (rand () % INIT_WAITING)) ); /* * If an event notification hook is present, send a notification of * the lease expiration when appropriate. (None is needed after a reboot). */ if (pLeaseData->eventHookRtn != NULL) { if (pLeaseData->prevState != REBOOTING && pLeaseData->prevState != INIT_REBOOT) result = (* pLeaseData->eventHookRtn) (DHCPC_LEASE_INVALID, pEvent->leaseId); } /* * Reset the network interface if it used the address * information provided by the indicated lease. */ if (pLeaseData->autoConfig || pLeaseData->leaseType == DHCP_AUTOMATIC) { reset_if (&pLeaseData->ifData); } dhcpcMsgOut.dhcp->secs = 0; dhcpcMsgOut.udp->uh_sum = 0; dhcpcMsgOut.udp->uh_sum = udp_cksum (&spudph, (char *)dhcpcMsgOut.udp, ntohs (spudph.ulen)); if (time (&pLeaseData->initEpoch) == -1) {#ifdef DHCPC_DEBUG logMsg ("time() error setting initEpoch\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); }#ifdef DHCPC_DEBUG logMsg ("Sending DHCPDISCOVER\n", 0, 0, 0, 0, 0, 0);#endif if (etherOutput (pLeaseData->ifData.iface, dhcpcMsgOut.ether, &sbuf.buf [DHCPC_OFF + ETHERHL], sbuf.size - ETHERHL) == ERROR) {#ifdef DHCPC_DEBUG logMsg ("Can't send DHCPDISCOVER\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } /* Set lease data to execute next state and start retransmission timer. */ pLeaseData->prevState = INIT; pLeaseData->currState = WAIT_OFFER; pLeaseData->timeout = FIRSTTIMER; pLeaseData->numRetry = 0; wdStart (pLeaseData->timer, sysClkRateGet() * SLEEP_RANDOM (pLeaseData->timeout), (FUNCPTR)retrans_wait_offer, (int)pLeaseData); return (OK); /* Next state is WAIT_OFFER */ }/********************************************************************************* wait_offer - Initial offering state of client finite state machine** This routine contains the initial part of the second state of the finite * state machine. It handles all processing until an acceptable DHCP offer is * received. If a timeout occurred, it retransmits the DHCP discover message. * Otherwise, it evaluates the parameters contained in the received DHCP offer. * If the minimum requirements are met, processing will continue with the * selecting() routine. If no offer is received before the retransmission* limit is reached, the negotiation process fails.* .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 completes), DHCPC_DONE (remove lease), or ERROR.** ERRNO: N/A** NOMANUAL*/int wait_offer ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { int arpans = 0; char errmsg [255]; char * option; int timer = 0; int retry = 0; struct dhcp_param * pParams = NULL; LEASE_DATA * pLeaseData = NULL; /* * 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 and verify user events, which are meaningless here. */ if (pEvent->source == DHCP_USER_EVENT) return (OK); /* * 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; bzero (errmsg, sizeof (errmsg));#ifdef DHCPC_DEBUG logMsg ("dhcpc: Entered WAIT_OFFER state.\n", 0, 0, 0, 0, 0, 0);#endif if (pLeaseData->prevState == INIT) { /* Clear any previous parameter settings. */ if (pLeaseData->dhcpcParam != NULL) { clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = NULL; } pLeaseData->prevState = WAIT_OFFER; } if (pEvent->type == DHCP_TIMEOUT) {#ifdef DHCPC_DEBUG logMsg ("dhcp: timed out in WAIT_OFFER state.\n", 0, 0, 0, 0, 0, 0);#endif /* Handle timeout - no DHCP offers received yet. */ retry = pLeaseData->numRetry; timer = pLeaseData->timeout; retry++; if (retry == DISCOVER_RETRANS) /* Retransmission limit reached. */ {#ifdef DHCPC_DEBUG logMsg ("No lease offers received by client.\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } else { /* Try to retransmit appropriate DHCP message for current state. */ /* Recreate DHCP_DISCOVER message using the same transaction ID. */ make_discover (pLeaseData, FALSE); gen_retransmit (pLeaseData); } 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_wait_offer, (int)pLeaseData); pLeaseData->timeout = timer; pLeaseData->numRetry = retry; } else { /* * Process DHCP message stored in receive buffer by monitor task. * Access receive buffer at offset to provide 4-byte alignment of * IP header needed by Sun BSP's. */ align_msg (&dhcpcMsgIn, &pDhcpcRecvBuf [DHCPC_OFF]); /* Examine type of message. Accept DHCP offers or BOOTP replies. */ option = (char *)pickup_opt (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), _DHCP_MSGTYPE_TAG); if (option == NULL) { /* * Message type not found - check message length. Ignore * untyped DHCP messages, but accept (shorter) BOOTP replies. */ if (DHCPLEN (dhcpcMsgIn.udp) >= DFLTDHCPLEN) return (OK); } else { if (*OPTBODY (option) != DHCPOFFER) return (OK); } /* Allocate memory for configuration parameters. */ pParams = (struct dhcp_param *)calloc (1, sizeof (struct dhcp_param)); if (pParams == NULL) return (OK); /* Fill in host requirements defaults. */ dhcpcDefaultsSet (pParams); /* Check offered parameters. Save in lease structure 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, &pLeaseData->ifData)) == OK && pParams->lease_duration >= dhcpcMinLease) { /* * Initial offer accepted. Set lease data * to execute next routine and start timer. */ pParams->lease_origin = pLeaseData->initEpoch; pLeaseData->dhcpcParam = pParams; pLeaseData->currState = SELECTING; /* * Reset timer from retransmission * interval to limit for collecting replies. */ wdCancel (pLeaseData->timer); wdStart (pLeaseData->timer, sysClkRateGet() * pLeaseData->leaseReqSpec.waitsecs, (FUNCPTR)alarm_selecting, (int)pLeaseData); } else { /* * Offer is insufficient. Remove stored parameters * and set lease data to repeat current routine. */ pLeaseData->currState = WAIT_OFFER; clean_param (pParams); free (pParams); } } else { /* * Conversion unsuccessful - remove stored parameters * and set lease data to repeat current routine. */ pLeaseData->currState = WAIT_OFFER; clean_param (pParams); free (pParams); } } return (OK); }/********************************************************************************* selecting - 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 longest 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 lease.** .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 selecting ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { int arpans = 0; struct dhcp_param *pParams = NULL; int status; LEASE_DATA * pLeaseData = NULL; char * option;#ifdef DHCPC_DEBUG logMsg ("dhcp: Entered SELECTING state.\n", 0, 0, 0, 0, 0, 0);#endif /* * 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 and verify user events, which are meaningless here. */ if (pEvent->source == DHCP_USER_EVENT) return (OK); /* * 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; if (pEvent->type == DHCP_TIMEOUT) { /* Collection time ended - parameters structure holds chosen offer. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -