📄 dhcp.c
字号:
/*-----------------------------------------------------------------*/ /* Ensure rebind time is set and is less than lease time. */ /*-----------------------------------------------------------------*/ if ((dhcp.rebindT2 == 0) || (dhcp.rebindT2 >= dhcp.leaseTime)) dhcp.rebindT2 = 35 * dhcp.leaseTime / 40; /* 87.5 percent */ /*-----------------------------------------------------------------*/ /* Ensure renewal time is set and is less than rebind time. */ /*-----------------------------------------------------------------*/ if ((dhcp.renewT1 == 0) || (dhcp.renewT1 >= dhcp.rebindT2)) dhcp.renewT1 = dhcp.leaseTime / 2; /*-----------------------------------------------------------------*/ /* Calculate elapsed ticks between request and receipt of lease. */ /*-----------------------------------------------------------------*/ temp = NetTickCount - dhcp.req_time; /*-----------------------------------------------------------------*/ /* Set lease timer to expire when it is time to renew. */ /*-----------------------------------------------------------------*/ temp = (dhcp.renewT1 * TICKS_PER_SEC) - temp; NetTimerStart(&dhcp.leaseTimer, temp); break; case LEASE_TIMEOUT: dhcp_renew(TRANSITION); break; } return;bound_err: /*-------------------------------------------------------------------*/ /* Reset state machine to DHCP_INIT state. */ /*-------------------------------------------------------------------*/ dhcp_init(TRANSITION); /*-------------------------------------------------------------------*/ /* Change to DHCP_SELECT 10 seconds later. */ /*-------------------------------------------------------------------*/ NetTimerStart(&dhcp.msgTimer, K10_SECONDS);}/***********************************************************************//* dhcp_renew: Unicast DHCPREQUEST to original server, move to *//* DHCP_BIND at 87.5% expiration *//* *//***********************************************************************/static void dhcp_renew(int event){ uint i; switch (event) { case TRANSITION: /*-----------------------------------------------------------------*/ /* Initialize state. */ /*-----------------------------------------------------------------*/ dhcp.state = DHCP_RENEW; /*-----------------------------------------------------------------*/ /* Record tick count at beginning of lease renewal attempt. */ /*-----------------------------------------------------------------*/ dhcp.req_time = NetTickCount; /*-----------------------------------------------------------------*/ /* Set lease timer to expire after renewal time elapses. */ /*-----------------------------------------------------------------*/ i = dhcp.rebindT2 - dhcp.renewT1; NetTimerStart(&dhcp.leaseTimer, i * TICKS_PER_SEC); /*-----------------------------------------------------------------*/ /* Set retransmission timer to expire midway in renewal period. */ /*-----------------------------------------------------------------*/ i >>= 1; if (i < 60) /* 60 second minimum */ i = 60; NetTimerStart(&dhcp.msgTimer, i * TICKS_PER_SEC); /*lint -fallthrough */ case MSG_TIMEOUT: send_msg(dhcp.ni, dhcp.reqAddr, DHCPREQUEST); break; case DHCPACK: /*-----------------------------------------------------------------*/ /* Transition to DHCP_BOUND state. */ /*-----------------------------------------------------------------*/ dhcp_bound(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; case LEASE_TIMEOUT: /*-----------------------------------------------------------------*/ /* Transition to DHCP_REBIND state. */ /*-----------------------------------------------------------------*/ dhcp_rebind(TRANSITION); break; }}/***********************************************************************//* dhcp_rebind: Broadcast DHCPREQUEST to all servers, move to DHCPINIT *//* if lease expires *//* *//***********************************************************************/static void dhcp_rebind(int event){ uint i; switch (event) { case TRANSITION: /*-----------------------------------------------------------------*/ /* Initialize state. */ /*-----------------------------------------------------------------*/ dhcp.state = DHCP_REBIND; /*-----------------------------------------------------------------*/ /* Set lease timer to expire after rebind time elapses. */ /*-----------------------------------------------------------------*/ i = dhcp.leaseTime - dhcp.rebindT2; NetTimerStart(&dhcp.leaseTimer, i * TICKS_PER_SEC); /*-----------------------------------------------------------------*/ /* Set retransmission timer to expire midway in rebind period. */ /*-----------------------------------------------------------------*/ i >>= 1; if (i < 60) /* 60 second minimum */ i = 60; NetTimerStart(&dhcp.msgTimer, i * TICKS_PER_SEC); /*lint -fallthrough */ case MSG_TIMEOUT: send_msg(dhcp.ni, dhcp.reqAddr, DHCPREQUEST); break; case DHCPACK: /*-----------------------------------------------------------------*/ /* Transition to DHCP_BOUND state. */ /*-----------------------------------------------------------------*/ dhcp_bound(TRANSITION); break; case LEASE_TIMEOUT: /*-----------------------------------------------------------------*/ /* Reset state machine to DHCP_INIT and then DHCP_REQUEST. */ /*-----------------------------------------------------------------*/ dhcp_init(TRANSITION); dhcp_init(MSG_TIMEOUT); break; case DHCPNAK: /*-----------------------------------------------------------------*/ /* Reset to DHCP_INIT and change to DHCP_SELECT 10 seconds later. */ /*-----------------------------------------------------------------*/ dhcp_init(TRANSITION); NetTimerStart(&dhcp.msgTimer, K10_SECONDS); break; }}/***********************************************************************//* lease_timer: action function for DHCP lease timer *//* *//***********************************************************************/static void lease_timer(void *unused){ DhcpSwitch[dhcp.state](LEASE_TIMEOUT);}/***********************************************************************//* msg_timer: action function for DHCP retransmission timer *//* *//***********************************************************************/static void msg_timer(void *unused){ DhcpSwitch[dhcp.state](MSG_TIMEOUT);}/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* DhcpInit: Initialize DHCP client *//* *//***********************************************************************/void DhcpInit(void){ int flag = TRUE; struct sockaddr_in addr; /*-------------------------------------------------------------------*/ /* Initialize DHCP timers. */ /*-------------------------------------------------------------------*/ dhcp.msgTimer.action = msg_timer; dhcp.leaseTimer.action = lease_timer; /*-------------------------------------------------------------------*/ /* Allocate UDP socket for DHCP requests and replies. */ /*-------------------------------------------------------------------*/ DnsS = socket(AF_INET, SOCK_DGRAM, 0); if (DnsS == -1) return; /*-------------------------------------------------------------------*/ /* Assign local address to socket. */ /*-------------------------------------------------------------------*/ memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(DHCP_CLNT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(DnsS, &addr, sizeof(struct sockaddr_in))) { closesocket(DnsS); return; } /*-------------------------------------------------------------------*/ /* Set SO_BROADCAST option. */ /*-------------------------------------------------------------------*/ if (setsockopt(DnsS, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag))) return; /*-------------------------------------------------------------------*/ /* Install socket callback function. */ /*-------------------------------------------------------------------*/ if (setsockopt(DnsS, SOL_SOCKET, SO_CALLBACK, (void *)get_response, 4)) return; /*-------------------------------------------------------------------*/ /* Assign transaction identifier for this boot. */ /*-------------------------------------------------------------------*/ while ((TransactionId = rand()) == 0) ;}/***********************************************************************//* DhcpAdd: Start IP address resolution using DHCP client *//* *//* Input: ni = pointer to network interface structure *//* *//***********************************************************************/int DhcpAdd(Ni *ni){ /*-------------------------------------------------------------------*/ /* Ensure only one interface uses DHCP, then save its pointer. */ /*-------------------------------------------------------------------*/ if (dhcp.ni) return -1; dhcp.ni = ni; /*-------------------------------------------------------------------*/ /* Initialize DHCP state machine. Move to DHCP_SELECT within random */ /* period between 1 and 10 seconds. */ /*-------------------------------------------------------------------*/ dhcp_init(TRANSITION); NetTimerStart(&dhcp.msgTimer, K1_SECOND + (rand() % K9_SECONDS)); return 0;}/***********************************************************************//* DhcpDel: Stop DHCP client IP address resolution *//* *//* Input: ni = pointer to network interface structure *//* *//***********************************************************************/int DhcpDel(const Ni *ni){ /*-------------------------------------------------------------------*/ /* Ensure the input interface is using DHCP. */ /*-------------------------------------------------------------------*/ if (dhcp.ni != ni) return -1; /*-------------------------------------------------------------------*/ /* Shutdown DHCP state machine. */ /*-------------------------------------------------------------------*/ dhcp_free(TRANSITION); /*-------------------------------------------------------------------*/ /* Release and reacquire internal access to let last message go out. */ /*-------------------------------------------------------------------*/ semPost(Net.IntSem); semPend(Net.IntSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Clear global DHCP network interface pointer. */ /*-------------------------------------------------------------------*/ dhcp.ni = 0; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -