📄 dhcp.c
字号:
int offset;
int retry = 0;
offset = InitDhcpPacket(DHCPDISCOVER, 1);
/* End Option */
dhcppacket.options[offset] = DHCP_END_OPTION;
while (retry < 4)
{
int timeout = DHCP_TIMEOUT;
int len;
if (SendIPBroadcast() != DHCP_OK)
{
printf("DHCP: Send Discovery Broadcast error!\n");
return DHCP_ERROR;
}
bzero((void *) &recv_packet, sizeof(s_dhcppacket));
if (readable_timeo(sockfd, timeout) <= 0)
{
printf("DHCP: Timeout waiting for Offer\n");
}
else
{
if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0)
{
perror("recvfrom");
return DHCP_ERROR;
}
printf("DHCP: Got one message to Discovery\n");
if (recv_packet.op == BOOT_REPLY &&
recv_packet.xid == client_xid &&
ParseDhcpOption() == DHCPOFFER)
{
return DHCP_OK;
}
}
timeout *= 2;
retry++;
}
printf("DHCP: DO Discovery -- no response\n");
return DHCP_RETRY;
}
int DoDhcpRequest(int sockfd)
{
int offset;
int retry = 0;
int macCount = 0;
int timeout,lasttime;
int isRetry = 0;
unsigned int timeBegin,timeEnd;
offset = InitDhcpPacket(DHCPREQUEST, 1);
/* server identifier */
dhcppacket.options[offset++] = DHCP_SERVERID_OPTION;
dhcppacket.options[offset++] = 4;
memcpy(dhcppacket.options + offset, &dhcp_server, 4);
offset += 4;
/* requested IP address */
dhcppacket.options[offset++] = DHCP_REQIP_OPTION;
dhcppacket.options[offset++] = 4;
memcpy(dhcppacket.options + offset, &dhcp_allocated, 4);
offset += 4;
/* End Option */
dhcppacket.options[offset] = DHCP_END_OPTION;
timeout = DHCP_TIMEOUT;
lasttime = DHCP_TIMEOUT;
while (retry < 4)
{
int len;
isRetry = 0;
timeBegin = tickGet();
if (SendIPBroadcast() != DHCP_OK)
{
return DHCP_ERROR;
}
bzero((void *) &recv_packet, sizeof(s_dhcppacket));
if (readable_timeo(sockfd, timeout) <= 0)
{
printf("DHCP: Timeout waiting for Ack\n");
}
else
{
if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0)
{
perror("recvfrom");
return DHCP_ERROR;
}
/*** all the phone's xid is the same
if(recv_packet.xid !=client_xid)
{
printf("xid error!\n");
return DHCP_RETRY;
}
****/
/***check if receive dhcp packets is not send to this mac*****/
timeEnd= tickGet();
for(macCount = 0;macCount <MAC_ADD_LEN;macCount ++)
{
printf("0x%x\n",mac_addr.MACByte[macCount]);
printf("0x%x\n",recv_packet.chaddr[macCount]);
if(mac_addr.MACByte[macCount] != recv_packet.chaddr[macCount])
{
printf("This is not for my MAC\n");
timeout -= (timeEnd -timeBegin)/100;
if(timeout > 0)
{
isRetry = 1;
break;
}
}
}
if(isRetry)
continue;
if (recv_packet.op == BOOT_REPLY && recv_packet.xid == client_xid)
{
int ret = ParseDhcpOption();
if (ret == DHCPACK)
{
return DHCP_OK;
}
else if (ret == DHCPNAK)
{
return DHCP_RETRY;
}
}
}
timeout = 2*lasttime;
lasttime = timeout;
retry++;
}
return DHCP_RETRY;
}
int RenewDhcpLease()
{
int clientSock;
int result;
unsigned short renew_ok = 1;
unsigned int T1, T2;
for (;;)
{
if (!renew_ok)
{
/* Time over */
break;
}
T1 = dhcp_lease / 2;
T2 = dhcp_lease * 4 / 5;
taskDelay((T1 - 5) * sysClkRateGet());
semTake(dhcpClientSem, WAIT_FOREVER);
if ((clientSock = InitDhcpClientSock()) != DHCP_ERROR)
{
InitDhcpServerAddr(0);
if ((result = RequestPreAddr(clientSock, 0)) == DHCP_OK)
{
renew_ok = 1;
close(clientSock);
semGive(dhcpClientSem);
continue;
}
else if (result == DHCP_RETRY)
{
close(clientSock);
semGive(dhcpClientSem);
}
else
{
renew_ok = 0;
close(clientSock);
semGive(dhcpClientSem);
continue;
}
}
semGive(dhcpClientSem);
taskDelay((T2 - T1 - 10) * sysClkRateGet());
semTake(dhcpClientSem, WAIT_FOREVER);
if ((clientSock = InitDhcpClientSock()) != DHCP_ERROR)
{
InitDhcpServerAddr(1);
if ((result = RequestPreAddr(clientSock, 1)) == DHCP_OK)
{
renew_ok = 1;
close(clientSock);
semGive(dhcpClientSem);
continue;
}
else if (result == DHCP_RETRY)
{
close(clientSock);
semGive(dhcpClientSem);
}
else
{
renew_ok = 0;
close(clientSock);
semGive(dhcpClientSem);
continue;
}
}
semGive(dhcpClientSem);
renew_ok = 0;
taskDelay((dhcp_lease - T2) * sysClkRateGet());
}
/* 需要通知用户IP地址过期 */
renew_task_id = 0;
}
int RequestPreAddr(int sockfd, unsigned char broadcast)
{
int offset;
int retry = 0;
client_xid = htonl(rand());
offset = InitDhcpPacket(DHCPREQUEST, broadcast);
dhcppacket.options[offset] = DHCP_END_OPTION;
dhcppacket.ciaddr.s_addr = dhcp_allocated;
while (retry < 4)
{
int timeout = DHCP_TIMEOUT;
int len;
if (broadcast)
{
if (SendIPBroadcast() != DHCP_OK)
{
return DHCP_ERROR;
}
}
else if ((len = sendto(sockfd, (void *) &dhcppacket, DHCP_MIN_LEN, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) < 0)
{
perror("sendto");
return DHCP_ERROR;
}
bzero((void *) &recv_packet, sizeof(s_dhcppacket));
if (readable_timeo(sockfd, timeout) <= 0)
{
return DHCP_ERROR;
}
else
{
if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0)
{
perror("recvfrom");
return DHCP_ERROR;
}
if (recv_packet.op == BOOT_REPLY && recv_packet.xid == client_xid)
{
int ret = ParseDhcpOption();
if (ret == DHCPACK)
{
return DHCP_OK;
}
else
{
return DHCP_ERROR;
}
}
timeout *= 2;
retry++;
}
}
return DHCP_RETRY;
}
/*
* 断开连接后重新申请原先的地址
*/
int InitWithKnownIP()
{
int offset;
int retry = 0;
int result, sockfd;
semTake(dhcpClientSem, WAIT_FOREVER);
if ((sockfd = InitDhcpClientSock()) == DHCP_ERROR)
{
semGive(dhcpClientSem);
return DHCP_ERROR;
}
offset = InitDhcpPacket(DHCPREQUEST, 1);
/* requested IP address */
dhcppacket.options[offset++] = DHCP_REQIP_OPTION;
dhcppacket.options[offset++] = 4;
memcpy(dhcppacket.options + offset, &dhcp_allocated, 4);
offset += 4;
/* End Option */
dhcppacket.options[offset] = DHCP_END_OPTION;
result = DHCP_RETRY;
while (retry < 4 && result == DHCP_RETRY)
{
int timeout = DHCP_TIMEOUT;
int len;
if (SendIPBroadcast() != DHCP_OK)
{
result = DHCP_ERROR;
}
bzero((void *) &recv_packet, sizeof(s_dhcppacket));
if (readable_timeo(sockfd, timeout) <= 0)
{
printf("DHCP: Init Reboot Timeout for Ack\n");
}
else
{
if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0)
{
perror("recvfrom");
result = DHCP_ERROR;
}
if (recv_packet.op == BOOT_REPLY && recv_packet.xid == client_xid)
{
int ret = ParseDhcpOption();
if (ret == DHCPACK)
{
result = DHCP_OK;
}
else if (ret == DHCPNAK)
{
result = DHCP_ERROR;
}
}
}
timeout *= 2;
retry++;
}
close(sockfd);
semGive(dhcpClientSem);
if (result == DHCP_OK && renew_task_id != 0)
{
taskDelete(renew_task_id);
renew_task_id = taskSpawn( "tDhcpRenew",150,0,4096,(FUNCPTR)RenewDhcpLease,0,0,0,0,0,0,0,0,0,0);
}
else if (result == DHCP_ERROR)
{
return DHCP_ERROR;
}
return DHCP_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -