/*
 * Worldvisions Tunnel Vision Software:
 *   Copyright (C) 1998 Worldvisions Computer Technology, Inc.
 * 
 * Classes for establishing a network tunnel on top of any stream and
 * managing encrypted communications over the tunnel.
 * 
 * This uses the proprietary Tunnel Vision protocol and WvCryptoStream
 * facilities.
 */

#ifndef __WVTUNNEL_H
#define __WVTUNNEL_H

#include "wvcrypto.h"
#include "wvtcp.h"
#include "wvlog.h"
#include "wvconf.h"
#include "wvinterface.h"

#define MAX_VTUNNELS 16


DeclareWvList(WvIPNet);


class WvTunnelList;


/*
 * A WvTunnel connects /dev/tap0 to an arbitrary WvStream... after the
 * authentication process with the WvTunnel on the other side of the
 * stream.
 */
class WvTunnel : public WvStreamList
{
    int tunlnum;
    WvStream *tunnel, *etunnel;
    WvFile *tap;
    WvLog log;
    bool server_mode, trusted, vpn_started;
    
    // if added_route or added_gwroute is not NULL, we added a route to
    // the remote Tunnel Vision host so that we could tunnel to their local
    // net without losing our route directly to them.
    WvString added_ifc;
    WvIPNet added_route, added_gwroute;
    
    enum ClientState {Greeting, RSA, Blowfish, IHAVE1, Password, IHAVE2, VPN};
    ClientState clientstate;
    unsigned char keybuf[16];
    __u16 inpkt_size;
    WvConf &cfg;
    WvString remote_rsa;
    WvInterface ifc;
    time_t last_receive;

    static Callback server_callback, client_callback, vpn_callback;
    
    void newcrypt(WvStream *_etunnel);
    WvFile *tapinit();
    void process_ihave(char *buf);
    void generate_ihave();
    
public:
    static WvTunnelList all_tunnels;
    WvIPNetList remote_nets;
    
    WvTunnel(WvStream *_tunnel, bool server_mode, WvConf &_cfg);
    virtual ~WvTunnel();
    
    virtual void close();
    
    virtual bool isok() const;
    virtual int geterr() const;
    virtual const char *errstr() const;
    
    virtual const WvAddr *src() const;
    
    bool vpn_up() const
        { return vpn_started; }
};


DeclareWvList(WvTunnel);


/*
 * WvTunnelListener waits for a TCP connection and starts a WvTunnel on
 * that connection at the right time.  It adds the WvTunnel to the _list
 * given to the constructor.
 */
class WvTunnelListener : public WvTCPListener
{
    static Callback accept_callback;
    WvStreamList *list;
    WvConf &cfg;
    
public:
    WvTunnelListener(const WvIPPortAddr &_listenport, WvStreamList *_list,
		     WvConf &_cfg);
};


#endif // __WVTUNNEL_H
