/*
 * $Id: interface.h,v 1.1.1.1 1998/08/10 20:06:50 dogcow Exp $
 * originally Id: interface.h,v 1.4 1998/05/29 19:54:38 masaki Exp 
 */

#ifndef _INTERFACE_H
#define _INTERFACE_H

/* Some of this code taken from Berkely routed software */

#include <mrt.h>
#include <trace.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>

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

typedef struct _ll_addr_t {
    prefix_t *prefix;		/* interface addresess */
    prefix_t *broadcast;	/* destination or broadcast address
				   broadcast address is defined in case of v4
				   prefixlen will be ignored */
} ll_addr_t;

#define IFF_TUNNEL  0x80000000  /* tunnel interface (special treatment
                                   when adding a route into the kernel) */
#define MAX_INTERFACES 32	/* the maximum is limited by the 'bit' field
				   in the following structure */
typedef struct _interface_t {
    u_long bit;			/* each interface assigned a unique bit */
    u_long flags;		/* interface flags (from the ioctl) */
    u_long mtu;			/* interface mtu (from the ioctl) */
    char name[IFNAMSIZ + 1];
    u_long index;			/* index number */
    u_long dlist_in[PROTO_MAX];	/* list num for input filtering */
    u_long dlist_out[PROTO_MAX];	/* list num for output filtering */
    u_long metric_in;		/* input metric */
    u_long metric_out;		/* output metric */
    u_long default_pref;

    LINKED_LIST *ll_addr;	/* address list */
    ll_addr_t *primary;		/* primary address for ipv4 */
#ifdef HAVE_IPV6
    ll_addr_t *primary6;	/* primary address for ipv6 (global) */
    ll_addr_t *link_local;	/* ipv6 link local address */
#endif				/* HAVE_IPV6 */

#define mrt_compat 1
#ifdef mrt_compat
/*
 * The following are defined for compatible purpose & easy use
 * and may be deleted after checking ipv4 routing protocols.
 */

    /* ipv4 */
    prefix_t *prefix;
    u_long dest;		/* we should merge dest & broadcast */
    u_long broadcast;

#ifdef HAVE_IPV6
    /* ipv6 */
    prefix_t *prefix6;
    struct in6_addr dest6;
#endif				/* HAVE_IPV6 */
#endif				/* mrt_compat */

} interface_t;


typedef struct _interface_master_t {
    u_long number;		/* number of interfaces */
    interface_t *default_interface;
#ifdef HAVE_IPV6
    interface_t *default_interface6;
#endif				/* HAVE_IPV6 */
    trace_t *trace;
    LINKED_LIST *ll_interfaces;	/* IPv4 & v6 Interfaces */
    u_long max_mtu;		/* maximum MTU */
    interface_t *index2if[MAX_INTERFACES];
    int sockfd;			/* general purpose socket (v4) */
    int sockfd6;		/* general purpose socket (v6) */
} interface_master_t;

extern interface_master_t *INTERFACE_MASTER;

/* public functions */
interface_t *new_interface (char *name, u_long flags, int mtu, int index);
interface_t *add_addr_to_interface (interface_t * interface, int family,
				    void *addr, int len, void *broadcast);
int read_interfaces ();

interface_t *find_interface (prefix_t * prefix);
interface_t *find_interface_flags (prefix_t * prefix, u_long flags);
interface_t *find_interface_byname (char *name);
interface_t *find_interface_byindex (int index);
interface_t *find_interface_local (prefix_t * prefix);
LINKED_LIST *find_network (prefix_t * prefix);
interface_t *local_interface (int familly, void *cp);
int is_prefix_on (prefix_t *prefix, interface_t *interface);
int init_interfaces (trace_t * ltrace);

int show_interfaces (uii_connection_t *uii);
int mask2len (void *mask, int bytes);
u_char *len2mask (int bitlen, void *mask, int bytes);

int kernel_update_route (int cmd, prefix_t *dest,
                         prefix_t *next_hop, prefix_t *old_hop, 
			 int index, int oldindex);
int kernel_init ();
int kernel_read_rt_table ();
int add_kernel_route (int family, void *dest, void *nhop, int masklen, 
		      int index);

#endif /* INTERFACE_H */
