📄 dhcpcstate2.c
字号:
if (time (&curr_epoch) == -1) {#ifdef DHCPC_DEBUG logMsg ("time() error in rebinding()\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } /* * 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->source == DHCP_AUTO_EVENT) { if (pEvent->type == DHCP_TIMEOUT) { /* * The interval between a timeout event and the entry to the * rebinding() routine depends on the workload of the client * monitor task and is completely unpredictable. The lease * may have expired during that time, and the final retransmission * timeout will always end after the lease has expired. In either * case, set the lease data to restart the negotiation with the * init() routine. Otherwise, repeat the broadcast of the request * message. */ limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->lease_duration; if (limit <= curr_epoch) { /* Lease has expired: * shut down network and return to initial state. */#ifdef DHCPC_DEBUG logMsg ("Can't extend lease. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = REBINDING; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* Retransmit rebinding request. */ if (make_request (pLeaseData, REBINDING, FALSE) < 0) {#ifdef DHCPC_DEBUG logMsg ("Error making rebind request. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = REBINDING; pLeaseData->currState = INIT; return (DHCPC_MORE); } dhcpcMsgOut.udp->uh_sum = 0; dhcpcMsgOut.udp->uh_sum = udp_cksum(&spudph, (char *)dhcpcMsgOut.udp, ntohs (spudph.ulen)); if (etherOutput (pLeaseData->ifData.iface, dhcpcMsgOut.ether, &sbuf.buf [DHCPC_OFF + ETHERHL], sbuf.size - ETHERHL) == ERROR) {#ifdef DHCPC_DEBUG logMsg ("Can't send DHCPREQUEST(REBINDING)\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = REBINDING; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* DHCP request sent. Set lease data to repeat current state. */ pLeaseData->prevState = REBINDING; pLeaseData->currState = REBINDING; pLeaseData->initEpoch = curr_epoch; /* * Set the retransmission timer to wait for one-half of the * remaining time before the lease expires, or 60 seconds if it * expires in less than one minute. */ timeout = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->lease_duration - curr_epoch; if (timeout > 60) timeout /= 2; else timeout = 60; /* Set timer for retransmission of request message. */ wdStart (pLeaseData->timer, sysClkRateGet() * timeout, (FUNCPTR)retrans_rebinding, (int)pLeaseData); } /* End of timeout processing. */ else { bzero ( (char *)&tmpparam, sizeof (tmpparam)); /* * 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 DHCPACK or DHCPNAK replies. */ option = (char *)pickup_opt (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), _DHCP_MSGTYPE_TAG); if (option == NULL) { /* * Message type not found - ignore untyped DHCP messages, and * any BOOTP replies. */ return (OK); } else { msgtype = *OPTBODY (option); if (msgtype == DHCPNAK) {#ifdef DHCPC_DEBUG logMsg ("Got DHCPNAK in rebinding()\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 clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = NULL; pLeaseData->prevState = REBINDING; pLeaseData->currState = INIT; return (DHCPC_MORE); } else if (msgtype == DHCPACK) { /* Fill in host requirements defaults. */ dhcpcDefaultsSet (&tmpparam); if (dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), &tmpparam) == 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 status = use_parameter (pLeaseData->dhcpcParam, pLeaseData); semTake (dhcpcMutexSem, WAIT_FOREVER); if (status != 0) {#ifdef DHCPC_DEBUG logMsg ("Error configuring network. Shutting down.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->leaseGood = FALSE; } else { pLeaseData->leaseGood = TRUE; } semGive (dhcpcMutexSem); pLeaseData->prevState = REBINDING; pLeaseData->currState = BOUND; } return (DHCPC_MORE); } } /* End of processing for typed DHCP message. */ } /* End of DHCP message processing. */ } else { /* Process user requests. */ if (pEvent->type == DHCP_USER_RELEASE) /* Relinquish lease. */ { release (pLeaseData); return (DHCPC_DONE); } if (pEvent->type == DHCP_USER_VERIFY) /* Verify lease. */ { /* Set the lease data to execute verify() routine. */ pLeaseData->prevState = REBINDING; pLeaseData->currState = VERIFY; return (DHCPC_MORE); } } return (OK); }/********************************************************************************* init_reboot - Rebooting state of the client finite state machine** This routine implements the "zeroth" state of the client finite state* machine. It attempts to renew an active lease after the client has* rebooted. This generally requires the presence of a cache, but the lease* data may also be read from global variables to renew the lease obtained* during system startup. If no lease data is found or renewal fails, processing* continues with the INIT state.* .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 dhcpcVerify() routine are * ignored.** RETURNS: OK (processing complete), DHCPC_DONE (remove lease),* DHCPC_MORE (continue), or ERROR.** ERRNO: N/A** INTERNAL** When calculating the values for the lease timers, floating-point calculations* can't be used because some boards (notably the SPARC architectures) disable* software floating point by default to speed up context switching. These* boards abort with an exception when floating point operations are* encountered. The error introduced by the integer approximations is not* significant.** NOMANUAL*/int init_reboot ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { char *rbufp = NULL; STATUS result; int length = 0; unsigned long origin = 0; int tmp; int status; 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 verify user events, which are meaningless here. */ if (pEvent->source == DHCP_USER_EVENT && pEvent->type != DHCP_USER_BIND) return (OK); /* * Safety check - ignore timeouts and message arrivals, which are * theoretically possible under extremely unlikely chains of events. */ if (pEvent->source == DHCP_AUTO_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 a cache is needed and unavailable, restart from the INIT state. */ if (pLeaseData->cacheHookRtn == NULL && pLeaseData->leaseType == DHCP_MANUAL) { pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = INIT; return (DHCPC_MORE); }#ifdef DHCPC_DEBUG logMsg("dhcpc: Attempting to re-use parameters.\n", 0, 0, 0, 0, 0, 0);#endif /* * Access buffer at offset to provide 4-byte alignment of IP header * needed by Sun BSP's. */ rbufp = &pDhcpcRecvBuf [DHCPC_OFF]; if (pLeaseData->leaseType == DHCP_MANUAL) { /* Post-boot: read from cache. */ length = DFLTDHCPLEN + UDPHL + IPHL + ETHERHL; result = (* pLeaseData->cacheHookRtn) (DHCP_CACHE_READ, &origin, &length, rbufp); if (result != OK) /* Can't re-use stored parameters. */ { pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = INIT; return (DHCPC_MORE); } } dhcpcMsgIn.ether = (struct ether_header *) rbufp; dhcpcMsgIn.ip = (struct ip *)&rbufp [ETHERHL];#if BSD<44 dhcpcMsgIn.udp = (struct udphdr *)&rbufp [ETHERHL + (dhcpcMsgIn.ip->ip_v_hl & 0xf) * WORD]; dhcpcMsgIn.dhcp = (struct dhcp *) &rbufp [ETHERHL + (dhcpcMsgIn.ip->ip_v_hl & 0xf) * WORD + UDPHL];#else dhcpcMsgIn.udp = (struct udphdr *)&rbufp [ETHERHL + dhcpcMsgIn.ip->ip_hl * WORD]; dhcpcMsgIn.dhcp = (struct dhcp *) &rbufp [ETHERHL + dhcpcMsgIn.ip->ip_hl * WORD + UDPHL];#endif if (pLeaseData->dhcpcParam == NULL) { pLeaseData->dhcpcParam = (struct dhcp_param *)calloc (1, sizeof (struct dhcp_param)); if (pLeaseData->dhcpcParam == NULL) {#ifdef DHCPC_DEBUG logMsg ("calloc() error in init_reboot()\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = INIT; return (DHCPC_MORE); } } if (pLeaseData->leaseType == DHCP_AUTOMATIC) { /* Get parameters previously read from bootline. */ bcopy ( (char *)&dhcpcBootLease.yiaddr, (char *)&pLeaseData->dhcpcParam->yiaddr, sizeof (struct in_addr));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -