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

📄 dhcp_client.c

📁 wimax bs模拟器
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************\


			Copyright  (c)	2007,  UTStarcom,Inc. (ShenZhen R&D Center)
			All Rights Reserved.

			Subsystem		: WIMAX
			Group			: GW/AnchorEP/DHCP
			File				: dhcp_client.c
			Version			: 
			Build			: 
			Author			: kevin.shi
			Maintained by		: kevin.shi
			Create Date		: 2007-01-01
			Last Modify		: 
			Description		: DHCP clients sim
																			  
\******************************************************************************/
/*
-----------------------------------------------------------
Software Develop CodeName :

Module Reference :
	
-----------------------------------------------------------
Change History:

07-01.01	kevin.shi	create file.
*/

/* includes */

#include <stdio.h>
#include <stdlib.h>
#include <ioLib.h>
#include <socket.h>
#include <sockLib.h>
#include <inetLib.h>
#include <in.h>
#include <intLib.h>

#include "vxWorks.h"
#include "net/mbuf.h"
#include "net/protosw.h"
#include "sys/socket.h"
#include "net/socketvar.h"
#include "errno.h"

#include "net/if.h"
#include "net/route.h"

#include "netinet/in.h"
#include "netinet/in_pcb.h"
#include "netinet/in_systm.h"
#include "netinet/ip.h"
#include "netinet/in_var.h"
#include "netinet/ip_var.h"
#include "netinet/ip_icmp.h"
#include "netinet/udp.h"
#include "netinet/udp_var.h"
#include "net/systm.h"
#include "global.h"
#include "bs_common.h"

#include "dhcp_client.h"
#include "dhcp.h"
#include "dhcp_comm.h"
#include "gw_up_if.h"


#define DHCP_CLIENT_BINDING_MAX_NUM		2048
#define DHCP_CLIENT_RESOURCE_MAX_NUM 	DHCP_CLIENT_BINDING_MAX_NUM

#define DHCP_CLIENT_MSGQ_MSG_LEN		2048
#define DHCP_CLIENT_MSGQ_MSG_NUM		600
#define DHCP_CLIENT_TASK_PRIORITY		100
#define DHCP_CLIENT_TASK_STACK_SIZE	0x10000

#define DHCP_CLIENT_CID_HASH_LEN		1024
#define DHCP_CLIENT_HADDR_HASH_LEN 	DHCP_CLIENT_CID_HASH_LEN

/* DHCP client states */
#define  INIT         0
#define  WAIT_OFFER   1
#define  SELECTING    2
#define  REQUESTING   3
#define  BOUND        4
#define  RENEWING     5
#define  REBINDING    6
#define  INIT_REBOOT  7
/*#define  VERIFY       8*/
#define  REBOOTING    9
#define  VERIFYING   10
#define  INFORMING   11
#define  RENEW_RETRY 12
#define REBIND_RETRY 13
#define  MAX_STATES  REBIND_RETRY + 1

#define	MAX_MBUF_PEND	256
typedef struct SysUdpStat
{
	unsigned int		sysUdpInput;
	unsigned int		sysUdpInputRaw;
	unsigned int		sysUdpInputRawDiscard;
	unsigned int		sysUdpInputHooker;
	unsigned int		sysUdpInputHookerDiscard;

	unsigned int		sysUdpInputHookerCopy;
	unsigned int		sysUdpInputHookerNonCopy;
	unsigned int		sysUdpInputHookerPullup;
	unsigned int		sysUdpInputHookerPullFail;
	
	unsigned int		sysUdpOutput;
	unsigned int		sysUdpOutputSegment;
	unsigned int		sysUdpOutputDiscard;
	unsigned int		sysUdpOutputCacheRoute;
	unsigned int		sysUdpOutputFailed;

	unsigned int		sysIpOutput;
}St_SysUdpStat;
	
St_SysUdpStat gSysUdpStat;

/* vendor suboptions for UTStarcom */
#define UTS_PAD					0
#define UTS_OPERATOR_DOMAIN		1

#define MAX_DOMAIN_LEN			64
struct dhcp_domain
{
	int ref_cnt;
	char name[MAX_DOMAIN_LEN];
};


typedef struct dhcp_client_global_config
{
	int dhcpServerPort;		/* server port */
	int dhcpClientPort;		/* client port */
	int dhcpMaxMsgSize;		/* max msg size */
	
	unsigned int localIp;
	unsigned int serverIp;

	unsigned char domainName[DHCP_DOMAIN_NAME_MAX_LEN];

	/* some test control */
	unsigned char reqOrDiscover;
	unsigned char discoverWithBroadcast;
		
	unsigned char cidFlag;
	unsigned char haddrFlag;
	unsigned char reqListFlag;

	struct vendor_class_id vendor_id;
	struct user_class_id user_id;

	struct dhcp_domain domain;

	unsigned int subnet;
	unsigned int reqLease;
	unsigned short maxMsgSize;

	unsigned int reqListLen;
	unsigned char reqList[128];
}St_DhcpClientGlobalConfig;

St_DhcpClientGlobalConfig gDhcpClientGlobalConfig;

St_DhcpStat gDhcpClientStat;
St_DhcpRes	gDhcpClientRes[DHCP_CLIENT_RESOURCE_MAX_NUM];	
St_DhcpBinding	gDhcpClientBinding[DHCP_CLIENT_BINDING_MAX_NUM];
St_DhcpBinding_List	gDhcpClientBindFreeList;
St_DhcpBinding_List	gDhcpClientBindCidList[DHCP_CLIENT_CID_HASH_LEN];
St_DhcpBinding_List	gDhcpClientBindHaddrList[DHCP_CLIENT_HADDR_HASH_LEN];

int gDhcpClientTaskId;
int gDhcpTestTaskId;

MSG_Q_ID gDhcpClientMsgQId;

unsigned int rx_dhcpclentlen;
unsigned int gDhcpTestStop = 0;

GW_UP_DHCP_MSG gDhcpClientMsgOut; /* for out to dhcp server's msgQ as gw_up_dhcp_msg structure */
unsigned int gDhcpBroadcastIp = 0xffffffff;

struct msg dhcpcMsgIn;		/* rx dhcp msg */
struct ip *pIpOut;			/* point to gDhcpClientMsgOut.pktBuf[0] */
struct udphdr *pUdpOut;
struct dhcp *pDhcpcOut;		

unsigned int gDhcpTestDelayTime;
unsigned int gDhcpTestNum;

St_DhcpBinding *gpDhcpClientTestBinding = NULL;	

unsigned char dhcpCookie[] = RFC1048_MAGIC; /* DHCP message indicator. */

int gDhcpClientSubnet = 0;

int make_discover(St_DhcpBinding *pBinding);
int make_request(St_DhcpBinding * pBinding);
int make_decline(St_DhcpBinding * pBinding);
int make_release(St_DhcpBinding * pBinding);

extern unsigned char dhcpCookie[];
extern int get_cid (struct dhcp *, int, struct client_id *);
extern int get_haddr(struct dhcp *msg,struct chaddr *haddr);
extern int bindcidcmp(struct client_id * key, struct dhcp_binding *bp);
extern int bindhaddrcmp(struct chaddr *key, struct dhcp_binding *bp);

St_DhcpBinding* dhcp_client_alloc_binding();
int dhcp_client_free_binding(St_DhcpBinding *pBinding);

struct sockaddr_in gstAddrFrom;
struct sockaddr_in gstAddrTo;

char * gDhcpStateString[] = {
	"NULL",
	"ADFS_W4_INIT_DISCOVER",
	"ADFS_W4_INIT_OFFER",
	"ADFS_W4_INIT_REQUEST",
	"ADFS_W4_INIT_ACK",
	"ADFS_NORMAL",
	"ADFS_W4_NORMAL_ACK",
	NULL
};

char * gDhcpMsgString[] = {
	"BOOTP",
	"DHCPDISCOVER",
	"DHCPOFFER",
	"DHCPREQUEST",
	"DHCPDECLINE",
	"DHCPACK",
	"DHCPNAK",
	"DHCPRELEASE",
	"DHCPINFORM",
	NULL
};

char *gDhcpActingString[] = {
	"NULL"
	"Proxy",
	"Proxy_Lap",
	"Relay",
	NULL
};


#ifdef BSSIM_BINDED_2_GW
extern MSG_Q_ID g_msgq_gwcp;
#define AEP_MSG_Q_ID g_msgq_gwcp
#else
#define AEP_MSG_Q_ID NULL
#endif

#if (defined(_DHCP_DEBUG_ ) && defined(_DHCP_USING_PRIV_DEBUG_))
unsigned int gDhcpTraceLevel;
unsigned int gDhcpDumpLevel;
#endif

#ifdef _DHCP_USING_PRIV_DEBUG_
void dhcp_breakpoint()
{
	/* do nothing */
	return;
}
unsigned int gDhcpAssertDebug = 0;
void Dhcp_Exception_Handle()
{
	extern STATUS tt(int);
	if (gDhcpAssertDebug) {
		tt(0);
		ti(0);
		ts(0);
	}
	return ;
}

#endif


void CommUdpStat_Show(unsigned int clearFlag)
{
	printf("UDP Stat :\n");
	printf("sysUdpInput                %8d\n",gSysUdpStat.sysUdpInput);
	printf("sysUdpInputRaw             %8d\n",gSysUdpStat.sysUdpInputRaw);
	printf("sysUdpInputRawDiscard      %8d\n",gSysUdpStat.sysUdpInputRawDiscard);
	printf("sysUdpInputHooker          %8d\n",gSysUdpStat.sysUdpInputHooker);
	printf("sysUdpInputHookerDiscard   %8d\n",gSysUdpStat.sysUdpInputHookerDiscard);
	printf("sysUdpInputHookerCopy      %8d\n",gSysUdpStat.sysUdpInputHookerCopy);
	printf("sysUdpInputHookerNonCopy   %8d\n",gSysUdpStat.sysUdpInputHookerNonCopy);
	printf("sysUdpInputHookerPullup    %8d\n",gSysUdpStat.sysUdpInputHookerPullup);
	printf("sysUdpInputHookerPullFail  %8d\n",gSysUdpStat.sysUdpInputHookerPullFail);
	printf("\n");
	printf("sysUdpOutput               %8d\n",gSysUdpStat.sysUdpOutput);
	printf("sysUdpOutputSegment        %8d\n",gSysUdpStat.sysUdpOutputSegment);
	printf("sysUdpOutputDiscard        %8d\n",gSysUdpStat.sysUdpOutputDiscard);
	printf("sysUdpOutputCacheRoute     %8d\n",gSysUdpStat.sysUdpOutputCacheRoute);
	printf("sysUdpOutputFailed         %8d\n\n",gSysUdpStat.sysUdpOutputFailed);
	printf("\n");
	printf("sysIpOutput                %8d\n",gSysUdpStat.sysIpOutput);
	
	if (clearFlag) {
		bzero((void *)&gSysUdpStat,sizeof(gSysUdpStat));
	}

	return ;

}


/* called by bsd_udp_output
    support ip segmentation
*/
int
bsd_ip_output(struct mbuf *m0)
{
	struct ip *ip, *mhip;
	struct ifnet *ifp;
	struct mbuf *m = m0;
	struct sockaddr_in *dst;
	struct in_ifaddr *ia;
	int hlen = sizeof (struct ip);
	int len, off, error = 0;
	struct route *ro;
	struct route iproute;

	ip = mtod(m, struct ip *);
	/*
	 * Fill in IP header.
	 */
	ip->ip_v = IPVERSION;
	ip->ip_off &= IP_DF;
	ip->ip_id = htons(ip_id++);
	ip->ip_hl = hlen >> 2;

	/*
	 * Route packet.
	 */
	ro = &iproute;
	bzero((caddr_t)ro, sizeof (*ro));

	dst = (struct sockaddr_in *)&ro->ro_dst;
	dst->sin_family = AF_INET;
	dst->sin_len = sizeof(*dst);
	dst->sin_addr = ip->ip_dst;
	TOS_SET (dst, ip->ip_tos);

	/*
	 * If routing to interface only,
	 * short circuit routing lookup.
	 */
#define ifatoia(ifa)	((struct in_ifaddr *)(ifa))
#define sintosa(sin)	((struct sockaddr *)(sin))

	/*
	 * Ip route lookup
	 */
	rtalloc(ro);
	if (0 == ro->ro_rt) {
		ipstat.ips_noroute++;
		error = EHOSTUNREACH;
		goto bad;
	}

	ia = ifatoia(ro->ro_rt->rt_ifa);
	ifp = ro->ro_rt->rt_ifp;
	ro->ro_rt->rt_use++;
	if (ro->ro_rt->rt_flags & RTF_GATEWAY)
		dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;

	/*
	 * If source address not specified yet, use address
	 * of outgoing interface.
	 */
	if (ip->ip_src.s_addr == INADDR_ANY)
		ip->ip_src = IA_SIN(ia)->sin_addr;

	/*
	 * Look for broadcast address and
	 * and verify user is allowed to send
	 * such a packet.
	 */
	m->m_flags &= ~M_BCAST;

	if (ifp->if_snd.ifq_len >= MAX_MBUF_PEND) {
		error = ENOBUFS;
		gSysUdpStat.sysUdpOutputDiscard++;
		goto bad;
	}

sendit:
	/*
	 * If small enough for interface, can just send directly.
	 */
	if ((u_short)ip->ip_len <= ifp->if_mtu) {
		ip->ip_len = htons((u_short)ip->ip_len);
		ip->ip_off = htons((u_short)ip->ip_off);

		ip->ip_sum = 0;
		ip->ip_sum = in_cksum(m, hlen);

		error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, ro->ro_rt);

		gSysUdpStat.sysIpOutput++;
		
		goto done;
	}

	gSysUdpStat.sysUdpOutputSegment++;
	/*
	 * Too large for interface; fragment if possible.
	 * Must be able to put at least 8 bytes per fragment.
	 */
	if (ip->ip_off & IP_DF) {
		error = EMSGSIZE;
		ipstat.ips_cantfrag++;
		goto bad;
	}
	len = (ifp->if_mtu - hlen) &~ 7;
	if (len < 8) {
		error = EMSGSIZE;
		goto bad;
	}

	if (1) {
		int mhlen, firstlen = len;
		struct mbuf **mnext = &m->m_nextpkt;

		/*
		 * Loop through length of segment after first fragment,
		 * make new header and copy data of each part and link onto chain.
		 */
		m0 = m;
		mhlen = sizeof (struct ip);
		for (off = hlen + len; off < (u_short)ip->ip_len; off += len) {
			m = mHdrClGet(M_DONTWAIT, MT_HEADER, CL_SIZE_128, TRUE);
			if (m == 0) {
				error = ENOBUFS;
				ipstat.ips_odropped++;
				goto sendorfree;
			}
			m->m_flags = m0->m_flags;
			m->m_data += max_linkhdr;
			mhip = mtod(m, struct ip *);
			*mhip = *ip;
			if (hlen > sizeof (struct ip)) {
				mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
				mhip->ip_hl = mhlen >> 2;
			}
			m->m_len = mhlen;
			mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
			if (ip->ip_off & IP_MF)
				mhip->ip_off |= IP_MF;
			if (off + len >= (u_short)ip->ip_len)
				len = (u_short)ip->ip_len - off;
			else
				mhip->ip_off |= IP_MF;
			mhip->ip_len = htons((u_short)(len + mhlen));
			m->m_next = m_copy(m0, off, len);
			if (m->m_next == 0) {
				(void) m_free(m);
				error = ENOBUFS;	/* ??? */
				ipstat.ips_odropped++;
				goto sendorfree;
			}
			m->m_pkthdr.len = mhlen + len;
			m->m_pkthdr.rcvif = (struct ifnet *)0;
			mhip->ip_off = htons((u_short)mhip->ip_off);

			mhip->ip_sum = 0;
			mhip->ip_sum = in_cksum(m, mhlen);

			*mnext = m;
			mnext = &m->m_nextpkt;
			ipstat.ips_ofragments++;
		}
		/*
		 * Update first fragment by trimming what's been copied out

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -