#ifndef _CHANNELS_H_a7674d47_ #define _CHANNELS_H_a7674d47_ typedef struct chanops CHANOPS; #include "bpp.h" #include "str.h" /* * Operations on a channel. */ struct chanops { /* * Called when the open succeeds or fails. Arglist: * (int channel_number, int status) * where status is an OPENSTAT_* from below. It is safe to assume * that a zero status constitutes success and a nonzero status * failure; also, it is safe to call the other channel functions * while inside a success callback call - the channel is completely * ready to operate at that point. */ void (*opendone)(int, int); /* * Called to handle received data. Arglist: * (int chan, int ext, unsigned int code, const void *buf, int len) * chan is the channel number. For normal data, ext is zero and * code is meaningless; for extended data, ext is nonzero and code * is the data type code. buf and len describe the data itself. * * len will never be zero in normal operation. When EOF is received, * this is called once with all but the first argument 0. */ void (*gotdata)(int, int, unsigned int, const void *, int); /* * Called when a window adjustment is received. Arglist: * (int chan, unsigned int addl, unsigned int newwin) * chan is the channel number. addl is the number of bytes of * window added; newwin is the new send window. On a successful * open this will be called immedately after the success callback, * as if the connection started with a zero window. Note that addl * may occasionally be zero (and the window unchanged). */ void (*morewin)(int, unsigned int, unsigned int); /* * Called when a CHANNEL_REQUEST is received. Arglist: * (int chan, ROSTR req, int wantreply, const void *rest, int restlen) * chan is the channel number. req is a ROSTR giving the request * string. wantreply is nonzero if a reply is requested, or zero if * no specific reply is requested. rest and restlen describe the * request-specific portion of the packet, suitable for passing to * parse_data(). * * The storage areas pointed to by the second and fourth arguments * are owned by the caller and must not be modified; they must be * considered to go invalid once the function returns - they must be * copied if they are to be saved. * * Return value is one of the CHANREQRET_* values. */ int (*chanreq)(int, ROSTR, int, const void *, int); /* Request completely processed, including sending any reply. */ #define CHANREQRET_DONE 1 /* Request successful, no reply yet sent. */ #define CHANREQRET_OK 2 /* Request failed, no reply yet sent. */ #define CHANREQRET_FAIL 3 /* Request not recognized. */ #define CHANREQRET_UNK 4 /* * Called when a CHANNEL_CLOSE is received. The first arg is the * channel number. If chan_close() has already been called on the * channel, the second arg will be nonzero, and the channel has * finally been destroyed; if not, the second arg will be zero, and * the channel remains active for output until chan_close() is * called on it (which may be done from within this routine). */ void (*closed)(int, int); } ; /* * Open a channel to the peer. * * Values for first arg are CHANTYPE_* from below. Second arg is a * (pointer to a) CHANOPS function vector. The remaining args, if * any, depend on the first argument. * * The channel number is returned from chan_open as well as being * passed to the callback routines. If the open completion callback * indicates failure, the channel number is has become invalid and * must not be used. Channel numbers are arbitrary ints; code should * not assume anything about them, except that CHAN_NO_CHANNEL is * available as a value which will never be a valid channel number. */ #define CHAN_NO_CHANNEL (-1) extern int chan_open(int, const CHANOPS *, ...); /* CHANTYPE_* values */ /* Interactive session. No args. */ #define CHANTYPE_SESSION 1 /* Forwarded X connection. Args: const char * Source address (string form, eg "10.20.30.40") unsigned short int Source port */ #define CHANTYPE_X 2 /* Forwarded TCP connection, forwarded by peer request. Args: const char * Address connected to unsigned short int Port connected to const char * Originator address unsigned short int Originator port */ #define CHANTYPE_FWD_TCP 3 /* Forwarded TCP conenction, forwarded by local decision. Args: const char * Host to connect to (FQDN or address string) unsigned short int Port to connect to const char * Originator address unsigned short int Originator port */ #define CHANTYPE_DIR_TCP 4 /* OPENSTAT_* values */ /* Success. Channel is available for use. */ #define OPENSTAT_SUCCESS 0 /* Failure. The reason code was SSH_OPEN_ADMINISTRATIVELY_PROHIBITED. */ #define OPENSTAT_ADMIN_PROHIB 1 /* Failure. The reason code was SSH_OPEN_CONNECT_FAILED. */ #define OPENSTAT_CONNECT_FAILED 2 /* Failure. The reason code was SSH_OPEN_UNKNOWN_CHANNEL_TYPE */ #define OPENSTAT_BAD_TYPE 3 /* Failure. The reason code was SSH_OPEN_RESOURCE_SHORTAGE */ #define OPENSTAT_RESOURCE 4 /* Failure. The reason code was not recognized. */ #define OPENSTAT_UNKNOWN 5 /* * Calls to manipulate an established channel. It is an error to call * these before the channel's open has succeeded. */ /* Query window space. Returns the number of bytes receivable before window enlargement. Argument: channel number. */ extern unsigned int chan_get_rwin(int); /* Add window space. Channels start with zero window advertised. Arguments: (int chan_no, unsigned int additional_space) It is an error to call this such as to increase the abstract window-available value above 0xffffffff. It is also an error to call this after receiving EOF. */ extern void chan_add_rwin(int, unsigned int); /* Query window space. Returns the number of bytes sendable before window enlargement. Argument: channel number. It is not an error to call this after sending EOF, but it always returns zero then. */ extern unsigned int chan_get_wwin(int); /* Construct the beginning of a CHANNEL_REQUEST message. Returns a pointer to just after the header. */ extern unsigned char *chan_rq_hdr(int); /* Send a CHANNEL_REQUEST message. First arg is channel number. Second arg points at end of message. Third arg is a callback, called when the request succeeds (with arg CREQ_OK) or fails (with arg CREQ_FAIL), or if the channel is destroyed before either happens, with arg CREQ_CLOSE. */ extern void chan_send_req(int, unsigned char *, void (*)(int)); #define CREQ_OK 1 #define CREQ_FAIL 2 #define CREQ_CLOSE 3 /* Send data on a channel. Args are as for the data callback argument to chan_open(), above, except as noted. It is an error to try to send more data than the peer has window space for (see chan_get_wwin(), above). Sending zero bytes is not an error and does not send anything (in particular, does not send EOF). It is an error to call this after sending EOF. */ extern void chan_send_data(int, int, unsigned int, const void *, int); /* Declare EOF for sending on a channel. Arg is channel number. */ extern void chan_send_eof(int); /* Send a CHANNEL_SUCCESS (second arg nonzero) or CHANNEL_FAILURE (zero) on a channel. (First arg is channel number.) */ extern void chan_reqrep(int, int); /* Send a close on a channel. If a close has been received on the channel (indicated by a call through the closed member of the ops vector), this does final channel teardown and returns nonzero; otherwise, this initiates the process, the channel remains valid until the peer's close arrives (at which point teardown occurs), and this call returns zero. (Either way, no further output calls on the channel may be done.) */ extern int chan_close(int); extern LAYERDESC layer_channels; #endif