📄 dhcp.c
字号:
/*-------------------------------------------------------------------*/ buf = sock->rq_head; if (buf == NULL) return; /*-------------------------------------------------------------------*/ /* Extract buffer from receive queue. */ /*-------------------------------------------------------------------*/ sock->rq_head = buf->next; --sock->q_count; /*-------------------------------------------------------------------*/ /* Extract options from packet and then free buffer. */ /*-------------------------------------------------------------------*/ type = parse_response((DhcpMsg *)buf->app_data); tcpRetBuf(&buf); /*-------------------------------------------------------------------*/ /* If packet was error-free, process the packet received event. */ /*-------------------------------------------------------------------*/ if (type != -1) DhcpSwitch[dhcp.state](type);}/***********************************************************************//* dhcp_free: DHCP state machine shutdown *//* *//***********************************************************************/static void dhcp_free(int event){ switch (event) { case TRANSITION: if (dhcp.state >= DHCP_BOUND) send_msg(dhcp.ni, dhcp.reqAddr, DHCPRELEASE); dhcp.state = DHCP_FREE; NetTimerStop(&dhcp.msgTimer); NetTimerStop(&dhcp.leaseTimer); break; }}/***********************************************************************//* dhcp_init: DHCP state machine initialization *//* *//***********************************************************************/static void dhcp_init(int event){ switch (event) { case TRANSITION: /*-----------------------------------------------------------------*/ /* If interface was bound, have to remove all interface routes. */ /*-----------------------------------------------------------------*/ if (dhcp.state >= DHCP_BOUND) NiRtDel(dhcp.ni); /*-----------------------------------------------------------------*/ /* Else if restarting, call event callback function if installed. */ /*-----------------------------------------------------------------*/ else if ((dhcp.state > DHCP_FREE) && dhcp.ni->report) dhcp.ni->report(dhcp.ni, NIE_RESTART); /*-----------------------------------------------------------------*/ /* Assign state. */ /*-----------------------------------------------------------------*/ dhcp.state = DHCP_INIT; /*-----------------------------------------------------------------*/ /* Stop the lease and retransmission timers. */ /*-----------------------------------------------------------------*/ NetTimerStop(&dhcp.msgTimer); NetTimerStop(&dhcp.leaseTimer); /*-----------------------------------------------------------------*/ /* Initially clear all values potentially read from DHCP server. */ /*-----------------------------------------------------------------*/ dhcp.renewT1 = dhcp.rebindT2 = dhcp.leaseTime = 0; dhcp.router = dhcp.serverID = dhcp.subnetMask = 0; dhcp.ni->ip_addr = 0; break; case MSG_TIMEOUT: /*-----------------------------------------------------------------*/ /* Transition to DHCP_SELECT state. */ /*-----------------------------------------------------------------*/ dhcp_select(TRANSITION); break; }}/***********************************************************************//* dhcp_select: Broadcast DHCPDISCOVER, look for DHCPOFFER *//* *//***********************************************************************/static void dhcp_select(int event){ uint i; switch (event) { case TRANSITION: /*-----------------------------------------------------------------*/ /* Initialize state and retransmission delay. */ /*-----------------------------------------------------------------*/ dhcp.state = DHCP_SELECT; dhcp.retransDelay = K4_SECONDS; /*-----------------------------------------------------------------*/ /* Record tick count at beginning of lease attempt. */ /*-----------------------------------------------------------------*/ dhcp.req_time = NetTickCount; /*lint -fallthrough */ case MSG_TIMEOUT: /*-----------------------------------------------------------------*/ /* If max retry period exceeded, reset state to DHCP_INIT. */ /*-----------------------------------------------------------------*/ if (dhcp.retransDelay >= K64_SECONDS) { dhcp_init(TRANSITION); dhcp_init(MSG_TIMEOUT); } /*-----------------------------------------------------------------*/ /* Otherwise, broadcast a DHCPDISCOVER message. */ /*-----------------------------------------------------------------*/ else { send_msg(dhcp.ni, 0, DHCPDISCOVER); i = (dhcp.retransDelay - K1_SECOND) + (rand() % K2_SECONDS); NetTimerStart(&dhcp.msgTimer, i); dhcp.retransDelay <<= 1; } break; case DHCPOFFER: /*-----------------------------------------------------------------*/ /* Transition to DHCP_REQUEST state. */ /*-----------------------------------------------------------------*/ dhcp_request(TRANSITION); break; }}/***********************************************************************//* dhcp_request: Broadcast DHCPREQUEST, look for DHCPACK *//* *//***********************************************************************/static void dhcp_request(int event){ uint i; switch (event) { case TRANSITION: dhcp.state = DHCP_REQUEST; dhcp.retransDelay = K4_SECONDS; /*lint -fallthrough */ case MSG_TIMEOUT: /*-----------------------------------------------------------------*/ /* If max retry period exceeded, reset state to DHCP_INIT. */ /*-----------------------------------------------------------------*/ if (dhcp.retransDelay >= K64_SECONDS) { dhcp_init(TRANSITION); dhcp_init(MSG_TIMEOUT); } /*-----------------------------------------------------------------*/ /* Otherwise, send a DHCPREQUEST message. */ /*-----------------------------------------------------------------*/ else { send_msg(dhcp.ni, 0, DHCPREQUEST); i = (dhcp.retransDelay - K1_SECOND) + (rand() % K2_SECONDS); NetTimerStart(&dhcp.msgTimer, i); dhcp.retransDelay <<= 1; } break; case DHCPACK: /*-----------------------------------------------------------------*/ /* Transition to either DHCP_BOUND or DHCP_ARP state. */ /*-----------------------------------------------------------------*/ if (dhcp.ni->flags & NIF_P2P) { /*---------------------------------------------------------------*/ /* Assign the supplied IP address and mask. */ /*---------------------------------------------------------------*/ dhcp.ni->ip_addr = dhcp.reqAddr; dhcp.ni->ip_mask = dhcp.subnetMask; dhcp_bound(TRANSITION); } else dhcp_arp(TRANSITION); break; case DHCPNAK: /*-----------------------------------------------------------------*/ /* Reset to DHCP_INIT and change to DHCP_SELECT 10 seconds later. */ /*-----------------------------------------------------------------*/ dhcp_init(TRANSITION); NetTimerStart(&dhcp.msgTimer, K10_SECONDS); break; }}/***********************************************************************//* dhcp_arp: Final check whether address is in use *//* *//***********************************************************************/static void dhcp_arp(int event){ switch (event) { case TRANSITION: /*-----------------------------------------------------------------*/ /* Initialize state. */ /*-----------------------------------------------------------------*/ dhcp.state = DHCP_ARP; /*-----------------------------------------------------------------*/ /* Send ARP request and use timer to wait one second. */ /*-----------------------------------------------------------------*/ DhcpArpReq(dhcp.ni, dhcp.reqAddr); NetTimerStart(&dhcp.msgTimer, TICKS_PER_SEC); break; case MSG_TIMEOUT: /*-----------------------------------------------------------------*/ /* Check whether any host claimed IP address. */ /*-----------------------------------------------------------------*/ if (DhcpArpCached(dhcp.reqAddr)) { /*---------------------------------------------------------------*/ /* Address is already in use! Must decline it. */ /*---------------------------------------------------------------*/ send_msg(dhcp.ni, 0, DHCPDECLINE); /*---------------------------------------------------------------*/ /* Reset to DHCP_INIT and change to DHCP_SELECT 10 secs later. */ /*---------------------------------------------------------------*/ dhcp_init(TRANSITION); NetTimerStart(&dhcp.msgTimer, K10_SECONDS); } else { /*---------------------------------------------------------------*/ /* Assign the supplied IP address and mask. */ /*---------------------------------------------------------------*/ dhcp.ni->ip_addr = dhcp.reqAddr; dhcp.ni->ip_mask = dhcp.subnetMask; /*---------------------------------------------------------------*/ /* Clear outdated ARP entries and change to DHCP_BOUND state. */ /*---------------------------------------------------------------*/ DhcpArpReply(dhcp.ni); dhcp_bound(TRANSITION); } break; }}/***********************************************************************//* dhcp_bound: Bind address, move to DHCP_RENEW at 50% expiration *//* *//***********************************************************************/static void dhcp_bound(int event){ uint temp; switch (event) { case TRANSITION: /*-----------------------------------------------------------------*/ /* Check if this is first transition to DHCP_BOUND. */ /*-----------------------------------------------------------------*/ if (dhcp.state < DHCP_BOUND) { /*---------------------------------------------------------------*/ /* Add interface routes. */ /*---------------------------------------------------------------*/ if (NiRtAdd(dhcp.ni)) goto bound_err; /*---------------------------------------------------------------*/ /* If new gateway, add DHCP-supplied router as default gateway. */ /*---------------------------------------------------------------*/ if (dhcp.router) RtAdd(dhcp.router, 0, INADDR_ANY, dhcp.ni, RT_GATEWAY); } /*-----------------------------------------------------------------*/ /* Initialize state and stop message retransmission timer. */ /*-----------------------------------------------------------------*/ dhcp.state = DHCP_BOUND; NetTimerStop(&dhcp.msgTimer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -