code:
/*-
 * Copyright (c) 2000-2001 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netsmb/smb_conn.h 206361 2010-04-07 16:50:38Z joel $
 */

/*
 * Two levels of connection hierarchy
 */
#define	SMBL_SM		0
#define SMBL_VC		1
#define SMBL_SHARE	2
#define SMBL_NUM	3
#define SMBL_NONE	(-1)

#define	SMB_CS_NONE	0x0000
#define	SMB_CS_UPPER	0x0001		/* convert passed string to upper case */
#define	SMB_CS_LOWER	0x0002		/* convert passed string to lower case */

/*
 * Common object flags
 */
#define SMBO_GONE		0x1000000

/*
 * access modes
 */
#define	SMBM_READ		0400	/* read conn attrs.(like list shares) */
#define	SMBM_WRITE		0200	/* modify conn attrs */
#define	SMBM_EXEC		0100	/* can send SMB requests */
#define	SMBM_READGRP		0040
#define	SMBM_WRITEGRP		0020
#define	SMBM_EXECGRP		0010
#define	SMBM_READOTH		0004
#define	SMBM_WRITEOTH		0002
#define	SMBM_EXECOTH		0001
#define	SMBM_MASK		0777
#define	SMBM_EXACT		010000	/* check for specified mode exactly */
#define	SMBM_ALL		(SMBM_READ | SMBM_WRITE | SMBM_EXEC)
#define	SMBM_DEFAULT		(SMBM_READ | SMBM_WRITE | SMBM_EXEC)
#define	SMBM_ANY_OWNER		((uid_t)-1)
#define	SMBM_ANY_GROUP		((gid_t)-1)

/*
 * VC flags
 */
#define SMBV_PERMANENT		0x0002
#define SMBV_LONGNAMES		0x0004	/* connection is configured to use long names */
#define	SMBV_ENCRYPT		0x0008	/* server asked for encrypted password */
#define	SMBV_WIN95		0x0010	/* used to apply bugfixes for this OS */
#define	SMBV_PRIVATE		0x0020	/* connection can be used only by creator */
#define	SMBV_RECONNECTING	0x0040	/* conn is in the process of reconnection */
#define SMBV_SINGLESHARE	0x0080	/* only one share connecting should be allowed */
#define SMBV_CREATE		0x0100	/* lookup for create operation */
/*#define SMBV_FAILED		0x0200*/	/* last reconnect attempt has failed */
#define SMBV_UNICODE		0x0400	/* connection is configured to use Unicode */

/*
 * smb_share flags
 */
#define SMBS_PERMANENT		0x0001
#define SMBS_RECONNECTING	0x0002
#define SMBS_CONNECTED		0x0004

/*
 * share types
 */
#define	SMB_ST_DISK		0x0	/* A: */
#define	SMB_ST_PRINTER		0x1	/* LPT: */
#define	SMB_ST_PIPE		0x2	/* IPC */
#define	SMB_ST_COMM		0x3	/* COMM */
#define	SMB_ST_ANY		0x4
#define	SMB_ST_MAX		0x4
#define SMB_ST_NONE		0xff	/* not a part of protocol */

/*
 * Negotiated protocol parameters
 */
struct smb_sopt {
	int		sv_proto;
	int16_t		sv_tz;		/* offset in min relative to UTC */
	u_int32_t	sv_maxtx;	/* maximum transmit buf size */
	u_char		sv_sm;		/* security mode */
	u_int16_t	sv_maxmux;	/* max number of outstanding rq's */
	u_int16_t 	sv_maxvcs;	/* max number of VCs */
	u_int16_t	sv_rawmode;
	u_int32_t	sv_maxraw;	/* maximum raw-buffer size */
	u_int32_t	sv_skey;	/* session key */
	u_int32_t	sv_caps;	/* capabilities SMB_CAP_ */
};

/*
 * network IO daemon states
 */
enum smbiod_state {
	SMBIOD_ST_NOTCONN,	/* no connect request was made */
	SMBIOD_ST_RECONNECT,	/* a [re]connect attempt is in progress */
	SMBIOD_ST_TRANACTIVE,	/* transport level is up */
	SMBIOD_ST_VCACTIVE,	/* session established */
	SMBIOD_ST_DEAD		/* connection broken, transport is down */
};

/*
 * Info structures
 */
#define	SMB_INFO_NONE		0
#define	SMB_INFO_VC		2
#define	SMB_INFO_SHARE		3

struct smb_vc_info {
	int		itype;
	int		usecount;
	uid_t		uid;		/* user id of connection */
	gid_t		gid;		/* group of connection */
	mode_t		mode;		/* access mode */
	int		flags;
	enum smbiod_state iodstate;
	struct smb_sopt	sopt;
	char		srvname[SMB_MAXSRVNAMELEN + 1];
	char		vcname[128];
};

struct smb_share_info {
	int		itype;
	int		usecount;
	u_short		tid;		/* TID */
	int		type;		/* share type */
	uid_t		uid;		/* user id of connection */
	gid_t		gid;		/* group of connection */
	mode_t		mode;		/* access mode */
	int		flags;
	char		sname[128];
};

#ifdef _KERNEL

#include <sys/lock.h>
#include <sys/lockmgr.h>
#include <netsmb/smb_subr.h>

#define CONNADDREQ(a1,a2)	((a1)->sa_len == (a2)->sa_len && \
				 bcmp(a1, a2, (a1)->sa_len) == 0)

struct smb_vc;
struct smb_share;
struct smb_cred;
struct smb_rq;
struct mbdata;
struct smbioc_oshare;
struct smbioc_ossn;
struct uio;

TAILQ_HEAD(smb_rqhead, smb_rq);

#define SMB_DEFRQTIMO	5

#define SMB_DIALECT(vcp)	((vcp)->vc_sopt.sv_proto)

struct smb_tran_desc;

/*
 * Connection object
 */
struct smb_connobj;

typedef void smb_co_gone_t (struct smb_connobj *cp, struct smb_cred *scred);
typedef void smb_co_free_t (struct smb_connobj *cp);

#define	SMB_CO_LOCK(cp)		smb_sl_lock(&(cp)->co_interlock)
#define	SMB_CO_UNLOCK(cp)	smb_sl_unlock(&(cp)->co_interlock)

struct smb_connobj {
	int			co_level;	/* SMBL_ */
	int			co_flags;
	struct lock		co_lock;
	struct smb_slock	co_interlock;
	int			co_usecount;
	struct smb_connobj *	co_parent;
	SLIST_HEAD(,smb_connobj)co_children;
	SLIST_ENTRY(smb_connobj)co_next;
	smb_co_gone_t *		co_gone;
	smb_co_free_t *		co_free;
};

#define	SMBCO_FOREACH(var, cp)	SLIST_FOREACH((var), &(cp)->co_children, co_next)

/*
 * Virtual Circuit (session) to a server.
 * This is the most (over)complicated part of SMB protocol.
 * For the user security level (usl), each session with different remote
 * user name has its own VC.
 * It is unclear however, should share security level (ssl) allow additional
 * VCs, because user name is not used and can be the same. On other hand,
 * multiple VCs allows us to create separate sessions to server on a per
 * user basis.
 */

/*
 * This lock protects vc_flags
 */
#define	SMBC_ST_LOCK(vcp)	smb_sl_lock(&(vcp)->vc_stlock)
#define	SMBC_ST_UNLOCK(vcp)	smb_sl_unlock(&(vcp)->vc_stlock)

struct smb_vc {
	struct smb_connobj obj;
	char *		vc_srvname;
	struct sockaddr*vc_paddr;	/* server addr */
	struct sockaddr*vc_laddr;	/* local addr, if any */
	char *		vc_username;
	char *		vc_pass;	/* password for usl case */
	char *		vc_domain;	/* workgroup/primary domain */

	u_int		vc_timo;	/* default request timeout */
	int		vc_maxvcs;	/* maximum number of VC per connection */

	void *		vc_tolower;	/* local charset */
	void *		vc_toupper;	/* local charset */
	void *		vc_toserver;	/* local charset to server one */
	void *		vc_tolocal;	/* server charset to local one */
	int		vc_number;	/* number of this VC from the client side */
	int		vc_genid;
	uid_t		vc_uid;		/* user id of connection */
	gid_t		vc_grp;		/* group of connection */
	mode_t		vc_mode;	/* access mode */
	u_short		vc_smbuid;	/* unique vc id assigned by server */

	u_char		vc_hflags;	/* or'ed with flags in the smb header */
	u_short		vc_hflags2;	/* or'ed with flags in the smb header */
	void *		vc_tdata;	/* transport control block */
	struct smb_tran_desc *vc_tdesc;
	int		vc_chlen;	/* actual challenge length */
	u_char 		vc_ch[SMB_MAXCHALLENGELEN];
	u_short		vc_mid;		/* multiplex id */
	struct smb_sopt	vc_sopt;	/* server options */
	int		vc_txmax;	/* max tx/rx packet size */
	int		vc_rxmax;	/* max readx data size */
	int		vc_wxmax;	/* max writex data size */
	struct smbiod *	vc_iod;
	struct smb_slock vc_stlock;
	u_int32_t	vc_seqno;	/* my next sequence number */
	u_int8_t	*vc_mackey;	/* MAC key */
	int		vc_mackeylen;	/* length of MAC key */
};

#define vc_maxmux	vc_sopt.sv_maxmux
#define	vc_flags	obj.co_flags

#define SMB_UNICODE_STRINGS(vcp)	((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE)

/*
 * smb_share structure describes connection to the given SMB share (tree).
 * Connection to share is always built on top of the VC.
 */

/*
 * This lock protects ss_flags
 */
#define	SMBS_ST_LOCK(ssp)	smb_sl_lock(&(ssp)->ss_stlock)
#define	SMBS_ST_LOCKPTR(ssp)	(&(ssp)->ss_stlock)
#define	SMBS_ST_UNLOCK(ssp)	smb_sl_unlock(&(ssp)->ss_stlock)

struct smb_share {
	struct smb_connobj obj;
	char *		ss_name;
	u_short		ss_tid;		/* TID */
	int		ss_type;	/* share type */
	uid_t		ss_uid;		/* user id of connection */
	gid_t		ss_grp;		/* group of connection */
	mode_t		ss_mode;	/* access mode */
	int		ss_vcgenid;
	char *		ss_pass;	/* password to a share, can be null */
	struct smb_slock ss_stlock;
};

#define	ss_flags	obj.co_flags

#define CPTOVC(cp)	((struct smb_vc*)(cp))
#define VCTOCP(vcp)	(&(vcp)->obj)
#define CPTOSS(cp)	((struct smb_share*)(cp))
#define	SSTOVC(ssp)	CPTOVC(((ssp)->obj.co_parent))
#define SSTOCP(ssp)	(&(ssp)->obj)

struct smb_vcspec {
	char *		srvname;
	struct sockaddr*sap;
	struct sockaddr*lap;
	int		flags;
	char *		username;
	char *		pass;
	char *		domain;
	mode_t		mode;
	mode_t		rights;
	uid_t		owner;
	gid_t		group;
	char *		localcs;
	char *		servercs;
	struct smb_sharespec *shspec;
	struct smb_share *ssp;		/* returned */
	/*
	 * The rest is an internal data
	 */
	struct smb_cred *scred;
};

struct smb_sharespec {
	char *		name;
	char *		pass;
	mode_t		mode;
	mode_t		rights;
	uid_t		owner;
	gid_t		group;
	int		stype;
	/*
	 * The rest is an internal data
	 */
	struct smb_cred *scred;
};

/*
 * Session level functions
 */
int  smb_sm_init(void);
int  smb_sm_done(void);
int  smb_sm_lookup(struct smb_vcspec *vcspec,
	struct smb_sharespec *shspec, struct smb_cred *scred,
	struct smb_vc **vcpp);

/*
 * Connection object
 */
void smb_co_ref(struct smb_connobj *cp);
void smb_co_rele(struct smb_connobj *cp, struct smb_cred *scred);
int  smb_co_get(struct smb_connobj *cp, int flags, struct smb_cred *scred);
void smb_co_put(struct smb_connobj *cp, struct smb_cred *scred);
int  smb_co_lock(struct smb_connobj *cp, int flags);
void smb_co_unlock(struct smb_connobj *cp, int flags);

/*
 * session level functions
 */
int  smb_vc_create(struct smb_vcspec *vcspec,
	struct smb_cred *scred, struct smb_vc **vcpp);
int  smb_vc_connect(struct smb_vc *vcp, struct smb_cred *scred);
int  smb_vc_access(struct smb_vc *vcp, struct smb_cred *scred, mode_t mode);
int  smb_vc_get(struct smb_vc *vcp, int flags, struct smb_cred *scred);
void smb_vc_put(struct smb_vc *vcp, struct smb_cred *scred);
void smb_vc_ref(struct smb_vc *vcp);
void smb_vc_rele(struct smb_vc *vcp, struct smb_cred *scred);
int  smb_vc_lock(struct smb_vc *vcp, int flags);
void smb_vc_unlock(struct smb_vc *vcp, int flags);
int  smb_vc_lookupshare(struct smb_vc *vcp, struct smb_sharespec *shspec,
	struct smb_cred *scred, struct smb_share **sspp);
const char * smb_vc_getpass(struct smb_vc *vcp);
u_short smb_vc_nextmid(struct smb_vc *vcp);

/*
 * share level functions
 */
int  smb_share_create(struct smb_vc *vcp, struct smb_sharespec *shspec,
	struct smb_cred *scred, struct smb_share **sspp);
int  smb_share_access(struct smb_share *ssp, struct smb_cred *scred, mode_t mode);
void smb_share_ref(struct smb_share *ssp);
void smb_share_rele(struct smb_share *ssp, struct smb_cred *scred);
int  smb_share_get(struct smb_share *ssp, int flags, struct smb_cred *scred);
void smb_share_put(struct smb_share *ssp, struct smb_cred *scred);
int  smb_share_lock(struct smb_share *ssp, int flags);
void smb_share_unlock(struct smb_share *ssp, int flags);
void smb_share_invalidate(struct smb_share *ssp);
int  smb_share_valid(struct smb_share *ssp);
const char * smb_share_getpass(struct smb_share *ssp);

/*
 * SMB protocol level functions
 */
int  smb_smb_negotiate(struct smb_vc *vcp, struct smb_cred *scred);
int  smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred);
int  smb_smb_ssnclose(struct smb_vc *vcp, struct smb_cred *scred);
int  smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred);
int  smb_smb_treedisconnect(struct smb_share *ssp, struct smb_cred *scred);
int  smb_read(struct smb_share *ssp, u_int16_t fid, struct uio *uio,
	struct smb_cred *scred);
int  smb_write(struct smb_share *ssp, u_int16_t fid, struct uio *uio,
	struct smb_cred *scred);
int  smb_smb_echo(struct smb_vc *vcp, struct smb_cred *scred);

/*
 * smbiod thread
 */

#define	SMBIOD_EV_NEWRQ		0x0001
#define	SMBIOD_EV_SHUTDOWN	0x0002
#define	SMBIOD_EV_CONNECT	0x0003
#define	SMBIOD_EV_DISCONNECT	0x0004
#define	SMBIOD_EV_TREECONNECT	0x0005
#define	SMBIOD_EV_MASK		0x00ff
#define	SMBIOD_EV_SYNC		0x0100
#define	SMBIOD_EV_PROCESSING	0x0200

struct smbiod_event {
	int	ev_type;
	int	ev_error;
	void *	ev_ident;
	STAILQ_ENTRY(smbiod_event)	ev_link;
};

#define	SMBIOD_SHUTDOWN		0x0001

struct smbiod {
	int			iod_id;
	int			iod_flags;
	enum smbiod_state	iod_state;
	int			iod_muxcnt;	/* number of active outstanding requests */
	int			iod_sleeptimo;
	struct smb_vc *		iod_vc;
	struct smb_slock	iod_rqlock;	/* iod_rqlist, iod_muxwant */
	struct smb_rqhead	iod_rqlist;	/* list of outstanding requests */
	int			iod_muxwant;
	struct proc *		iod_p;
	struct thread *		iod_td;
	struct smb_cred		iod_scred;
	struct smb_slock	iod_evlock;	/* iod_evlist */
	STAILQ_HEAD(,smbiod_event) iod_evlist;
	struct timespec 	iod_lastrqsent;
	struct timespec 	iod_pingtimo;
};

int  smb_iod_init(void);
int  smb_iod_done(void);
int  smb_iod_create(struct smb_vc *vcp);
int  smb_iod_destroy(struct smbiod *iod);
int  smb_iod_request(struct smbiod *iod, int event, void *ident);
int  smb_iod_addrq(struct smb_rq *rqp);
int  smb_iod_waitrq(struct smb_rq *rqp);
int  smb_iod_removerq(struct smb_rq *rqp);

#endif /* _KERNEL */


code:
/*-
 * Copyright (c) 2000-2001 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netsmb/smb_dev.h 217174 2011-01-08 23:06:54Z csjp $
 */
#ifndef _NETSMB_DEV_H_
#define _NETSMB_DEV_H_

#ifndef _KERNEL
#include <sys/types.h>
#endif
#include <sys/ioccom.h>

#include <netsmb/smb.h>

#define	NSMB_NAME		"nsmb"

#define NSMB_VERMAJ	1
#define NSMB_VERMIN	3006
#define NSMB_VERSION	(NSMB_VERMAJ * 100000 + NSMB_VERMIN)

#define NSMBFL_OPEN		0x0001

#define	SMBVOPT_CREATE		0x0001	/* create object if necessary */
#define	SMBVOPT_PRIVATE		0x0002	/* connection should be private */
#define	SMBVOPT_SINGLESHARE	0x0004	/* keep only one share at this VC */
#define	SMBVOPT_PERMANENT	0x0010	/* object will keep last reference */

#define	SMBSOPT_CREATE		0x0001	/* create object if necessary */
#define	SMBSOPT_PERMANENT	0x0010	/* object will keep last reference */

/*
 * SMBIOC_LOOKUP flags
 */
#define SMBLK_CREATE		0x0001

struct smbioc_ossn {
	int		ioc_opt;
	uint32_t	ioc_svlen;	/* size of ioc_server address */
	struct sockaddr*ioc_server;
	uint32_t	ioc_lolen;	/* size of ioc_local address */
	struct sockaddr*ioc_local;
	char		ioc_srvname[SMB_MAXSRVNAMELEN + 1];
	int		ioc_timeout;
	int		ioc_retrycount;	/* number of retries before giveup */
	char		ioc_localcs[16];/* local charset */
	char		ioc_servercs[16];/* server charset */
	char		ioc_user[SMB_MAXUSERNAMELEN + 1];
	char		ioc_workgroup[SMB_MAXUSERNAMELEN + 1];
	char		ioc_password[SMB_MAXPASSWORDLEN + 1];
	uid_t		ioc_owner;	/* proposed owner */
	gid_t		ioc_group;	/* proposed group */
	mode_t		ioc_mode;	/* desired access mode */
	mode_t		ioc_rights;	/* SMBM_* */
};

struct smbioc_oshare {
	int		ioc_opt;
	int		ioc_stype;	/* share type */
	char		ioc_share[SMB_MAXSHARENAMELEN + 1];
	char		ioc_password[SMB_MAXPASSWORDLEN + 1];
	uid_t		ioc_owner;	/* proposed owner of share */
	gid_t		ioc_group;	/* proposed group of share */
	mode_t		ioc_mode;	/* desired access mode to share */
	mode_t		ioc_rights;	/* SMBM_* */
};

struct smbioc_rq {
	u_char		ioc_cmd;
	u_char		ioc_twc;
	void *		ioc_twords;
	u_short		ioc_tbc;
	void *		ioc_tbytes;
	int		ioc_rpbufsz;
	char *		ioc_rpbuf;
	u_char		ioc_rwc;
	u_short		ioc_rbc;
	u_int8_t	ioc_errclass;
	u_int16_t	ioc_serror;
	u_int32_t	ioc_error;
};

struct smbioc_t2rq {
	u_int16_t	ioc_setup[3];
	int		ioc_setupcnt;
	char *		ioc_name;
	u_short		ioc_tparamcnt;
	void *		ioc_tparam;
	u_short		ioc_tdatacnt;
	void *		ioc_tdata;
	u_short		ioc_rparamcnt;
	void *		ioc_rparam;
	u_short		ioc_rdatacnt;
	void *		ioc_rdata;
};

struct smbioc_flags {
	int		ioc_level;	/* 0 - session, 1 - share */
	int		ioc_mask;
	int		ioc_flags;
};

struct smbioc_lookup {
	int		ioc_level;
	int		ioc_flags;
	struct smbioc_ossn	ioc_ssn;
	struct smbioc_oshare	ioc_sh;
};

struct smbioc_rw {
	smbfh	ioc_fh;
	char *	ioc_base;
	off_t	ioc_offset;
	int	ioc_cnt;
};

/*
 * Device IOCTLs
 */
#define	SMBIOC_OPENSESSION	_IOW('n',  100, struct smbioc_ossn)
#define	SMBIOC_OPENSHARE	_IOW('n',  101, struct smbioc_oshare)
#define	SMBIOC_REQUEST		_IOWR('n', 102, struct smbioc_rq)
#define	SMBIOC_T2RQ		_IOWR('n', 103, struct smbioc_t2rq)
#define	SMBIOC_SETFLAGS		_IOW('n',  104, struct smbioc_flags)
#define	SMBIOC_LOOKUP		_IOW('n',  106, struct smbioc_lookup)
#define	SMBIOC_READ		_IOWR('n', 107, struct smbioc_rw)
#define	SMBIOC_WRITE		_IOWR('n', 108, struct smbioc_rw)

#ifdef _KERNEL

#define SMBST_CONNECTED	1

STAILQ_HEAD(smbrqh, smb_rq);

struct smb_dev {
	int		sd_opened;
	int		sd_level;
	struct smb_vc * sd_vc;		/* reference to VC */
	struct smb_share *sd_share;	/* reference to share if any */
	int		sd_poll;
	int		sd_seq;
/*	struct ifqueue	sd_rdqueue;
	struct ifqueue	sd_wrqueue;
	struct selinfo	sd_pollinfo;
	struct smbrqh	sd_rqlist;
	struct smbrqh	sd_rplist;
	struct ucred 	*sd_owner;*/
	int		sd_flags;
};

struct smb_cred;
/*
 * Compound user interface
 */
int  smb_usr_lookup(struct smbioc_lookup *dp, struct smb_cred *scred,
	struct smb_vc **vcpp, struct smb_share **sspp);
int  smb_usr_opensession(struct smbioc_ossn *data,
	struct smb_cred *scred,	struct smb_vc **vcpp);
int  smb_usr_openshare(struct smb_vc *vcp, struct smbioc_oshare *data,
	struct smb_cred *scred, struct smb_share **sspp);
int  smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *data,
	struct smb_cred *scred);
int  smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *data,
	struct smb_cred *scred);
int  smb_dev2share(int fd, int mode, struct smb_cred *scred,
	struct smb_share **sspp);

#endif /* _KERNEL */

#endif /* _NETSMB_DEV_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Copyright (c) 2000-2001 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netsmb/smb_rq.h 206361 2010-04-07 16:50:38Z joel $
 */
#ifndef _NETSMB_SMB_RQ_H_
#define	_NETSMB_SMB_RQ_H_

#ifndef MB_MSYSTEM
#include <sys/mchain.h>
#endif

#define	SMBR_ALLOCED		0x0001	/* structure was malloced */
#define	SMBR_SENT		0x0002	/* request successfully transmitted */
#define	SMBR_REXMIT		0x0004	/* request should be retransmitted */
#define	SMBR_INTR		0x0008	/* request interrupted */
#define	SMBR_RESTART		0x0010	/* request should be repeated if possible */
#define	SMBR_NORESTART		0x0020	/* request is not restartable */
#define	SMBR_MULTIPACKET	0x0040	/* multiple packets can be sent and received */
#define	SMBR_INTERNAL		0x0080	/* request is internal to smbrqd */
#define	SMBR_XLOCK		0x0100	/* request locked and can't be moved */
#define	SMBR_XLOCKWANT		0x0200	/* waiter on XLOCK */

#define SMBT2_ALLSENT		0x0001	/* all data and params are sent */
#define SMBT2_ALLRECV		0x0002	/* all data and params are received */
#define	SMBT2_ALLOCED		0x0004
#define	SMBT2_RESTART		0x0008
#define	SMBT2_NORESTART		0x0010
#define	SMBT2_SECONDARY		0x0020	/* secondary request */

#define SMBRQ_SLOCK(rqp)	smb_sl_lock(&(rqp)->sr_slock)
#define SMBRQ_SUNLOCK(rqp)	smb_sl_unlock(&(rqp)->sr_slock)
#define SMBRQ_SLOCKPTR(rqp)	(&(rqp)->sr_slock)

enum smbrq_state {
	SMBRQ_NOTSENT,		/* rq have data to send */
	SMBRQ_SENT,		/* send procedure completed */
	SMBRQ_REPLYRECEIVED,
	SMBRQ_NOTIFIED		/* owner notified about completion */
};

struct smb_vc;
struct smb_t2rq;

struct smb_rq {
	enum smbrq_state	sr_state;
	struct smb_vc * 	sr_vc;
	struct smb_share*	sr_share;
	u_short			sr_mid;
	u_int32_t		sr_seqno;
	u_int32_t		sr_rseqno;
	struct mbchain		sr_rq;
	u_int8_t		sr_rqflags;
	u_int16_t		sr_rqflags2;
	u_char *		sr_wcount;
	void *			sr_bcount;	/* Points to 2-byte buffer. */
	struct mdchain		sr_rp;
	int			sr_rpgen;
	int			sr_rplast;
	int			sr_flags;	/* SMBR_* */
	int			sr_rpsize;
	struct smb_cred *	sr_cred;
	int			sr_timo;
	int			sr_rexmit;
	int			sr_sendcnt;
	struct timespec 	sr_timesent;
	int			sr_lerror;
	u_int8_t *		sr_rqsig;
	void *			sr_rqtid;	/* Points to 2-byte buffer. */
	void *			sr_rquid;	/* Points to 2-byte buffer. */
	u_int8_t		sr_errclass;
	u_int16_t		sr_serror;
	u_int32_t		sr_error;
	u_int8_t		sr_rpflags;
	u_int16_t		sr_rpflags2;
	u_int16_t		sr_rptid;
	u_int16_t		sr_rppid;
	u_int16_t		sr_rpuid;
	u_int16_t		sr_rpmid;
	struct smb_slock	sr_slock;	/* short term locks */
	struct smb_t2rq *	sr_t2;
	TAILQ_ENTRY(smb_rq)	sr_link;
};

struct smb_t2rq {
	u_int16_t	t2_setupcount;
	u_int16_t *	t2_setupdata;
	u_int16_t	t2_setup[2];	/* most of rqs has setupcount of 1 */
	u_int8_t	t2_maxscount;	/* max setup words to return */
	u_int16_t	t2_maxpcount;	/* max param bytes to return */
	u_int16_t	t2_maxdcount;	/* max data bytes to return */
	u_int16_t	t2_fid;		/* for T2 request */
	char *		t_name;		/* for T request, should be zero for T2 */
	int		t2_flags;	/* SMBT2_ */
	struct mbchain	t2_tparam;	/* parameters to transmit */
	struct mbchain	t2_tdata;	/* data to transmit */
	struct mdchain	t2_rparam;	/* received parameters */
	struct mdchain	t2_rdata;	/* received data */
	struct smb_cred*t2_cred;
	struct smb_connobj *t2_source;
	struct smb_rq *	t2_rq;
	struct smb_vc * t2_vc;
};

int  smb_rq_alloc(struct smb_connobj *layer, u_char cmd,
	struct smb_cred *scred, struct smb_rq **rqpp);
int  smb_rq_init(struct smb_rq *rqp, struct smb_connobj *layer, u_char cmd,
	struct smb_cred *scred);
void smb_rq_done(struct smb_rq *rqp);
int  smb_rq_getrequest(struct smb_rq *rqp, struct mbchain **mbpp);
int  smb_rq_getreply(struct smb_rq *rqp, struct mdchain **mbpp);
void smb_rq_wstart(struct smb_rq *rqp);
void smb_rq_wend(struct smb_rq *rqp);
void smb_rq_bstart(struct smb_rq *rqp);
void smb_rq_bend(struct smb_rq *rqp);
int  smb_rq_intr(struct smb_rq *rqp);
int  smb_rq_simple(struct smb_rq *rqp);

int  smb_t2_alloc(struct smb_connobj *layer, u_short setup, struct smb_cred *scred,
	struct smb_t2rq **rqpp);
int  smb_t2_init(struct smb_t2rq *rqp, struct smb_connobj *layer, u_short setup,
	struct smb_cred *scred);
void smb_t2_done(struct smb_t2rq *t2p);
int  smb_t2_request(struct smb_t2rq *t2p);

#endif /* !_NETSMB_SMB_RQ_H_ */


code:
/*-
 * Copyright (c) 2000-2001 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netsmb/smb_subr.h 217174 2011-01-08 23:06:54Z csjp $
 */
#ifndef _NETSMB_SMB_SUBR_H_
#define _NETSMB_SMB_SUBR_H_

#ifndef _KERNEL
#error "This file shouldn't be included from userland programs"
#endif

#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_SMBTEMP);
#endif

#define SMBERROR(format, args...) printf("%s: "format, __func__ ,## args)
#define SMBPANIC(format, args...) printf("%s: "format, __func__ ,## args)

#ifdef SMB_SOCKET_DEBUG
#define SMBSDEBUG(format, args...) printf("%s: "format, __func__ ,## args)
#else
#define SMBSDEBUG(format, args...)
#endif

#ifdef SMB_IOD_DEBUG
#define SMBIODEBUG(format, args...) printf("%s: "format, __func__ ,## args)
#else
#define SMBIODEBUG(format, args...)
#endif

#ifdef SMB_SOCKETDATA_DEBUG
void m_dumpm(struct mbuf *m);
#else
#define m_dumpm(m)
#endif

#define	SMB_SIGMASK(set) 						\
	(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) ||	\
	 SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) ||	\
	 SIGISMEMBER(set, SIGQUIT))

#define	smb_suser(cred)	priv_check_cred(cred, PRIV_NETSMB, 0)

/*
 * Compatibility wrappers for simple locks
 */

#include <sys/lock.h>
#include <sys/mutex.h>

#define	smb_slock			mtx
#define	smb_sl_init(mtx, desc)		mtx_init(mtx, desc, NULL, MTX_DEF)
#define	smb_sl_destroy(mtx)		mtx_destroy(mtx)
#define	smb_sl_lock(mtx)		mtx_lock(mtx)
#define	smb_sl_unlock(mtx)		mtx_unlock(mtx)

#define SMB_STRFREE(p)	do { if (p) smb_strfree(p); } while(0)

typedef u_int16_t	smb_unichar;
typedef	smb_unichar	*smb_uniptr;

/*
 * Crediantials of user/process being processing in the connection procedures
 */
struct smb_cred {
	struct thread *	scr_td;
	struct ucred *	scr_cred;
};

extern smb_unichar smb_unieol;

struct mbchain;
struct smb_vc;
struct smb_rq;

void smb_makescred(struct smb_cred *scred, struct thread *td, struct ucred *cred);
int  smb_td_intr(struct thread *);
char *smb_strdup(const char *s);
void *smb_memdup(const void *umem, int len);
char *smb_strdupin(char *s, size_t maxlen);
void *smb_memdupin(void *umem, size_t len);
void smb_strtouni(u_int16_t *dst, const char *src);
void smb_strfree(char *s);
void smb_memfree(void *s);
void *smb_zmalloc(size_t size, struct malloc_type *type, int flags);

int  smb_calcmackey(struct smb_vc *vcp);
int  smb_encrypt(const u_char *apwd, u_char *C8, u_char *RN);
int  smb_ntencrypt(const u_char *apwd, u_char *C8, u_char *RN);
int  smb_maperror(int eclass, int eno);
int  smb_put_dmem(struct mbchain *mbp, struct smb_vc *vcp,
	const char *src, size_t len, int caseopt);
int  smb_put_dstring(struct mbchain *mbp, struct smb_vc *vcp,
	const char *src, int caseopt);
int  smb_put_string(struct smb_rq *rqp, const char *src);
int  smb_put_asunistring(struct smb_rq *rqp, const char *src);
int  smb_rq_sign(struct smb_rq *rqp);
int  smb_rq_verify(struct smb_rq *rqp);

#endif /* !_NETSMB_SMB_SUBR_H_ */


code:
/*-
 * Copyright (c) 2000-2001 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netsmb/smb_tran.h 206361 2010-04-07 16:50:38Z joel $
 */

#ifndef _NETSMB_SMB_TRAN_H_
#define	_NETSMB_SMB_TRAN_H_

#include <sys/socket.h>

/*
 * Known transports
 */
#define	SMBT_NBTCP	1

/*
 * Transport parameters
 */
#define	SMBTP_SNDSZ	1		/* R  - int */
#define	SMBTP_RCVSZ	2		/* R  - int */
#define	SMBTP_TIMEOUT	3		/* RW - struct timespec */
#define	SMBTP_SELECTID	4		/* RW - (void *) */
#define SMBTP_UPCALL	5		/* RW - (* void)(void *) */

struct smb_tran_ops;

struct smb_tran_desc {
	sa_family_t	tr_type;
	int	(*tr_create)(struct smb_vc *vcp, struct thread *td);
	int	(*tr_done)(struct smb_vc *vcp, struct thread *td);
	int	(*tr_bind)(struct smb_vc *vcp, struct sockaddr *sap, struct thread *td);
	int	(*tr_connect)(struct smb_vc *vcp, struct sockaddr *sap, struct thread *td);
	int	(*tr_disconnect)(struct smb_vc *vcp, struct thread *td);
	int	(*tr_send)(struct smb_vc *vcp, struct mbuf *m0, struct thread *td);
	int	(*tr_recv)(struct smb_vc *vcp, struct mbuf **mpp, struct thread *td);
	void	(*tr_timo)(struct smb_vc *vcp);
	void	(*tr_intr)(struct smb_vc *vcp);
	int	(*tr_getparam)(struct smb_vc *vcp, int param, void *data);
	int	(*tr_setparam)(struct smb_vc *vcp, int param, void *data);
	int	(*tr_fatal)(struct smb_vc *vcp, int error);
#ifdef notyet
	int	(*tr_poll)(struct smb_vc *vcp, struct thread *td);
	int	(*tr_cmpaddr)(void *addr1, void *addr2);
#endif
	LIST_ENTRY(smb_tran_desc)	tr_link;
};

#define SMB_TRAN_CREATE(vcp,p)		(vcp)->vc_tdesc->tr_create(vcp,p)
#define SMB_TRAN_DONE(vcp,p)		(vcp)->vc_tdesc->tr_done(vcp,p)
#define	SMB_TRAN_BIND(vcp,sap,p)	(vcp)->vc_tdesc->tr_bind(vcp,sap,p)
#define	SMB_TRAN_CONNECT(vcp,sap,p)	(vcp)->vc_tdesc->tr_connect(vcp,sap,p)
#define	SMB_TRAN_DISCONNECT(vcp,p)	(vcp)->vc_tdesc->tr_disconnect(vcp,p)
#define	SMB_TRAN_SEND(vcp,m0,p)		(vcp)->vc_tdesc->tr_send(vcp,m0,p)
#define	SMB_TRAN_RECV(vcp,m,p)		(vcp)->vc_tdesc->tr_recv(vcp,m,p)
#define	SMB_TRAN_TIMO(vcp)		(vcp)->vc_tdesc->tr_timo(vcp)
#define	SMB_TRAN_INTR(vcp)		(vcp)->vc_tdesc->tr_intr(vcp)
#define	SMB_TRAN_GETPARAM(vcp,par,data)	(vcp)->vc_tdesc->tr_getparam(vcp, par, data)
#define	SMB_TRAN_SETPARAM(vcp,par,data)	(vcp)->vc_tdesc->tr_setparam(vcp, par, data)
#define	SMB_TRAN_FATAL(vcp, error)	(vcp)->vc_tdesc->tr_fatal(vcp, error)

#endif /* _NETSMB_SMB_TRAN_H_ */


code:
/*-
 * Copyright (c) 2000-2001 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netsmb/smb_trantcp.h 206361 2010-04-07 16:50:38Z joel $
 */
#ifndef _NETSMB_SMB_TRANTCP_H_
#define	_NETSMB_SMB_TRANTCP_H_

#ifdef _KERNEL

#ifdef NB_DEBUG
#define NBDEBUG(format, args...)	 printf("%s(%d): "format,	\
					    __func__ , __LINE__ ,## args)
#else
#define NBDEBUG(format, args...)
#endif

enum nbstate {
	NBST_CLOSED,
	NBST_RQSENT,
	NBST_SESSION,
	NBST_RETARGET,
	NBST_REFUSED
};

/*
 * socket specific data
 */
struct nbpcb {
	struct smb_vc *	nbp_vc;
	struct socket *	nbp_tso;	/* transport socket */
	struct sockaddr_nb *nbp_laddr;	/* local address */
	struct sockaddr_nb *nbp_paddr;	/* peer address */

	int		nbp_flags;
#define	NBF_LOCADDR	0x0001		/* has local addr */
#define	NBF_CONNECTED	0x0002
#define	NBF_RECVLOCK	0x0004

	enum nbstate	nbp_state;
	struct timespec	nbp_timo;
	int		nbp_sndbuf;
	int		nbp_rcvbuf;
	void *		nbp_selectid;

/*	LIST_ENTRY(nbpcb) nbp_link;*/
};

/*
 * Nominal space allocated per a NETBIOS socket.
 */
#define	NB_SNDQ		(64 * 1024)
#define	NB_RCVQ		(64 * 1024)

/*
 * TCP slowstart presents a problem in conjunction with large
 * reads.  To ensure a steady stream of ACKs while reading using
 * large transaction sizes, we call soreceive() with a smaller
 * buffer size.  See nbssn_recv().
 */
#define NB_SORECEIVE_CHUNK	(8 * 1024)

extern struct smb_tran_desc smb_tran_nbtcp_desc;

#endif /* _KERNEL */

#endif /* !_NETSMB_SMB_TRANTCP_H_ */


code:
/*	$NetBSD: krpc.h,v 1.4 1995/12/19 23:07:11 cgd Exp $	*/
/* $FreeBSD: release/9.0.0/sys/nfs/krpc.h 221032 2011-04-25 22:22:51Z rmacklem $	*/

#include <sys/cdefs.h>

struct mbuf;
struct thread;
struct sockaddr;
struct sockaddr_in;

int krpc_call(struct sockaddr_in *_sin,
	u_int prog, u_int vers, u_int func,
	struct mbuf **data, struct sockaddr **from, struct thread *td);

int krpc_portmap(struct sockaddr_in *_sin,
	u_int prog, u_int vers, u_int16_t *portp, struct thread *td);

struct mbuf *xdr_string_encode(char *str, int len);

/*
 * RPC definitions for the portmapper
 */
#define	PMAPPORT		111
#define	PMAPPROG		100000
#define	PMAPVERS		2
#define	PMAPPROC_NULL		0
#define	PMAPPROC_SET		1
#define	PMAPPROC_UNSET		2
#define	PMAPPROC_GETPORT	3
#define	PMAPPROC_DUMP		4
#define	PMAPPROC_CALLIT		5


code:
/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)nfsm_subs.h	8.2 (Berkeley) 3/30/95
 * $FreeBSD: release/9.0.0/sys/nfs/nfs_common.h 203732 2010-02-09 23:45:14Z marius $
 */

#ifndef _NFS_NFS_COMMON_H_
#define _NFS_NFS_COMMON_H_

extern enum vtype nv3tov_type[];
extern nfstype nfsv3_type[];

#define	vtonfsv2_mode(t, m) \
    txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : MAKEIMODE((t), (m)))

#define	nfsv3tov_type(a)	nv3tov_type[fxdr_unsigned(u_int32_t,(a))&0x7]
#define	vtonfsv3_type(a)	txdr_unsigned(nfsv3_type[((int32_t)(a))])

int	nfs_adv(struct mbuf **, caddr_t *, int, int);
u_quad_t nfs_curusec(void);
void	*nfsm_disct(struct mbuf **, caddr_t *, int, int, int);
int	nfs_realign(struct mbuf **, int);

/* ****************************** */
/* Build request/reply phase macros */

void	*nfsm_build_xx(int s, struct mbuf **mb, caddr_t *bpos);

#define	nfsm_build(c, s) \
	(c)nfsm_build_xx((s), &mb, &bpos)

/* ****************************** */
/* Interpretation phase macros */

void	*nfsm_dissect_xx(int s, struct mbuf **md, caddr_t *dpos);
void	*nfsm_dissect_xx_nonblock(int s, struct mbuf **md, caddr_t *dpos);
int	nfsm_strsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
int	nfsm_adv_xx(int s, struct mbuf **md, caddr_t *dpos);

/* Error check helpers */
#define nfsm_dcheck(t1, mrep) \
do { \
	if (t1 != 0) { \
		error = t1; \
		m_freem((mrep)); \
		(mrep) = NULL; \
		goto nfsmout; \
	} \
} while (0)

#define nfsm_dcheckp(retp, mrep) \
do { \
	if (retp == NULL) { \
		error = EBADRPC; \
		m_freem((mrep)); \
		(mrep) = NULL; \
		goto nfsmout; \
	} \
} while (0)

#define	nfsm_dissect(c, s) \
({ \
	void *ret; \
	ret = nfsm_dissect_xx((s), &md, &dpos); \
	nfsm_dcheckp(ret, mrep); \
	(c)ret; \
})

#define	nfsm_dissect_nonblock(c, s) \
({ \
	void *ret; \
	ret = nfsm_dissect_xx_nonblock((s), &md, &dpos); \
	nfsm_dcheckp(ret, mrep); \
	(c)ret; \
})

#define	nfsm_strsiz(s,m) \
do { \
	int t1; \
	t1 = nfsm_strsiz_xx(&(s), (m), &md, &dpos); \
	nfsm_dcheck(t1, mrep); \
} while(0)

#define nfsm_mtouio(p,s) \
do {\
	int32_t t1 = 0; \
	if ((s) > 0) \
		t1 = nfsm_mbuftouio(&md, (p), (s), &dpos); \
	nfsm_dcheck(t1, mrep); \
} while (0)

#define nfsm_rndup(a)	(((a)+3)&(~0x3))

#define	nfsm_adv(s) \
do { \
	int t1; \
	t1 = nfsm_adv_xx((s), &md, &dpos); \
	nfsm_dcheck(t1, mrep); \
} while (0)

#ifdef __NO_STRICT_ALIGNMENT
#define nfsm_aligned(p, t)	1
#else
#define nfsm_aligned(p, t)	((((u_long)(p)) & (sizeof(t) - 1)) == 0)
#endif

#endif


code:
/*-
 * Copyright (c) 2009 Robert N. M. Watson
 * All rights reserved.
 *
 * This software was developed at the University of Cambridge Computer
 * Laboratory with support from a grant from Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/nfs/nfs_kdtrace.h 222813 2011-06-07 08:46:13Z attilio $
 */

#ifndef _NFSCLIENT_NFS_KDTRACE_H_
#define	_NFSCLIENT_NFS_KDTRACE_H_

#ifdef KDTRACE_HOOKS
#include <sys/dtrace_bsd.h>

/*
 * Definitions for NFS access cache probes.
 */
extern uint32_t nfsclient_accesscache_flush_done_id;
extern uint32_t nfsclient_accesscache_get_hit_id;
extern uint32_t nfsclient_accesscache_get_miss_id;
extern uint32_t nfsclient_accesscache_load_done_id;

#define	KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp)	do {			\
	if (dtrace_nfsclient_accesscache_flush_done_probe != NULL)	\
		(dtrace_nfsclient_accesscache_flush_done_probe)(	\
		    nfsclient_accesscache_flush_done_id, (vp));		\
} while (0)

#define	KDTRACE_NFS_ACCESSCACHE_GET_HIT(vp, uid, mode)	do {		\
	if (dtrace_nfsclient_accesscache_get_hit_probe != NULL)		\
		(dtrace_nfsclient_accesscache_get_hit_probe)(		\
		    nfsclient_accesscache_get_hit_id, (vp), (uid),	\
		    (mode));						\
} while (0)

#define	KDTRACE_NFS_ACCESSCACHE_GET_MISS(vp, uid, mode)	do {		\
	if (dtrace_nfsclient_accesscache_get_miss_probe != NULL)	\
		(dtrace_nfsclient_accesscache_get_miss_probe)(		\
		    nfsclient_accesscache_get_miss_id, (vp), (uid),	\
		    (mode));						\
} while (0)

#define	KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, uid, rmode, error) do {	\
	if (dtrace_nfsclient_accesscache_load_done_probe != NULL)	\
		(dtrace_nfsclient_accesscache_load_done_probe)(		\
		    nfsclient_accesscache_load_done_id, (vp), (uid),	\
		    (rmode), (error));					\
} while (0)

/*
 * Definitions for NFS attribute cache probes.
 */
extern uint32_t nfsclient_attrcache_flush_done_id;
extern uint32_t nfsclient_attrcache_get_hit_id;
extern uint32_t nfsclient_attrcache_get_miss_id;
extern uint32_t nfsclient_attrcache_load_done_id;

#define	KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp)	do {			\
	if (dtrace_nfsclient_attrcache_flush_done_probe != NULL)	\
		(dtrace_nfsclient_attrcache_flush_done_probe)(		\
		    nfsclient_attrcache_flush_done_id, (vp));		\
} while (0)

#define	KDTRACE_NFS_ATTRCACHE_GET_HIT(vp, vap)	do {			\
	if (dtrace_nfsclient_attrcache_get_hit_probe != NULL)		\
		(dtrace_nfsclient_attrcache_get_hit_probe)(		\
		    nfsclient_attrcache_get_hit_id, (vp), (vap));	\
} while (0)

#define	KDTRACE_NFS_ATTRCACHE_GET_MISS(vp)	do {			\
	if (dtrace_nfsclient_attrcache_get_miss_probe != NULL)		\
		(dtrace_nfsclient_attrcache_get_miss_probe)(		\
			    nfsclient_attrcache_get_miss_id, (vp));	\
} while (0)

#define	KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error)	do {		\
	if (dtrace_nfsclient_attrcache_load_done_probe != NULL)		\
		(dtrace_nfsclient_attrcache_load_done_probe)(		\
		    nfsclient_attrcache_load_done_id, (vp), (vap),	\
		    (error));						\
} while (0)

#else /* !KDTRACE_HOOKS */

#define	KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp)
#define	KDTRACE_NFS_ACCESSCACHE_GET_HIT(vp, uid, mode)
#define	KDTRACE_NFS_ACCESSCACHE_GET_MISS(vp, uid, mode)
#define	KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, uid, rmode, error)

#define	KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp)
#define	KDTRACE_NFS_ATTRCACHE_GET_HIT(vp, vap)
#define	KDTRACE_NFS_ATTRCACHE_GET_MISS(vp)
#define	KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error)

#endif /* KDTRACE_HOOKS */

#endif /* !_NFSCLIENT_NFS_KDTRACE_H_ */


code:
/*-
 * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Berkeley Software Design Inc's name may not be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      from nfs_lock.h,v 2.2 1998/04/28 19:38:41 don Exp
 * $FreeBSD: release/9.0.0/sys/nfs/nfs_lock.h 214048 2010-10-19 00:20:00Z rmacklem $
 */

/*
 * lockd uses the nfssvc system call to get the unique kernel services it needs.
 * It passes in a request structure with a version number at the start.
 * This prevents libc from needing to change if the information passed
 * between lockd and the kernel needs to change.
 *
 * If a structure changes, you must bump the version number.
 */

/*
 * The fifo where the kernel writes requests for locks on remote NFS files,
 * and where lockd reads these requests.
 *
 */
#define	_PATH_NFSLCKDEV	"nfslock"

/*
 * This structure is used to uniquely identify the process which originated
 * a particular message to lockd.  A sequence number is used to differentiate
 * multiple messages from the same process.  A process start time is used to
 * detect the unlikely, but possible, event of the recycling of a pid.
 */
struct lockd_msg_ident {
	pid_t		pid;            /* The process ID. */
	struct timeval	pid_start;	/* Start time of process id */
	int		msg_seq;	/* Sequence number of message */
};

#define LOCKD_MSG_VERSION	3

/*
 * The structure that the kernel hands us for each lock request.
 */
typedef struct __lock_msg {
	TAILQ_ENTRY(__lock_msg)	lm_link;	/* internal linkage */
	int			lm_version;	/* which version is this */
	struct lockd_msg_ident	lm_msg_ident;	/* originator of the message */
	struct flock		lm_fl;             /* The lock request. */
	int			lm_wait;           /* The F_WAIT flag. */
	int			lm_getlk;		/* is this a F_GETLK request */
	struct sockaddr_storage lm_addr;		/* The address. */
	int			lm_nfsv3;		/* If NFS version 3. */
	size_t			lm_fh_len;		/* The file handle length. */
	struct xucred		lm_cred;		/* user cred for lock req */
	u_int8_t		lm_fh[NFSX_V3FHMAX];/* The file handle. */
} LOCKD_MSG;

#define LOCKD_ANS_VERSION	1

struct lockd_ans {
	int		la_vers;
	struct lockd_msg_ident	la_msg_ident;	/* originator of the message */
	int		la_errno;
	int		la_set_getlk_pid;		/* use returned pid */
	int		la_getlk_pid;		/* returned pid for F_GETLK */
};

#ifdef _KERNEL
int	nfs_dolock(struct vop_advlock_args *ap);
extern	vop_advlock_t *nfs_advlock_p;
extern	vop_reclaim_t *nfs_reclaim_p;
#endif


code:
/*-
 * Copyright (c) 2009 Rick Macklem, University of Guelph
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/nfs/nfs_mountcommon.h 216931 2011-01-03 20:37:31Z rmacklem $
 */

#ifndef _NFS_MOUNTCOMMON_H_
#define	_NFS_MOUNTCOMMON_H_

/*
 * The common fields of the nfsmount structure for the two clients
 * used by the nlm. It includes a function pointer that provides
 * a mechanism for getting the client specific info for an nfs vnode.
 */
typedef void	nfs_getinfofromvp_ftype(struct vnode *, uint8_t *, size_t *,
		    struct sockaddr_storage *, int *, off_t *,
		    struct timeval *);
typedef int	nfs_vinvalbuf_ftype(struct vnode *, int, struct thread *, int);

struct	nfsmount_common {
	struct mtx	nmcom_mtx;
	int	nmcom_flag;		/* Flags for soft/hard... */
	int	nmcom_state;		/* Internal state flags */
	struct	mount *nmcom_mountp;	/* Vfs structure for this filesystem */
	int	nmcom_timeo;		/* Init timer for NFSMNT_DUMBTIMR */
	int	nmcom_retry;		/* Max retries */
	char	nmcom_hostname[MNAMELEN];	/* server's name */
	nfs_getinfofromvp_ftype	*nmcom_getinfo;	/* Get info from nfsnode */
	nfs_vinvalbuf_ftype	*nmcom_vinvalbuf; /* Invalidate buffers */
};

#endif	/* _NFS_MOUNTCOMMON_H_ */


code:
/*-
 * Copyright (c) 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)nfsdiskless.h	8.2 (Berkeley) 3/30/95
 * $FreeBSD: release/9.0.0/sys/nfs/nfsdiskless.h 221032 2011-04-25 22:22:51Z rmacklem $
 */

#ifndef _NFSCLIENT_NFSDISKLESS_H_
#define _NFSCLIENT_NFSDISKLESS_H_

/*
 * Structure that must be initialized for a diskless nfs client.
 * This structure is used by nfs_mountroot() to set up the root vnode,
 * and to do a partial ifconfig(8) and route(8) so that the critical net
 * interface can communicate with the server.
 * The primary bootstrap is expected to fill in the appropriate fields before
 * starting the kernel.
 * Currently only works for AF_INET protocols.
 * NB: All fields are stored in net byte order to avoid hassles with
 * client/server byte ordering differences.
 */

/*
 * I have defined a new structure that can handle an NFS Version 3 file handle
 * but the kernel still expects the old Version 2 one to be provided. The
 * changes required in nfs_vfsops.c for using the new are documented there in
 * comments. (I felt that breaking network booting code by changing this
 * structure would not be prudent at this time, since almost all servers are
 * still Version 2 anyhow.)
 */
struct nfsv3_diskless {
	struct ifaliasreq myif;			/* Default interface */
	struct sockaddr_in mygateway;		/* Default gateway */
	struct nfs_args	root_args;		/* Mount args for root fs */
	int		root_fhsize;		/* Size of root file handle */
	u_char		root_fh[NFSX_V3FHMAX];	/* File handle of root dir */
	struct sockaddr_in root_saddr;		/* Address of root server */
	char		root_hostnam[MNAMELEN];	/* Host name for mount pt */
	long		root_time;		/* Timestamp of root fs */
	char		my_hostnam[MAXHOSTNAMELEN]; /* Client host name */
};

/*
 * Old arguments to mount NFS
 */
struct onfs_args {
	struct sockaddr	*addr;		/* file server address */
	int		addrlen;	/* length of address */
	int		sotype;		/* Socket type */
	int		proto;		/* and Protocol */
	u_char		*fh;		/* File handle to be mounted */
	int		fhsize;		/* Size, in bytes, of fh */
	int		flags;		/* flags */
	int		wsize;		/* write size in bytes */
	int		rsize;		/* read size in bytes */
	int		readdirsize;	/* readdir size in bytes */
	int		timeo;		/* initial timeout in .1 secs */
	int		retrans;	/* times to retry send */
	int		maxgrouplist;	/* Max. size of group list */
	int		readahead;	/* # of blocks to readahead */
	int		leaseterm;	/* Term (sec) of lease */
	int		deadthresh;	/* Retrans threshold */
	char		*hostname;	/* server's name */
};

struct nfs_diskless {
	struct ifaliasreq myif;			/* Default interface */
	struct sockaddr_in mygateway;		/* Default gateway */
	struct onfs_args root_args;		/* Mount args for root fs */
	u_char		root_fh[NFSX_V2FH];	/* File handle of root dir */
	struct sockaddr_in root_saddr;		/* Address of root server */
	char		root_hostnam[MNAMELEN];	/* Host name for mount pt */
	long		root_time;		/* Timestamp of root fs */
	char		my_hostnam[MAXHOSTNAMELEN]; /* Client host name */
};

#ifdef _KERNEL
extern struct nfsv3_diskless nfsv3_diskless;
extern struct nfs_diskless nfs_diskless;
extern int	nfs_diskless_valid;
void bootpc_init(void);
void nfs_setup_diskless(void);
void nfs_parse_options(const char *, struct nfs_args *);
#endif

#endif


code:
/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)nfsproto.h  8.2 (Berkeley) 3/30/95
 * $FreeBSD: release/9.0.0/sys/nfs/nfsproto.h 164725 2006-11-28 19:33:28Z rees $
 */

#ifndef _NFS_NFSPROTO_H_
#define _NFS_NFSPROTO_H_

/*
 * nfs definitions as per the Version 2 and 3 specs
 */

/*
 * Constants as defined in the Sun NFS Version 2 and 3 specs.
 * "NFS: Network File System Protocol Specification" RFC1094
 * and in the "NFS: Network File System Version 3 Protocol
 * Specification"
 */

#define NFS_PORT	2049
#define	NFS_PROG	100003
#define NFS_VER2	2
#define	NFS_VER3	3
#define NFS_VER4	4

#define NFS_V2MAXDATA	8192
#define	NFS_MAXDGRAMDATA 16384
#define	NFS_MAXDATA	32768
#define	NFS_MAXPATHLEN	1024
#define	NFS_MAXNAMLEN	255
#define	NFS_MAXPKTHDR	404	/* XXXv4 this needs to be adjust for v4 */
#define NFS_MAXPACKET	(NFS_MAXPKTHDR + NFS_MAXDATA)
#define	NFS_MINPACKET	20
#define	NFS_FABLKSIZE	512	/* Size in bytes of a block wrt fa_blocks */

/* Stat numbers for rpc returns (version 2, 3 and 4) */
#define	NFS_OK			0
#define	NFSERR_PERM		1
#define	NFSERR_NOENT		2
#define	NFSERR_IO		5
#define	NFSERR_NXIO		6
#define	NFSERR_ACCES		13
#define	NFSERR_EXIST		17
#define	NFSERR_XDEV		18	/* Version 3 only */
#define	NFSERR_NODEV		19
#define	NFSERR_NOTDIR		20
#define	NFSERR_ISDIR		21
#define	NFSERR_INVAL		22	/* Version 3 only */
#define	NFSERR_FBIG		27
#define	NFSERR_NOSPC		28
#define	NFSERR_ROFS		30
#define	NFSERR_MLINK		31	/* Version 3 only */
#define	NFSERR_NAMETOL		63
#define	NFSERR_NOTEMPTY		66
#define	NFSERR_DQUOT		69
#define	NFSERR_STALE		70
#define	NFSERR_REMOTE		71	/* Version 3 only */
#define	NFSERR_WFLUSH		99	/* Version 2 only */
#define	NFSERR_BADHANDLE	10001	/* The rest Version 3, 4 only */
#define	NFSERR_NOT_SYNC		10002
#define	NFSERR_BAD_COOKIE	10003
#define	NFSERR_NOTSUPP		10004
#define	NFSERR_TOOSMALL		10005
#define	NFSERR_SERVERFAULT	10006
#define	NFSERR_BADTYPE		10007
#define	NFSERR_JUKEBOX		10008
#define NFSERR_TRYLATER		NFSERR_JUKEBOX
#define	NFSERR_SAME		10009   /* The rest Version 4 only */
#define	NFSERR_DENIED		10010
#define	NFSERR_EXPIRED		10011
#define	NFSERR_LOCKED		10012
#define	NFSERR_GRACE		10013
#define	NFSERR_FHEXPIRED	10014
#define	NFSERR_SHARDE_DENIED	10015
#define	NFSERR_WRONGSEC		10016
#define	NFSERR_CLID_INUSE	10017
#define	NFSERR_RESOURCE		10018
#define	NFSERR_MOVED		10019
#define	NFSERR_NOFILEHANDLE	10020
#define	NFSERR_MINOR_VERS_MISMATCH 10021
#define	NFSERR_STALE_CLIENTID	10022
#define	NFSERR_STALE_STATEID	10023
#define	NFSERR_OLD_STATEID	10024
#define	NFSERR_BAD_STATEID	10025
#define	NFSERR_BAD_SEQID	10026
#define	NFSERR_NOT_SAME		10027
#define	NFSERR_LOCK_RANGE	10028
#define	NFSERR_SYMLINK		10029
#define	NFSERR_READDIR_NOSPC	10030
#define	NFSERR_LEASE_MOVED	10031
#define	NFSERR_ATTRNOTSUPP	10032
#define	NFSERR_NO_GRACE		10033
#define	NFSERR_RECLAIM_BAD	10034
#define	NFSERR_RECLAIM_CONFLICT	10035
#define	NFSERR_BADXDR		10036
#define	NFSERR_LOCKS_HELD	10037
#define	NFSERR_OPENMODE		10038
#define	NFSERR_BADOWNER		10039
#define	NFSERR_BADCHAR		10040
#define	NFSERR_BADNAME		10041
#define	NFSERR_BAD_RANGE	10042
#define	NFSERR_LOCK_NOTSUPP	10043
#define	NFSERR_OP_ILLEGAL	10044
#define	NFSERR_DEADLOCK		10045
#define	NFSERR_FILE_OPEN	10046
#define	NFSERR_STALEWRITEVERF	30001	/* Fake return for nfs_commit() */

#define NFSERR_RETVOID		0x20000000 /* Return void, not error */
#define NFSERR_AUTHERR		0x40000000 /* Mark an authentication error */
#define NFSERR_RETERR		0x80000000 /* Mark an error return for V3 */

/* Sizes in bytes of various nfs rpc components */
#define	NFSX_UNSIGNED	4

/* specific to NFS Version 2 */
#define	NFSX_V2FH	32
#define	NFSX_V2FATTR	68
#define	NFSX_V2SATTR	32
#define	NFSX_V2COOKIE	4
#define NFSX_V2STATFS	20

/* specific to NFS Version 3 */
#define NFSX_V3FH		(sizeof (fhandle_t)) /* size this server uses */
#define	NFSX_V3FHMAX		64	/* max. allowed by protocol */
#define NFSX_V3FATTR		84
#define NFSX_V3SATTR		60	/* max. all fields filled in */
#define NFSX_V3SRVSATTR		(sizeof (struct nfsv3_sattr))
#define NFSX_V3POSTOPATTR	(NFSX_V3FATTR + NFSX_UNSIGNED)
#define NFSX_V3WCCDATA		(NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED)
#define NFSX_V3COOKIEVERF 	8
#define NFSX_V3WRITEVERF 	8
#define NFSX_V3CREATEVERF	8
#define NFSX_V3STATFS		52
#define NFSX_V3FSINFO		48
#define NFSX_V3PATHCONF		24

/* specific to NFS Version 4 */
#define NFSX_V4VERF		8
#define NFSX_V4FH		128
#define NFSX_V4STATEID		16

/* variants for both versions */
#define NFSX_FH(v3)		((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \
					NFSX_V2FH)
#define NFSX_SRVFH(v3)		((v3) ? NFSX_V3FH : NFSX_V2FH)
#define	NFSX_FATTR(v3)		((v3) ? NFSX_V3FATTR : NFSX_V2FATTR)
#define NFSX_PREOPATTR(v3)	((v3) ? (7 * NFSX_UNSIGNED) : 0)
#define NFSX_POSTOPATTR(v3)	((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : 0)
#define NFSX_POSTOPORFATTR(v3)	((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : \
					NFSX_V2FATTR)
#define NFSX_WCCDATA(v3)	((v3) ? NFSX_V3WCCDATA : 0)
#define NFSX_WCCORFATTR(v3)	((v3) ? NFSX_V3WCCDATA : NFSX_V2FATTR)
#define	NFSX_SATTR(v3)		((v3) ? NFSX_V3SATTR : NFSX_V2SATTR)
#define	NFSX_COOKIEVERF(v3)	((v3) ? NFSX_V3COOKIEVERF : 0)
#define	NFSX_WRITEVERF(v3)	((v3) ? NFSX_V3WRITEVERF : 0)
#define NFSX_READDIR(v3)	((v3) ? (5 * NFSX_UNSIGNED) : \
					(2 * NFSX_UNSIGNED))
#define	NFSX_STATFS(v3)		((v3) ? NFSX_V3STATFS : NFSX_V2STATFS)

/* nfs rpc procedure numbers (before version mapping) */
#define	NFSPROC_NULL		0
#define	NFSPROC_GETATTR		1
#define	NFSPROC_SETATTR		2
#define	NFSPROC_LOOKUP		3
#define	NFSPROC_ACCESS		4
#define	NFSPROC_READLINK	5
#define	NFSPROC_READ		6
#define	NFSPROC_WRITE		7
#define	NFSPROC_CREATE		8
#define	NFSPROC_MKDIR		9
#define	NFSPROC_SYMLINK		10
#define	NFSPROC_MKNOD		11
#define	NFSPROC_REMOVE		12
#define	NFSPROC_RMDIR		13
#define	NFSPROC_RENAME		14
#define	NFSPROC_LINK		15
#define	NFSPROC_READDIR		16
#define	NFSPROC_READDIRPLUS	17
#define	NFSPROC_FSSTAT		18
#define	NFSPROC_FSINFO		19
#define	NFSPROC_PATHCONF	20
#define	NFSPROC_COMMIT		21
#define NFSPROC_NOOP		22
#define	NFS_NPROCS		23

/* Actual Version 2 procedure numbers */
#define	NFSV2PROC_NULL		0
#define	NFSV2PROC_GETATTR	1
#define	NFSV2PROC_SETATTR	2
#define	NFSV2PROC_NOOP		3
#define	NFSV2PROC_ROOT		NFSV2PROC_NOOP	/* Obsolete */
#define	NFSV2PROC_LOOKUP	4
#define	NFSV2PROC_READLINK	5
#define	NFSV2PROC_READ		6
#define	NFSV2PROC_WRITECACHE	NFSV2PROC_NOOP	/* Obsolete */
#define	NFSV2PROC_WRITE		8
#define	NFSV2PROC_CREATE	9
#define	NFSV2PROC_REMOVE	10
#define	NFSV2PROC_RENAME	11
#define	NFSV2PROC_LINK		12
#define	NFSV2PROC_SYMLINK	13
#define	NFSV2PROC_MKDIR		14
#define	NFSV2PROC_RMDIR		15
#define	NFSV2PROC_READDIR	16
#define	NFSV2PROC_STATFS	17

/* Version 4 procedure numbers */
#define NFSV4PROC_NULL         0
#define NFSV4PROC_COMPOUND     1

/* Version 4 operation numbers */
#define NFSV4OP_ACCESS		3
#define NFSV4OP_CLOSE		4
#define NFSV4OP_COMMIT		5
#define NFSV4OP_CREATE		6
#define NFSV4OP_DELEGPURGE	7
#define NFSV4OP_DELEGRETURN	8
#define NFSV4OP_GETATTR		9
#define NFSV4OP_GETFH		10
#define NFSV4OP_LINK		11
#define NFSV4OP_LOCK		12
#define NFSV4OP_LOCKT		13
#define NFSV4OP_LOCKU		14
#define NFSV4OP_LOOKUP		15
#define NFSV4OP_LOOKUPP		16
#define NFSV4OP_NVERIFY		17
#define NFSV4OP_OPEN		18
#define NFSV4OP_OPENATTR	19
#define NFSV4OP_OPEN_CONFIRM	20
#define NFSV4OP_OPEN_DOWNGRADE	21
#define NFSV4OP_PUTFH		22
#define NFSV4OP_PUTPUBFH	23
#define NFSV4OP_PUTROOTFH	24
#define NFSV4OP_READ		25
#define NFSV4OP_READDIR		26
#define NFSV4OP_READLINK	27
#define NFSV4OP_REMOVE		28
#define NFSV4OP_RENAME		29
#define NFSV4OP_RENEW		30
#define NFSV4OP_RESTOREFH	31
#define NFSV4OP_SAVEFH		32
#define NFSV4OP_SECINFO		33
#define NFSV4OP_SETATTR		34
#define NFSV4OP_SETCLIENTID	35
#define NFSV4OP_SETCLIENTID_CONFIRM 36
#define NFSV4OP_VERIFY		37
#define NFSV4OP_WRITE		38

/*
 * Constants used by the Version 3 protocol for various RPCs
 */
#define NFSV3SATTRTIME_DONTCHANGE	0
#define NFSV3SATTRTIME_TOSERVER		1
#define NFSV3SATTRTIME_TOCLIENT		2

#define NFSV3ACCESS_READ		0x01
#define NFSV3ACCESS_LOOKUP		0x02
#define NFSV3ACCESS_MODIFY		0x04
#define NFSV3ACCESS_EXTEND		0x08
#define NFSV3ACCESS_DELETE		0x10
#define NFSV3ACCESS_EXECUTE		0x20

#define NFSV3WRITE_UNSTABLE		0
#define NFSV3WRITE_DATASYNC		1
#define NFSV3WRITE_FILESYNC		2

#define NFSV3CREATE_UNCHECKED		0
#define NFSV3CREATE_GUARDED		1
#define NFSV3CREATE_EXCLUSIVE		2

#define NFSV3FSINFO_LINK		0x01
#define NFSV3FSINFO_SYMLINK		0x02
#define NFSV3FSINFO_HOMOGENEOUS		0x08
#define NFSV3FSINFO_CANSETTIME		0x10

/*
 * Constants used by the Version 4 protocol for various RPCs
 */

#define NFSV4ACCESS_READ		0x01
#define NFSV4ACCESS_LOOKUP		0x02
#define NFSV4ACCESS_MODIFY		0x04
#define NFSV4ACCESS_EXTEND		0x08
#define NFSV4ACCESS_DELETE		0x10
#define NFSV4ACCESS_EXECUTE		0x20

#define NFSV4OPENRES_MLOCK		0x01
#define NFSV4OPENRES_CONFIRM		0x02

#define NFSV4OPENSHARE_ACCESS_READ	0x01
#define NFSV4OPENSHARE_ACCESS_WRITE	0x02
#define NFSV4OPENSHARE_ACCESS_BOTH	0x03
#define NFSV4OPENSHARE_DENY_NONE	0x00
#define NFSV4OPENSHARE_DENY_READ	0x01
#define NFSV4OPENSHARE_DENY_WRITE	0x02
#define NFSV4OPENSHARE_DENY_BOTH	0x03

/* File types */
typedef enum {
	NFNON=0,
	NFREG=1,
	NFDIR=2,
	NFBLK=3,
	NFCHR=4,
	NFLNK=5,
	NFSOCK=6,
	NFFIFO=7,
	NFATTRDIR = 8,
	NFNAMEDATTR = 9,
	NFBAD = 10,
} nfstype;

/* NFSv4 claim type */
typedef enum {
	NCLNULL = 0,
	NCLPREV = 1,
	NCLDELEGCUR = 2,
	NCLDELEGPREV = 3,
} nfsv4cltype;

/* Other NFSv4 types */
typedef enum {
	NSHUNSTABLE = 0,
	NSHDATASYNC = 1,
	NSHFILESYNC = 2,
} nfsv4stablehow;

typedef enum { OTNOCREATE = 0, OTCREATE = 1 } nfsv4opentype;
typedef enum { CMUNCHECKED = 0, CMGUARDED = 1, CMEXCLUSIVE = 2 } nfsv4createmode;
typedef enum { THSERVERTIME = 0, THCLIENTTIME = 1 } nfsv4timehow;
typedef enum { ODNONE = 0, ODREAD = 1, ODWRITE = 2 } nfsv4opendelegtype;

/* Structs for common parts of the rpc's */

/*
 * File Handle (32 bytes for version 2), variable up to 64 for version 3.
 * File Handles of up to NFS_SMALLFH in size are stored directly in the
 * nfs node, whereas larger ones are malloc'd. (This never happens when
 * NFS_SMALLFH is set to 64.)
 * NFS_SMALLFH should be in the range of 32 to 64 and be divisible by 4.
 */
#ifndef NFS_SMALLFH
#define NFS_SMALLFH	128
#endif
union nfsfh {
	fhandle_t	fh_generic;
	u_char		fh_bytes[NFS_SMALLFH];
};
typedef union nfsfh nfsfh_t;

struct nfsv2_time {
	u_int32_t	nfsv2_sec;
	u_int32_t	nfsv2_usec;
};
typedef struct nfsv2_time	nfstime2;

struct nfsv3_time {
	u_int32_t	nfsv3_sec;
	u_int32_t	nfsv3_nsec;
};
typedef struct nfsv3_time	nfstime3;

/*
 * Quads are defined as arrays of 2 longs to ensure dense packing for the
 * protocol and to facilitate xdr conversion.
 */
struct nfs_uquad {
	u_int32_t	nfsuquad[2];
};
typedef	struct nfs_uquad	nfsuint64;

/*
 * Used to convert between two u_longs and a u_quad_t.
 */
union nfs_quadconvert {
	u_int32_t	lval[2];
	u_quad_t	qval;
};
typedef union nfs_quadconvert	nfsquad_t;

/*
 * NFS Version 3 special file number.
 */
struct nfsv3_spec {
	u_int32_t	specdata1;
	u_int32_t	specdata2;
};
typedef	struct nfsv3_spec	nfsv3spec;

/*
 * NFS Version 4 bitmap.
 */
struct nfsv4_bitmap {
	uint32_t	bmlen;
	uint32_t	*bmval;
};
typedef struct nfsv4_bitmap nfsv4bitmap;

struct nfsv4_changeinfo {
	u_int		ciatomic;
	uint64_t	cibefore;
	uint64_t	ciafter;
};
typedef struct nfsv4_changeinfo nfsv4changeinfo;

/*
 * File attributes and setable attributes. These structures cover both
 * NFS version 2 and the version 3 protocol. Note that the union is only
 * used so that one pointer can refer to both variants. These structures
 * go out on the wire and must be densely packed, so no quad data types
 * are used. (all fields are longs or u_longs or structures of same)
 * NB: You can't do sizeof(struct nfs_fattr), you must use the
 *     NFSX_FATTR(v3) macro.
 */
struct nfs_fattr {
	u_int32_t	fa_type;
	u_int32_t	fa_mode;
	u_int32_t	fa_nlink;
	u_int32_t	fa_uid;
	u_int32_t	fa_gid;
	union {
		struct {
			u_int32_t	nfsv2fa_size;
			u_int32_t	nfsv2fa_blocksize;
			u_int32_t	nfsv2fa_rdev;
			u_int32_t	nfsv2fa_blocks;
			u_int32_t	nfsv2fa_fsid;
			u_int32_t	nfsv2fa_fileid;
			nfstime2	nfsv2fa_atime;
			nfstime2	nfsv2fa_mtime;
			nfstime2	nfsv2fa_ctime;
		} fa_nfsv2;
		struct {
			nfsuint64	nfsv3fa_size;
			nfsuint64	nfsv3fa_used;
			nfsv3spec	nfsv3fa_rdev;
			nfsuint64	nfsv3fa_fsid;
			nfsuint64	nfsv3fa_fileid;
			nfstime3	nfsv3fa_atime;
			nfstime3	nfsv3fa_mtime;
			nfstime3	nfsv3fa_ctime;
		} fa_nfsv3;
	} fa_un;
};

/* and some ugly defines for accessing union components */
#define	fa2_size		fa_un.fa_nfsv2.nfsv2fa_size
#define	fa2_blocksize		fa_un.fa_nfsv2.nfsv2fa_blocksize
#define	fa2_rdev		fa_un.fa_nfsv2.nfsv2fa_rdev
#define	fa2_blocks		fa_un.fa_nfsv2.nfsv2fa_blocks
#define	fa2_fsid		fa_un.fa_nfsv2.nfsv2fa_fsid
#define	fa2_fileid		fa_un.fa_nfsv2.nfsv2fa_fileid
#define	fa2_atime		fa_un.fa_nfsv2.nfsv2fa_atime
#define	fa2_mtime		fa_un.fa_nfsv2.nfsv2fa_mtime
#define	fa2_ctime		fa_un.fa_nfsv2.nfsv2fa_ctime
#define	fa3_size		fa_un.fa_nfsv3.nfsv3fa_size
#define	fa3_used		fa_un.fa_nfsv3.nfsv3fa_used
#define	fa3_rdev		fa_un.fa_nfsv3.nfsv3fa_rdev
#define	fa3_fsid		fa_un.fa_nfsv3.nfsv3fa_fsid
#define	fa3_fileid		fa_un.fa_nfsv3.nfsv3fa_fileid
#define	fa3_atime		fa_un.fa_nfsv3.nfsv3fa_atime
#define	fa3_mtime		fa_un.fa_nfsv3.nfsv3fa_mtime
#define	fa3_ctime		fa_un.fa_nfsv3.nfsv3fa_ctime

struct nfsv4_fattr {
	u_int		fa4_valid;
	nfstype		fa4_type;
	off_t		fa4_size;
	uint64_t	fa4_fsid_major;
	uint64_t	fa4_fsid_minor;
	uint64_t	fa4_fileid;
	mode_t		fa4_mode;
	nlink_t		fa4_nlink;
	uid_t		fa4_uid;
	gid_t		fa4_gid;
	uint32_t	fa4_rdev_major;
	uint32_t	fa4_rdev_minor;
	struct timespec	fa4_atime;
	struct timespec	fa4_btime;
	struct timespec	fa4_ctime;
	struct timespec	fa4_mtime;
	uint64_t	fa4_maxread;
	uint64_t	fa4_maxwrite;
	uint64_t	fa4_ffree;
	uint64_t	fa4_ftotal;
	uint32_t	fa4_maxname;
	uint64_t	fa4_savail;
	uint64_t	fa4_sfree;
	uint64_t	fa4_stotal;
	uint64_t	fa4_changeid;
	uint32_t	fa4_lease_time;
	uint64_t	fa4_maxfilesize;
};

/* Flags for fa4_valid */
#define FA4V_SIZE	0x00000001
#define FA4V_FSID	0x00000002
#define FA4V_FILEID	0x00000004
#define FA4V_MODE	0x00000008
#define FA4V_NLINK	0x00000010
#define FA4V_UID	0x00000020
#define FA4V_GID	0x00000040
#define FA4V_RDEV	0x00000080
#define FA4V_ATIME	0x00000100
#define FA4V_BTIME	0x00000200
#define FA4V_CTIME	0x00000400
#define FA4V_MTIME	0x00000800
#define FA4V_MAXREAD	0x00001000
#define FA4V_MAXWRITE	0x00002000
#define FA4V_TYPE	0x00004000
#define FA4V_FFREE	0x00008000
#define FA4V_FTOTAL	0x00010000
#define FA4V_MAXNAME	0x00020000
#define FA4V_SAVAIL	0x00040000
#define FA4V_SFREE	0x00080000
#define FA4V_STOTAL	0x00100000
#define FA4V_CHANGEID	0x00200000
#define FA4V_LEASE_TIME	0x00400000
#define FA4V_MAXFILESIZE 0x00800000
#define FA4V_ACL	0x01000000

/* Offsets into bitmask */
#define FA4_SUPPORTED_ATTRS	0
#define FA4_TYPE		1
#define FA4_FH_EXPIRE_TYPE	2
#define FA4_CHANGE		3
#define FA4_SIZE		4
#define FA4_LINK_SUPPORT	5
#define FA4_SYMLINK_SUPPORT	6
#define FA4_NAMED_ATTR		7
#define FA4_FSID		8
#define FA4_UNIQUE_HANDLES	9
#define FA4_LEASE_TIME		10
#define FA4_RDATTR_ERROR	11
#define FA4_ACL			12
#define FA4_ACLSUPPORT		13
#define FA4_ARCHIVE		14
#define FA4_CANSETTIME		15
#define FA4_CASE_INSENSITIVE	16
#define FA4_CASE_PRESERVING	17
#define FA4_CHOWN_RESTRICTED	18
#define FA4_FILEHANDLE		19
#define FA4_FILEID		20
#define FA4_FILES_AVAIL		21
#define FA4_FILES_FREE		22
#define FA4_FILES_TOTAL		23
#define FA4_FS_LOCATIONS	24
#define FA4_HIDDEN		25
#define FA4_HOMOGENEOUS		26
#define FA4_MAXFILESIZE		27
#define FA4_MAXLINK		28
#define FA4_MAXNAME		29
#define FA4_MAXREAD		30
#define FA4_MAXWRITE		31
#define FA4_MIMETYPE		32
#define FA4_MODE		33
#define FA4_NO_TRUNC		34
#define FA4_NUMLINKS		35
#define FA4_OWNER		36
#define FA4_OWNER_GROUP		37
#define FA4_QUOTA_HARD		38
#define FA4_QUOTA_SOFT		39
#define FA4_QUOTA_USED		40
#define FA4_RAWDEV		41
#define FA4_SPACE_AVAIL		42
#define FA4_SPACE_FREE		43
#define FA4_SPACE_TOTAL		44
#define FA4_SPACE_USED		45
#define FA4_SYSTEM		46
#define FA4_TIME_ACCESS		47
#define FA4_TIME_ACCESS_SET	48
#define FA4_TIME_BACKUP		49
#define FA4_TIME_CREATE		50
#define FA4_TIME_DELTA		51
#define FA4_TIME_METADATA	52
#define FA4_TIME_MODIFY		53
#define FA4_TIME_MODIFY_SET	54
#define FA4_ATTR_MAX		55

/* Macros for v4 fattr manipulation */
#define FA4_SET(n, p)	((p)[(n)/32] |= (1 << ((n) % 32)))
#define FA4_CLR(n, p)	((p)[(n)/32] &= ~(1 << ((n) % 32)))
#define FA4_ISSET(n, p)	((p)[(n)/32] & (1 << ((n) % 32)))
#define FA4_ZERO(p)	bzero((p), 8)
#define FA4_SKIP(p)	((p) += 2)

struct nfsv2_sattr {
	u_int32_t	sa_mode;
	u_int32_t	sa_uid;
	u_int32_t	sa_gid;
	u_int32_t	sa_size;
	nfstime2	sa_atime;
	nfstime2	sa_mtime;
};

/*
 * NFS Version 3 sattr structure for the new node creation case.
 */
struct nfsv3_sattr {
	u_int32_t	sa_modetrue;
	u_int32_t	sa_mode;
	u_int32_t	sa_uidfalse;
	u_int32_t	sa_gidfalse;
	u_int32_t	sa_sizefalse;
	u_int32_t	sa_atimetype;
	nfstime3	sa_atime;
	u_int32_t	sa_mtimetype;
	nfstime3	sa_mtime;
};

struct nfs_statfs {
	union {
		struct {
			u_int32_t	nfsv2sf_tsize;
			u_int32_t	nfsv2sf_bsize;
			u_int32_t	nfsv2sf_blocks;
			u_int32_t	nfsv2sf_bfree;
			u_int32_t	nfsv2sf_bavail;
		} sf_nfsv2;
		struct {
			nfsuint64	nfsv3sf_tbytes;
			nfsuint64	nfsv3sf_fbytes;
			nfsuint64	nfsv3sf_abytes;
			nfsuint64	nfsv3sf_tfiles;
			nfsuint64	nfsv3sf_ffiles;
			nfsuint64	nfsv3sf_afiles;
			u_int32_t	nfsv3sf_invarsec;
		} sf_nfsv3;
	} sf_un;
};

#define sf_tsize	sf_un.sf_nfsv2.nfsv2sf_tsize
#define sf_bsize	sf_un.sf_nfsv2.nfsv2sf_bsize
#define sf_blocks	sf_un.sf_nfsv2.nfsv2sf_blocks
#define sf_bfree	sf_un.sf_nfsv2.nfsv2sf_bfree
#define sf_bavail	sf_un.sf_nfsv2.nfsv2sf_bavail
#define sf_tbytes	sf_un.sf_nfsv3.nfsv3sf_tbytes
#define sf_fbytes	sf_un.sf_nfsv3.nfsv3sf_fbytes
#define sf_abytes	sf_un.sf_nfsv3.nfsv3sf_abytes
#define sf_tfiles	sf_un.sf_nfsv3.nfsv3sf_tfiles
#define sf_ffiles	sf_un.sf_nfsv3.nfsv3sf_ffiles
#define sf_afiles	sf_un.sf_nfsv3.nfsv3sf_afiles
#define sf_invarsec	sf_un.sf_nfsv3.nfsv3sf_invarsec

struct nfsv3_fsinfo {
	u_int32_t	fs_rtmax;
	u_int32_t	fs_rtpref;
	u_int32_t	fs_rtmult;
	u_int32_t	fs_wtmax;
	u_int32_t	fs_wtpref;
	u_int32_t	fs_wtmult;
	u_int32_t	fs_dtpref;
	nfsuint64	fs_maxfilesize;
	nfstime3	fs_timedelta;
	u_int32_t	fs_properties;
};

struct nfsv3_pathconf {
	u_int32_t	pc_linkmax;
	u_int32_t	pc_namemax;
	u_int32_t	pc_notrunc;
	u_int32_t	pc_chownrestricted;
	u_int32_t	pc_caseinsensitive;
	u_int32_t	pc_casepreserving;
};

#endif


code:
/*-
 * Copyright (c) 1989, 1993, 1995
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/nfs/nfssvc.h 221439 2011-05-04 13:36:18Z rmacklem $
 */

#ifndef _NFS_NFSSVC_H_
#define _NFS_NFSSVC_H_

/*
 * Flags for nfssvc() system call.
 */
#define	NFSSVC_OLDNFSD	0x004
#define	NFSSVC_ADDSOCK	0x008
#define	NFSSVC_NFSD	0x010

/*
 * and ones for nfsv4.
 */
#define	NFSSVC_NOPUBLICFH	0x00000020
#define	NFSSVC_STABLERESTART	0x00000040
#define	NFSSVC_NFSDNFSD		0x00000080
#define	NFSSVC_NFSDADDSOCK	0x00000100
#define	NFSSVC_IDNAME		0x00000200
#define	NFSSVC_GSSDDELETEALL	0x00000400
#define	NFSSVC_GSSDADDPORT	0x00000800
#define	NFSSVC_NFSUSERDPORT	0x00001000
#define	NFSSVC_NFSUSERDDELPORT	0x00002000
#define	NFSSVC_V4ROOTEXPORT	0x00004000
#define	NFSSVC_ADMINREVOKE	0x00008000
#define	NFSSVC_DUMPCLIENTS	0x00010000
#define	NFSSVC_DUMPLOCKS	0x00020000
#define	NFSSVC_GSSDADDFIRST	0x00040000
#define	NFSSVC_PUBLICFH		0x00080000
#define	NFSSVC_NFSCBD		0x00100000
#define	NFSSVC_CBADDSOCK	0x00200000
#define	NFSSVC_GETSTATS		0x00400000
#define	NFSSVC_BACKUPSTABLE	0x00800000
#define	NFSSVC_ZEROCLTSTATS	0x01000000	/* modifier for GETSTATS */
#define	NFSSVC_ZEROSRVSTATS	0x02000000	/* modifier for GETSTATS */

#endif /* _NFS_NFSSVC_H */


code:
/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)xdr_subs.h	8.3 (Berkeley) 3/30/95
 * $FreeBSD: release/9.0.0/sys/nfs/xdr_subs.h 139823 2005-01-07 01:45:51Z imp $
 */

#ifndef _NFS_XDR_SUBS_H_
#define _NFS_XDR_SUBS_H_

/*
 * Macros used for conversion to/from xdr representation by nfs...
 * These use the MACHINE DEPENDENT routines ntohl, htonl
 * As defined by "XDR: External Data Representation Standard" RFC1014
 *
 * To simplify the implementation, we use ntohl/htonl even on big-endian
 * machines, and count on them being `#define'd away.  Some of these
 * might be slightly more efficient as quad_t copies on a big-endian,
 * but we cannot count on their alignment anyway.
 */

#define	fxdr_unsigned(t, v)	((t)ntohl((int32_t)(v)))
#define	txdr_unsigned(v)	(htonl((int32_t)(v)))

#define	fxdr_nfsv2time(f, t) \
do { \
	(t)->tv_sec = ntohl(((struct nfsv2_time *)(f))->nfsv2_sec); \
	if (((struct nfsv2_time *)(f))->nfsv2_usec != 0xffffffff) \
		(t)->tv_nsec = 1000 * ntohl(((struct nfsv2_time *)(f))->nfsv2_usec); \
	else \
		(t)->tv_nsec = 0; \
} while (0)
#define	txdr_nfsv2time(f, t) \
do { \
	((struct nfsv2_time *)(t))->nfsv2_sec = htonl((f)->tv_sec); \
	if ((f)->tv_nsec != -1) \
		((struct nfsv2_time *)(t))->nfsv2_usec = htonl((f)->tv_nsec / 1000); \
	else \
		((struct nfsv2_time *)(t))->nfsv2_usec = 0xffffffff; \
} while (0)

#define	fxdr_nfsv3time(f, t) \
do { \
	(t)->tv_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \
	(t)->tv_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \
} while (0)
#define	txdr_nfsv3time(f, t) \
do { \
	((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->tv_sec); \
	((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->tv_nsec); \
} while (0)

#define	fxdr_hyper(f) \
	((((u_quad_t)ntohl(((u_int32_t *)(f))[0])) << 32) | \
	 (u_quad_t)(ntohl(((u_int32_t *)(f))[1])))
#define	txdr_hyper(f, t) \
do { \
	((u_int32_t *)(t))[0] = htonl((u_int32_t)((f) >> 32)); \
	((u_int32_t *)(t))[1] = htonl((u_int32_t)((f) & 0xffffffff)); \
} while (0)

#endif


code:
/*-
 * Copyright (c) 1989, 1993, 1995
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
 * $FreeBSD: release/9.0.0/sys/nfsclient/nfs.h 221986 2011-05-16 13:12:09Z rmacklem $
 */

#ifndef _NFSCLIENT_NFS_H_
#define _NFSCLIENT_NFS_H_

#ifdef _KERNEL
#include "opt_nfs.h"
#endif

#include <nfsclient/nfsargs.h>

/*
 * Tunable constants for nfs
 */

#define NFS_TICKINTVL	10		/* Desired time for a tick (msec) */
#define NFS_HZ		(hz / nfs_ticks) /* Ticks/sec */
#define	NFS_TIMEO	(1 * NFS_HZ)	/* Default timeout = 1 second */
#define	NFS_MINTIMEO	(1 * NFS_HZ)	/* Min timeout to use */
#define	NFS_MAXTIMEO	(60 * NFS_HZ)	/* Max timeout to backoff to */
#define	NFS_MINIDEMTIMEO (5 * NFS_HZ)	/* Min timeout for non-idempotent ops*/
#define	NFS_MAXREXMIT	100		/* Stop counting after this many */
#define	NFS_RETRANS	10		/* Num of retrans for UDP soft mounts */
#define	NFS_RETRANS_TCP	2		/* Num of retrans for TCP soft mounts */
#define	NFS_MAXGRPS	16		/* Max. size of groups list */
#ifndef NFS_MINATTRTIMO
#define	NFS_MINATTRTIMO 3		/* VREG attrib cache timeout in sec */
#endif
#ifndef NFS_MAXATTRTIMO
#define	NFS_MAXATTRTIMO 60
#endif
#ifndef NFS_MINDIRATTRTIMO
#define	NFS_MINDIRATTRTIMO 3		/* VDIR attrib cache timeout in sec */
#endif
#ifndef NFS_MAXDIRATTRTIMO
#define	NFS_MAXDIRATTRTIMO 60
#endif
#ifndef	NFS_ACCESSCACHESIZE
#define	NFS_ACCESSCACHESIZE 8		/* Per-node access cache entries */
#endif
#define	NFS_WSIZE	8192		/* Def. write data size <= 8192 */
#define	NFS_RSIZE	8192		/* Def. read data size <= 8192 */
#define NFS_READDIRSIZE	8192		/* Def. readdir size */
#define	NFS_DEFRAHEAD	1		/* Def. read ahead # blocks */
#define	NFS_MAXRAHEAD	4		/* Max. read ahead # blocks */
#define	NFS_MAXASYNCDAEMON 	64	/* Max. number async_daemons runnable */
#define	NFS_DIRBLKSIZ	4096		/* Must be a multiple of DIRBLKSIZ */
#ifdef _KERNEL
#define	DIRBLKSIZ	512		/* XXX we used to use ufs's DIRBLKSIZ */
#endif
#define NFS_MAXDEADTHRESH	9	/* How long till we say 'server not responding' */

/*
 * Oddballs
 */
#define NFS_CMPFH(n, f, s) \
	((n)->n_fhsize == (s) && !bcmp((caddr_t)(n)->n_fhp, (caddr_t)(f), (s)))
#define NFS_ISV3(v)	(VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV3)
#define NFS_ISV4(v)	(VFSTONFS((v)->v_mount)->nm_flag & NFSMNT_NFSV4)

#define NFSSTA_HASWRITEVERF	0x00040000  /* Has write verifier for V3 */
#define NFSSTA_GOTFSINFO	0x00100000  /* Got the V3 fsinfo */
#define	NFSSTA_SNDLOCK		0x01000000  /* Send socket lock */
#define	NFSSTA_WANTSND		0x02000000  /* Want above */
#define	NFSSTA_TIMEO		0x10000000  /* Experiencing a timeout */
#define	NFSSTA_LOCKTIMEO	0x20000000  /* Experiencing a lockd timeout */

/*
 * XXX to allow amd to include nfs.h without nfsproto.h
 */
#ifdef NFS_NPROCS
#include <nfsclient/nfsstats.h>
#endif

/*
 * vfs.oldnfs sysctl(3) identifiers
 */
#define NFS_NFSSTATS	1		/* struct: struct nfsstats */

#ifdef _KERNEL

#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_NFSREQ);
MALLOC_DECLARE(M_NFSDIROFF);
MALLOC_DECLARE(M_NFSBIGFH);
MALLOC_DECLARE(M_NFSHASH);
MALLOC_DECLARE(M_NFSDIRECTIO);
#endif

extern struct uma_zone *nfsmount_zone;

extern struct nfsstats nfsstats;
extern struct mtx nfs_iod_mtx;
extern struct task nfs_nfsiodnew_task;

extern int nfs_numasync;
extern unsigned int nfs_iodmax;
extern int nfs_pbuf_freecnt;
extern int nfs_ticks;

/* Data constants in XDR form */
extern u_int32_t nfs_true, nfs_false, nfs_xdrneg1;
extern u_int32_t rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers;
extern u_int32_t rpc_auth_unix, rpc_msgaccepted, rpc_call, rpc_autherr;

extern int nfsv3_procid[NFS_NPROCS];

/*
 * Socket errors ignored for connectionless sockets??
 * For now, ignore them all
 */
#define	NFSIGNORE_SOERROR(s, e) \
		((e) != EINTR && (e) != EIO && \
		(e) != ERESTART && (e) != EWOULDBLOCK && \
		((s) & PR_CONNREQUIRED) == 0)

struct nfsmount;

struct buf;
struct socket;
struct uio;
struct vattr;

/*
 * Pointers to ops that differ from v3 to v4
 */
struct nfs_rpcops {
	int	(*nr_readrpc)(struct vnode *vp, struct uio *uiop,
		    struct ucred *cred);
	int	(*nr_writerpc)(struct vnode *vp, struct uio *uiop,
		    struct ucred *cred, int *iomode, int *must_commit);
	int	(*nr_writebp)(struct buf *bp, int force, struct thread *td);
	int	(*nr_readlinkrpc)(struct vnode *vp, struct uio *uiop,
		    struct ucred *cred);
	void	(*nr_invaldir)(struct vnode *vp);
	int	(*nr_commit)(struct vnode *vp, u_quad_t offset, int cnt,
		    struct ucred *cred, struct thread *td);
};

/*
 * Defines for WebNFS
 */

#define WEBNFS_ESC_CHAR		'%'
#define WEBNFS_SPECCHAR_START	0x80

#define WEBNFS_NATIVE_CHAR	0x80
/*
 * ..
 * Possibly more here in the future.
 */

/*
 * Macro for converting escape characters in WebNFS pathnames.
 * Should really be in libkern.
 */

#define HEXTOC(c) \
	((c) >= 'a' ? ((c) - ('a' - 10)) : \
	    ((c) >= 'A' ? ((c) - ('A' - 10)) : ((c) - '0')))
#define HEXSTRTOI(p) \
	((HEXTOC(p[0]) << 4) + HEXTOC(p[1]))

/* nfs_sigintr() helper, when 'rep' has all we need */
#define NFS_SIGREP(rep)		nfs_sigintr((rep)->r_nmp, (rep), (rep)->r_td)

#ifdef NFS_DEBUG

extern int nfs_debug;
#define NFS_DEBUG_ASYNCIO	1 /* asynchronous i/o */
#define NFS_DEBUG_WG		2 /* server write gathering */
#define NFS_DEBUG_RC		4 /* server request caching */

#define NFS_DPF(cat, args)					\
	do {							\
		if (nfs_debug & NFS_DEBUG_##cat) printf args;	\
	} while (0)

#else

#define NFS_DPF(cat, args)

#endif

/*
 * On fast networks, the estimator will try to reduce the
 * timeout lower than the latency of the server's disks,
 * which results in too many timeouts, so cap the lower
 * bound.
 */
#define NFS_MINRTO	(NFS_HZ >> 2)

/*
 * Keep the RTO from increasing to unreasonably large values
 * when a server is not responding.
 */
#define NFS_MAXRTO	(20 * NFS_HZ)

enum nfs_rto_timer_t {
	NFS_DEFAULT_TIMER,
	NFS_GETATTR_TIMER,
	NFS_LOOKUP_TIMER,
	NFS_READ_TIMER,
	NFS_WRITE_TIMER,
};
#define NFS_MAX_TIMER	(NFS_WRITE_TIMER)

#define NFS_INITRTT	(NFS_HZ << 3)

vfs_init_t nfs_init;
vfs_uninit_t nfs_uninit;
int	nfs_mountroot(struct mount *mp);

void	nfs_purgecache(struct vnode *);
int	nfs_vinvalbuf(struct vnode *, int, struct thread *, int);
int	nfs_readrpc(struct vnode *, struct uio *, struct ucred *);
int	nfs_writerpc(struct vnode *, struct uio *, struct ucred *, int *,
	    int *);
int	nfs_commit(struct vnode *vp, u_quad_t offset, int cnt,
	    struct ucred *cred, struct thread *td);
int	nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *);
void	nfs_nfsiodnew(void);
void	nfs_nfsiodnew_tq(__unused void *, int);
int	nfs_asyncio(struct nfsmount *, struct buf *, struct ucred *, struct thread *);
int	nfs_doio(struct vnode *, struct buf *, struct ucred *, struct thread *);
void	nfs_doio_directwrite (struct buf *);
int	nfs_readlinkrpc(struct vnode *, struct uio *, struct ucred *);
int	nfs_sigintr(struct nfsmount *, struct thread *);
int	nfs_readdirplusrpc(struct vnode *, struct uio *, struct ucred *);
int	nfs_request(struct vnode *, struct mbuf *, int, struct thread *,
	    struct ucred *, struct mbuf **, struct mbuf **, caddr_t *);
int	nfs_loadattrcache(struct vnode **, struct mbuf **, caddr_t *,
	    struct vattr *, int);
int	nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *);
void	nfs_nhinit(void);
void	nfs_nhuninit(void);
int	nfs_nmcancelreqs(struct nfsmount *);
void	nfs_timer(void*);

int	nfs_connect(struct nfsmount *);
void	nfs_disconnect(struct nfsmount *);
void	nfs_safedisconnect(struct nfsmount *);
int	nfs_getattrcache(struct vnode *, struct vattr *);
int	nfs_iosize(struct nfsmount *nmp);
int	nfsm_strtmbuf(struct mbuf **, char **, const char *, long);
int	nfs_bioread(struct vnode *, struct uio *, int, struct ucred *);
int	nfsm_uiotombuf(struct uio *, struct mbuf **, int, caddr_t *);
void	nfs_clearcommit(struct mount *);
int	nfs_writebp(struct buf *, int, struct thread *);
int	nfs_fsinfo(struct nfsmount *, struct vnode *, struct ucred *,
	    struct thread *);
int	nfs_meta_setsize (struct vnode *, struct ucred *,
	    struct thread *, u_quad_t);

void	nfs_set_sigmask(struct thread *td, sigset_t *oldset);
void	nfs_restore_sigmask(struct thread *td, sigset_t *set);
int	nfs_msleep(struct thread *td, void *ident, struct mtx *mtx,
	    int priority, char *wmesg, int timo);

#endif	/* _KERNEL */

#endif


code:
/*-
 * Copyright (c) 1989, 1993, 1995
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Macklem at The University of Guelph.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
 * $FreeBSD: release/9.0.0/sys/nfsclient/nfsargs.h 221436 2011-05-04 13:27:45Z ru $
 */

#ifndef _NFSCLIENT_NFSARGS_H_
#define _NFSCLIENT_NFSARGS_H_

/*
 * Arguments to mount NFS
 */
#define NFS_ARGSVERSION	3		/* change when nfs_args changes */
struct nfs_args {
	int		version;	/* args structure version number */
	struct sockaddr	*addr;		/* file server address */
	int		addrlen;	/* length of address */
	int		sotype;		/* Socket type */
	int		proto;		/* and Protocol */
	u_char		*fh;		/* File handle to be mounted */
	int		fhsize;		/* Size, in bytes, of fh */
	int		flags;		/* flags */
	int		wsize;		/* write size in bytes */
	int		rsize;		/* read size in bytes */
	int		readdirsize;	/* readdir size in bytes */
	int		timeo;		/* initial timeout in .1 secs */
	int		retrans;	/* times to retry send */
	int		maxgrouplist;	/* Max. size of group list */
	int		readahead;	/* # of blocks to readahead */
	int		wcommitsize;	/* Max. write commit size in bytes */
	int		deadthresh;	/* Retrans threshold */
	char		*hostname;	/* server's name */
	int		acregmin;	/* cache attrs for reg files min time */
	int		acregmax;	/* cache attrs for reg files max time */
	int		acdirmin;	/* cache attrs for dirs min time */
	int		acdirmax;	/* cache attrs for dirs max time */
};

/*
 * NFS mount option flags
 */
#define	NFSMNT_SOFT		0x00000001  /* soft mount (hard is default) */
#define	NFSMNT_WSIZE		0x00000002  /* set write size */
#define	NFSMNT_RSIZE		0x00000004  /* set read size */
#define	NFSMNT_TIMEO		0x00000008  /* set initial timeout */
#define	NFSMNT_RETRANS		0x00000010  /* set number of request retries */
#define	NFSMNT_MAXGRPS		0x00000020  /* set maximum grouplist size */
#define	NFSMNT_INT		0x00000040  /* allow interrupts on hard mount */
#define	NFSMNT_NOCONN		0x00000080  /* Don't Connect the socket */
/* 0x100 free, was NFSMNT_NQNFS */
#define	NFSMNT_NFSV3		0x00000200  /* Use NFS Version 3 protocol */
#define	NFSMNT_KERB		0x00000400  /* Use RPCSEC_GSS/Krb5 */
#define	NFSMNT_DUMBTIMR		0x00000800  /* Don't estimate rtt dynamically */
#define	NFSMNT_WCOMMITSIZE	0x00001000  /* set max write commit size */
#define	NFSMNT_READAHEAD	0x00002000  /* set read ahead */
#define	NFSMNT_DEADTHRESH	0x00004000  /* set dead server retry thresh */
#define	NFSMNT_RESVPORT		0x00008000  /* Allocate a reserved port */
#define	NFSMNT_RDIRPLUS		0x00010000  /* Use Readdirplus for V3 */
#define	NFSMNT_READDIRSIZE	0x00020000  /* Set readdir size */
#define	NFSMNT_ACREGMIN		0x00040000
#define	NFSMNT_ACREGMAX		0x00080000
#define	NFSMNT_ACDIRMIN		0x00100000
#define	NFSMNT_ACDIRMAX		0x00200000
#define	NFSMNT_NOLOCKD		0x00400000 /* Locks are local */
#define	NFSMNT_NFSV4		0x00800000 /* Use NFS Version 4 protocol */
#define	NFSMNT_HASWRITEVERF	0x01000000 /* NFSv4 Write verifier */
#define	NFSMNT_INTEGRITY	0x02000000 /* Use integrity with RPCSEC_GSS */
#define	NFSMNT_PRIVACY		0x04000000 /* Use privacy with RPCSEC_GSS */
#define	NFSMNT_ALLGSSNAME	0x08000000 /* Use principal for all accesses */
#define	NFSMNT_STRICT3530	0x10000000 /* Adhere strictly to RFC3530 */
#define	NFSMNT_NOCTO		0x20000000 /* Don't flush attrcache on open */

#endif