📄 dhcpc.c
字号:
uint8_t *PktPos = NULL;
ipaddr htonlIpAddr=0;
memset(&DhClientRequestPkt, 0, sizeof(DhClientRequestPkt));
memset(caSendingPkt, 0, sizeof(caSendingPkt));
DhClientRequestPkt.op = BOOTREQUEST;
DhClientRequestPkt.htype = 1;
DhClientRequestPkt.hlen = 6;
DhClientRequestPkt.hops = 0;
DhClientRequestPkt.secs = 0;
DhClientRequestPkt.xid = htonl(pCurCtxtBlock->ulTransActionId);
DhClientRequestPkt.ciaddr = pCurCtxtBlock->LeasedIpAddress;
//memcpy(DhClientRequestPkt.chaddr, pCurCtxtBlock->aucHwAddress, 6);
GetHwAddr(DhClientRequestPkt.chaddr, pCurCtxtBlock->cszIfName);
memcpy(caSendingPkt, &DhClientRequestPkt, sizeof(DhClientRequestPkt));
index = sizeof(DhClientRequestPkt);
PktPos = caSendingPkt + index;
memcpy(PktPos, DHCP_OPTIONS_COOKIE, 4);
PktPos += 4;
*PktPos++ = DHCP_MESSAGE_TYPE;
*PktPos++ = DHCP_MESSAGE_OPTION_LEN;
*PktPos++ = DHCPRELEASE;
index += 7;
uiLen = index;
DHCPCFunctionInfo.FillOptions(pCurCtxtBlock->cszIfName, caSendingPkt, &uiLen, DHCPRELEASE);
PktPos += (uiLen-index);
index = uiLen;
*PktPos++ = DHO_DHCP_SERVER_IDENTIFIER;
*PktPos++ = sizeof(ipaddr);
index += 2;
htonlIpAddr = htonl(pCurCtxtBlock->DHCPServerIpAddr);
memcpy(PktPos, &htonlIpAddr, sizeof(ipaddr));
PktPos += sizeof(ipaddr);
index += sizeof(ipaddr);
*PktPos = END_OPTION;
index += 1;
printf("*************************Send DHCP Release*************************\n");
if (DHCPCFunctionInfo.SendPacket(pCurCtxtBlock->cszIfName,
caSendingPkt,
index,
htonl(pCurCtxtBlock->LeasedIpAddress),
pCurCtxtBlock->DHCPServerIpAddr)<0)
{
printf("Sending Release pkt error\n");
return FALSE;
}
return TRUE;
}
int DHCPClientSendDHCPRequest(DHCPClientBlock_t *pCurCtxtBlock)
{
uint8_t caSendingPkt[1024];
uint32_t ulTotLen = 0, iRet = 0;
uint32_t t;
time((time_t *)&t);
memset(caSendingPkt, 0, sizeof(caSendingPkt));
memset(&DhClientRequestPkt, 0, sizeof(struct dhcp_packet));
GetHwAddr(pCurCtxtBlock->aucHwAddress, pCurCtxtBlock->cszIfName);
DhClientRequestPkt.op = BOOTREQUEST;
DhClientRequestPkt.htype = ETHERNET_HW_TYPE;
DhClientRequestPkt.hlen = ETHERNET_HWADDR_LEN;
DhClientRequestPkt.xid = pCurCtxtBlock->ulTransActionId;
DhClientRequestPkt.secs = t;
memcpy(DhClientRequestPkt.chaddr, pCurCtxtBlock->aucHwAddress, ETHERNET_HWADDR_LEN);
switch (pCurCtxtBlock->CurrentState)
{
case DHCP_CLIENT_SELECT:
case DHCP_CLIENT_REQUEST:
DhClientRequestPkt.flags = htons(DhClientRequestPkt.flags | DHCP_CLIENT_BROADCAST);
break;
case DHCP_CLIENT_RENEW:
//DhClientRequestPkt.ciaddr = pCurCtxtBlock->LeasedIpAddress; /*xhema */
DhClientRequestPkt.flags = htons(DhClientRequestPkt.flags | DHCP_CLIENT_BROADCAST);
DhClientRequestPkt.ciaddr = 0;
break;
case DHCP_CLIENT_REBIND:
DhClientRequestPkt.flags = htons(DhClientRequestPkt.flags | DHCP_CLIENT_BROADCAST);
DhClientRequestPkt.ciaddr = htonl(pCurCtxtBlock->LeasedIpAddress);
break;
default:
break;
}
memcpy(caSendingPkt, &DhClientRequestPkt, sizeof(DhClientRequestPkt));
ulTotLen += sizeof(DhClientRequestPkt);
DHCPCAddOptionsToPkt(caSendingPkt, pCurCtxtBlock, &ulTotLen, DHCPREQUEST);
//printf("========Sending Request Server ip = %d\n", pCurCtxtBlock->DHCPServerIpAddr);
//judge
if (pCurCtxtBlock->CurrentState == DHCP_CLIENT_RENEW)
{
//Lease time is over half (续租)
//printf("renewing server ip = %d\n", pCurCtxtBlock->DHCPServerIpAddr);
DHCPCIpAddressInfo.ulServerIpAddress = BROADCAST_IP_ADDRESS;
//DHCPCIpAddressInfo.ulServerIpAddress = pCurCtxtBlock->DHCPServerIpAddr;/*xhema*/
iRet = DHCPCFunctionInfo.SendPacket(pCurCtxtBlock->cszIfName, (uint8_t *)caSendingPkt,
ulTotLen, htonl(DhClientRequestPkt.ciaddr), DHCPCIpAddressInfo.ulServerIpAddress);
if (iRet<0)
{
printf("send request pkt error\n");
return FALSE;
}
}
else
{
DHCPCIpAddressInfo.ulServerIpAddress = BROADCAST_IP_ADDRESS;
DhClientRequestPkt.ciaddr = ntohl(DhClientRequestPkt.ciaddr);
iRet = DHCPCFunctionInfo.SendPacket(
pCurCtxtBlock->cszIfName,
(uint8_t *)caSendingPkt,
ulTotLen,
DhClientRequestPkt.ciaddr,
DHCPCIpAddressInfo.ulServerIpAddress);
if (iRet<0)
{
printf("send request pkt error\n");
return FALSE;
}
}
return TRUE;
}
int DHCPClientReadPort68Message(void)
{
int n;
uint32_t ulLeasedTime = 0, ulRenewTmOut=0,ulRebindTmOut = 0;
ipaddr DHCPServerIpAddr=0, addr1, addr2;
uint8_t DhcpMessageType = 0;
uint8_t pReplyPkt[1024],Buff[1024], hwaddr[6],desthwaddr[6];
DhcpcIPSetting_t ConfigStruct = {0};
DHCPClientBlock_t *pCurBlock = NULL;
ArpReplyType_t ArpReply;
struct dhcp_packet *pkt = NULL;
ipaddr AddressArr[10];
int AddressLen = 0;
struct sockaddr_ll from;
int iFromLen = sizeof(from);
int ulIPHdrLen /*,iUdpLen*/ ;
int iInterfaceIndex = -1;
char szInterfaceName[16] = {0};
static uint32_t ulAckedID;
memset(pReplyPkt, 0, sizeof(pReplyPkt));
n = recvfrom(s_iDCSocket, Buff, 1024, 0,
(struct sockaddr *)&from, &iFromLen);
Buff[n] = '\0';
ulIPHdrLen = ((Buff[0] & 0x0f) << 2);
if ((Buff[9]!=17) ||
(IGW_BUFGET16(Buff+ulIPHdrLen+0) != 67)||
(IGW_BUFGET16(Buff+ulIPHdrLen+2) != 68))
{
//printf("Not a DHCP packet!\n");
return TRUE;
}
memcpy(pReplyPkt, Buff+ulIPHdrLen+8, n-ulIPHdrLen-8);
//printf("port 68 have message\n");
pkt = (struct dhcp_packet *)pReplyPkt;
if (memcmp(&pReplyPkt[DHCP_FIXED_NON_UDP], DHCP_OPTIONS_COOKIE, 4) != 0)
{
printf("Magic cookie is not match\n");
return TRUE;
}
//printf("Magic cookie is match and received card index = %d\n",
// from.sll_ifindex);
//在链表中判断此接口是否已经分配,如果没有则分配并加入到链表中。如果已经分配过
//则判断链表中接口是否处于Active状态,如果没有处于Active,则判断系统中此接口卡
//的状态,如果可用则将链表中接口卡的Active=TRUE,否则Active=FALSE
iInterfaceIndex = from.sll_ifindex;
if (FALSE == getIfNamebyIndex(iInterfaceIndex, szInterfaceName))
{
printf("can't get interface name from index!\n");
//send a error msg to config server
return TRUE;
}
pCurBlock = DHCPClientIfaceIsAllocByIndex(
iInterfaceIndex,
0,
TRUE);
if (NULL == pCurBlock)
{
//this card is not be alloc, that is to say: config server haven't set it to DHCP Client
return TRUE;
}
else
{
//interface is in list
//judge if it is Active state
if (FALSE == IsInterfaceUp(szInterfaceName))
{
//系统中此接口不处于活动状态
g_pDHCPClientCurrent->bIfActive = FALSE;
return TRUE;
}
//printf("point change to set to %s !!!!!!!!!!!!!!!!\n", szInterfaceName);
g_pDHCPClientCurrent = pCurBlock;
}
if (DHCPClientGetOptionBuf(&pReplyPkt[DHCP_FIXED_NON_UDP+4],
(n-DHCP_FIXED_NON_UDP-4), &DhcpMessageType, &DHCPServerIpAddr,
&ulLeasedTime, &ulRenewTmOut, &ulRebindTmOut) == FALSE)
{
printf("get option buffer error\n");
return TRUE;
}
//Get DNS
DHCPClientGetDNS(&pReplyPkt[DHCP_FIXED_NON_UDP+4],
(n-DHCP_FIXED_NON_UDP-4), AddressArr, &AddressLen);
//fill in network mask, dns, router
DHCPClientGetParam(&pReplyPkt[DHCP_FIXED_NON_UDP+4],
(n-DHCP_FIXED_NON_UDP-4), &ConfigStruct);
if ((DhcpMessageType != DHCPOFFER) &&
(DhcpMessageType != DHCPACK) &&
(DhcpMessageType != DHCPNAK))
{
printf("message type error\n");
return FALSE;
}
switch (DhcpMessageType)
{
case DHCPOFFER://Send discover the recv offer pkt
if (g_pDHCPClientCurrent->ulTransActionId == ntohl(pkt->xid))
{
printf("this off packet is me\n");
if (ulAckedID == g_pDHCPClientCurrent->ulTransActionId)
{
printf("this id have been the other server acked!{}{}{}{}{}\n");
return TRUE;
}
g_pDHCPClientCurrent->pTimer->iSendNums = 0;
g_pDHCPClientCurrent->pTimer->bStartWaitEvent = FALSE;
printf("this packet's ulTransActionId is me\n");
g_pDHCPClientCurrent->bRequestToConnect = FALSE;
g_pDHCPClientCurrent->ulTransActionId = ntohl(pkt->xid);
g_pDHCPClientCurrent->DHCPServerIpAddr = pkt->siaddr;
g_pDHCPClientCurrent->LeasedIpAddress = pkt->yiaddr;
memcpy(g_pDHCPClientCurrent->aucHwAddress, pkt->chaddr, 6);
if (FALSE == IsValidIP(g_pDHCPClientCurrent->LeasedIpAddress))
{
printf("**************false ip*****************\n");
//Server given ip is not correct
DHCPClientSendDHCPDecline(g_pDHCPClientCurrent); //refuse this addr
sleep(1);
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_INITIALIZED;
TimerStart(g_pDHCPClientCurrent->pTimer,
DEFAULT_DISCOVER_TIMEOUT,
WAIT_DISCOVER);
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_SELECT;
DHCPClientSendDHCPDiscover(g_pDHCPClientCurrent);
}
TimerStart(g_pDHCPClientCurrent->pTimer,
DEFAULT_REQUEST_TIMEOUT,
WAIT_REQUEST);
g_pDHCPClientCurrent->CurrentState= DHCP_CLIENT_REQUEST;
if (FALSE == DHCPClientSendDHCPRequest(g_pDHCPClientCurrent))
{
printf("send request error\n");
}
}
else
{
printf("this offer pkt isn't me!\n");
}
break;
case DHCPACK:
#ifdef RUNONPC
if (g_pDHCPClientCurrent->ulTransActionId != pkt->xid)
#else
if (g_pDHCPClientCurrent->ulTransActionId != ntohl(pkt->xid))
#endif
{
printf("this ack isn't me!%d\n", ntohl(pkt->xid));
return TRUE;
}
else
{
printf("this ack is me!%d\n", ntohl(pkt->xid));
}
ulAckedID = g_pDHCPClientCurrent->ulTransActionId;
g_pDHCPClientCurrent->pTimer->iSendNums = 0;
g_pDHCPClientCurrent->pTimer->fWillSend = FALSE;
g_pDHCPClientCurrent->pTimer->iTimeOutNums = 0;
g_pDHCPClientCurrent->pTimer->bStartWaitEvent = FALSE;
g_pDHCPClientCurrent->bRequestToConnect = FALSE;
if (g_pDHCPClientCurrent->CurrentState == DHCP_CLIENT_RENEW)
{
time((time_t *)&g_pDHCPClientCurrent->ulStartLeaseTime);
g_pDHCPClientCurrent->pTimer->uiStartLeaseTime = g_pDHCPClientCurrent->ulStartLeaseTime;
g_pDHCPClientCurrent->ulTransActionId = pkt->xid;
g_pDHCPClientCurrent->DHCPServerIpAddr = DHCPServerIpAddr; //get option buff's result
g_pDHCPClientCurrent->LeasedIpAddress = pkt->yiaddr;// inet_addr("192.168.12.29");
memcpy(g_pDHCPClientCurrent->aucHwAddress, pkt->chaddr, 6); //copy hw addr
g_pDHCPClientCurrent->ulLeasedTime = ulLeasedTime;
g_pDHCPClientCurrent->ulRemainingTime = ulLeasedTime;
//set ip addr
ConfigStruct.ulIP= pkt->yiaddr;
memset(&g_pDHCPClientCurrent->sAllocedStruct, 0,
sizeof(g_pDHCPClientCurrent->sAllocedStruct));
memcpy((void *)&g_pDHCPClientCurrent->sAllocedStruct,
(void *)&ConfigStruct,
sizeof(ConfigStruct));
//xhema not set parma
if (FALSE == DHCPCFunctionInfo.DHCPNetworkConfig(g_pDHCPClientCurrent->cszIfName , &ConfigStruct))
{
printf("RENEW: set network parma error\n");
return FALSE;
}
//retry set DNS
/*if (FALSE == DHCPClientSystemDNSet(AddressArr, AddressLen))
{
printf("set dns error\n");
return FALSE;
}*/
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_BOUND;
g_pDHCPClientCurrent->pTimer->bStartWaitEvent = FALSE;
g_pDHCPClientCurrent->bUsed = TRUE;
time((time_t *)&g_pDHCPClientCurrent->ulLeaveArpSendTime);
}
else
{
GetHwAddr(hwaddr, g_pDHCPClientCurrent->cszIfName);
memset(desthwaddr, 0, 6);
addr1 = inet_addr("127.0.0.1");
addr2 = pkt->yiaddr;
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_ARP_AWAIT;
ArpReply = DHCPClientSendArp(g_pDHCPClientCurrent->cszIfName, hwaddr, desthwaddr,
addr1, addr2);
if (ArpReply == ARP_HAVE_SAME_ADDR)
{
printf("In network a machine hava the same addr\n");
//judge whether this interface is me
if (0 == memcmp(g_pDHCPClientCurrent->aucHwAddress, desthwaddr, 6))
{
//this clash IP is myself, then continue to set it
goto ARP;
}
DHCPClientSendDHCPDecline(g_pDHCPClientCurrent); //refuse this addr
sleep(1);
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_INITIALIZED;
TimerStart(g_pDHCPClientCurrent->pTimer,
DEFAULT_DISCOVER_TIMEOUT,
WAIT_DISCOVER);
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_SELECT;
DHCPClientSendDHCPDiscover(g_pDHCPClientCurrent);
return TRUE;
}
if (ArpReply == ARP_SUCCESS)
{
//printf("IP ACK, i will set it to interface, Get Server IP = %d\n", DHCPServerIpAddr);
ARP:
time((time_t *)&g_pDHCPClientCurrent->ulStartLeaseTime);
g_uiStartLeaseTime = g_pDHCPClientCurrent->ulStartLeaseTime;
g_pDHCPClientCurrent->ulTransActionId = pkt->xid;
g_pDHCPClientCurrent->DHCPServerIpAddr = DHCPServerIpAddr; //get option buff's result
g_pDHCPClientCurrent->LeasedIpAddress = pkt->yiaddr;// inet_addr("192.168.12.29");
memcpy(g_pDHCPClientCurrent->aucHwAddress, pkt->chaddr, 6); //copy hw addr
g_pDHCPClientCurrent->ulLeasedTime = ulLeasedTime;
g_pDHCPClientCurrent->ulRemainingTime = ulLeasedTime;
//set ip addr
ConfigStruct.ulIP= pkt->yiaddr;
memset(&g_pDHCPClientCurrent->sAllocedStruct, 0,
sizeof(g_pDHCPClientCurrent->sAllocedStruct));
memcpy((void *)&g_pDHCPClientCurrent->sAllocedStruct,
(void *)&ConfigStruct,
sizeof(ConfigStruct));
if (FALSE == DHCPCFunctionInfo.DHCPNetworkConfig(g_pDHCPClientCurrent->cszIfName, &ConfigStruct))
{
printf("ARP: set network parma error\n");
return FALSE;
}
//retry set DNS
/*if (FALSE == DHCPClientSystemDNSet(AddressArr, AddressLen))
{
printf("set dns error\n");
return FALSE;
}*/
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_BOUND;
g_pDHCPClientCurrent->pTimer->bStartWaitEvent = FALSE;
g_pDHCPClientCurrent->bUsed = TRUE;
time((time_t *)&g_pDHCPClientCurrent->ulLeaveArpSendTime);
}
}
break;
case DHCPNAK:
if (g_pDHCPClientCurrent->ulTransActionId != ntohl(pkt->xid))
{
printf("this nak isn't me\n");
return TRUE;
}
if (ulAckedID == g_pDHCPClientCurrent->ulTransActionId)
{
printf("this id have been the other server acked!{}{}{}{}{}\n");
return TRUE;
}
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_INITIALIZED;
sleep(1); //sleep 1 second
TimerStart(g_pDHCPClientCurrent->pTimer,
DEFAULT_DISCOVER_TIMEOUT,
WAIT_DISCOVER);
g_pDHCPClientCurrent->CurrentState = DHCP_CLIENT_SELECT;
DHCPClientSendDHCPDiscover(g_pDHCPClientCurrent);
break;
default:
break;
}
return TRUE;
}
//////////////////////////////////////////////////////////////
int DhcpMonitorStartup(void)
{
int opt = 1, len = sizeof(opt);
bzero(&s_DhcpServerAddr, sizeof(s_DhcpServerAddr));
s_DhcpServerAddr.sin_family = AF_INET;
s_DhcpServerAddr.sin_port = htons(DHCP_CLIENT_CONFIG_PORT);
//s_DhcpServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
//s_DhcpServerAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
s_DhcpServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
s_iConfigServerSocket = socket(AF_INET, SOCK_DGRAM, 0);
//if socket bind a port, when this socket close or the process is exit. this port
//will be the bind state in a while, but the next source will solve the problem
setsockopt(s_iConfigServerSocket, SOL_SOCKET, SO_REUSEADDR, &opt, len);
if (INVALID_SOCKET == s_iConfigServerSocket)
{
perror("Create Socket error!");
return FALSE;
}
if (-1 == bind(s_iConfigServerSocket, (struct sockaddr *)&s_DhcpServerAddr,
sizeof(struct sockaddr_in)))
{
perror("bind error!");
return FALSE;
}
return TRUE;
}
#define CONFIG_MAXLEN 255
static uint32_t s_ConfigServerRequest[CONFIG_MAXLEN/sizeof(uint32_t)] = {0};
void ClientMonitor(void)
{
uint32_t count;
DHCPClientBlock_t *sReturnStruct;
int32_t iLen;
int32_t iFdResult = 0, iFdsChecked = 0;
int ii = 0;
time((time_t *)&CurrentTime); //get current time
DHCPClientTimerProc(); //find timeout or the other event
DHCPClientPo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -