Example #1
0
static int
setopt(int fd, int level, int name, int value)
{
	struct t_optmgmt req, resp;
	struct {
		struct opthdr opt;
		int value;
	} reqbuf;

	reqbuf.opt.level = level;
	reqbuf.opt.name = name;
	reqbuf.opt.len = sizeof (int);

	reqbuf.value = value;

	req.flags = T_NEGOTIATE;
	req.opt.len = sizeof (reqbuf);
	req.opt.buf = (char *)&reqbuf;

	resp.flags = 0;
	resp.opt.buf = (char *)&reqbuf;
	resp.opt.maxlen = sizeof (reqbuf);

	if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) {
		t_error("t_optmgmt");
		return (-1);
	}
	return (0);
}
Example #2
0
static int
get_opt(int fd, int level, int name)
{
	struct t_optmgmt req, res;
	struct {
		struct opthdr opt;
		int value;
	} reqbuf;

	reqbuf.opt.level = level;
	reqbuf.opt.name = name;
	reqbuf.opt.len = sizeof (int);
	reqbuf.value = 0;

	req.flags = T_CURRENT;
	req.opt.len = sizeof (reqbuf);
	req.opt.buf = (char *)&reqbuf;

	res.flags = 0;
	res.opt.buf = (char *)&reqbuf;
	res.opt.maxlen = sizeof (reqbuf);

	if (t_optmgmt(fd, &req, &res) < 0 || res.flags != T_SUCCESS) {
		t_error("t_optmgmt");
		return (-1);
	}
	return (reqbuf.value);
}
Example #3
0
/*
 ****************************************************************
 *	Modifica algumas características da conexão		*
 ****************************************************************
 */
static int
set_param (int fd)
{
	T_OPTMGMT	req_optmgmt, ret_optmgmt;
	TCP_OPTIONS	options;

	/*
	 *	Obtém os valores em USO
	 */
	memset (&options, 0, sizeof (TCP_OPTIONS));

	req_optmgmt.flags = T_CHECK;

	req_optmgmt.opt.buf    = &options;
	req_optmgmt.opt.len    = sizeof (TCP_OPTIONS);

	ret_optmgmt.opt.buf    = &options;
	ret_optmgmt.opt.maxlen = sizeof (TCP_OPTIONS);

	if (t_optmgmt (fd, &req_optmgmt, &ret_optmgmt) < 0)
		return (-1);

	/*
	 *	Negocia o "max_wait" e "max_silence"
	 */
	req_optmgmt.flags = T_NEGOTIATE;

	options.max_wait     = 0;	/* Sem limite */
	options.max_silence  = 0;	/* Sem limite */

/***	req_optmgmt.opt.buf    = &options;		***/
/***	req_optmgmt.opt.len    = sizeof (TCP_OPTIONS);	***/

/***	ret_optmgmt.opt.buf    = &options;		***/
/***	ret_optmgmt.opt.maxlen = sizeof (TCP_OPTIONS);	***/

	if (t_optmgmt (fd, &req_optmgmt, &ret_optmgmt) < 0)
		return (-1);

	return (0);

}	/* end set_param */
Example #4
0
int
xti_getopt(int fd, int level, int name, void *optval, socklen_t *optlenp)
{
	int					rc, len;
	struct t_optmgmt	*req, *ret;
	struct t_opthdr		*topt;

	req = T_alloc(fd, T_OPTMGMT, T_ALL);
	ret = T_alloc(fd, T_OPTMGMT, T_ALL);
	if (req->opt.maxlen == 0)
		err_quit("xti_getopt: opt.maxlen == 0");

	topt = (struct t_opthdr *) req->opt.buf;
	topt->level = level;
	topt->name = name;
	topt->len = sizeof(struct t_opthdr);	/* just a t_opthdr{} */
	req->opt.len = topt->len;

	req->flags = T_CURRENT;
	if (t_optmgmt(fd, req, ret) < 0) {
		T_free(req, T_OPTMGMT);
		T_free(ret, T_OPTMGMT);
		return(-1);
	}
	rc = ret->flags;

	if (rc == T_SUCCESS || rc == T_READONLY) {
			/*4copy back value and length */
		topt = (struct t_opthdr *) ret->opt.buf;
		len = topt->len - sizeof(struct t_opthdr);
		len = min(len, *optlenp);
		memcpy(optval, topt+1, len);
		*optlenp = len;
	}

	T_free(req, T_OPTMGMT);
	T_free(ret, T_OPTMGMT);

	if (rc == T_SUCCESS || rc == T_READONLY)
		return(0);
	return(-1);		/* T_NOTSUPPORT */
}
Example #5
0
File: tlx.c Project: alhazred/onarm
static int
tlx_setsockopt(int fd, int level, int optname, const void *optval,
    socklen_t optlen)
{
	struct t_optmgmt request, reply;
	struct {
		struct opthdr sockopt;
		char data[256];
	} optbuf;

	debug_msg("Entering tlx_setsockopt, "
	    "fd: %d, level: %d, optname: %d, optval: %x, optlen: %d",
	    fd, level, optname, optval, optlen);

	if (optlen > sizeof (optbuf.data)) {
		error_msg(gettext("t_optmgmt request too long"));
		return (-1);
	}

	optbuf.sockopt.level = level;
	optbuf.sockopt.name = optname;
	optbuf.sockopt.len = optlen;
	(void) memcpy(optbuf.data, optval, optlen);

	request.opt.len = sizeof (struct opthdr) + optlen;
	request.opt.buf = (char *)&optbuf;
	request.flags = T_NEGOTIATE;

	reply.opt.maxlen = sizeof (struct opthdr) + optlen;
	reply.opt.buf = (char *)&optbuf;
	reply.flags = 0;

	if ((t_optmgmt(fd, &request, &reply) == -1) ||
	    (reply.flags != T_SUCCESS)) {
		error_msg("t_optmgmt: %s", t_strerror(t_errno));
		return (-1);
	}
	return (0);
}
Example #6
0
void
xti_set_ulong_opt(int fd, const char *str, u_long level, u_long name)
{
	struct t_opthdr		*topt;

	topt = (struct t_opthdr *) req->opt.buf;
	topt->level = level;
	topt->name = name;
	topt->len = sizeof(struct t_opthdr);
	req->opt.len = topt->len;
	
	req->flags = T_CURRENT;
	printf("%s: ", str);
	if (t_optmgmt(fd, req, ret) == -1) {
		printf("t_optmgmt error\n");
	} else {
		topt = (struct t_opthdr *) ret->opt.buf;
		if (topt->status == T_SUCCESS || topt->status == T_READONLY)
			printf("%lu\n", *((u_long *) (topt + 1)));
		else
			printf("status = %ld\n", topt->status);
	}
}
void
xti_def_uchar_opt(int fd, const char *str, t_scalar_t level, t_scalar_t name)
{
	struct t_opthdr		*topt;

	topt = (struct t_opthdr *) req->opt.buf;
	topt->level = level;
	topt->name = name;
	topt->len = sizeof(struct t_opthdr);
	req->opt.len = topt->len;
	
	req->flags = T_DEFAULT;
	printf("%s: ", str);
	if (t_optmgmt(fd, req, ret) == -1) {
		printf("t_optmgmt error\n");
	} else {
		topt = (struct t_opthdr *) ret->opt.buf;
		printf("len = %d, ", topt->len);
		if (topt->status == T_SUCCESS || topt->status == T_READONLY)
			printf("%u\n", *((u_char *) (topt + 1)));
		else
			printf("status = %ld\n", topt->status);
	}
}
Example #8
0
{
	struct {
		struct t_opthdr hdr;
		char optval[64];
	} opt;
	struct t_optmgmt opts = {
		{
		 .maxlen = sizeof(opt),
		 .len = optlen,
		 .buf = opt.optval,
		 }
		, T_NEGOTIATE,
	};
	int retval;

	retval = t_optmgmt(s, &opts, &opts);
	if (retval == -1) {
		switch (t_errno) {
		case TBADF:
			errno = EBADF;
			break;
		default:
		case TBADFLAG:
		case TBADOPT:
		case TBUFOVFLW:
		case TNOTSUPPORT:
		case TOUTSTATE:
			errno = EINVAL;
			break;
		case TPROTO:
			errno = EPROTO;
Example #9
0
int
nfslib_bindit(struct netconfig *nconf, struct netbuf **addr,
	struct nd_hostserv *hs, int backlog)
{
	int fd;
	struct t_bind  *ntb;
	struct t_bind tb;
	struct nd_addrlist *addrlist;
	struct t_optmgmt req, resp;
	struct opthdr *opt;
	char reqbuf[128];
	bool_t use_any = FALSE;
	bool_t gzone = TRUE;

	if ((fd = nfslib_transport_open(nconf)) == -1) {
		syslog(LOG_ERR, "cannot establish transport service over %s",
		    nconf->nc_device);
		return (-1);
	}

	addrlist = (struct nd_addrlist *)NULL;

	/* nfs4_callback service does not used a fieed port number */

	if (strcmp(hs->h_serv, "nfs4_callback") == 0) {
		tb.addr.maxlen = 0;
		tb.addr.len = 0;
		tb.addr.buf = 0;
		use_any = TRUE;
		gzone = (getzoneid() == GLOBAL_ZONEID);
	} else if (netdir_getbyname(nconf, hs, &addrlist) != 0) {

		syslog(LOG_ERR,
		"Cannot get address for transport %s host %s service %s",
		    nconf->nc_netid, hs->h_host, hs->h_serv);
		(void) t_close(fd);
		return (-1);
	}

	if (strcmp(nconf->nc_proto, "tcp") == 0) {
		/*
		 * If we're running over TCP, then set the
		 * SO_REUSEADDR option so that we can bind
		 * to our preferred address even if previously
		 * left connections exist in FIN_WAIT states.
		 * This is somewhat bogus, but otherwise you have
		 * to wait 2 minutes to restart after killing it.
		 */
		if (reuseaddr(fd) == -1) {
			syslog(LOG_WARNING,
			"couldn't set SO_REUSEADDR option on transport");
		}
	} else if (strcmp(nconf->nc_proto, "udp") == 0) {
		/*
		 * In order to run MLP on UDP, we need to handle creds.
		 */
		if (recvucred(fd) == -1) {
			syslog(LOG_WARNING,
			    "couldn't set SO_RECVUCRED option on transport");
		}
	}

	/*
	 * Make non global zone nfs4_callback port MLP
	 */
	if (use_any && is_system_labeled() && !gzone) {
		if (anonmlp(fd) == -1) {
			/*
			 * failing to set this option means nfs4_callback
			 * could fail silently later. So fail it with
			 * with an error message now.
			 */
			syslog(LOG_ERR,
			    "couldn't set SO_ANON_MLP option on transport");
			(void) t_close(fd);
			return (-1);
		}
	}

	if (nconf->nc_semantics == NC_TPI_CLTS)
		tb.qlen = 0;
	else
		tb.qlen = backlog;

	/* LINTED pointer alignment */
	ntb = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL);
	if (ntb == (struct t_bind *)NULL) {
		syslog(LOG_ERR, "t_alloc failed:  t_errno %d, %m", t_errno);
		(void) t_close(fd);
		netdir_free((void *)addrlist, ND_ADDRLIST);
		return (-1);
	}

	/*
	 * XXX - what about the space tb->addr.buf points to? This should
	 * be either a memcpy() to/from the buf fields, or t_alloc(fd,T_BIND,)
	 * should't be called with T_ALL.
	 */
	if (addrlist)
		tb.addr = *(addrlist->n_addrs);		/* structure copy */

	if (t_bind(fd, &tb, ntb) == -1) {
		syslog(LOG_ERR, "t_bind failed:  t_errno %d, %m", t_errno);
		(void) t_free((char *)ntb, T_BIND);
		netdir_free((void *)addrlist, ND_ADDRLIST);
		(void) t_close(fd);
		return (-1);
	}

	/* make sure we bound to the right address */
	if (use_any == FALSE &&
	    (tb.addr.len != ntb->addr.len ||
	    memcmp(tb.addr.buf, ntb->addr.buf, tb.addr.len) != 0)) {
		syslog(LOG_ERR, "t_bind to wrong address");
		(void) t_free((char *)ntb, T_BIND);
		netdir_free((void *)addrlist, ND_ADDRLIST);
		(void) t_close(fd);
		return (-1);
	}

	/*
	 * Call nfs4svc_setport so that the kernel can be
	 * informed what port number the daemon is listing
	 * for incoming connection requests.
	 */

	if ((nconf->nc_semantics == NC_TPI_COTS ||
	    nconf->nc_semantics == NC_TPI_COTS_ORD) && Mysvc4 != NULL)
		(*Mysvc4)(fd, NULL, nconf, NFS4_SETPORT, &ntb->addr);

	*addr = &ntb->addr;
	netdir_free((void *)addrlist, ND_ADDRLIST);

	if (strcmp(nconf->nc_proto, "tcp") == 0) {
		/*
		 * Disable the Nagle algorithm on TCP connections.
		 * Connections accepted from this listener will
		 * inherit the listener options.
		 */

		/* LINTED pointer alignment */
		opt = (struct opthdr *)reqbuf;
		opt->level = IPPROTO_TCP;
		opt->name = TCP_NODELAY;
		opt->len = sizeof (int);

		/* LINTED pointer alignment */
		*(int *)((char *)opt + sizeof (*opt)) = 1;

		req.flags = T_NEGOTIATE;
		req.opt.len = sizeof (*opt) + opt->len;
		req.opt.buf = (char *)opt;
		resp.flags = 0;
		resp.opt.buf = reqbuf;
		resp.opt.maxlen = sizeof (reqbuf);

		if (t_optmgmt(fd, &req, &resp) < 0 ||
		    resp.flags != T_SUCCESS) {
			syslog(LOG_ERR,
	"couldn't set NODELAY option for proto %s: t_errno = %d, %m",
			    nconf->nc_proto, t_errno);
		}

		nfslib_set_sockbuf(fd);
	}

	return (fd);
}
Example #10
0
void
xti_set_uchar_opt(int fd, const char *str, u_long level, u_long name, u_int val)
{
	struct t_opthdr		*topt;

		/* first check that option is supported */
	topt = (struct t_opthdr *) req->opt.buf;
	topt->level = level;
	topt->name = name;
	topt->len = sizeof(struct t_opthdr);	/* just the header, no value */
	req->opt.len = topt->len;
	
	req->flags = T_CHECK;
	printf("%s: check: ", str);
	if (t_optmgmt(fd, req, ret) == -1) {
		printf("t_optmgmt error %d", t_errno);
	} else {
		if (ret->opt.len >= sizeof(struct t_opthdr)) {
			topt = (struct t_opthdr *) ret->opt.buf;
			printf("%s", xti_flag_str(topt->status));
		} else
			printf("*ret->opt.len = %d", ret->opt.len);
	}

		/* get default value of option */
		/* ret is "const", so it was not changed by t_optmgmt() */
	topt = (struct t_opthdr *) req->opt.buf;
	topt->status = 0;
	req->flags = T_DEFAULT;
	printf("; default: ");
	if (t_optmgmt(fd, req, ret) == -1) {
		printf("t_optmgmt error %d", t_errno);
	} else {
		topt = (struct t_opthdr *) ret->opt.buf;
		printf("(ret->opt.len = %d, len = %d) ", ret->opt.len, topt->len);
		if (topt->status == T_SUCCESS || topt->status == T_READONLY)
			printf("%u", *((u_char *) (topt + 1)));
		else
			printf("status = %ld", topt->status);
	}

		/* now change value */
	topt = (struct t_opthdr *) req->opt.buf;
	topt->status = 0;
	topt->len += sizeof(u_long);
	req->opt.len = topt->len;
	*((u_long *) (topt + 1)) = val;
	req->flags = T_NEGOTIATE;
	printf("; negotiated: ");
	if (t_optmgmt(fd, req, ret) == -1) {
		printf("t_optmgmt error %d", t_errno);
	} else {
		topt = (struct t_opthdr *) ret->opt.buf;
		if (topt->status == T_SUCCESS)
			printf("T_SUCCESS");
		else if (topt->status == T_PARTSUCCESS)
			printf("T_PARTSUCCESS");
		else if (topt->status == T_READONLY)
			printf("T_READONLY");
		else if (topt->status == T_FAILURE)
			printf("T_FAILURE");
		else if (topt->status == T_NOTSUPPORT)
			printf("T_NOTSUPPORT");
		else
			printf("status = %ld\n", topt->status);
	}

	topt = (struct t_opthdr *) req->opt.buf;
	topt->len -= sizeof(u_long);
	req->opt.len = topt->len;
	req->flags = T_CURRENT;
	printf("; current: ");
	if (t_optmgmt(fd, req, ret) == -1) {
		printf("t_optmgmt error %d", t_errno);
	} else {
		topt = (struct t_opthdr *) ret->opt.buf;
		if (topt->status == T_SUCCESS || topt->status == T_READONLY)
			printf("%u", *((u_long *) (topt + 1)));
		else
			printf("status = %ld", topt->status);
	}
	printf("\n");
}