📄 dhcp.c
字号:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "bepcommon.h"
#include "h/drv/eeprom/BackPane.h"
#include "dhcp.h"
#include "routeLib.h"
#include "etherLib.h"
#include "pgi_ifLib.h"
static s_dhcppacket dhcppacket;
static s_dhcppacket recv_packet;
static MACADD mac_addr;
static unsigned int client_xid;
static struct sockaddr_in server_addr;
static struct sockaddr_in client_addr;
static unsigned int dhcp_lease; /* 服务器分配的IP租期 */
/**
* 网络字节顺序的IP地址
*/
static unsigned int dhcp_server; /* DHCP服务器地址 */
static unsigned int dhcp_allocated; /* 分配的IP地址 */
static unsigned int dhcp_mask; /* 子网掩码 */
static unsigned int dhcp_router; /* 路由 */
static int renew_task_id = 0;
SEM_ID dhcpClientSem;
int DhcpAllocate()
{
char data[16];
int result;
semTake(dhcpClientSem, WAIT_FOREVER);
if (GetMACAddress(0, (char *)&mac_addr) == 0)
{
semGive(dhcpClientSem);
return ERROR;
}
if (renew_task_id != 0)
{
taskDelete(renew_task_id);
}
if ((result = RequestNewAddr()) != DHCP_OK)
{
fprintf(stderr, "GetDhcpConf error\n");
semGive(dhcpClientSem);
return ERROR;
}
if (ifMaskSet(LOCAL_IF0, ntohl(dhcp_mask)) != OK)
{
perror("DHCP: Unable to set netMask\n" );
semGive(dhcpClientSem);
return (ERROR);
}
phoneconfig.conf_network.subnetmask = ntohl(dhcp_mask);
memset(data, 0, 16);
ConvertInt2CharNum(data, ntohl(dhcp_allocated), 2);
if (ifAddrSet(LOCAL_IF0, data) != OK)
{
perror("DHCP: Unable to set IP addr\n");
semGive(dhcpClientSem);
return (ERROR);
}
phoneconfig.conf_network.ipaddr = ntohl(dhcp_allocated);
routeDelete("0.0.0.0", "0.0.0.0");
/*routeAdd(data, "127.0.0.1");*/
memset(data, 0, 16);
ConvertInt2CharNum(data, ntohl(dhcp_router),2);
if (routeAdd("0.0.0.0", data) != OK)
{
perror("H323Init: Unable to add route\n" );
semGive(dhcpClientSem);
return (ERROR);
}
phoneconfig.conf_network.gateway = ntohl(dhcp_router);
renew_task_id = taskSpawn( "tDhcpRenew",150,0,4096,(FUNCPTR)RenewDhcpLease,0,0,0,0,0,0,0,0,0,0);
printf("DHCP: OK\n");
semGive(dhcpClientSem);
return OK;
}
int readable_timeo(int fd, int sec)
{
fd_set rset;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(fd, &rset);
tv.tv_sec = sec;
tv.tv_usec = 0;
return select(fd + 1, &rset, NULL, NULL, &tv);
}
int SendIPBroadcast()
{
int i;
unsigned short checksum, tmp;
struct ifnet * pIf;
struct ether_header MAC_Header;
unsigned char ippacket[IP_HEADER_LEN + UDP_HEADER_LEN + DHCP_MIN_LEN] = {
0x45, 0,
(IP_HEADER_LEN + UDP_HEADER_LEN + DHCP_MIN_LEN) >> 8,
(unsigned char) (IP_HEADER_LEN + UDP_HEADER_LEN + DHCP_MIN_LEN),
0, 0, 0, 0,
0x40, 0x11, 0x78, 0xae,
0, 0, 0, 0,
0xff, 0xff, 0xff, 0xff,
DHCP_CLIENT_PORT >> 8,
(unsigned char) DHCP_CLIENT_PORT,
DHCP_SERVER_PORT >> 8,
(unsigned char) DHCP_SERVER_PORT,
(UDP_HEADER_LEN + DHCP_MIN_LEN) >> 8,
(unsigned char) (UDP_HEADER_LEN + DHCP_MIN_LEN),
0,
0
};
if ((pIf = ifunit(LOCAL_IF0)) == NULL)
{
perror("error getting ifUnit");
return DHCP_ERROR;
}
memcpy(&MAC_Header.ether_shost, &mac_addr, ETHER_ADDR_LEN);
memset(&MAC_Header.ether_dhost, 0xff, ETHER_ADDR_LEN);
MAC_Header.ether_type = ETH_IP;
memcpy(ippacket + IP_HEADER_LEN + UDP_HEADER_LEN, &dhcppacket, DHCP_MIN_LEN);
if (etherOutput(pIf, &MAC_Header, ippacket, sizeof(ippacket)) != OK)
{
perror("ether output");
return DHCP_ERROR;
}
return DHCP_OK;
}
/**
* init client socket and bind to port 68
*/
int InitDhcpClientSock(void)
{
int sockfd;
int yes = 1;
int addrLen = sizeof(struct sockaddr_in);
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
return DHCP_ERROR;
}
memset((void *) &client_addr, 0, addrLen);
client_addr.sin_len = addrLen;
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(DHCP_CLIENT_PORT);
client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof(yes)) < 0)
{
perror("reuseaddr");
close(sockfd);
return DHCP_ERROR;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *) &yes, sizeof(yes)) < 0)
{
perror("broadcast");
close(sockfd);
return DHCP_ERROR;
}
if (bind(sockfd, (struct sockaddr *) &client_addr, sizeof(struct sockaddr)) < 0)
{
perror("bind");
close(sockfd);
return DHCP_ERROR;
}
return sockfd;
}
void InitDhcpServerAddr(unsigned char broadcast)
{
char data[16];
/**
* init server address
*/
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_len = sizeof(struct sockaddr_in);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(DHCP_SERVER_PORT);
server_addr.sin_addr.s_addr = broadcast ? htonl(INADDR_BROADCAST) : dhcp_server;
}
int InitDhcpPacket(unsigned char msgtype, unsigned char broadcast)
{
int offset = 4;
bzero((void *) &dhcppacket, sizeof(dhcppacket));
dhcppacket.op = BOOT_REQUEST;
dhcppacket.htype = HTYPE_ETHER;
dhcppacket.hlen = ETHER_ADDR_LEN;
dhcppacket.xid = client_xid;
if (broadcast)
{
memcpy(dhcppacket.flags, FLAG_BROADCAST, 2);
}
memcpy(dhcppacket.chaddr, mac_addr.MACByte, ETHER_ADDR_LEN);
/* Option Cookie */
memcpy(dhcppacket.options, DHCP_OPTIONS_COOKIE, 4);
/* Message Type Option */
dhcppacket.options[offset++] = DHCP_MSGTYPE_OPTION;
dhcppacket.options[offset++] = 1;
dhcppacket.options[offset++] = msgtype;
/* Maximum DHCP Message Size 576 */
/*
dhcppacket.options[offset++] = DHCP_MAXSIZE_OPTION;
dhcppacket.options[offset++] = 2;
dhcppacket.options[offset++] = DHCP_MAX_SIZE >> 8;
dhcppacket.options[offset++] = (unsigned char) DHCP_MAX_SIZE;
*/
/* Client-identifier htype + haddr */
dhcppacket.options[offset++] = DHCP_CLIENTID_OPTION;
dhcppacket.options[offset++] = ETHER_ADDR_LEN + 1;
dhcppacket.options[offset++] = HTYPE_ETHER;
memcpy(dhcppacket.options + offset, mac_addr.MACByte, ETHER_ADDR_LEN);
offset += ETHER_ADDR_LEN;
if (phoneconfig.conf_basic.linename[0] != 0)
{
char tempName[25];
strncpy(tempName, phoneconfig.conf_basic.linename, 14);
tempName[14] = '\0';
sprintf(tempName, "%s.bp8805h", tempName);
dhcppacket.options[offset++] = DHCP_HOST_NAME;
dhcppacket.options[offset++] = strlen(tempName);
memcpy(dhcppacket.options + offset, tempName, strlen(tempName)*sizeof(char));
offset += sizeof(tempName);
}
/* Parameter Request List */
dhcppacket.options[offset++] = DHCP_REQPARAM_OPTION;
dhcppacket.options[offset++] = 2;
dhcppacket.options[offset++] = DHCP_SUBMASK_OPTION;
dhcppacket.options[offset++] = DHCP_ROUTER_OPTION;
return offset;
}
int ParseDhcpOption()
{
int offset = 4;
int len = 0;
unsigned char tag;
int ret = DHCP_ERROR;
dhcp_allocated = recv_packet.yiaddr.s_addr;
while (((tag = recv_packet.options[offset++]) != DHCP_END_OPTION) &&
(offset <= DHCP_OPTION_LEN))
{
printf("DHCP: Option tag -- %u\n", tag);
switch (tag)
{
case DHCP_LEASE_OPTION:
len = recv_packet.options[offset++];
memcpy((void *) &dhcp_lease, &recv_packet.options[offset], 4);
dhcp_lease = ntohl(dhcp_lease);
offset += len;
break;
case DHCP_MSGTYPE_OPTION:
len = recv_packet.options[offset++];
ret = recv_packet.options[offset++];
break;
case DHCP_SUBMASK_OPTION:
len = recv_packet.options[offset++];
memcpy((void *) &dhcp_mask, &recv_packet.options[offset], 4);
offset += len;
break;
case DHCP_ROUTER_OPTION:
len = recv_packet.options[offset++];
memcpy((void *) &dhcp_router, &recv_packet.options[offset], 4);
offset += len;
break;
case DHCP_SERVERID_OPTION:
len = recv_packet.options[offset++];
memcpy((void *) &dhcp_server, &recv_packet.options[offset], 4);
offset += len;
break;
case 0:
offset++;
break;
default:
len = recv_packet.options[offset++];
offset += len;
break;
}
}
printf("DHCP: Parse Option -- %d\n", ret);
if (offset > DHCP_OPTION_LEN)
{
return DHCP_ERROR;
}
else
{
return ret;
}
}
int RequestNewAddr()
{
int sockfd;
unsigned short retry = 0;
int result = DHCP_ERROR;
if ((sockfd = InitDhcpClientSock()) == DHCP_ERROR)
{
return DHCP_ERROR;
}
client_xid = htonl(rand());
while (retry < 2)
{
if ((result = DoDhcpDiscover(sockfd)) == DHCP_RETRY)
{
retry++;
continue;
}
else if (result != DHCP_OK)
{
break;
}
if ((result = DoDhcpRequest(sockfd)) == DHCP_RETRY)
{
retry++;
}
else
{
break;
}
}
printf("DHCP: Request New Addr -- %d\n", result);
close(sockfd);
return result;
}
int DoDhcpDiscover(int sockfd)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -