/* Copyright (c) 1995,1996,1997 NEC Corporation.  All rights reserved.       */
/*                                                                           */
/* The redistribution, use and modification in source or binary forms of     */
/* this software is subject to the conditions set forth in the copyright     */
/* document ("Copyright") included with this distribution.                   */

/*
 * $Id: confutil.h,v 1.16.4.1 1998/07/19 22:33:22 wlu Exp $
 */

#ifndef CONFUTIL_H
#define CONFUTIL_H

#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif

#ifdef __alpha__                /* avoid some warnings                       */
#ifdef HAVE_SYS_MBUF_H
#include <sys/mbuf.h>
#endif

#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
#endif

#include <net/if.h>
#define ifssi(x) ((ssi *)&(x.ifr_addr))

#define SKIPSPACE(x)     while(*(x) != '\n' &&  isspace((int)(*(x)))) (x)++
#define SKIPNONSPACE(x)  while(*(x) != '\0' && !isspace((int)(*(x)))) (x)++
#define SKIPNSPNCOMMA(x) while(*(x) != '\0' && !isspace((int)(*(x))) && *(x) != ',') (x)++
#define SKIPNSPNCOLNCOM(x) while(*(x) != '\0' && !isspace((int)(*(x))) && *(x) != ',' && *(x) != ':') (x)++
    
#define S5_HOSTALIASES_NUM 16
#define S5_HOSTIP_NUM	   16

#define NET_STAT 0
#define NET_ADDR 1
#define NET_MASK 2
#define NET_TYPE 3

#define IN_ADDR 0		/* is the type for address                    */
#define IN_PORT 0		/* is the type d_port (is it a port range?)   */
#define NAME    1		/* is the type for name                       */

/* a struct telling us how the address is stored...(for matching). It can be  */
/* stred as an ip address and mask (type = IN_ADDR) or as a string/substring  */
/* (type = NAME).                                                             */
struct host {
    char type;
    char resolve;
    struct in_addr ip;
    struct in_addr mask;
    char name[S5_HOSTNAME_SIZE];
    int length;
    char aliases[S5_HOSTALIASES_NUM][S5_HOSTNAME_SIZE];
    int aliascnt;
    struct in_addr back[S5_HOSTIP_NUM];
    int ipcnt;
};

/* a struct telling us how the service is stored...(for matching). It can be  */
/* stred as an ip port range (type = IN_PORT) or as a string & fallback port  */
/* (type = NAME).                                                             */
struct port {
    u_short lport;
    u_short hport; 
};

/* a structure contains the interface's IP address and mask                   */
struct intaddr {
    struct in_addr ip;
    struct in_addr net;
};

/* a structure contains interfaces' information                               */
struct intfc {
    char name[16];
    int type;
    int up;
    int addrcnt;
    struct intaddr *addrlist;
};

/* macros for using struct port...they hide the union-ness of it all....      */
#define checkport(x, y) (((x) >= (y).lport) && ((x) <= (y).hport))

/* macros for using struct intaddr...      */
#define checkifc(x, y) (((x).net.s_addr != 0) && (((x).ip.s_addr & (x).net.s_addr) == ((y).s_addr & (x).net.s_addr)))

/* A generic structure for linked lists...Pretty straight forward...only thng */
/* slightly unusual is the ptrmalloced field which tells us to free it or not */
struct lls {
  union data {
    void *ptr;
    int n;
  } data;

  int ptrmalloced;
  struct lls *next;
};

typedef struct lls list;

#define dataptr data.ptr
#define dataint data.n

struct confid { 
    char *string, *abbrev;	 /* the string/abbreviation for these lines   */
    void (*handler)(void **, int, int, char *); /* the function for ""        */
    void **array;		 /* ptr to the array the data is stored in.   */
    int *number;		 /* ptr to the total number of things in ""   */
    int *cnum;			 /* ptr to the current index in array...      */
    int size;			 /* sizeof an array element (if owner)        */
};

typedef struct confid confid;

/* Some convenient routines for linked list manipulation...                   */
extern void lsDeleteLinkedList P((list **));
extern int  lsLinkedListInsertUnaligned P((list **l, size_t s));
extern int  lsLinkedListInsertAligned   P((list **l, size_t s));

extern int  lsGetHostAddress        P((char **, S5NetAddr *));
extern int  lsGetHostPort           P((char **, S5NetAddr *));
extern int  lsGetHostAddressAndPort P((char **, S5NetAddr *));

extern int  lsGetHostAndMask   P((char **, struct host *));
extern int  lsGetPortOrService P((char **, struct port *));
extern int  lsGetPermCommand   P((char **, list **));
extern int  lsGetAuthMethods   P((char **, list **));
extern int  lsGetPermUsers     P((char **, list **));

extern int  lsCheckHost  P((struct host *,  const S5NetAddr *, const char *));
extern int  lsCheckPort  P((struct port *, const S5NetAddr *, const char *, char *));
extern int  lsCheckByte  P((list *, u_char, const char *));
extern int  lsCheckUser  P((list *, const char *));

extern void lsSetupIntfcs P((struct intfc **, int *));
extern int  lsLookupIntfc P((S5IOHandle, int, struct ifreq *ifr));

extern void lsReadConfig P((const char *, struct confid *, int));

extern int lsLineNo;

#endif
