/* * 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))); }
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)); } }
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; }
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)); } }
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; }
/* * 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); }
/* * 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); }
/*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 */ }
/* * 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); }