⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -