📄 dhcpc.c
字号:
iTmpAddr = pCurCtxtBlock->DHCPServerIpAddr;
memcpy((void *)PktPos, (void *)&iTmpAddr, sizeof(ipaddr));
PktPos += sizeof(ipaddr);
*ulTotLength += sizeof(ipaddr);
}
}
//xhema 11.10
if ((pCurCtxtBlock->CurrentState == DHCP_CLIENT_RENEW) ||
(pCurCtxtBlock->CurrentState == DHCP_CLIENT_REQUEST))
{
if (pCurCtxtBlock->LeasedIpAddress>0)
{
*PktPos++ = DHO_DHCP_REQUESTED_ADDRESS;
*PktPos++ = sizeof(ipaddr);
*ulTotLength += 2;
#ifdef DEBUG_NAK_PKT
iTmpAddr = 0;
#else
iTmpAddr = pCurCtxtBlock->LeasedIpAddress;//htonl(pCurCtxtBlock->LeasedIpAddress);
#endif
memcpy((void *)PktPos, (void *)&iTmpAddr, sizeof(ipaddr));
PktPos += sizeof(ipaddr);
*ulTotLength += sizeof(ipaddr);
}
}
printf("Fill options in %s\n", pCurCtxtBlock->cszIfName);
DHCPCFunctionInfo.FillOptions(pCurCtxtBlock->cszIfName, caSendingPkt, ulTotLength, ucDHCPMsgType);
}
void DHCPCFillOptions(
const char *cszIfName,
uint8_t *pData,
uint32_t *ulDataLen,
uint8_t ucDHCPMsgType
)
{
uint8_t OptString[100];
uint32_t iOptLen = 0;
uint8_t *PktPos = pData + *ulDataLen;
/*//host name
memset(OptString, 0, sizeof(OptString));
GetHostName(OptString);
printf("host name = %s\n", OptString);
iOptLen = strlen(OptString);
if (iOptLen > 0)
{
*PktPos++ = DHO_HOST_NAME;
*PktPos++ = iOptLen;
*ulDataLen += 2;
memcpy(PktPos, OptString, iOptLen);
*PktPos += iOptLen;
*ulDataLen += iOptLen;
}*/
//client identifier
memset(OptString, 0, sizeof(OptString));
iOptLen = 0;
*PktPos++ = DHO_DHCP_CLIENT_IDENTIFIER;
*PktPos++ = 7;
*ulDataLen += 2;
*PktPos += 1;
PktPos++;
GetHwAddr(PktPos, cszIfName);
PktPos += 6;
*ulDataLen += 7;
#ifdef DEBUG_LEASE_TIME
uint32_t uiLeaseTime = 0;
/* get the lease time */
DHCPClientGetLeaseTime(&uiLeaseTime);
if (uiLeaseTime>0)
{
*PktPos++ = DHO_DHCP_LEASE_TIME;
*PktPos++ = 4;//sizeof(ipaddr)
*ulDataLen += 2;
uiLeaseTime = htonl(uiLeaseTime);
//g_DHCPClientBlock.ulLeasedTime = uiLeaseTime;
memcpy(PktPos, &uiLeaseTime, sizeof(ipaddr));
PktPos += 4;
*ulDataLen += 4;
}
#endif
/* get client id 61 */
if ((ucDHCPMsgType == DHCPDISCOVER) ||
(ucDHCPMsgType == DHCPREQUEST))
{
*PktPos++ = DHO_DHCP_PARAMETER_REQUEST_LIST;
*PktPos++ = 4;
*PktPos++ = DHO_SUBNET_MASK;
*PktPos++ = DHO_ROUTERS;
*PktPos++ = DHO_DOMAIN_NAME_SERVERS;
*PktPos++ = DHO_BROADCAST_ADDRESS;
*ulDataLen += 6;
}
*PktPos++ = DHO_END;
*ulDataLen += 1;
}
int DHCPClientGetDNS(
uint8_t *pBuffer,
int32_t iLength,
ipaddr *addr,
int *Len
)
{
uint8_t *ucStart;
uint8_t *ucEnd = pBuffer + iLength;
int iLen, iCode;
int i = 0;
for (ucStart=pBuffer; (*ucStart!=END_OPTION)&&(ucStart<ucEnd);)
{
iCode = ucStart[0];
iLen = ucStart[1];
if (iCode == DHO_PAD)
{
++ucStart;
continue;
}
if ((ucStart+iLen+2)>ucEnd)
{
return FALSE;
}
switch (iCode)
{
case DHO_DOMAIN_NAME_SERVERS:
for (i=0; i<iLen/sizeof(ipaddr); i++)
{
(*Len)++;
memcpy(addr, &ucStart[2], sizeof(ipaddr));
ucStart += sizeof(ipaddr);
addr++;
}
break;
default:
break;
}
ucStart += (iLen +2);
}
return TRUE;
}
int DHCPClientGetParam(
uint8_t *pBuffer,
int32_t iLength,
DhcpcIPSetting_t *ConfigStruct
)
{
uint8_t *ucStart;
uint8_t *ucEnd = pBuffer + iLength;
int iLen, iCode;
for (ucStart=pBuffer; (*ucStart!=END_OPTION)&&(ucStart<ucEnd);)
{
iCode = ucStart[0];
iLen = ucStart[1];
if (iCode == DHO_PAD)
{
++ucStart;
continue;
}
if ((ucStart+iLen+2)>ucEnd)
{
return FALSE;
}
switch (iCode)
{
case DHO_SUBNET_MASK:
memcpy(&ConfigStruct->ulNetmask, &ucStart[2], IPADDR_LEN);
break;
case DHO_ROUTERS:
memcpy(&ConfigStruct->ulGateway, &ucStart[2], IPADDR_LEN);
//gateway only one
/*if (iLen>IPADDR_LEN)
{
ucStart += IPADDR_LEN;
memcpy(&ConfigStruct->ifGateway[1], &ucStart[2], IPADDR_LEN);
}*/
break;
case DHO_DOMAIN_NAME_SERVERS:
//DNS
memcpy(&ConfigStruct->ulDNS[0], &ucStart[2], IPADDR_LEN);
if (iLen>IPADDR_LEN)
{
ucStart += IPADDR_LEN;
memcpy(&ConfigStruct->ulDNS[1], &ucStart[2], IPADDR_LEN);
}
break;
default:
break;
}
ucStart += (iLen +2);
}
return TRUE;
}
int DHCPClientGetOptionBuf(uint8_t *pBuffer,
int32_t iLength,
uint8_t *DhcpMessageType,
ipaddr *DHCPServerIpAddr,
uint32_t *ulLeasedTime,
uint32_t *ulRenewTmOut,
uint32_t *ulRebindTmOut
)
{
uint8_t *ucStart;
uint8_t *ucEnd = pBuffer + iLength;
int iLen, iCode;
for (ucStart=pBuffer; (*ucStart!=END_OPTION)&&(ucStart<ucEnd);)
{
iCode = ucStart[0];
iLen = ucStart[1];
if (iCode == DHO_PAD)
{
++ucStart;
continue;
}
if ((ucStart+iLen+2)>ucEnd)
{
return FALSE;
}
//printf("**in GetOptional buffer iCode = %d iLength = %d, *ucStart=%c\n", iCode,iLength,*ucStart);
switch (iCode)
{
case DHO_DHCP_MESSAGE_TYPE:
memcpy(DhcpMessageType, &ucStart[2], DHCP_MESSAGE_OPTION_LEN);
break;
case DHO_DHCP_LEASE_TIME:
memcpy(ulLeasedTime, &ucStart[2], TIME_LEN);
*ulLeasedTime = ntohl(*ulLeasedTime);
//printf("********Get Leased Time: Leased time = %d\n", *ulLeasedTime);
break;
case DHO_DHCP_SERVER_IDENTIFIER:
memcpy(DHCPServerIpAddr, &ucStart[2], IPADDR_LEN);
*DHCPServerIpAddr = ntohl(*DHCPServerIpAddr);
break;
case DHO_DHCP_RENEWAL_TIME:
memcpy(ulRenewTmOut, &ucStart[2], TIME_LEN);
*ulRenewTmOut = ntohl(*ulRenewTmOut);
break;
case DHO_DHCP_REBINDING_TIME:
memcpy(ulRebindTmOut, &ucStart[2], TIME_LEN);
*ulRebindTmOut = ntohl(*ulRebindTmOut);
break;
default:
break;
}
ucStart += (iLen +2);
}
return TRUE;
}
int32_t IGWCreateLpfSock (int8_t *cszIfName)
{
int32_t LpfSockFd;
struct sockaddr_ll to;
memset(&to, 0, sizeof(to));
/* Create an LPF socket. */
//xhema if ((LpfSockFd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0)
if ((LpfSockFd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0)
{
perror("Unable To Create the LPF Socket");
return -1;
}
to.sll_ifindex = getIndexByIfName(cszIfName);
to.sll_family = AF_PACKET;
printf("Create LPF Socket Card index = %d, name =%s\n", to.sll_ifindex, cszIfName);
if (bind (LpfSockFd, (struct sockaddr *)&to, sizeof(to))<0)
{
perror("Unable To Bind the LPF Socket");
close(LpfSockFd);
return -1;
}
return LpfSockFd;
}
void make_discover(struct dhcp_packet *pkt, DHCPClientBlock_t *pCurCtxtBlock)
{
uint32_t t;
time((time_t *)&t);
srand(t);
memset(pkt, 0, sizeof(struct dhcp_packet));
pkt->op = BOOTREQUEST;
pkt->htype = 1;
pkt->hlen = 6;
pkt->hops = 0;
pkt->xid = (uint32_t)rand();
pkt->secs = t;
pkt->flags = htons(BOOTP_BROADCAST);
memset(&pkt->ciaddr, 0, sizeof(pkt->ciaddr));
memset(&pkt->yiaddr, 0, sizeof(pkt->yiaddr));
memset(&pkt->siaddr, 0, sizeof(pkt->siaddr));
memset(&pkt->giaddr, 0, sizeof(pkt->giaddr));
GetHwAddr(pkt->chaddr, pCurCtxtBlock->cszIfName);
//g_DHCPClientBlock.ulTransActionId = htonl(pkt->xid);
pCurCtxtBlock->ulTransActionId = htonl(pkt->xid);
}
//SendPacket
int DHCPClientSendPacket(
int8_t *cszIfName,
uint8_t *data,
uint32_t len,
ipaddr source,
ipaddr dest
)
{
return (ZCOM_IGWSendPacket(cszIfName, data, len, htonl(source), htonl(dest))<0?FALSE:TRUE);
}
int32_t ZCOM_IGWSendPacket(int8_t *cszIfName, uint8_t *data,
uint32_t len, ipaddr source, ipaddr dest)
{
int32_t sd, index = 0, LpfSd, result=0, i=1;
uint8_t buff[1500];
struct sockaddr sa;
struct sockaddr_ll ll;
struct ifreq ifr;
struct hardware hfrom, hto;
memset(buff, 0, sizeof(buff));
memset(&ifr, 0, sizeof(ifr));
memset(&sa, 0, sizeof(sa));
memset(&hfrom, 0, sizeof(hfrom));
memset(&hto, 0, sizeof(hto));
memset(&ll, 0, sizeof(ll));
sd = socket(AF_INET, SOCK_DGRAM, 0);
GetHwAddr(hfrom.haddr, cszIfName);
hfrom.htype = 1;
hfrom.hlen = 6;
strcpy(ifr.ifr_name, cszIfName);
ioctl(sd, SIOCGIFFLAGS, &ifr);
close(sd);
if (dest> 0x0 && dest< BROADCAST_IP_ADDRESS)
{
hto.htype = 1;
hto.hlen = 6;
//memcpy(hto.haddr, g_DHCPClientBlock.serHwAddress, 6);
//send arp packet
while((result = DHCPClientSendArp(cszIfName,hfrom.haddr,hto.haddr,source,dest))<0 && i++<=3);
}
if (ARP_HAVE_SAME_ADDR == result)
{
IGWAssembleEthernetHeader(buff, &index, &hfrom, &hto);
}
else
{
IGWAssembleEthernetHeader(buff, &index, &hfrom, (struct hardware *)0); //broadcast
}
/*switch (g_DHCPClientBlock.CurrentState)
{
case DHCP_CLIENT_RENEW:
IGWAssembleEthernetHeader(buff, &index, &hfrom, &hto);
break;
default:
IGWAssembleEthernetHeader(buff, &index, &hfrom, (struct hardware *)0); //broadcast
break;
}*/
//IGWAssembleEthernetHeader(buff, &index, &hfrom, &hto);
IGWAssembleUdpIpHeader(buff, &index, source, dest, BOOTP_PORT,
data, len);
memcpy(buff+index, data, len);
memset(&sa, 0, sizeof(sa));
sa.sa_family = AF_PACKET;
ll.sll_family = AF_PACKET;
ll.sll_ifindex = getIndexByIfName(cszIfName);
printf("send packet index = %d\n", ll.sll_ifindex);
strncpy(sa.sa_data, (uint8_t *)&ifr, sizeof(sa.sa_data));
LpfSd = IGWCreateLpfSock(cszIfName);
//xhema result = sendto(LpfSd, buff, index+len, 0, (struct sockaddr *)&sa, sizeof(sa));
result = sendto(LpfSd, buff, index+len, 0, (struct sockaddr *)&ll, sizeof(ll));
close(LpfSd);
return result;
}
ArpReplyType_t DHCPClientSendArp(
char *cszIfName,
uint8_t *shaddr, //source hardware addr
uint8_t *thaddr,
ipaddr source,
ipaddr dest
)
{
struct arpheader arp,reparp;
struct ifreq ifr;
struct sockaddr sa;
struct sockaddr_ll ll;
uint8_t buff[1500];
int index=0,sd,result,LpfSd,arptype,htype,op,ethsize,arpsize;
struct ethhdr e,eh;
struct pollfd pfd[1];//wait response
memset(pfd, 0, sizeof(pfd));
memset(buff, 0, sizeof(buff));
memset(&arp, 0, sizeof(arp));
memset(&reparp, 0, sizeof(reparp));
memset(&ll, 0, sizeof(ll));
sd = socket(AF_INET, SOCK_DGRAM, 0);
strcpy(ifr.ifr_name, cszIfName);
ioctl(sd, SIOCGIFFLAGS, &ifr);
close(sd);
//adding eth header
memset(eh.h_dest, 0xff, 6);
memcpy(eh.h_source, shaddr, 6);
eh.h_proto = htons(0x0806);
memcpy(buff, &eh, sizeof(eh));
index += sizeof(eh);
//adding arp header
arp.ar_hrd = htons(ARPHRD_ETHER);
arp.ar_pro = htons(0x0800); //ip protocol
arp.ar_hlen = 6;
arp.ar_plen = 4;
arp.ar_op = htons(ARPOP_REQUEST);
memcpy(&arp.sha, shaddr, 6);
memcpy(&arp.sip, &source, 4);
memcpy(&arp.tip, &dest, 4);
memcpy(&buff[index], &arp, sizeof(arp));
index += sizeof(arp);
arptype = htons(0x0806);
htype = htons(ARPHRD_ETHER);
op = htons(ARPOP_REPLY);
ethsize = sizeof(e);
arpsize = sizeof(arp);
memset(&sa, 0, sizeof(sa));
strncpy(sa.sa_data, (char *)&ifr, sizeof(sa.sa_data));
ll.sll_family = AF_PACKET;
ll.sll_ifindex = getIndexByIfName(cszIfName);
if ((LpfSd=IGWCreateLpfSock(cszIfName))<0)
{
printf("send arp, create lpf socket error\n");
return ARP_ERROR;
}
pfd[0].fd = LpfSd;
pfd[0].events = POLLIN;
//xhema if ((result=sendto(LpfSd, buff, index, 0, &sa, sizeof(sa)))<0)
if ((result=sendto(LpfSd, buff, index, 0, (struct sockaddr *)&ll, sizeof(ll)))<0)
{
close(LpfSd);
perror("send lpf socket error");
return ARP_ERROR;
}
result = 0;
while (TRUE)
{
//wait arp reply
if (poll(pfd, 1, 1000)>0)
{
recvfrom(LpfSd, buff, 1500, 0, NULL, NULL);
if (result++>25)
{
return ARP_SUCCESS;
//printf("return successful\n");
//break;
}
memcpy(&e, buff, sizeof(e));
if (e.h_proto == arptype)
{
//copy arp header
memcpy(&reparp, &buff[ethsize], arpsize);
if (reparp.ar_hrd == htype && reparp.ar_op == op &&
!memcmp(&reparp.sip, &dest, 4))
{
//a pc have same ip addr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -