


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include	<sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

unsigned long on=1;

#if 0
#define NAMESERVER "158.152.40.104"
#else
#define NAMESERVER "158.152.1.193"	/* demon */
#endif

main(int argc, char *argv[])
	{
	int s,n;
	FILE *fp;
	FILE *sin,*sout;
	struct sockaddr_in servaddr,hostaddr;
	struct hostent *he;
	int bit,writebit,readbit,exceptbit=0,iobit;
	char *hostname;
	char string[256];
	unsigned char buff[1024],*b;
	int bytes;
	struct timeval t;
	char *username;
	int portnum,len;
	int sendlength;

	if (argc!=2)
		{
		printf("UDPTEST machine.host.domain\n");
		exit(1);
		}

	hostname = strdup(argv[1]);

	if (!so_init()) printf("Socket interface failed to initialise.\n");

/* create the socket */

	s = socket(AF_INET, SOCK_DGRAM, 0);

/* set up receive address */

	hostaddr.sin_family = AF_INET;
	hostaddr.sin_port = htons(4000);
	hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);

/* set up domain name server address */

	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(53);
	servaddr.sin_addr.s_addr = inet_addr(NAMESERVER);

/* allocate the local port (fixed at 4000 'cos I'm a lazy bugger) */

	if (bind(s, (struct sockaddr *)&hostaddr,sizeof(hostaddr)) == -1)
		{
		exit(1);
		}

/* set the header, now to arse around writing to a char array as words */

	((short *)buff)[0] = htons(1234);  /* this is an id number to make  */
                                     /* sure you are getting the same */
                                     /* message back so it should be different */
                                     /* each time */

	((short *)buff)[1] = 0;        /* no flags */

	((short *)buff)[2] = htons(1); /* only one request */
	((short *)buff)[3] = 0;        /* no answers      */
	((short *)buff)[4] = 0;        /* no crap         */
	((short *)buff)[5] = 0;        /* no money        */

/* that's the header finished, now onto the buggery with the name */
/* separate all the separate parts of the name out                */

	b = buff+12;

	while (strchr(hostname,'.'))
		{
		*strchr(hostname,'.') = '\0';

		*b++ = strlen(hostname);
		strcpy(b,hostname);
		b += strlen(hostname);	/* set pointer to null terminator (it has to be overwritten) */

		hostname += strlen(hostname)+1;
		}

/* copy the remaining name over */

	*b++ = strlen(hostname);
	strcpy(b,hostname);
	b += strlen(hostname);

	*b++ = 0;		/* zero length string finishes list */

	*((short *)b)++ = htons(1);	/* query type = 1 (address) */
	*((short *)b)++ = htons(1);	/* query class= 1 (internet  */

	sendlength = b-buff;

	len = sizeof(struct sockaddr_in);

	sendto(s,(char *)&buff,sendlength,0,(struct sockaddr *)&servaddr,sizeof(struct sockaddr_in));

/* this is to enable polling of the socket */

	if (ioctl(s, FIONBIO, (long *)&on) < 0)
		{
		printf("Unable to unblock socket.\n");
		exit(1);
		}

/* poll the socket */

	printf("Waiting for data on port %d.\n",53);

	for (n=0;n<5000;n++)
		{
		apiPause();
		len = sizeof(struct sockaddr_in);
		bytes = recvfrom(s,(char *)&buff,sizeof(buff),0,(struct sockaddr *)&servaddr,&len);
		if (bytes>=0) break;
		}

	if (bytes<0)
		{
		printf("Timed out without response.\n");
		so_close(s);
		so_exit();
		return;
		}

/*	printf("Received %d bytes from %s.\n\n",bytes,inet_ntoa(servaddr.sin_addr));
*/

/* check the id of the packet */

	if (htons(((short *)buff)[0]) != 1234)
		{
		printf("Returned packet didn't match.\n");
		}

/* check how many records are in the reply section */

	if (htons(((short *)buff)[3]) <1 )
		{
		printf("No reply fields in packet.\n");
		so_close(s);
		so_exit();
		exit(0);
		}

	b = buff+12;

/* skip over any query headers (ie. what we sent over there) */

	for (n=0;n< htons(((short *)buff)[2]) ; n++)
		{
		while (*b)
			{
			if (((*b)&192) == 192) { b++; break; }
			else b += *b+1;
			}

		b += 5;  /* skip class and type fields and last byte of string */
		}


/* skip over the name string in the reply structure */

	while (*b)
		{
		if (((*b)&192) == 192) { b++; break; }
		else b += *b+1;
		}

	b++;		/* skip over last byte of string */

	if (htons(*((short *)b)++) != 1)
		printf("Unrecognised type!\n");

	if (htons(*((short *)b)++) != 1)
		printf("Unrecognised class!\n");

	b+=4;		/* ignore time record */

	if (htons(*((short *)b)++) != 4)
		printf("IP address is not 4 bytes in length!\n");

	printf("%s is ",argv[1]);

	for (n=0;n<4;n++)
		printf("%d.",b[n]);
	

	so_close(s);

	so_exit();
	}

