📄 dhcpcstate2.c
字号:
} if (pLeaseData->leaseType == DHCP_AUTOMATIC) { /* Get parameters previously read from bootline. */ bcopy ((char *) &dhcpcBootLease.yiaddr, (char *) &pLeaseData->dhcpcParam->yiaddr, sizeof (struct in_addr)); origin = dhcpcBootLease.lease_origin; pLeaseData->dhcpcParam->lease_duration = dhcpcBootLease.lease_duration; pLeaseData->dhcpcParam->dhcp_t1 = pLeaseData->dhcpcParam->lease_duration / 2; SETBIT (pLeaseData->dhcpcParam->got_option, _DHCP_T1_TAG); /* Set t2 to .875 of lease without using floating point. */ tmp = (pLeaseData->dhcpcParam->lease_duration * 7) >> 3; pLeaseData->dhcpcParam->dhcp_t2 = (unsigned long) tmp; SETBIT (pLeaseData->dhcpcParam->got_option, _DHCP_T2_TAG); } else { /* Get parameters from cached message. */ /* Host requirements defaults. */ dhcpcDefaultsSet (pLeaseData->dhcpcParam); if (dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), pLeaseData->dhcpcParam) != OK) {#ifdef DHCPC_DEBUG logMsg ("dhcp_msgtoparam() error in init_reboot()\n", 0, 0, 0, 0, 0, 0);#endif clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = NULL; pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = INIT; return (DHCPC_MORE); } } pLeaseData->dhcpcParam->lease_origin = origin; /* * If the cache contained a BOOTP reply, no further processing is needed. * Set the lease type to prevent the inclusion of timing information in * the bootline so that a later reboot will not attempt to renew the lease. */ if (pLeaseData->leaseType == DHCP_MANUAL && pLeaseData->dhcpcParam->msgtype == DHCP_BOOTP) { pLeaseData->leaseType = DHCP_BOOTP; pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = BOUND; 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; pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = INIT; } else { pLeaseData->leaseGood = TRUE; } semGive (dhcpcMutexSem); if (status != 0) return (DHCPC_MORE); return (OK); } /* The cache contained the record of a DHCP lease. Send the request. */ length = make_request (pLeaseData, REBOOTING, TRUE); if (length < 0) {#ifdef DHCPC_DEBUG logMsg ("error constructing REBOOTING message. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = INIT; return (DHCPC_MORE); } dhcpcMsgOut.udp->uh_sum = 0; dhcpcMsgOut.udp->uh_sum = udp_cksum (&spudph, (char *) dhcpcMsgOut.udp, ntohs (spudph.ulen)); 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; pIf = pLeaseData->ifData.iface; if (dhcpSend (pIf, &dest, sbuf.buf, length, TRUE) == ERROR) {#ifdef DHCPC_DEBUG logMsg ("Can't send DHCPREQUEST(REBOOTING)\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* Set lease data to execute next state and start retransmission timer. */ pLeaseData->prevState = INIT_REBOOT; pLeaseData->currState = REBOOTING; pLeaseData->timeout = FIRSTTIMER; pLeaseData->numRetry = 0; wdStart (pLeaseData->timer, sysClkRateGet () * SLEEP_RANDOM (pLeaseData->timeout), (FUNCPTR) retrans_reboot_verify, (int) pLeaseData); return (OK);}/********************************************************************************* verify - Initial lease verification state of client finite state machine** This routine begins the verification process by broadcasting a DHCP verify* message. It is called in response to the user request generated by the* dhcpcVerify() routine in the API.** RETURNS: OK (processing complete), ERROR (failure), or DHCPC_MORE (continue).** ERRNO: N/A** NOMANUAL*/int verify (EVENT_DATA * pEvent /* pointer to event descriptor */ ){ int limit = 0; int length; time_t curr_epoch; LEASE_DATA *pLeaseData; struct sockaddr_in dest; struct ifnet *pIf; struct ifreq ifr; if (dhcpTime (&curr_epoch) == -1) {#ifdef DHCPC_DEBUG logMsg ("time() error in verify()\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 (pLeaseData->prevState == BOUND) { /* Resume filtering with the BPF device (suspended while bound). */ bzero ((char *) &ifr, sizeof (struct ifreq)); sprintf (ifr.ifr_name, "%s%d", pLeaseData->ifData.iface->if_name, pLeaseData->ifData.iface->if_unit); ioctl (pLeaseData->ifData.bpfDev, BIOCSTART, (int) &ifr); } /* * The interval between the user request and the entry to the verify() * routine depends on the workload of the client monitor task and the * status of the lease timers. The lease may have expired before this * routine executes, which will cause the negotiation process to restart * with the init() routine. */ limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->lease_duration; if (limit <= curr_epoch) { pLeaseData->prevState = VERIFY; pLeaseData->currState = INIT; return (DHCPC_MORE); } length = make_request (pLeaseData, VERIFYING, TRUE); if (length < 0) {#ifdef DHCPC_DEBUG logMsg ("Unable to construct verify message. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = VERIFY; 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 (dhcpTime (&pLeaseData->initEpoch) == -1) {#ifdef DHCPC_DEBUG logMsg ("time() error setting initEpoch\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } 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; pIf = pLeaseData->ifData.iface; if (dhcpSend (pIf, &dest, sbuf.buf, length, TRUE) == ERROR) {#ifdef DHCPC_DEBUG logMsg ("Can't send DHCPREQUEST(VERIFY)\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = VERIFY; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* Set lease data to execute next state and start retransmission timer. */ pLeaseData->prevState = VERIFY; pLeaseData->currState = VERIFYING; pLeaseData->timeout = FIRSTTIMER; pLeaseData->numRetry = 0; wdStart (pLeaseData->timer, sysClkRateGet () * SLEEP_RANDOM (pLeaseData->timeout), (FUNCPTR) retrans_reboot_verify, (int) pLeaseData); return (OK); /* Next state is REBOOT_VERIFY */}/********************************************************************************* reboot_verify - Final lease verification state of client finite state machine** This routine continues the verification process of the finite state machine* by waiting for a server response until the current timeout value expires.* If a timeout occurs, the DHCP message is retransmitted. This routine collects* the replies for manual lease renewals and lease renewals resulting from a* reboot of the client.** RETURNS: OK (processing complete), DHCPC_DONE (remove lease),* DHCPC_MORE (continue), or ERROR.** ERRNO: N/A** NOMANUAL*/int reboot_verify (EVENT_DATA * pEvent /* pointer to event descriptor */ ){ int arpans = 0; time_t curr_epoch = 0; char *option = NULL; char errmsg[255]; int timer = 0; int retry = 0; int msgtype; struct dhcp_param tmpparam; struct dhcp_reqspec tmp_reqspec; int status = 0;#ifdef DHCPC_DEBUG char newAddr[INET_ADDR_LEN];#endif LEASE_DATA *pLeaseData = NULL; char *pMsgData; int length; /* * 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 and verify user events, which are meaningless here. */ if (pEvent->source == DHCP_USER_EVENT) return (OK); bzero (errmsg, sizeof (errmsg)); bzero ((char *) &tmpparam, sizeof (tmpparam)); bzero ((char *) &tmp_reqspec, sizeof (tmp_reqspec)); if (dhcpTime (&curr_epoch) == -1) {#ifdef DHCPC_DEBUG logMsg ("time() error in reboot_verify()\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } if (pEvent->type == DHCP_TIMEOUT) { /* * The interval between a timeout event and the entry to the * reboot_verify() routine depends on the workload of the client * monitor task and is completely unpredictable. The lease * may have expired during that time. The lease may also expire * before the retransmission limit is reached. In either case, set * the lease data to restart the negotiation with the init() routine. * If the retransmission limit is reached before the lease expires, * return to the BOUND state. Otherwise, retransmit the request * message. */ retry = pLeaseData->numRetry; timer = pLeaseData->timeout; retry++; if (retry > REQUEST_RETRANS) { /* Retransmission limit reached. */#ifdef DHCPC_DEBUG logMsg ("No server response received. Giving up.\n", 0, 0, 0, 0, 0, 0);#endif if (pLeaseData->prevState == INIT_REBOOT) { pLeaseData->currState = INIT; } else if (pLeaseData->dhcpcParam->lease_origin == 0 || pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->lease_duration <= curr_epoch) {#ifdef DHCPC_DEBUG logMsg ("The lease has expired. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif if (pLeaseData->prevState == INIT_REBOOT) pLeaseData->prevState = REBOOTING; else if (pLeaseData->prevState == VERIFY); pLeaseData->prevState = VERIFYING; pLeaseData->currState = INIT; } else {#ifdef DHCPC_DEBUG logMsg ("Entering BOUND state.\n", 0, 0, 0, 0, 0, 0);#endif /* * Send an ARP reply to update the ARP cache on other hosts * if the assigned IP address was applied to the underlying * network interface. */ if (pLeaseData->autoConfig || pLeaseData->leaseType == DHCP_AUTOMATIC) arp_reply (&pLeaseData->dhcpcParam->yiaddr, &pLeaseData->ifData); pLeaseData->prevState = VERIFYING; pLeaseData->currState = BOUND; } return (DHCPC_MORE); } else { /* Try to retransmit appropriate DHCP message for current state. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -