#ifndef _SMB_CONN_H
#define _SMB_CONN_H
#include <sys/dditypes.h>
#include <sys/t_lock.h>
#include <sys/queue.h>
#include <sys/uio.h>
#include <netsmb/smb_dev.h>
#include <netsmb/nsmb_kcrypt.h>
typedef struct smb_cred {
struct cred *scr_cred;
} smb_cred_t;
#define SMBO_GONE 0x1000000
#define SMBV_UNICODE 0x0040
#define SMBV_EXT_SEC 0x0080
#define SMBV_SIGNING 0x0100
#define SMBV_SMB2 0x0200
#define SMBV_HAS_FILEIDS 0x0400
#define SMBV_NO_WRITE_THRU 0x0800
#define SMBV_GONE SMBO_GONE
#define SMBS_RECONNECTING 0x0002
#define SMBS_CONNECTED 0x0004
#define SMBS_TCON_WAIT 0x0008
#define SMBS_FST_FAT 0x0010
#define SMBS_GONE SMBO_GONE
#define SMBFH_VALID 0x0002
#define SMBFH_GONE SMBO_GONE
struct smb_rq;
TAILQ_HEAD(smb_rqhead, smb_rq);
#define SMB_NBTIMO 15
#define SMB_DEFRQTIMO 30
#define SMBWRTTIMO 60
#define SMBSSNSETUPTIMO 60
#define SMBNOREPLYWAIT (0)
#define SMB_DIALECT(vcp) ((vcp)->vc_sopt.sv_proto)
#define SMB_CO_LOCK(cp) mutex_enter(&(cp)->co_lock)
#define SMB_CO_UNLOCK(cp) mutex_exit(&(cp)->co_lock)
struct smb_connobj {
kmutex_t co_lock;
int co_level;
int co_flags;
int co_usecount;
struct smb_connobj *co_parent;
SLIST_HEAD(, smb_connobj) co_children;
SLIST_ENTRY(smb_connobj) co_next;
void (*co_gone)(struct smb_connobj *);
void (*co_free)(struct smb_connobj *);
};
typedef struct smb_connobj smb_connobj_t;
enum smbco_level {
SMBL_SM = 0,
SMBL_VC = 1,
SMBL_SHARE = 2,
SMBL_FH = 3
};
struct smb_sopt {
uint16_t sv_proto;
uchar_t sv_sm;
int16_t sv_tz;
uint16_t sv_maxmux;
uint16_t sv_maxvcs;
uint16_t sv_rawmode;
uint32_t sv_maxtx;
uint32_t sv_maxraw;
uint32_t sv_skey;
uint32_t sv_caps;
uint32_t sv2_capabilities;
uint32_t sv2_maxtransact;
uint32_t sv2_maxread;
uint32_t sv2_maxwrite;
uint16_t sv2_security_mode;
uint16_t sv2_sessflags;
uint8_t sv2_guid[16];
};
typedef struct smb_sopt smb_sopt_t;
struct smb_iods {
uint8_t is_hflags;
uint16_t is_hflags2;
uint16_t is_smbuid;
uint16_t is_next_mid;
uint32_t is_txmax;
uint32_t is_rwmax;
uint32_t is_rxmax;
uint32_t is_wxmax;
uint32_t is_next_seq;
};
typedef struct smb_iods smb_iods_t;
typedef struct smb_vc {
struct smb_connobj vc_co;
enum smbiod_state vc_state;
kcondvar_t vc_statechg;
zoneid_t vc_zoneid;
uid_t vc_owner;
int vc_genid;
int vc_mackeylen;
int vc_ssnkeylen;
uint8_t *vc_mackey;
uint8_t *vc_ssnkey;
smb_crypto_mech_t vc_signmech;
struct smb_mac_ops *vc_sign_ops;
struct smb_tran_desc *vc_tdesc;
void *vc_tdata;
uint64_t vc2_oldest_message_id;
uint64_t vc2_next_message_id;
uint64_t vc2_limit_message_id;
uint64_t vc2_session_id;
uint64_t vc2_prev_session_id;
uint32_t vc2_lease_key;
smb_crypto_mech_t *vc3_crypt_mech;
uint8_t vc3_encrypt_key[SMB3_KEYLEN];
uint32_t vc3_encrypt_key_len;
uint8_t vc3_decrypt_key[SMB3_KEYLEN];
uint32_t vc3_decrypt_key_len;
uint64_t vc3_nonce_high;
uint64_t vc3_nonce_low;
kcondvar_t iod_idle;
krwlock_t iod_rqlock;
struct smb_rqhead iod_rqlist;
struct _kthread *iod_thr;
int iod_flags;
uint_t iod_muxcnt;
uint_t iod_muxwant;
kcondvar_t iod_muxwait;
boolean_t iod_noresp;
smb_iods_t vc_iods;
smb_sopt_t vc_sopt;
smbioc_ssn_work_t vc_work;
smbioc_ossn_t vc_ssn;
} smb_vc_t;
#define vc_lock vc_co.co_lock
#define vc_flags vc_co.co_flags
#define vc_owner vc_ssn.ssn_owner
#define vc_vopt vc_ssn.ssn_vopt
#define vc_minver vc_ssn.ssn_minver
#define vc_maxver vc_ssn.ssn_maxver
#define vc_srvname vc_ssn.ssn_srvname
#define vc_srvaddr vc_ssn.ssn_id.id_srvaddr
#define vc_domain vc_ssn.ssn_id.id_domain
#define vc_username vc_ssn.ssn_id.id_user
#define vc_cl_guid vc_work.wk_cl_guid
#define vc_maxmux vc_sopt.sv_maxmux
#define vc_hflags vc_iods.is_hflags
#define vc_hflags2 vc_iods.is_hflags2
#define vc_smbuid vc_iods.is_smbuid
#define vc_next_mid vc_iods.is_next_mid
#define vc_txmax vc_iods.is_txmax
#define vc_rwmax vc_iods.is_rwmax
#define vc_rxmax vc_iods.is_rxmax
#define vc_wxmax vc_iods.is_wxmax
#define vc_next_seq vc_iods.is_next_seq
#define SMB_VC_LOCK(vcp) mutex_enter(&(vcp)->vc_lock)
#define SMB_VC_UNLOCK(vcp) mutex_exit(&(vcp)->vc_lock)
#define CPTOVC(cp) ((struct smb_vc *)((void *)(cp)))
#define VCTOCP(vcp) (&(vcp)->vc_co)
#define SMB_UNICODE_STRINGS(vcp) \
(((vcp)->vc_flags & SMBV_SMB2) != 0 || \
((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE) != 0)
#define SMBIOD_RUNNING 0x0001
#define SMBIOD_SHUTDOWN 0x0002
typedef struct smb_share {
struct smb_connobj ss_co;
kcondvar_t ss_conn_done;
int ss_conn_waiters;
int ss_vcgenid;
uint16_t ss_tid;
uint16_t ss_options;
uint32_t ss2_tree_id;
uint32_t ss2_share_flags;
uint32_t ss2_share_caps;
smbioc_oshare_t ss_ioc;
} smb_share_t;
#define ss_lock ss_co.co_lock
#define ss_flags ss_co.co_flags
#define ss_use ss_ioc.sh_use
#define ss_type ss_ioc.sh_type
#define ss_name ss_ioc.sh_name
#define ss_pass ss_ioc.sh_pass
#define SMB_SS_LOCK(ssp) mutex_enter(&(ssp)->ss_lock)
#define SMB_SS_UNLOCK(ssp) mutex_exit(&(ssp)->ss_lock)
#define CPTOSS(cp) ((struct smb_share *)((void *)(cp)))
#define SSTOCP(ssp) (&(ssp)->ss_co)
#define SSTOVC(ssp) CPTOVC(((ssp)->ss_co.co_parent))
typedef struct smb2fid {
uint64_t fid_persistent;
uint64_t fid_volatile;
} smb2fid_t;
typedef struct smb_fh {
struct smb_connobj fh_co;
int fh_vcgenid;
uint32_t fh_rights;
smb2fid_t fh_fid2;
uint16_t fh_fid1;
} smb_fh_t;
#define fh_lock fh_co.co_lock
#define fh_flags fh_co.co_flags
#define SMB_FH_LOCK(fhp) mutex_enter(&(fhp)->fh_lock)
#define SMB_FH_UNLOCK(fhp) mutex_exit(&(fhp)->fh_lock)
#define CPTOFH(cp) ((struct smb_fh *)((void *)(cp)))
#define FHTOCP(fhp) (&(fhp)->fh_co)
#define FHTOSS(fhp) CPTOSS(((fhp)->fh_co.co_parent))
typedef struct smb_fscb {
void (*fscb_disconn)(smb_share_t *);
void (*fscb_connect)(smb_share_t *);
} smb_fscb_t;
void smb_fscb_set(smb_fscb_t *);
typedef struct smb_dev {
kmutex_t sd_lock;
struct smb_vc *sd_vc;
struct smb_share *sd_share;
struct smb_fh *sd_fh;
int sd_level;
int sd_vcgenid;
int sd_poll;
int sd_flags;
#define NSMBFL_OPEN 0x0001
#define NSMBFL_IOD 0x0004
#define NSMBFL_IOCTL 0x0010
zoneid_t zoneid;
} smb_dev_t;
extern const uint32_t nsmb_version;
int smb_dev2share(int fd, struct smb_share **sspp);
int smb_usr_ioctl(smb_dev_t *, int, intptr_t, int, cred_t *);
int smb_usr_get_flags2(smb_dev_t *sdp, intptr_t arg, int flags);
int smb_usr_get_ssnkey(smb_dev_t *sdp, intptr_t arg, int flags);
int smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags);
int smb_usr_simplerq(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
int smb_usr_t2request(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
int smb_usr_closefh(smb_dev_t *, cred_t *);
int smb_usr_rw(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr);
int smb_usr_ntcreate(smb_dev_t *, intptr_t, int, cred_t *);
int smb_usr_printjob(smb_dev_t *, intptr_t, int, cred_t *);
int smb_usr_get_ssn(smb_dev_t *, int, intptr_t, int, cred_t *);
int smb_usr_drop_ssn(smb_dev_t *sdp, int cmd);
int smb_usr_get_tree(smb_dev_t *, int, intptr_t, int, cred_t *);
int smb_usr_drop_tree(smb_dev_t *sdp, int cmd);
int smb_usr_iod_work(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
int smb_usr_iod_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags,
cred_t *cr);
int smb_pkey_ioctl(int, intptr_t, int, cred_t *);
int smb_iod_create(smb_vc_t *vcp);
int smb_iod_destroy(smb_vc_t *vcp);
void smb_iod_disconnect(smb_vc_t *vcp);
int smb2_iod_addrq(struct smb_rq *rqp);
int smb1_iod_addrq(struct smb_rq *rqp);
int smb1_iod_multirq(struct smb_rq *rqp);
int smb_iod_waitrq(struct smb_rq *rqp);
int smb_iod_waitrq_int(struct smb_rq *rqp);
void smb_iod_removerq(struct smb_rq *rqp);
int smb_iod_sendrecv(struct smb_rq *, int);
void smb_iod_shutdown_share(smb_share_t *ssp);
void smb_iod_sendall(smb_vc_t *);
int smb_iod_recvall(smb_vc_t *, boolean_t);
int nsmb_iod_connect(smb_vc_t *vcp, cred_t *cr);
int nsmb_iod_negotiate(smb_vc_t *vcp, cred_t *cr);
int nsmb_iod_ssnsetup(smb_vc_t *vcp, cred_t *cr);
int smb_iod_vc_work(smb_vc_t *, int, cred_t *);
int smb_iod_vc_idle(smb_vc_t *);
int smb_iod_vc_rcfail(smb_vc_t *);
int smb_iod_reconnect(smb_vc_t *);
int smb_sm_init(void);
int smb_sm_idle(void);
void smb_sm_done(void);
void smb_vc_hold(smb_vc_t *vcp);
void smb_vc_rele(smb_vc_t *vcp);
void smb_vc_kill(smb_vc_t *vcp);
int smb_vc_findcreate(smbioc_ossn_t *, smb_cred_t *, smb_vc_t **);
int smb_vc_create(smbioc_ossn_t *ossn, smb_cred_t *scred, smb_vc_t **vcpp);
const char *smb_vc_getpass(smb_vc_t *vcp);
uint16_t smb_vc_nextmid(smb_vc_t *vcp);
void *smb_vc_getipaddr(smb_vc_t *vcp, int *ipvers);
typedef void (*walk_share_func_t)(smb_share_t *);
void smb_vc_walkshares(struct smb_vc *, walk_share_func_t);
int smb_share_findcreate(smbioc_tcon_t *, smb_vc_t *,
smb_share_t **, smb_cred_t *);
void smb_share_hold(smb_share_t *ssp);
void smb_share_rele(smb_share_t *ssp);
void smb_share_kill(smb_share_t *ssp);
void smb_share_invalidate(smb_share_t *ssp);
int smb_share_tcon(smb_share_t *, smb_cred_t *);
int smb_fh_create(smb_share_t *ssp, struct smb_fh **fhpp);
void smb_fh_opened(struct smb_fh *fhp);
void smb_fh_close(struct smb_fh *fhp);
void smb_fh_hold(struct smb_fh *fhp);
void smb_fh_rele(struct smb_fh *fhp);
#endif