📄 dhcpcstate2.c
字号:
limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t2; if (timeout <= curr_epoch && curr_epoch < limit) { /* * First timer expired: * attempt to renew lease with current server. * 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); #ifdef DHCPC_DEBUG logMsg ("Entering RENEWING state.\n", 0, 0, 0, 0, 0, 0);#endif length = make_request (pLeaseData, RENEWING, TRUE); /* Ignore transmission failures for handling by timeout. */ status = send_unicast (&pLeaseData->dhcpcParam->server_id, dhcpcMsgOut.dhcp, length);#ifdef DHCPC_DEBUG if (status < 0) logMsg ("Can't send DHCPREQUEST(RENEWING)\n.", 0, 0, 0, 0, 0, 0);#endif /* DHCP request sent. Set lease data to execute next state. */ pLeaseData->prevState = BOUND; pLeaseData->currState = RENEWING; pLeaseData->initEpoch = curr_epoch; /* * Set the retransmission timer to wait for one-half of the * remaining time before T2 expires, or 60 seconds if T2 * expires in less than one minute. */ timeout = limit - curr_epoch; timeout /= 2; if (timeout < 60) timeout = 60; /* Set timer for retransmission of request message. */ wdStart (pLeaseData->timer, sysClkRateGet() * timeout, (FUNCPTR)retrans_renewing, (int)pLeaseData); return (OK); } } /* End of timeout processing. */ } /* End of automatic events. */ else { /* Process user requests. */ if (pEvent->type == DHCP_USER_RELEASE) /* Relinquish lease. */ { release (pLeaseData, TRUE); return (DHCPC_DONE); } if (pEvent->type == DHCP_USER_VERIFY) /* Verify lease */ { /* Set the lease data to execute verify() routine. */ pLeaseData->prevState = BOUND; pLeaseData->currState = VERIFY; return (DHCPC_MORE); } } return (OK); }/********************************************************************************* renewing - Specific lease renewal state of client finite state machine** This routine contains the fifth state of the client finite state machine.* During this state, a DHCP lease is active. The routine handles all * processing after the first lease timer has expired. If the server which * issued the corresponding lease acknowledges the request for renewal, * processing returns to the bound() routine. If the request is denied, the * negotiation process restarts with the init() routine. If a timeout occurs* before the second lease timer has expired, the DHCP request message is * retransmitted. Otherwise, processing continues with the rebinding() routine.* .IP* This routine is invoked by the event handler of the client monitor task,* and should only be called internally. Any arriving DHCP messages containing* stale offers from earlier states are discarded. User requests generated* by calls to the dhcpcRelease() and dhcpcVerify() routines are accepted.** RETURNS: OK (processing complete), DHCPC_DONE (remove lease),* DHCPC_MORE (continue), or ERROR.** ERRNO: N/A** NOMANUAL*/int renewing ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { char *option = NULL; char errmsg[255]; time_t curr_epoch = 0; int timeout = 0; int limit; int length; struct dhcp_param tmpparam; int msgtype;#ifdef DHCPC_DEBUG char newAddr [INET_ADDR_LEN];#endif LEASE_DATA * pLeaseData; char * pMsgData; struct sockaddr_in dest; struct ifnet * pIf; bzero (errmsg, sizeof (errmsg)); if (dhcpTime (&curr_epoch) == -1) {#ifdef DHCPC_DEBUG logMsg ("time() error in renewing()\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 * renewing() routine depends on the workload of the client * monitor task and is completely unpredictable. Either the * entire lease or the second lease timer may have expired * during that time. Also, the final (60 second) retransmission * timeout will always end after timer T2 has expired. If T2 * has expired but the lease has not, set the lease data to * continue with the rebinding() routine. If the lease has * expired, return to the initial state. Otherwise (the most * likely case), retransmit the request message since T2 has * not expired. */ limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->lease_duration; if (curr_epoch >= limit) { /* Lease expired before processing started. */ pLeaseData->prevState = RENEWING; pLeaseData->currState = INIT; return (DHCPC_MORE); } limit = pLeaseData->dhcpcParam->lease_origin + pLeaseData->dhcpcParam->dhcp_t2; if (limit <= curr_epoch) { /* * Second timer expired: * request configuration data from any server. */ length = make_request (pLeaseData, REBINDING, TRUE); if (length < 0) {#ifdef DHCPC_DEBUG logMsg ("Error making rebind request. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = RENEWING; 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(REBINDING)\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = RENEWING; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* DHCP request sent. Set lease data to execute next state. */ pLeaseData->prevState = RENEWING; 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; timeout /= 2; if (timeout < 60) timeout = 60; /* Set timer for retransmission of request message. */ wdStart (pLeaseData->timer, sysClkRateGet() * timeout, (FUNCPTR)retrans_rebinding, (int)pLeaseData); } else { /* Transmit lease renewal request to issuing server. */ length = make_request (pLeaseData, RENEWING, FALSE); if (send_unicast (&pLeaseData->dhcpcParam->server_id, dhcpcMsgOut.dhcp, length) < 0) {#ifdef DHCPC_DEBUG logMsg ("Can't send DHCPREQUEST(RENEWING)\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = RENEWING; pLeaseData->currState = INIT; return (DHCPC_MORE); } pLeaseData->prevState = RENEWING; pLeaseData->currState = RENEWING; pLeaseData->initEpoch = curr_epoch; /* * Set the retransmission timer to wait for one-half of the * remaining time before T2 expires, or 60 seconds if T2 * expires in less than one minute. */ timeout = limit - curr_epoch; timeout /= 2; if (timeout < 60) timeout = 60; /* Set timer for retransmission of request message. */ wdStart (pLeaseData->timer, sysClkRateGet() * timeout, (FUNCPTR)retrans_renewing, (int)pLeaseData); } } /* End of timeout processing. */ 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 - ignore untyped DHCP messages, and * any BOOTP replies. */ return (OK); } else { msgtype = *OPTBODY (option); if (msgtype == DHCPNAK) {#ifdef DHCPC_DEBUG logMsg ("Got DHCPNAK in renewing()\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 = RENEWING; 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 /* * 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 = RENEWING; pLeaseData->currState = BOUND; } return (DHCPC_MORE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -