/*
 * Set protocol-independent source filter list in use on socket.
 */
int
setsourcefilter(int s, uint32_t interface, struct sockaddr *group,
	socklen_t grouplen, uint32_t fmode, uint32_t numsrc,
	struct sockaddr_storage *slist)
{
	struct __msfilterreq	 msfr;
	sockunion_t		*psu;
	int			 level, optname;

	if (fmode != MCAST_INCLUDE && fmode != MCAST_EXCLUDE)
	{
		errno = EINVAL;
		return (-1);
	}

	psu = (sockunion_t *)group;
	switch (psu->ss.ss_family) {
#ifdef INET
	case AF_INET:
		if ((grouplen != sizeof(struct sockaddr_in) ||
			!IN_MULTICAST(ntohl(psu->sin.sin_addr.s_addr))))
		{
			errno = EINVAL;
			return (-1);
		}

		level = IPPROTO_IP;
		optname = IP_MSFILTER;
		break;
#endif
#ifdef INET6
	case AF_INET6:
		if (grouplen != sizeof(struct sockaddr_in6) ||
		    !IN6_IS_ADDR_MULTICAST(&psu->sin6.sin6_addr))
		{
			errno = EINVAL;
			return (-1);
		}

		level = IPPROTO_IPV6;
		optname = IPV6_MSFILTER;
		break;
#endif
	default:
		errno = EAFNOSUPPORT;
		return (-1);
	}

	memset(&msfr, 0, sizeof(msfr));
	msfr.msfr_ifindex = interface;
	msfr.msfr_fmode = fmode;
	msfr.msfr_nsrcs = numsrc;
	memcpy(&msfr.msfr_group, &psu->ss, psu->ss.ss_len);
	msfr.msfr_srcs = slist;		/* pointer */

	return (_setsockopt(s, level, optname, &msfr, sizeof(msfr)));
}
Example #2
0
static void set_ttl( const int t, const uint8 ttl )
{
	int _ttl = ttl; // defensive programming, I know VCx

	if(_setsockopt( sockets[t].s, IPPROTO_IP, IP_TTL, (const char *)&_ttl, sizeof(int) ) == SOCKET_ERROR  ) {
		D(bug("<%d> could not set ttl to %d, error=%d\r\n", t, ttl, _WSAGetLastError()));
	} else {
		D(bug("<%d> ttl set to %d.\r\n", t, ttl));
	}
}
Example #3
0
int
/*ARGSUSED*/
__rpc_broadenable(int af, int s, struct broadif *bip)
{
	int o = 1;

#if 0
	if (af == AF_INET6) {
		fprintf(stderr, "set v6 multicast if to %d\n", bip->index);
		if (_setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &bip->index,
		    sizeof bip->index) < 0)
			return -1;
	} else
#endif
		if (_setsockopt(s, SOL_SOCKET, SO_BROADCAST, &o, sizeof o) < 0)
			return -1;

	return 0;
}
Example #4
0
void socket_t::set_ttl( uint8 ttl )
{
	int _ttl = ttl; // defensive programming, I know VCx

	if(_setsockopt( s, IPPROTO_IP, IP_TTL, (const char *)&_ttl, sizeof(int) ) == SOCKET_ERROR  ) {
		D(bug("could not set ttl to %d.\r\n", ttl));
	} else {
		D(bug("ttl set to %d.\r\n", ttl));
	}
}
Example #5
0
int init_socket(int port) {
	int listenfd, t = 1;
	struct sockaddr_in servaddr;

	listenfd = _socket(PF_INET, SOCK_STREAM, 0);

	memset(&servaddr, sizeof(char), sizeof(servaddr));			

	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(port);

	_setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t));	

	_bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

	return listenfd;	
}
Example #6
0
/*
 * Generic client creation:  returns client handle.
 * Default options are set, which the user can
 * change using the rpc equivalent of _ioctl()'s : clnt_control().
 * If fd is RPC_ANYFD, it will be opened using nconf.
 * It will be bound if not so.
 * If sizes are 0; appropriate defaults will be chosen.
 */
