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

📄 slp_dhcp.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************//*                                                                         *//* Project:     OpenSLP - OpenSource implementation of Service Location    *//*              Protocol                                                   *//*                                                                         *//* File:        slp_dhcp.h                                                 *//*                                                                         *//* Abstract:    Implementation for functions that are related              *//*              to acquiring specific dhcp parameters.                     *//*                                                                         *//*-------------------------------------------------------------------------*//*                                                                         *//*     Please submit patches to http://www.openslp.org                     *//*                                                                         *//*-------------------------------------------------------------------------*//*                                                                         *//* Copyright (C) 2000 Caldera Systems, Inc                                 *//* All rights reserved.                                                    *//*                                                                         *//* Redistribution and use in source and binary forms, with or without      *//* modification, are permitted provided that the following conditions are  *//* met:                                                                    *//*                                                                         *//*      Redistributions of source code must retain the above copyright     *//*      notice, this list of conditions and the following disclaimer.      *//*                                                                         *//*      Redistributions in binary form must reproduce the above copyright  *//*      notice, this list of conditions and the following disclaimer in    *//*      the documentation and/or other materials provided with the         *//*      distribution.                                                      *//*                                                                         *//*      Neither the name of Caldera Systems nor the names of its           *//*      contributors may be used to endorse or promote products derived    *//*      from this software without specific prior written permission.      *//*                                                                         *//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     *//* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      *//* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   *//* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      *//* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *//* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        *//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  *//* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       *//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *//* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   *//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    *//*                                                                         *//***************************************************************************/#include "slp_dhcp.h"#include "slp_message.h"#include "slp_xmalloc.h"#ifdef _WIN32#include <winsock.h>#include <windows.h>#include <iphlpapi.h>#define ETIMEDOUT	110#define ENOTCONN	107#else/* non-win32 platforms close sockets with 'close' */#define closesocket close#include <unistd.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if_arp.h>#include <sys/time.h>#endif#include <stdlib.h>#include <string.h>#include <time.h>#include <errno.h>/* UDP port numbers, server and client. */#define IPPORT_BOOTPS		67#define IPPORT_BOOTPC		68/* BOOTP header op codes */#define BOOTREQUEST			1#define BOOTREPLY				2/* BOOTP header field value maximums */#define MAXHTYPES				7		/* Number of htypes defined */#define MAXHADDRLEN			6 		/* Max hw address length in bytes */#define MAXSTRINGLEN			80		/* Max string length *//* Some other useful constants */#define MAX_MACADDR_SIZE	64		/* Max hardware address length */#define MAX_DHCP_RETRIES	2		/* Max dhcp request retries *//* timeout values */#define USECS_PER_MSEC		1000#define MSECS_PER_SEC		1000#define USECS_PER_SEC		(USECS_PER_MSEC * MSECS_PER_SEC)#define INIT_TMOUT_USECS	(250 * USECS_PER_MSEC)/* DHCP vendor area cookie values */#define DHCP_COOKIE1			99#define DHCP_COOKIE2			130#define DHCP_COOKIE3			83#define DHCP_COOKIE4			99/* DHCP Message Types for TAG_DHCP_MSG_TYPE */#define DHCP_MSG_DISCOVER	1#define DHCP_MSG_OFFER		2#define DHCP_MSG_REQUEST	3#define DHCP_MSG_DECLINE	4#define DHCP_MSG_ACK			5#define DHCP_MSG_NAK			6#define DHCP_MSG_RELEASE	7#define DHCP_MSG_INFORM		8/*=========================================================================*/ static int dhcpCreateBCSkt(struct sockaddr_in* peeraddr) /*	Creates a socket and provides a broadcast addr to which DHCP requests	should be sent. Also binds the socket to the DHCP client port.	peeraddr         (OUT) ptr to rcv addr to which DHCP requests are sent	Returns          Valid socket or -1 if no DA connection can be made  =========================================================================*/{	int sockfd;#ifdef _WIN32	BOOL on = 1;#else	int on = 1;#endif	/* setup dhcp broadcast-to-server address structure */	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)	{		struct sockaddr_in localaddr;		localaddr.sin_family = AF_INET;		localaddr.sin_port = htons(IPPORT_BOOTPC);		localaddr.sin_addr.s_addr = htonl(INADDR_ANY);		if(bind(sockfd, (struct sockaddr*)&localaddr, sizeof(localaddr))				|| setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,						(char*)&on, sizeof(on)))		{			closesocket(sockfd);			return -1;		}		peeraddr->sin_family = AF_INET;		peeraddr->sin_port = htons(IPPORT_BOOTPS);		peeraddr->sin_addr.s_addr = htonl(INADDR_BROADCAST);	}	return sockfd;}/*=========================================================================*/ static int dhcpSendRequest(int sockfd, void *buf, size_t bufsz,		struct sockaddr* peeraddr, struct timeval* timeout)/*	Sends a buffer to PEERADDR, times out after period specified in TIMEOUT	Returns  -		zero on success non-zero on failure	errno				EPIPE error during write						ETIMEDOUT read timed out  =========================================================================*/ {	fd_set writefds;	int xferbytes;	int flags = 0;#if defined(MSG_NOSIGNAL)	flags = MSG_NOSIGNAL;#endif	FD_ZERO(&writefds);	FD_SET(sockfd, &writefds);	if((xferbytes = select(sockfd + 1, 0, &writefds, 0, timeout)) > 0)	{		if((xferbytes = sendto(sockfd, (char*)buf, (int)bufsz, flags, 				peeraddr, sizeof(struct sockaddr_in))) <= 0)		{			errno = EPIPE;			return -1;		}	}	else if(xferbytes == 0)	{		errno = ETIMEDOUT;		return -1;	}	else	{		errno = EPIPE;		return -1;	}	return 0;}/*=========================================================================*/ static int dhcpRecvResponse(int sockfd, void *buf, size_t bufsz,		struct timeval* timeout)/*	Receives a DHCP response from a DHCP server. Since DHCP responses are	broadcasts, we compare XID with received response to ensure we are	returning the correct response from a prior request.	Returns  -    	zero on success, non-zero on failure	errno         	ENOTCONN error during read						ETIMEDOUT read timed out  =========================================================================*/ {	int xferbytes;	fd_set readfds;	FD_ZERO(&readfds);	FD_SET(sockfd, &readfds);	if((xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout)) > 0)	{		if((xferbytes = recvfrom(sockfd, (char*)buf, (int)bufsz, 0, 0, 0)) <= 0)		{			errno = ENOTCONN;			return -1;		}		return xferbytes;	}	else if(xferbytes == 0)	{		errno = ETIMEDOUT;		return -1;	}	errno = ENOTCONN;	return -1;}/*=========================================================================*/ static int dhcpProcessOptions(unsigned char *data, size_t datasz,		DHCPInfoCallBack *dhcpInfoCB, void *context)/*	Calls dhcpInfoCB once for each option returned by the dhcp server.	Returns	-		zero on success, non-zero on failure	errno				ENOTCONN error during read						ETIME read timed out						ENOMEM out of memory						EINVAL parse error  =========================================================================*/ {	int err, taglen;	unsigned char tag;	/* validate vendor data header */	if(datasz < 4 			|| *data++ != DHCP_COOKIE1 || *data++ != DHCP_COOKIE2 			|| *data++ != DHCP_COOKIE3 || *data++ != DHCP_COOKIE4) 		return -1;			/* invalid dhcp response */	datasz -= 4;			/* account for DHCP cookie values */	/* validate and process each tag in the vendor data */	while(datasz-- > 0 && (tag = *data++) != TAG_END) 	{		if(tag != TAG_PAD) 		{			if(!datasz-- || (taglen = *data++) > (int)datasz) 				return -1;	/* tag length greater than total data length */			if((err = dhcpInfoCB(tag, data, taglen, context)))				return err;			datasz -= taglen;			data += taglen;      		}	}	return 0;	}/*=========================================================================*/ static int dhcpGetAddressInfo(unsigned char *ipaddr, unsigned char *chaddr, 		unsigned char *hlen, unsigned char *htype)/*	return hardware MAC address for specified ip address.	Returns	-		zero on success, non-zero on failure  =========================================================================*/ {#ifdef _WIN32	HMODULE hmod;		DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);	char ipastr[16];	*hlen = 0;	sprintf(ipastr, "%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);		if((hmod = LoadLibrary("iphlpapi.dll")) != 0)	{		if((pGetAdaptersInfo = (DWORD(WINAPI *)(PIP_ADAPTER_INFO,PULONG))				GetProcAddress(hmod, "GetAdaptersInfo")) != 0)		{			DWORD dwerr;			ULONG bufsz = 0;			IP_ADAPTER_INFO *aip = 0;			if((dwerr = (*pGetAdaptersInfo)(aip, &bufsz)) == ERROR_BUFFER_OVERFLOW					&& (aip = (IP_ADAPTER_INFO *)xmalloc(bufsz)) != 0					&& (dwerr = (*pGetAdaptersInfo)(aip, &bufsz)) == ERROR_SUCCESS)			{				IP_ADAPTER_INFO *pcur;				for(pcur = aip; pcur && !*hlen; pcur = pcur->Next)				{					IP_ADDR_STRING *caddrp;					for(caddrp = &pcur->IpAddressList; caddrp && !*hlen; caddrp = caddrp->Next)					{						if(strcmp(ipastr, caddrp->IpAddress.String) == 0)						{							*hlen = pcur->AddressLength;							*htype = pcur->Type; /* win32 returns iana ARP values */							memcpy(chaddr, pcur->Address, pcur->AddressLength);							break;						}					}				}				if(!*hlen)	/* couldn't find the one we wanted, just use the first */				{					*hlen = aip->AddressLength;					*htype = aip->Type;					memcpy(chaddr, aip->Address, aip->AddressLength);				}			}			xfree(aip);		}		FreeLibrary(hmod);	}#elif defined(SIOCGARP)	/* Query the ARP cache for our hardware address */		int sockfd;	struct arpreq arpreq;	struct sockaddr_in *sin;	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)		return -1;

⌨️ 快捷键说明

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