示例#1
0
/*--------------------------------------------------------------------------*/
int ParseAuthBlock(SLPBuffer buffer, SLPAuthBlock* authblock)
/* Returns  - Zero on success, SLP_ERROR_INTERNAL_ERROR (out of memory) or  */
/*            SLP_ERROR_PARSE_ERROR.                                        */
/*--------------------------------------------------------------------------*/
{
    /* make sure that min size is met */
    if(buffer->end - buffer->curpos < 10)
    {
        return SLP_ERROR_PARSE_ERROR;
    }

    authblock->bsd          = AsUINT16(buffer->curpos);
    authblock->length       = AsUINT16(buffer->curpos + 2);

    if(authblock->length > buffer->end - buffer->curpos)
    {
        return SLP_ERROR_PARSE_ERROR;
    }

    authblock->timestamp    = AsUINT32(buffer->curpos + 4);
    authblock->spistrlen    = AsUINT16(buffer->curpos + 8);
    authblock->spistr       = buffer->curpos + 10;

    if(authblock->spistrlen > buffer->end - buffer->curpos + 10)
    {
        return SLP_ERROR_PARSE_ERROR;
    }

    authblock->authstruct   = buffer->curpos + authblock->spistrlen + 10;

    buffer->curpos = buffer->curpos + authblock->length;

    return 0;
}
示例#2
0
/*-------------------------------------------------------------------------*/
int ParseDAAdvert(SLPBuffer buffer, SLPDAAdvert* daadvert)
/*-------------------------------------------------------------------------*/
{
    int             result;
    int             i;

    /* make sure that min size is met */
    if(buffer->end - buffer->curpos < 4)
    {
        return SLP_ERROR_PARSE_ERROR;
    }

    /* parse out the error code */
    daadvert->errorcode = AsUINT16(buffer->curpos);
    buffer->curpos = buffer->curpos + 2;

    /* parse out the bootstamp */
    daadvert->bootstamp = AsUINT32(buffer->curpos);
    buffer->curpos = buffer->curpos + 4;

    /* parse out the url */
    daadvert->urllen = AsUINT16(buffer->curpos);
    buffer->curpos = buffer->curpos + 2;
    if(daadvert->urllen > buffer->end - buffer->curpos)
    {
        return SLP_ERROR_PARSE_ERROR;
    }
    daadvert->url = buffer->curpos;
    buffer->curpos = buffer->curpos + daadvert->urllen;

    /* parse the scope list */
    daadvert->scopelistlen = AsUINT16(buffer->curpos);
    buffer->curpos = buffer->curpos + 2;
    if(daadvert->scopelistlen > buffer->end - buffer->curpos)
    {
        return SLP_ERROR_PARSE_ERROR;
    }
    daadvert->scopelist = buffer->curpos;
    buffer->curpos = buffer->curpos + daadvert->scopelistlen;  

    /* parse the attr list */
    daadvert->attrlistlen = AsUINT16(buffer->curpos);
    buffer->curpos = buffer->curpos + 2;
    if(daadvert->attrlistlen > buffer->end - buffer->curpos)
    {
        return SLP_ERROR_PARSE_ERROR;
    }
    daadvert->attrlist = buffer->curpos;
    buffer->curpos = buffer->curpos + daadvert->attrlistlen;

    /* parse the SPI list */
    daadvert->spilistlen = AsUINT16(buffer->curpos);
    buffer->curpos = buffer->curpos + 2;
    if(daadvert->spilistlen > buffer->end - buffer->curpos)
    {
        return SLP_ERROR_PARSE_ERROR;
    }
    daadvert->spilist = buffer->curpos;
    buffer->curpos = buffer->curpos + daadvert->spilistlen;


    /* parse out auth block count */
    daadvert->authcount = *(buffer->curpos);
    buffer->curpos = buffer->curpos + 1;

    /* parse out the auth block (if any) */
    if(daadvert->authcount)
    {
        daadvert->autharray = (SLPAuthBlock*)malloc(sizeof(SLPAuthBlock) * daadvert->authcount);
        if(daadvert->autharray == 0)
        {
            return SLP_ERROR_INTERNAL_ERROR;
        }
        memset(daadvert->autharray,0,sizeof(SLPAuthBlock) * daadvert->authcount);

        for(i=0;i<daadvert->authcount;i++)
        {
            result = ParseAuthBlock(buffer,&(daadvert->autharray[i]));
            if(result) return result;
        }
    }

    return 0;
}
示例#3
0
/*=========================================================================*/ 
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;
}