/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos720 src/bos/usr/samples/tcpip/dynload/rnd_nw.c 1.2                  */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 1999                   */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/*
	    NOTICE TO USERS OF THE SOURCE CODE EXAMPLES

 INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THE SOURCE CODE
 EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, "AS IS" WITHOUT
 WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
 LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
 OF THE SOURCE CODE EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS,
 IS WITH YOU.  SHOULD ANY PART OF THE SOURCE CODE EXAMPLES PROVE
 DEFECTIVE, YOU (AND NOT IBM OR AN AUTHORIZED RISC System/6000* WORKSTATION
 DEALER) ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR
 CORRECTION.

  RISC System/6000 is a trademark of International Business Machines
   Corporation.
*/
/* INCLUDE for structure definitions */
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/nameser.h>
#include <sys/errno.h>
#include <resolv.h>
#include <netdb.h>
#include <fcntl.h>
#include <pthread.h>

struct nwent  {
	char	*n_name;  	/* office name of net */
	char	**n_aliases;	/* alias list */
	int	n_addrtype;	/* network type */
	void	*n_addr;	/* network address */
	int	n_length;	/* address length */
};


typedef struct _nw_pvt {
	pthread_t pvt_thd;		
	struct nwent	pvt_nwent;	/* nwent for return */
} nw_pvt;

void *nw_pvtinit();
void nw_close();
void nw_rewind();
void nw_minimize();
struct nwent *nw_next();
struct nwent *nw_byaddr();
struct nwent *nw_byname();
struct nwent *rnd_makenetwork();

void *
nw_pvtinit()
{
	/* Step 1: Allocate memory and clear it */
	nw_pvt *pvt = (nw_pvt *)malloc(sizeof(*pvt));
	bzero(pvt,sizeof(*pvt));

	/* Step 2: Initialize whatever needs be done per-process */
	pvt->pvt_thd = pthread_self();

	return pvt;
}

/*
 * nw_close() - inverse of nw_pvtinit();
 */
void
nw_close(void *this)
{
	if (!this) return;
	free(this);
}

void
nw_rewind(void *this)
{
	nw_pvt *pvt = NULL;
	
	if (!this) return;
	pvt = (nw_pvt *)this;
}

void
nw_minimize(void *this)
{
	/* Nothing to do */
}

/* nw_next is not supported in this example, since
 * we are not sequentially searching...
 */

/*
 * nw_byname() return a nwent struct, given a network name 
 * and address family(by now, it's always AF_INET)
 */
struct nwent *
nw_byname(void *this, const char *name, int type)
{
	nw_pvt  *pvt = NULL;
	if (!this)  {
		errno = EINVAL;
		return(NULL);
	}
	pvt = (nw_pvt *)this;

      	/* build up our servent */
	return(rnd_makenetwork(this, name, type, NULL));
}

/*
 * nw_byaddr() - return a nwent struct, given an network address,
 * its length and address family
 */
struct nwent *
nw_byaddr(void *this, void *net, int length, int type)
{
	nw_pvt *pvt = NULL;
	if (!this) {
		errno = EINVAL;
		return(NULL);
	}
	pvt = (nw_pvt *)this;

	/* make and return hostent from data */
	return(rnd_makenetwork(this,NULL, type, net));
}

/*
 * rnd_makeservice() - internal function to build servent from private data
 */
struct nwent *
rnd_makenetwork(void *this, char *network_name, int type, void *addr)
{
	nw_pvt *pvt = (nw_pvt *)this;
	int	len;
	unsigned long 	v4_prefix=inet_addr("1.4.8.0");
	
	/* getnetbyname case */
	if ( addr == NULL )  {
		struct in_addr  tmp;
		char  *ptr;
		char  buf[50];

		pvt->pvt_nwent.n_name = network_name;
		pvt->pvt_nwent.n_aliases = NULL;	
		pvt->pvt_nwent.n_addrtype = type;
		len = strlen(network_name);
		v4_prefix |= len;
		pvt->pvt_nwent.n_addr = &v4_prefix;
		pvt->pvt_nwent.n_length = 32;
	}

	/* getbyaddr case */
	else if ( network_name == NULL )  {
		char format[1024];
		int  tmp;
		char *ptr = (char *) addr;

		bzero(format, sizeof format);
		pvt->pvt_nwent.n_aliases = NULL;	
		pvt->pvt_nwent.n_addrtype = type;
		pvt->pvt_nwent.n_addr = addr;
		pvt->pvt_nwent.n_length = 32;
		tmp =(int) ptr[3];
		sprintf(format, "networkname%d", tmp);
		pvt->pvt_nwent.n_name = format;
	}

	/* Return */
	return(&(pvt->pvt_nwent));
}

