/**************************************************************************************************
	$Id: question.c,v 1.6 2005/03/22 17:44:56 bboy Exp $

	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at Your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**************************************************************************************************/

#include "mydns.h"

/* Set this to nonzero to enable debugging for this source file */
#define	QUESTION_DEBUG	1


/**************************************************************************************************
	DNS_MAKE_QUESTION
	Make a DNS query packet with the specified attributes.
	Returns a pointer to static data containing the question or NULL on error.
	Sets 'length' to the length of the question packet.
**************************************************************************************************/
char *
dns_make_question(uint16_t id, dns_qtype_t qtype, char *name, int rd, size_t *length)
{
	static char	req[1024];										/* Request buffer */
	char	*dest;													/* Current destination in 'req' */
	DNS_HEADER	header;											/* DNS header */
	char *mark;														/* Location of last label separator */
	register int labels = 0;									/* Number of labels found */
	register char *c;

	dest = req;
	if (length)
		*length = 0;
	if (!name)
	{
		if (length) *length = (int)ERR_MALFORMED_REQUEST;
		return (NULL);
	}

	memset(&header, 0, sizeof(DNS_HEADER));
	DNS_PUT16(dest, id);											/* ID */
	header.rd = rd;												/* Recursion desired? */
	memcpy(dest, &header, sizeof(DNS_HEADER)); dest += SIZE16;
	DNS_PUT16(dest, 1);											/* QDCOUNT */
	DNS_PUT16(dest, 0);											/* ANCOUNT */
	DNS_PUT16(dest, 0);											/* NSCOUNT */
	DNS_PUT16(dest, 0);											/* ARCOUNT */

	for (mark = dest++, c = name; *c; c++)					/* QNAME */
	{
		if ((c - name) > DNS_MAXNAMELEN)
		{
			if (length) *length = (int)ERR_Q_NAME_TOO_LONG;
			return NULL;											/* Name too long */
		}
		if (*c != '.')												/* Append current character */
			*dest++ = *c;
		if (mark && (*c == '.' || !c[1]))					/* Store current label length at 'mark' */
		{
			if ((*mark = dest - mark - 1) > DNS_MAXLABELLEN)
			{
				if (length) *length = (int)ERR_Q_LABEL_TOO_LONG;
				return NULL;	/* Label too long */
			}
			mark = dest++;
			labels++;
		}
		if (*c == '.' && !c[1])									/* Is this the end? */
		{
			*mark = 0;
			break;
		}
	}
	DNS_PUT16(dest, (uint16_t)qtype);						/* QTYPE */
	DNS_PUT16(dest, DNS_CLASS_IN);							/* QCLASS */

	if (length)
		*length = dest - req;

	return (req);
}
/*--- dns_make_question() -----------------------------------------------------------------------*/

/* vi:set ts=3: */


syntax highlighted by Code2HTML, v. 0.9.1