CLIENT *
clnt_tli_create(int fd, const struct netconfig *nconf,
	struct netbuf *svcaddr, rpcprog_t prog, rpcvers_t vers,
	uint sendsz, uint recvsz)
{
	CLIENT *cl;			/* client handle */
	bool_t madefd = FALSE;		/* whether fd opened here */
	long servtype;
	int one = 1;
	struct __rpc_sockinfo si;
	extern int __rpc_minfd;

	if (fd == RPC_ANYFD) {
		if (nconf == NULL) {
			rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
			return (NULL);
		}

		fd = __rpc_nconf2fd(nconf);

		if (fd == -1)
			goto err;
		if (fd < __rpc_minfd)
			fd = __rpc_raise_fd(fd);
		madefd = TRUE;
		servtype = nconf->nc_semantics;
		if (!__rpc_fd2sockinfo(fd, &si))
			goto err;
		bindresvport(fd, NULL);
	} else {
		if (!__rpc_fd2sockinfo(fd, &si))
			goto err;
		servtype = __rpc_socktype2seman(si.si_socktype);
		if (servtype == -1) {
			rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
			return (NULL);
		}
	}

	if (si.si_af != ((struct sockaddr *)svcaddr->buf)->sa_family) {
		rpc_createerr.cf_stat = RPC_UNKNOWNHOST;	/* XXX */
		goto err1;
	}

	switch (servtype) {
	case NC_TPI_COTS:
		cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz);
		break;
	case NC_TPI_COTS_ORD:
		if (nconf && ((strcmp(nconf->nc_protofmly, "inet") == 0))) {
			_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one,
			    sizeof (one));
		}
		cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz);
		break;
	case NC_TPI_CLTS:
		cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz);
		break;
	default:
		goto err;
	}

	if (cl == NULL)
		goto err1; /* borrow errors from clnt_dg/vc creates */
	if (nconf) {
		cl->cl_netid = strdup(nconf->nc_netid);
		cl->cl_tp = strdup(nconf->nc_device);
	} else {
		cl->cl_netid = "";
		cl->cl_tp = "";
	}
	if (madefd) {
		(void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL);
/*		(void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, NULL);  */
	};

	return (cl);

err:
	rpc_createerr.cf_stat = RPC_SYSTEMERROR;
	rpc_createerr.cf_error.re_errno = errno;
err1:	if (madefd)
		(void)_close(fd);
	return (NULL);
}
Example #7
0
/*
 * Create a socket endpoint for socket() and socketpair().
 * In SunOS 4.X and in SunOS 5.X prior to XPG 4.2 the only error
 * that could be returned due to invalid <family, type, protocol>
 * was EPROTONOSUPPORT. (While the SunOS 4.X source contains EPROTOTYPE
 * error as well that error can only be generated if the kernel is
 * incorrectly configured.)
 * For backwards compatibility only applications that request XPG 4.2
 * (through c89 or XOPEN_SOURCE) will get EPROTOTYPE or EAFNOSUPPORT errors.
 */
int
_socket_create(int family, int type, int protocol, int version)
{
	int fd;

	/*
	 * Try creating without knowing the device assuming that
	 * the transport provider is registered in /etc/sock2path.d.
	 * If none found fall back to using /etc/netconfig to look
	 * up the name of the transport device name. This provides
	 * backwards compatibility for transport providers that have not
	 * yet been converted to using /etc/sock2path.d.
	 * XXX When all transport providers use /etc/sock2path.d. this
	 * part of the code can be removed.
	 */
	fd = _so_socket(family, type, protocol, NULL, version);
	if (fd == -1) {
		char *devpath;
		int saved_errno = errno;
		int prototype = 0;

		switch (saved_errno) {
		case EAFNOSUPPORT:
		case EPROTOTYPE:
			if (version != SOV_XPG4_2)
				saved_errno = EPROTONOSUPPORT;
			break;
		case EPROTONOSUPPORT:
			break;

		default:
			errno = saved_errno;
			return (-1);
		}
		if (_s_netconfig_path(family, type, protocol,
		    &devpath, &prototype) == -1) {
			errno = saved_errno;
			return (-1);
		}
		fd = _so_socket(family, type, protocol, devpath, version);
		free(devpath);
		if (fd == -1) {
			errno = saved_errno;
			return (-1);
		}
		if (prototype != 0) {
			if (_setsockopt(fd, SOL_SOCKET, SO_PROTOTYPE,
			    (caddr_t)&prototype, (int)sizeof (prototype)) < 0) {
				(void) close(fd);
				/*
				 * setsockopt often fails with ENOPROTOOPT
				 * but socket() should fail with
				 * EPROTONOSUPPORT.
				 */
				errno = EPROTONOSUPPORT;
				return (-1);
			}
		}
	}
	return (fd);
}
Example #8
0
/*ARGSUSED*/
static bool_t
rendezvous_request(SVCXPRT *xprt, struct rpc_msg *msg)
{
	int sock, flags;
	struct cf_rendezvous *r;
	struct cf_conn *cd;
	struct sockaddr_storage addr;
	socklen_t len;
	struct __rpc_sockinfo si;
	SVCXPRT *newxprt;
	fd_set cleanfds;

	assert(xprt != NULL);
	assert(msg != NULL);

	r = (struct cf_rendezvous *)xprt->xp_p1;
again:
	len = sizeof addr;
	if ((sock = _accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr,
	    &len)) < 0) {
		if (errno == EINTR)
			goto again;
		/*
		 * Clean out the most idle file descriptor when we're
		 * running out.
		 */
		if (errno == EMFILE || errno == ENFILE) {
			cleanfds = svc_fdset;
			__svc_clean_idle(&cleanfds, 0, FALSE);
			goto again;
		}
		return (FALSE);
	}
	/*
	 * make a new transporter (re-uses xprt)
	 */
	newxprt = makefd_xprt(sock, r->sendsize, r->recvsize);
	newxprt->xp_rtaddr.buf = mem_alloc(len);
	if (newxprt->xp_rtaddr.buf == NULL)
		return (FALSE);
	memcpy(newxprt->xp_rtaddr.buf, &addr, len);
	newxprt->xp_rtaddr.len = len;
#ifdef PORTMAP
	if (addr.ss_family == AF_INET || addr.ss_family == AF_LOCAL) {
		newxprt->xp_raddr = *(struct sockaddr_in *)newxprt->xp_rtaddr.buf;
		newxprt->xp_addrlen = sizeof (struct sockaddr_in);
	}
#endif				/* PORTMAP */
	if (__rpc_fd2sockinfo(sock, &si) && si.si_proto == IPPROTO_TCP) {
		len = 1;
		/* XXX fvdl - is this useful? */
		_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &len, sizeof (len));
	}

	cd = (struct cf_conn *)newxprt->xp_p1;

	cd->recvsize = r->recvsize;
	cd->sendsize = r->sendsize;
	cd->maxrec = r->maxrec;

	if (cd->maxrec != 0) {
		flags = _fcntl(sock, F_GETFL, 0);
		if (flags  == -1)
			return (FALSE);
		if (_fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
			return (FALSE);
		if (cd->recvsize > cd->maxrec)
			cd->recvsize = cd->maxrec;
		cd->nonblock = TRUE;
		__xdrrec_setnonblock(&cd->xdrs, cd->maxrec);
	} else
		cd->nonblock = FALSE;

	gettimeofday(&cd->last_recv_time, NULL);

	return (FALSE); /* there is never an rpc msg to be processed */
}
Example #9
0
/*
 * Bind a socket to a privileged IP port
 */
int
bindresvport_sa(int sd, struct sockaddr *sa)
{
	int old, error, af;
	struct sockaddr_storage myaddr;
	struct sockaddr_in *sin;
#ifdef INET6
	struct sockaddr_in6 *sin6;
#endif
	int proto, portrange, portlow;
	u_int16_t *portp;
	socklen_t salen;

	if (sa == NULL) {
		salen = sizeof(myaddr);
		sa = (struct sockaddr *)&myaddr;

		if (_getsockname(sd, sa, &salen) == -1)
			return -1;	/* errno is correctly set */

		af = sa->sa_family;
		memset(sa, 0, salen);
	} else
		af = sa->sa_family;

	switch (af) {
	case AF_INET:
		proto = IPPROTO_IP;
		portrange = IP_PORTRANGE;
		portlow = IP_PORTRANGE_LOW;
		sin = (struct sockaddr_in *)sa;
		salen = sizeof(struct sockaddr_in);
		portp = &sin->sin_port;
		break;
#ifdef INET6
	case AF_INET6:
		proto = IPPROTO_IPV6;
		portrange = IPV6_PORTRANGE;
		portlow = IPV6_PORTRANGE_LOW;
		sin6 = (struct sockaddr_in6 *)sa;
		salen = sizeof(struct sockaddr_in6);
		portp = &sin6->sin6_port;
		break;
#endif
	default:
		errno = EPFNOSUPPORT;
		return (-1);
	}
	sa->sa_family = af;
	sa->sa_len = salen;

	if (*portp == 0) {
		socklen_t oldlen = sizeof(old);

		error = _getsockopt(sd, proto, portrange, &old, &oldlen);
		if (error < 0)
			return (error);

		error = _setsockopt(sd, proto, portrange, &portlow,
		    sizeof(portlow));
		if (error < 0)
			return (error);
	}

	error = _bind(sd, sa, salen);

	if (*portp == 0) {
		int saved_errno = errno;

		if (error < 0) {
			if (_setsockopt(sd, proto, portrange, &old,
			    sizeof(old)) < 0)
				errno = saved_errno;
			return (error);
		}

		if (sa != (struct sockaddr *)&myaddr) {
			/* Hmm, what did the kernel assign? */
			if (_getsockname(sd, sa, &salen) < 0)
				errno = saved_errno;
			return (error);
		}
	}
	return (error);
}