📄 dhcpcstate1.c
字号:
void retrans_requesting ( LEASE_DATA * pLeaseData /* lease-specific status information */ ) { /* * Ignore the timeout if a state transition occurred during * the scheduled timer interval. */ if (pLeaseData->currState != REQUESTING) return; /* Construct and send a timeout message to the lease monitor task. */ dhcpcEventAdd (DHCP_AUTO_EVENT, DHCP_TIMEOUT, pLeaseData, TRUE);#ifdef DHCPC_DEBUG logMsg ("retransmit DHCPREQUEST(REQUESTING)\n", 0, 0, 0, 0, 0, 0);#endif return; }/********************************************************************************* inform - external configuration state of client finite state machine** This routine begins the inform message process, which obtains additional* parameters for a host configured with an external address. This processing* is isolated from the normal progression through the state machine. Like the* DHCP discover message, the inform message is the first transmission. * However, the only valid response is an acknowledgement by a server. As a* result, the process is a hybrid between the implementations of the initial* state and the requesting state which finalizes the lease establishment.** The routine implements the initial state of the finite state machine for an* externally assigned IP address. It is invoked by the event handler of the* client monitor task, and should only be called internally.** RETURNS: OK (processing completes), DHCPC_DONE (remove lease), or ERROR.** ERRNO: N/A** NOMANUAL*/int inform ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { LEASE_DATA * pLeaseData = NULL; struct sockaddr_in dest; struct ifnet * pIf; int length; /* Amount of data in message */ if (pEvent->source == DHCP_AUTO_EVENT) { /* * Received DHCP messages or timeouts can only reach this * routine when repeating the DHCP INFORM message exchange. * Ignore these stale notifications. */ return (OK); } bzero (sbuf.buf, sbuf.size);#ifdef DHCPC_DEBUG logMsg ("dhcpc: Entered INFORM 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); } /* * Set lease to generate newer RFC 2131 messages. Older servers might * ignore messages if their length is less than the minimum length * obtained with a fixed options field, but will not recognize an * inform message anyway. */ pLeaseData->oldFlag = FALSE; /* Create DHCP INFORM message and assign new transaction ID. */ length = make_request (pLeaseData, INFORMING, TRUE); if (length < 0) {#ifdef DHCPC_DEBUG logMsg ("Error making DHCP inform message. Can't continue.\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } dhcpcMsgOut.dhcp->secs = 0; dhcpcMsgOut.udp->uh_sum = 0; dhcpcMsgOut.udp->uh_sum = udp_cksum (&spudph, (char *)dhcpcMsgOut.udp, ntohs (spudph.ulen));#ifdef DHCPC_DEBUG logMsg ("Sending DHCPINFORM.\n", 0, 0, 0, 0, 0, 0);#endif 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 DHCPINFORM.\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } /* Set lease data to execute next state and start retransmission timer. */ pLeaseData->prevState = INFORMING; pLeaseData->currState = REQUESTING; pLeaseData->timeout = FIRSTTIMER; pLeaseData->numRetry = 0; wdStart (pLeaseData->timer, sysClkRateGet() * SLEEP_RANDOM (pLeaseData->timeout), (FUNCPTR)retrans_requesting, (int)pLeaseData); return (OK); /* Next state is REQUESTING */ }/********************************************************************************* init - initial state of client finite state machine** This routine implements the initial state of the finite state machine. * After a random backoff delay, it resets the network interface if necessary* and transmits the DHCP discover message. This state may be repeated after a * later state if a lease is not renewed or a recoverable error occurs. It * could also be executed following unrecoverable errors. The routine is * invoked by the event handler of the client monitor task, and should only be * called internally.** RETURNS: OK (processing completes), DHCPC_DONE (remove lease), or ERROR.** ERRNO: N/A** NOMANUAL*/int init ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { LEASE_DATA * pLeaseData = NULL; STATUS result; struct sockaddr_in dest; struct ifnet * pIf; int length; bzero (sbuf.buf, sbuf.size);#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); /* * Set lease to generate newer RFC 2131 messages initially. The client * will revert to the older message format if it does not receive a * response to the initial set of discover messages. Older servers might * ignore messages less than the minimum length obtained with a fixed * options field. The older format pads the field to reach that length. */ pLeaseData->oldFlag = FALSE; /* Create DHCP_DISCOVER message and assign new transaction ID. */ length = 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 (dhcpTime (&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 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 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 */ ) { char errmsg [255]; char * option; int timer = 0; int retry = 0; struct dhcp_param * pParams = NULL; 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));#ifdef DHCPC_DEBUG logMsg ("dhcpc: Entered WAIT_OFFER state.\n", 0, 0, 0, 0, 0, 0);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -