📄 dhcpcstate2.c
字号:
/* 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); } } /* 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, TRUE); return (DHCPC_DONE); } if (pEvent->type == DHCP_USER_VERIFY) { /* Verify lease. */ /* Set the lease data to execute verify() routine. */ pLeaseData->prevState = RENEWING; pLeaseData->currState = VERIFY; return (DHCPC_MORE); } } return (OK);}/********************************************************************************* rebinding - Promiscuous lease renewal state of client finite state machine** This routine contains the sixth state of the client finite state machine.* During this state, a DHCP lease is active. The routine handles all* processing after the second lease timer has expired. It accepts* lease acknowledgements from any DHCP server in response to an earlier* subnet local broadcast of a lease request. If an acknowlegement is received,* processing returns to the bound() routine. If a DHCP server explicitly * denies the request, the negotiation restarts with the init() routine.* Otherwise, the broadcast is repeated periodically until the lease expires.* .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 rebinding (EVENT_DATA * pEvent /* pointer to event descriptor */ ){ char *option = NULL; char errmsg[255]; time_t curr_epoch = 0; int timeout; int limit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -