?? dhcpc.c
字號:
//dhcpc.c
//
/************************************
* Include files
***********************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h> //for time
#include <fcntl.h> //for O_RDWR,open
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> //for inet_ntoa, inet_aton
#include <sys/ioctl.h>
#include <sys/poll.h> //for poll
#include <linux/if.h> //for ifreq
#include <linux/route.h>
#include <unistd.h> //for close
#include <features.h> /* for the glibc version number */
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h> /* the L2 protocols */
#else
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* The L2 protocols */
#endif
#include "dhcpc.h"
#define INVALID_SOCKET_HANDLE -1
#define closesocket close
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif//!INVALID_SOCKET
#define UDP_HDRLEN sizeof(struct udphdr)
#define IGW_BUFGET16(cp) \
(((unsigned short)(*(char *)(cp)) << 8 & 0xFF00) | (*((char *)(cp) + 1) & 0xFF))
typedef int SOCKET;
static int g_dcskfd =INVALID_SOCKET_HANDLE;
static SOCKET s_iConfigClientSocket = INVALID_SOCKET;
static SOCKET s_iConfigServerSocket = INVALID_SOCKET;
int32_t Fds_To_Poll = MAX_FDS_TOPOLL - 1;
SOCKET s_iDCSocket = INVALID_SOCKET;
uint32_t CurrentTime = 0;
uint32_t g_uiStartLeaseTime = 0;
static struct sockaddr_in s_DhcpClientAddr= {0};
static struct sockaddr_in s_DhcpServerAddr = {0};
DHCPCIpAddressInfo_t DHCPCIpAddressInfo;
DHCPClientBlock_t *pDHCPClientCtxtBlockHead = NULL;
DHCPClientBlock_t *pDHCPClientCtxtBlockTail = NULL;
DHCPClientBlock_t *g_pDHCPClientCurrent = NULL; /* point to current interface*/
DHCPWAITEvent_t *pDHCPClientTimerHead = NULL;
DHCPWAITEvent_t *pDHCPClientTimerTail = NULL;
DHCPWAITEvent_t *pDHCPClientTimerCurrent = NULL;
struct DHCPClientFunctions DHCPCFunctionInfo;
struct dhcp_packet DhClientRequestPkt;
struct pollfd DHCPClientPollFds[MAX_FDS_TOPOLL];
struct sockaddr_in *DhcpClientAddr= NULL;
void DHCPClientPrintAllTransActionId(void);
static void ZComIOControlClose(void)
{
if (INVALID_SOCKET_HANDLE!=g_dcskfd)
{
close(g_dcskfd);
g_dcskfd = INVALID_SOCKET_HANDLE;
}
}
int ZComIOControl(int request, void* pData)
{
if (INVALID_SOCKET_HANDLE==g_dcskfd)
{
static int fIsFirstOpen = 1;
g_dcskfd = socket(AF_INET, SOCK_DGRAM, 0);
if (INVALID_SOCKET_HANDLE==g_dcskfd)
{
printf("%s: socket error!\n", __FUNCTION__);
return -1;
}
if (fIsFirstOpen)
{
fIsFirstOpen = 0;
atexit(ZComIOControlClose);
}
}
return ioctl(g_dcskfd, request, pData);
}
///////////////////////////////////////////////////////////////////////////////
// ifconfig routines
///////////////////////////////////////////////////////////////////////////////
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
bool_t IsInterfaceUp(const char *cszIfName)
{
struct ifreq ifr = {{{0}}};
strncpy(ifr.ifr_name, cszIfName, IFNAMSIZ);
if (ZComIOControl(SIOCGIFFLAGS, &ifr)>=0)
{
return (IFF_UP | IFF_RUNNING)
== (ifr.ifr_flags & (IFF_UP | IFF_RUNNING));
}
//printf("Iface: %s not exist!\n", cszIfName);
return FALSE;
}
static bool_t InterfaceSockaddrSet(
const char *cszIfName,
in_addr_t in_addr,
int request)
{
struct ifreq ifr = {{{0}}};
struct sockaddr_in *pSockAddr = (struct sockaddr_in *)&ifr.ifr_addr;
strncpy(ifr.ifr_name, cszIfName, IFNAMSIZ);
pSockAddr->sin_family = AF_INET;
pSockAddr->sin_addr.s_addr = in_addr;
return ZComIOControl(request, &ifr)>=0;
}
#if 0
static in_addr_t InterfaceSockaddrGet(const char *cszIfName, int request)
{
struct ifreq ifr = {{{0}}};
struct sockaddr_in *pSockAddr = (struct sockaddr_in *)&ifr.ifr_addr;
strncpy(ifr.ifr_name, cszIfName, IFNAMSIZ);
pSockAddr->sin_family = AF_INET;
if (ZComIOControl(request, &ifr)>=0
&& AF_INET==pSockAddr->sin_family)
{
return pSockAddr->sin_addr.s_addr;
}
return INADDR_ANY;
}
#endif
void GetHostName(char *str)
{
if (0 != gethostname(str, 100))
{
str[0] = '\0';
}
}
int DHCPClientGetLeaseTime(uint32_t *pReqLease)
{
*pReqLease = 100;//60*24*60*60; //Lease time
return TRUE;
}
void TimerStart(DHCPWAITEvent_t *p, uint32_t iTimeoutTime, enum WaitEventType EventType)
{
if (NULL == p)
{
return;
}
if (0!= iTimeoutTime)
{
time((time_t *)&(p->iWaitStartTime));
p->iWaitTimeOutTime = iTimeoutTime;
}
#ifdef XHEMA_DEBUG
printf("Timeout start : %s\n", p->pPointToBlock->cszIfName);
#endif
p->EventType = EventType;
p->bStartWaitEvent = TRUE;
}
void TimerStop(DHCPWAITEvent_t *p)
{
if (NULL == p)
{
return;
}
p->bStartWaitEvent = FALSE;
}
//Enable DHCP client and listen at 68 port(DHCP client)
int32_t DHCPClientActiveSocketFd(int32_t bActive)
{
int32_t iSockFd = 0;
if (bActive)
{
if ((iSockFd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)))<0)
{
perror("create lpf socket error");
return FALSE;
}
s_iDCSocket = iSockFd;
Fds_To_Poll = MAX_FDS_TOPOLL;
DHCPClientPollFds[1].fd = s_iDCSocket;
DHCPClientPollFds[1].events = POLLIN;
return TRUE;
}
else
{
if (s_iDCSocket)
{
close(s_iDCSocket);
s_iDCSocket = 0;
Fds_To_Poll = MAX_FDS_TOPOLL - 1;
}
}
return TRUE;
}
void Daemon_Init(bool_t fVerbose)
{
#if 1
if (fVerbose)
{
daemon(0, 1);
}
else
{
daemon(0, 0);
}
#else
int devnullfd;
chdir ("/");
switch (fork() )
{
case -1:
printf("Daemon_Init: error in fork\r\n");
exit(1);
case 0: /** Child **/
break;
default:
/** Parent **/
exit(0);
}
if ( setsid() == -1 )
{
printf("Daemon_Init: setsid error\r\n");
exit(1);
}
devnullfd = open("/dev/null", O_RDWR);
if ( devnullfd == -1 )
{
printf("Null device open failed\r\n");
return;
}
close(0);
close(1);
close(2);
dup2(devnullfd, 0);
dup2(devnullfd, 1);
dup2(devnullfd, 2);
close(devnullfd);
return;
#endif
}
uint32_t checksum (uint8_t *buf,int nbytes,uint32_t sum)
{
int i;
/* Checksum all the pairs of bytes first */
for (i = 0; i < (nbytes & ~1); i += 2) {
sum += (uint16_t) ntohs(*((uint16_t *)(buf + i)));
/* Add carry. */
if (sum > 0xFFFF)
sum -= 0xFFFF;
}
/* If there's a single byte left over, checksum it, too. Network
byte order is big-endian, so the remaining byte is the high byte. */
if (i < nbytes) {
sum += buf [i] << 8;
/* Add carry. */
if (sum > 0xFFFF)
sum -= 0xFFFF;
}
return sum;
}
uint32_t wrapsum (uint32_t sum)
{
sum = ~sum & 0xFFFF;
return htons(sum);
}
void GetHwAddr(uint8_t *hw, const char *cszIfName)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof ifr);
strcpy(ifr.ifr_name, cszIfName);
if (ZComIOControl(SIOCGIFHWADDR,&ifr)<0)
{
printf("Error In Getting The HWADDR fron Iface %s\n",cszIfName);
return;
}
memcpy(hw,ifr.ifr_addr.sa_data,6);
return;
}
int getIndexByIfName(const char *cszIfName)
{
struct ifreq ifr;
int32_t fd, iResult ;
if((fd = socket(PF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket failed");
return -1 ;
}
/*fill the given index value to get the Ifacename. */
strcpy(ifr.ifr_name, cszIfName);
if((iResult = ioctl(fd,SIOCGIFINDEX,&ifr)) < 0)
{
close(fd);
return -1 ;
}
close(fd);
return ifr.ifr_ifindex;
}
bool_t getIfNamebyIndex(int index, char *pIfName)
{
struct ifreq ifr;
int32_t fd, iResult ;
if((fd = socket(PF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket failed");
return FALSE ;
}
/*fill the given index value to get the Ifacename. */
ifr.ifr_ifindex=index;
if((iResult = ioctl(fd,SIOCGIFNAME,&ifr)) < 0)
{
close(fd);
return FALSE ;
}
strcpy(pIfName, ifr.ifr_name);
close(fd);
return TRUE;
}
void IGWAssembleEthernetHeader (
uint8_t *buf,
int *bufix,
struct hardware *from,
struct hardware *to
)
{
struct ethhdr eh;
if (to && to -> hlen == 6)
{
//memcpy(eh.h_dest, to->haddr, 6); /*xhema */
memset(eh.h_dest,0xff, 6);
}
else
{
memset(eh.h_dest,0xff, 6);
}
memcpy(eh.h_source,from->haddr,6);
eh.h_proto = htons(0x800);
memcpy(buf, &eh, sizeof(eh));
*bufix += sizeof eh;
}
void IGWAssembleUdpIpHeader(uint8_t *buf, int32_t *bufix, ipaddr from,
ipaddr to,int32_t port,uint8_t *data,int32_t len)
{
struct iphdr iphdr;
struct udphdr udp;
/* Fill out the IP header */
#if defined RUNONPC
iphdr.ver = 5;
iphdr.hlen = 4;
#else
iphdr.ver = 4;
iphdr.hlen = 5;
#endif
iphdr.tos = IPTOS_LOWDELAY;
iphdr.tot_len = htons(sizeof(iphdr) + sizeof(udp) + len);
iphdr.id = 0;
iphdr.frag_off = 0;
iphdr.ttl = 16;
iphdr.protocol = IPPROTO_UDP;
iphdr.check = 0;
iphdr.saddr = from;
iphdr.daddr = to;
/* Checksum the IP header */
iphdr.check = wrapsum (checksum ((uint8_t *)&iphdr, sizeof(iphdr), 0));
/* Copy the ip header into the buffer... */
memcpy(&buf[*bufix], &iphdr, sizeof(iphdr));
//memcpy(buf+*bufix, &iphdr, sizeof(iphdr));
*bufix += sizeof(iphdr);
/* Fill out the UDP header */
udp.source = htons(BOOTP_PORT + 1); /* XXX */
udp.dest = htons(port); /* XXX */
udp.len = htons(sizeof(udp) + len);
memset (&udp.check, 0, sizeof(udp.check));
/* Compute UDP checksums, including the ``pseudo-header'', the UDP
header and the data. */
udp.check = wrapsum (checksum ((uint8_t *)&udp, sizeof udp,checksum (data, len,checksum ((uint8_t *)&iphdr.saddr,2 * sizeof(iphdr.saddr),IPPROTO_UDP + (uint32_t)ntohs (udp.len)))));
//printf("udp source = %d udp dest = %d udp len =%d
/* Copy the udp header into the buffer */
memcpy (&buf[*bufix], &udp, sizeof udp);
*bufix += sizeof udp;
}
//////////////////////////////////////////////////////////////////
// DHCP protocol
//////////////////////////////////////////////////////////////////
void DHCPCAddOptionsToPkt(
uint8_t *caSendingPkt,
DHCPClientBlock_t *pCurCtxtBlock,
uint32_t *ulTotLength,
uint8_t ucDHCPMsgType
)
{
uint8_t *PktPos;
ipaddr iTmpAddr;
PktPos = caSendingPkt + *ulTotLength;
memcpy(PktPos, DHCP_OPTIONS_COOKIE, 4);
PktPos += 4;
*ulTotLength += 4;
*PktPos++ = DHCP_MESSAGE_TYPE;
*PktPos++ = DHCP_MESSAGE_OPTION_LEN;
if (ucDHCPMsgType == DHCPDISCOVER)
{
*PktPos++ = DHCPDISCOVER;
}
else
{
*PktPos++ = DHCPREQUEST;
}
*ulTotLength += 3;
if (pCurCtxtBlock->CurrentState == DHCP_CLIENT_REQUEST)
{
if (pCurCtxtBlock->DHCPServerIpAddr>0)
{
*PktPos++ = DHO_DHCP_SERVER_IDENTIFIER;
*PktPos++ = sizeof(ipaddr);
*ulTotLength += 2;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -