/*  -*- Mode: C;  -*- */

/******************************************************************************
*                                                                             *
*   Copyright 2005 University of Cambridge Computer Laboratory.               *
*                                                                             *
*   This file is part of Nprobe.                                              *
*                                                                             *
*   Nprobe 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.                                       *
*                                                                             *
*   Nprobe 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 Nprobe; if not, write to the Free Software                     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
*                                                                             *
******************************************************************************/


#ifndef _UDP_NS_H
#define _UDP_NS_H 

#ifndef SWIG_ONLY
/* 
 * The following loosely courtesy of nameser.h 
 */

typedef struct {
#if BYTE_ORDER == BIG_ENDIAN
			/* fields in first byte */
	unsigned short	qr: 1;		/* response flag */
	unsigned short	opcode: 4;	/* purpose of message */
	unsigned short  aa: 1;		/* authoritative answer */
	unsigned short	tc: 1;		/* truncated message */
	unsigned short	rd: 1;		/* recursion desired */
			/* fields in second byte */
	unsigned short	ra: 1;		/* recursion available */
	unsigned short	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
	unsigned short	ad: 1;		/* authentic data from named */
	unsigned short	cd: 1;		/* checking disabled by resolver */
	unsigned short	rcode :4;	/* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
			/* fields in first byte */
	unsigned short	rd :1;		/* recursion desired */
	unsigned short	tc :1;		/* truncated message */
	unsigned short	aa :1;		/* authoritative answer */
	unsigned short	opcode :4;	/* purpose of message */
	unsigned short	qr :1;		/* response flag */
			/* fields in second byte */
	unsigned short	rcode :4;	/* response code */
	unsigned short	cd: 1;		/* checking disabled by resolver */
	unsigned short	ad: 1;		/* authentic data from named */
	unsigned short	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
	unsigned short	ra :1;		/* recursion available */
#endif
} ns_parms_t;

#else 

typedef unsigned short ns_parms_t;

#endif /* ifndef SWIG_ONLY */

#define NS_MAX_RRBUFSZ 1024



struct ns_rec 
{
  unsigned int req_us;
  unsigned int rep_us;
  unsigned short state;
  unsigned short id;
  ns_parms_t ns_parms;
  int buflen;
};

typedef struct ns_rec ns_rec_t;

/* used when reading dump - rrbuf is dumped directly to disc in wan */
struct ns_fullrec 
{
  struct ns_rec ns_rec;
  char *rrbuf;
};

typedef struct ns_fullrec ns_fullrec_t;

#ifndef SWIG_ONLY

/* Used for pool queue */
union ns_q
{
  union ns_q *q;
  struct ns_rec rec;
};

typedef union ns_q ns_q_t;

#endif /* ifndef SWIG_ONLY */

/*
 * defs for state field (16 bits)
 */

#define NS_CLIENT_SEEN 0x1
#define NS_SERVER_SEEN 0x2
#define NS_REQ_REQ 0x4		/* ie actually was a request */
#define NS_RESP_RESP 0x8		/* ie actually was a response */
#define NS_RRS_FOLLOW 0x10

#define NS_DECODE_ERR 0x1000
#define NS_RR_TRUNC 0x2000	/* RRs too long */
#define NS_NONPRINT 0x4000	/* non-printing character in domain name */
#define NS_UNMATCHED_RESPONSE 0x8000	/* response id doesn't match */

/*
 * Values for preamble byte of our version of an RR 
 */

#define RR_NONE 0		/* end */
#define RR_IPADDR 1		/* domain name followed by 32 bit IP address */
#define RR_CNAME 2		/*  domain name followed by canonical form */

#define RR_REQ 50		/* a request domain name */

#define RR_NOT_INET 100
#define RR_OTHER_TYPE 101

#ifndef SWIG

/*
 * udp_ns.c 
 */

extern udp_serv_methods_t udp_ns_serv_methods;
extern udp_serv_methods_t udp_ns_serv_methods_nodump;
extern serv_control_t udp_ns_serv_control;
extern serv_control_t udp_ns_serv_control_nodump;

void udp_ns_open(prec_t *pp, struct udp_conn *uconnp, int way);
void udp_ns_close(prec_t *pp, struct udp_conn *uconnp, int way);
void udp_ns_dump(struct udp_conn *uconnp);
void udp_ns_dump(struct udp_conn *uconnp);
void udp_ns_nodump(struct udp_conn *uconnp);
int udp_ns_pkt(prec_t *pp, struct udp_conn *uconnp, int way, 
	       unsigned int tm);

#endif /* ifndef SWIG */

#ifdef SWIG

/*
 * Used only as the basis of a Python class used in decoding dumped NS 
 * resource records
 */
struct rrent 
{
  int code;
  char req[256];
  char can[256];
  int addr;
};
#endif


#endif /* ifndef  _UDP_NS_H */

/*
 * end udp_ns.h
 */
