📄 dhcpcstate1.c
字号:
if (pLeaseData->dhcpcParam->msgtype == DHCP_BOOTP) { /* * No DHCP request is needed if a BOOTP reply is chosen. Set * lease data to process future events with the bound() routine. */ pLeaseData->leaseType = DHCP_BOOTP; pLeaseData->prevState = SELECTING; 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; } else { pLeaseData->leaseGood = TRUE; } semGive (dhcpcMutexSem); return (OK); } /* * A DHCP offer was selected. Build and send the DHCP request using * a new transaction ID. */ if (make_request (pLeaseData, REQUESTING, TRUE) < 0) {#ifdef DHCPC_DEBUG logMsg ("Error making DHCP request. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = SELECTING; 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\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = SELECTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* * DHCP request sent. Set lease data to execute next state and * start the retransmission timer. */ pLeaseData->prevState = SELECTING; pLeaseData->currState = REQUESTING; pLeaseData->timeout = FIRSTTIMER; pLeaseData->numRetry = 0; wdStart (pLeaseData->timer, sysClkRateGet() * SLEEP_RANDOM (pLeaseData->timeout), (FUNCPTR)retrans_requesting, (int)pLeaseData); } else { /* * 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. Only accept DHCP offers. */ option = (char *)pickup_opt (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), _DHCP_MSGTYPE_TAG); if (option == NULL) { /* * Message type not found - discard untyped DHCP messages, and * any BOOTP replies. */ return (OK); } else { if (*OPTBODY (option) != DHCPOFFER) return (OK); } /* Allocate memory for configuration parameters. */ pParams = (struct dhcp_param *)calloc (1, sizeof (struct dhcp_param)); if (pParams == NULL) return (OK); /* Fill in host requirements defaults. */ dhcpcDefaultsSet (pParams); /* Switch to offered parameters if they provide a longer DHCP lease. */ if (dhcp_msgtoparam (dhcpcMsgIn.dhcp, DHCPLEN (dhcpcMsgIn.udp), pParams) == OK) { if (pParams->server_id.s_addr != 0 && (arpans = arp_check (&pParams->yiaddr, &pLeaseData->ifData)) == OK && pParams->lease_duration >= dhcpcMinLease) { /* Take any DHCP message over BOOTP, or take a longer lease. */ if (pLeaseData->dhcpcParam->msgtype == DHCP_BOOTP || pParams->lease_duration > pLeaseData->dhcpcParam->lease_duration) { pParams->lease_origin = pLeaseData->initEpoch; clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = pParams; } } else { /* Offer is insufficient. Remove stored parameters. */ clean_param (pParams); free (pParams); } } else { /* Conversion unsuccessful - remove stored parameters. */ clean_param (pParams); free (pParams); } } return (OK); }/********************************************************************************* requesting - Lease request state of client finite state machine** This routine implements the third state of the client finite state machine.* It handles all processing until a response to a transmitted DHCP request* message is received from the selected DHCP server or the retransmission * limit is reached. The DHCP request is retransmitted if a timeout occurs. * If the request is acknowledged, processing will continue with the bound()* routine. If it is refused or the retransmission limit is reached, the * negotiation process will restart with the init() routine.* .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 complete), DHCPC_DONE (remove lease),* DHCPC_MORE (continue), or ERROR.** ERRNO: N/A** NOMANUAL*/int requesting ( EVENT_DATA * pEvent /* pointer to event descriptor */ ) { int arpans = 0; char *option = NULL; char errmsg[255]; int timer = 0; int retry = 0; struct dhcp_param tmpparam; struct dhcp_reqspec tmp_reqspec; int status; int msgtype; LEASE_DATA * pLeaseData = NULL;#ifdef DHCPC_DEBUG char newAddr [INET_ADDR_LEN]; logMsg ("dhcpc: Entering requesting state.\n", 0, 0, 0, 0, 0, 0);#endif /* * 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); /* * 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; bzero (errmsg, sizeof (errmsg)); bzero ( (char *)&tmp_reqspec, sizeof (tmp_reqspec)); if (pEvent->type == DHCP_TIMEOUT) {#ifdef DHCPC_DEBUG logMsg ("Retransmission from requesting state.\n", 0, 0, 0, 0, 0, 0);#endif /* Handle timeout - no DHCP reply received yet. */ retry = pLeaseData->numRetry; timer = pLeaseData->timeout; retry++; if (retry > REQUEST_RETRANS) /* Retransmission limit reached. */ {#ifdef DHCPC_DEBUG logMsg ("Client can't get ACK/NAK reply from server\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } else { /* Try to retransmit DHCP request using the same transaction ID. */ if (make_request (pLeaseData, REQUESTING, FALSE) < 0) {#ifdef DHCPC_DEBUG logMsg ("Error making DHCP request. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } gen_retransmit (pLeaseData); } if (timer < MAXTIMER) { /* Double retransmission delay with each attempt. (RFC 1541). */ timer *= 2; } /* Set retransmission timer to randomized exponential backoff. */ wdStart (pLeaseData->timer, sysClkRateGet() * SLEEP_RANDOM (timer), (FUNCPTR)retrans_requesting, (int)pLeaseData); pLeaseData->timeout = timer; pLeaseData->numRetry = retry; } 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 - discard untyped DHCP messages, and * any BOOTP replies. */ return (OK); } else { msgtype = *OPTBODY (option); if (msgtype == DHCPNAK) {#ifdef DHCPC_DEBUG logMsg ("Got DHCPNAK from server\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 = REQUESTING; 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) { if ( (arpans = arp_check (&tmpparam.yiaddr, &pLeaseData->ifData)) == 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 pLeaseData->prevState = REQUESTING; pLeaseData->currState = BOUND; /* Use retrieved configuration parameters. */ status = use_parameter (pLeaseData->dhcpcParam, pLeaseData); if (status != 0) {#ifdef DHCPC_DEBUG logMsg ("Error configuring network. Shutting down.\n", 0, 0, 0, 0, 0, 0);#endif release (pLeaseData); semTake (dhcpcMutexSem, WAIT_FOREVER); pLeaseData->leaseGood = FALSE; semGive (dhcpcMutexSem); } else { semTake (dhcpcMutexSem, WAIT_FOREVER); pLeaseData->leaseGood = TRUE; semGive (dhcpcMutexSem); } if (status == 0) return (DHCPC_MORE); else return (ERROR); } else { /* Address in use? Ignore ACK and allow timeout. */ return (OK); } } } /* Unknown message type or invalid parameters - send DHCPDECLINE */ set_declinfo (&tmp_reqspec, pLeaseData, errmsg, arpans); dhcp_decline (&tmp_reqspec, &pLeaseData->ifData); clean_param (pLeaseData->dhcpcParam); free (pLeaseData->dhcpcParam); pLeaseData->dhcpcParam = NULL;#ifdef DHCPC_DEBUG logMsg ("Received unacceptable DHCPACK. Entering INIT state.\n", 0, 0, 0, 0, 0, 0);#endif pLeaseData->prevState = REQUESTING; pLeaseData->currState = INIT; return (DHCPC_MORE); } /* End of processing for typed DHCP message. */ } /* End of DHCP message processing. */ return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -