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

📄 slp_dhcp.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 2 页
字号:
	*hlen = 0;		sin = (struct sockaddr_in *)&arpreq.arp_pa;	memset(sin, 0, sizeof(struct sockaddr_in));	sin->sin_family = AF_INET;	memcpy(&sin->sin_addr, ipaddr, sizeof(struct in_addr));		if (ioctl(sockfd, SIOCGARP, &arpreq) >= 0 			&& (arpreq.arp_flags & ATF_COM))	{		*hlen = 6;	/* assume IEEE802 compatible */		*htype = arpreq.arp_ha.sa_family;		memcpy(chaddr, arpreq.arp_ha.sa_data, 6);	}	closesocket(sockfd);#else	/* figure out another way ... */	(void)ipaddr;	(void)chaddr;	(void)htype;	*hlen = 0;#endif	return *hlen? 0: -1;}/*=========================================================================*/ int DHCPGetOptionInfo(unsigned char *dhcpOptCodes, int dhcpOptCodeCnt, 		DHCPInfoCallBack *dhcpInfoCB, void *context)/* Calls dhcpInfoCB once for each requested option in dhcpOptCodes.	Returns  -    	zero on success, non-zero on failure	errno         	ENOTCONN error during read               	ETIME read timed out               	ENOMEM out of memory               	EINVAL parse error	BOOTP/DHCP packet header format:	Offs	Len	Name		Description	0		1		opcode	Message opcode: 1 = BOOTREQUEST, 2 = BOOTREPLY	1		1		htype		Hardware address type (eg., 1 = 10mb ethernet)	2		1		hlen		Hardware address length (eg., 6 = 10mb ethernet)	3		1		hops		Client sets to zero, optionally used by relay agents	4		4		xid		Transaction ID, random number chosen by client	8		2		secs		Client sets to seconds since start of boot process	10		2		flags		Bit 0: broadcast response bit	12		4		ciaddr	Client IP address - only filled if client is bound	16		4		yiaddr	'your' (Client) IP address	20		4		siaddr	IP address of next server to use in bootstrap	24		4		giaddr	Relay agent IP address, used in booting via RA	28		16		chaddr	Client hardware address	44		64		sname		Optional server host name, null-terminated string	108	128	file		Boot file name, null-terminated string	236	var	options	Optional parameters field	The options field has the following format:	Offs	Len	Name		Description	0		4		cookie	4-byte cookie field: 99.130.83.99 (0x63825363)		Followed by 1-byte option codes and 1-byte option lengths, except	for the two special fixed length options, pad (0) and end (255).	Options are defined in slp_dhcp.h as TAG_XXX values. The two we	really care about here are options TAG_SLP_DA and TAG_SLP_SCOPE,	78 and 79, respectively. 		The format for TAG_SLP_DA (starting with the tag) is:		Offs	Len	Name		Description	0		1		tag		TAG_SLP_DA - directory agent ip addresses	1		1		length	length of remaining data in the option	2		1		mand		flag: the use of these DA's is mandatory	3		4		a(0)		4-byte ip address	...	3+n*4	4		a(n)		4-byte ip address	The format for TAG_SLP_SCOPE (starting with the tag) is:	Offs	Len	Name		Description	0		1		tag		TAG_SLP_SCOPE - directory scopes to use	1		1		length	length of remaining data in the option	2		1		mand		flag: the use of these scopes is mandatory	3		var	scopes	a null-terminated, comma-separated string of scopes	The "DHCP Message Type" option must be included in every DHCP message.	All tags except for TAG_PAD(0) and TAG_END(255) begin with a tag value	followed by a length of remaining data value.   =========================================================================*/ {	UINT32 xid;	time_t timer;	struct timeval tv;	int sockfd, retries;	struct sockaddr_in sendaddr;	unsigned char chaddr[MAX_MACADDR_SIZE];	unsigned char hlen, htype;	unsigned char sndbuf[512];	unsigned char rcvbuf[512];	struct hostent *hep;	unsigned char *p;	size_t rcvbufsz = 0;	char host[256];	/* Get our IP and MAC addresses */	if(gethostname(host, (int)sizeof(host))			|| !(hep = gethostbyname(host))			|| dhcpGetAddressInfo((unsigned char *)hep->h_addr, 					chaddr, &hlen, &htype))		return -1;	/* get a reasonably random transaction id value */	xid = (UINT32)time(&timer);	/* BOOTP request header */	memset(sndbuf, 0, 236);		/* clear bootp header */	p = sndbuf;	*p++ = BOOTREQUEST;			/* opcode */	*p++ = htype;	*p++ = hlen;	p++;								/* hops */	ToUINT32(p, xid);	p += 2 * sizeof(UINT32);	/* xid, secs, flags */	memcpy(p, hep->h_addr, 4);	p += 4 * sizeof(UINT32);	/* ciaddr, yiaddr, siaddr, giaddr */	memcpy(p, chaddr, hlen);	p += 16 + 64 + 128;			/* chaddr, sname and file */	*p++ = DHCP_COOKIE1;			/* options, cookies 1-4 */	*p++ = DHCP_COOKIE2;	*p++ = DHCP_COOKIE3;	*p++ = DHCP_COOKIE4;	/* DHCP Message Type option */	*p++ = TAG_DHCP_MSG_TYPE;	*p++ = 1;						/* option length */	*p++ = DHCP_MSG_INFORM;		/* message type is DHCPINFORM */	/* DHCP Parameter Request option */	*p++ = TAG_DHCP_PARAM_REQ;	/* request for DHCP parms */	*p++ = (unsigned char)dhcpOptCodeCnt;	memcpy(p, dhcpOptCodes, dhcpOptCodeCnt);	p += dhcpOptCodeCnt;	/* DHCP Client Identifier option */	*p++ = TAG_CLIENT_IDENTIFIER;	*p++ = hlen + 1;				/* option length */	*p++ = htype;					/* client id is htype/haddr */	memcpy(p, chaddr, hlen);	p += hlen;	/* End option */	*p++ = TAG_END;	/* get a broadcast send/recv socket and address */	if((sockfd = dhcpCreateBCSkt(&sendaddr)) < 0)		return -1;	/* setup select timeout */	tv.tv_sec = 0;	tv.tv_usec = INIT_TMOUT_USECS;	retries = 0;	srand((unsigned)time(&timer));	while (retries++ < MAX_DHCP_RETRIES)	{		if(dhcpSendRequest(sockfd, sndbuf, p - sndbuf, 				(struct sockaddr *)&sendaddr, &tv) < 0)		{			if (errno != ETIMEDOUT)			{				closesocket(sockfd);				return -1;			}		}		else if((rcvbufsz = dhcpRecvResponse(sockfd, rcvbuf, 				sizeof(rcvbuf), &tv)) < 0)		{			if (errno != ETIMEDOUT)			{				closesocket(sockfd);				return -1;			}		}		else if(rcvbufsz >= 236 && AsUINT32(&rcvbuf[4]) == xid)			break;		/* exponential backoff randomized by a 			uniform number between -1 and 1 */		tv.tv_usec = tv.tv_usec * 2 + (rand() % 3) - 1;		tv.tv_sec = tv.tv_usec / USECS_PER_SEC;		tv.tv_usec %= USECS_PER_SEC;	}	closesocket(sockfd);	return rcvbufsz? dhcpProcessOptions(rcvbuf + 236, rcvbufsz - 236, 			dhcpInfoCB, context): -1;}/*-------------------------------------------------------------------------*/int DHCPParseSLPTags(int tag, void *optdata, size_t optdatasz, void *context)/* Callback routined tests each DA discovered from DHCP and add it to the	*//*	DA cache.																					*//*                                                                         *//* Returns: 0 on success, or nonzero to stop being called.						*//*-------------------------------------------------------------------------*/{	int cpysz, bufsz;	DHCPContext *ctxp = (DHCPContext *)context;	unsigned char *p = (unsigned char *)optdata;	unsigned char flags, dasize;	int encoding;	/* filter out zero length options */	if (!optdatasz)		return 0;	switch(tag)	{		case TAG_SLP_SCOPE:			/* Draft 3 format is only supported for ASCII and UNICODE				character encodings - UTF8 encodings must use rfc2610 format.				To determine the format, we parse 2 bytes and see if the result				is a valid encoding. If so it's draft 3, otherwise rfc2610. */			encoding = (optdatasz > 1)? AsUINT16(p): 0;			if (encoding != CT_ASCII && encoding != CT_UNICODE)			{				/* rfc2610 format */				if (optdatasz == 1)					break;		/*	UA's should ignore statically configured										scopes for this interface - 										add code to handle this later... 									 */				flags = *p++;	/* pick up the mandatory flag... */				optdatasz--;				if (flags)					;				/* ...and add code to handle it later... */				/* copy utf8 string into return buffer */				cpysz = optdatasz < sizeof(ctxp->scopelist)? 						optdatasz: sizeof(ctxp->scopelist);				strncpy(ctxp->scopelist, (char*)p, cpysz);				ctxp->scopelist[sizeof(ctxp->scopelist) - 1] = 0;			}			else			{				/* draft 3 format: defined to configure scopes for SA's only					so we should flag the scopes to be used only as registration					filter scopes - add code to handle this case later...					offs		len		name			description					0			2			encoding		character encoding used 					2			n			scopelist	list of scopes as asciiz string.				 */				optdatasz -= 2;	/* skip encoding bytes */				p += 2;				/* if UNICODE encoding is used convert to utf8 */				if (encoding == CT_UNICODE)					wcstombs(ctxp->scopelist, (wchar_t*)p, sizeof(ctxp->scopelist));				else				{					cpysz = optdatasz < sizeof(ctxp->scopelist)? 							optdatasz: sizeof(ctxp->scopelist);					strncpy(ctxp->scopelist, (char*)p, cpysz);					ctxp->scopelist[sizeof(ctxp->scopelist) - 1] = 0;				}			}			break;		case TAG_SLP_DA:			flags = *p++;			optdatasz--;			/* If the flags byte has the high bit set, we know we are				using draft 3 format, otherwise rfc2610 format. */			if (!(flags & DA_NAME_PRESENT))			{				/* rfc2610 format */				if (flags)				{					/*	If the mandatory byte is non-zero, indicate that 						multicast is not to be used to dynamically discover 						directory agents on this interface by setting the 						LACBF_STATIC_DA flag in the LACB for this interface. */					/* skip this for now - deal with it later... */				}				bufsz = sizeof(ctxp->addrlist) - ctxp->addrlistlen;				cpysz = (int)optdatasz < bufsz? optdatasz: bufsz;				memcpy(ctxp->addrlist + ctxp->addrlistlen, p, cpysz);				ctxp->addrlistlen += cpysz;			}			else			{				/* pre-rfc2610 (draft 3) format:						offs		len		name		description						0			1			flags		contains 4 flags (defined above)						1			1			dasize	name or addr length						2			dasize	daname	da name or ip address (flags)				 */				dasize = *p++;				optdatasz--;				if (dasize > optdatasz)					dasize = optdatasz;				if (flags & DA_NAME_IS_DNS)					;	/* DA name contains dns name - we have to resolve - later... */				else				{		/* DA name is one 4-byte ip address */					if (dasize < 4)						break;	/* oops, bad option format */					dasize = 4;					bufsz = sizeof(ctxp->addrlist) - ctxp->addrlistlen;					cpysz = dasize < bufsz? dasize: bufsz;					memcpy(ctxp->addrlist + ctxp->addrlistlen, p, cpysz);					ctxp->addrlistlen += cpysz;				}				if (flags & DISABLE_DA_MCAST)					;	/* this is the equivalent of the rfc2610 mandatory bit */			}			break;	}	return 0;}

⌨️ 快捷键说明

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