/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "Licence").
 * You may not use this file except in compliance with the Licence.
 *
 * You can obtain a copy of the licence at RISC OS path @.^.LICENCE
 * or  http://www.riscosdev.com/lanman98/LICENCE.CDDL
 * See the Licence for the specific language governing permissions
 * and limitations under the Licence.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the Licence file. If applicable, add the
 * following below this CDDL HEADER, with the fields enclosed by
 * brackets "[]" replaced with your own identifying information:
 * Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
 
/*
 *   Copyright 1996 Warm Silence Software Ltd.  All rights reserved.
 *   Use is subject to license terms.
 */

/*   PHBG 27/11/96: Initial version
 */

#ifndef _VC_
#define _VC_

#include "kernel.h"
#include "data.h"
#include "LanMan98BaseLib/tcp.h"


typedef struct vc_s *vc_t;


/*
    SMB is reachable over two transports.  Port 445 carries SMB directly
    over TCP.  Port 139 carries it over the NetBIOS session service, which
    requires a session request naming the server before any SMB traffic
    can flow, and which modern hosts frequently no longer run.

    Port 139 is what selects the NetBIOS transport; any other port, not
    only 445, is taken to carry SMB directly.

    Passing SMB_PORT_AUTO leaves the choice to VC(), which uses
    LanMan98$Port if it is set, and otherwise tries 445 before 139.
*/

#define SMB_PORT_AUTO   (0)
#define SMB_PORT_NBT    (139)
#define SMB_PORT_DIRECT (445)


vc_t VC(char *domain, tcp_port_t port, char *netbios_name);

tcp_port_t VCPort(vc_t);
/*
    The port the circuit was actually established on.  Worth recording
    when SMB_PORT_AUTO was used, so that a reconnection does not have to
    repeat the search.
*/

tcp_port_t VCParsePort(char *s);
/*
    Convert a decimal port number written by the user.  Throws if it is
    not a usable port.
*/

int VCCheckSignature(vc_t, const unsigned char *key, int key_len,
                     unsigned int seq);
/*
    Check the signature on the message just received, as though it had been
    signed with this key and this sequence number.  Nonzero if it matches.
    Used once, on the reply that completes the logon, to establish that the
    server derived the same key before anything is trusted to it.
*/

void VCSignFrom(vc_t, const unsigned char *key, int key_len,
                unsigned int seq);

void VCImpatient(int cs);
/*
    Wait this long, in centiseconds, rather than the usual patient amount,
    until told otherwise with zero.

    The usual waits suit a connection somebody asked for and is waiting on:
    twenty seconds for an answer is worth it if the alternative is failing
    a mount that would have worked.  They do not suit looking around a
    network, where several machines will be asked and some of them are not
    going to answer at all.  Waiting twenty seconds each to find that out
    turns a few seconds of looking into minutes of it.
*/

void VCLogErr(const char *what, _kernel_oserror *e);
void VCLog(const char *fmt, ...);
/*
    Add a line to the log, if one has been asked for.

    LanMan98$Log names a file; every message sent and received is written
    into it as a line saying what it was and how it went, along with what
    the connection settled on.  It is meant to be read, and to be sent to
    somebody who can read it, which the packet dump is not.

    Costs nothing when the variable is not set.
*/

void VCMarkDead(vc_t);
/*
    Give up on this circuit.  A signature that does not check out means the
    conversation can no longer be followed - the sequence is lost, and what
    is on the wire cannot be trusted anyway - so every later use of it fails
    at once instead of waiting on a server that will not be understood.
    Without this the tear-down that follows the failure blocks.
*/
/*
    Sign every request from here on, starting at this sequence number, and
    require a signature on every reply.  A request takes the number given
    and its reply the one after, so the count goes up in twos.
*/

void VCSetFlags2(vc_t, int bits);

int VCFlags2(vc_t);
/*
    Extra SMB header flags2 bits that apply to every request on this
    circuit, over and above whatever the individual request sets.  What
    belongs here is anything agreed once during connection setup and then
    true for the rest of the session - NT status codes being the first.
*/

void VCDestruct(vc_t);

data_t VCBuffer(vc_t);

void VCResizeBuffer(vc_t, int);

void VCSend(vc_t, int);

void VCReceive(vc_t);

int VCLength(vc_t);
/*
    The length of the message VCReceive last collected.  SMB1 could work
    this out from the fields as it walked them; an SMB2 reply has to be
    bounds checked against the whole, so the whole has to be known.
*/

int VCReceiveRaw(char *, int, vc_t);

void VCCommunicate(vc_t, int);

void VCFlush(vc_t);

#endif

