Esempio n. 1
0
static int
so_ioctl (rtems_libio_t *iop, struct socket *so, uint32_t   command, void *buffer)
{
	switch (command) {
	case FIONBIO:
		if (*(int *)buffer) {
			iop->flags |= O_NONBLOCK;
			so->so_state |= SS_NBIO;
		}
		else {
			iop->flags &= ~O_NONBLOCK;
			so->so_state &= ~SS_NBIO;
		}
		return 0;

	case FIONREAD:
		*(int *)buffer = so->so_rcv.sb_cc;
		return 0;
	}

	if (IOCGROUP(command) == 'i')
		return ifioctl (so, command, buffer, NULL);
	if (IOCGROUP(command) == 'r')
		return rtioctl (command, buffer, NULL);
	return (*so->so_proto->pr_usrreqs->pru_control)(so, command, buffer, 0);
}
Esempio n. 2
0
int
soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
{
	struct socket *so = (struct socket *)fp->f_data;

	switch (cmd) {

	case FIONBIO:
		if (*(int *)data)
			so->so_state |= SS_NBIO;
		else
			so->so_state &= ~SS_NBIO;
		return (0);

	case FIOASYNC:
		if (*(int *)data) {
			so->so_state |= SS_ASYNC;
			so->so_rcv.sb_flags |= SB_ASYNC;
			so->so_snd.sb_flags |= SB_ASYNC;
		} else {
			so->so_state &= ~SS_ASYNC;
			so->so_rcv.sb_flags &= ~SB_ASYNC;
			so->so_snd.sb_flags &= ~SB_ASYNC;
		}
		return (0);

	case FIONREAD:
		*(int *)data = so->so_rcv.sb_datacc;
		return (0);

	case SIOCSPGRP:
		so->so_pgid = *(int *)data;
		so->so_siguid = p->p_cred->p_ruid;
		so->so_sigeuid = p->p_ucred->cr_uid;
		return (0);

	case SIOCGPGRP:
		*(int *)data = so->so_pgid;
		return (0);

	case SIOCATMARK:
		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
		return (0);
	}
	/*
	 * Interface/routing/protocol specific ioctls:
	 * interface and routing ioctls should have a
	 * different entry since a socket's unnecessary
	 */
	if (IOCGROUP(cmd) == 'i')
		return (ifioctl(so, cmd, data, p));
	if (IOCGROUP(cmd) == 'r')
		return (rtioctl(cmd, data, p));
	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 
	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0, p));
}
Esempio n. 3
0
int add_route(const char * ifs, const char * dst, const char * msk, const char * gtw) {

    int s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) {
        perror("socket");
    }

    struct ecos_rtentry route;
    memset(&route, 0, sizeof (route));

    struct sockaddr_in addrp, gateway, mask;

    gateway.sin_family = AF_INET;
    gateway.sin_addr.s_addr = inet_addr(gtw);
    gateway.sin_len = sizeof (struct sockaddr_in);

    mask.sin_family = AF_INET;
    mask.sin_addr.s_addr = inet_addr(msk);
    mask.sin_len = sizeof (struct sockaddr_in);

    addrp.sin_family = AF_INET;
    addrp.sin_port = 0;
    addrp.sin_addr.s_addr = inet_addr(dst);
    addrp.sin_len = sizeof (struct sockaddr_in);

    memcpy(&route.rt_gateway, &gateway, sizeof (gateway));
    memcpy(&route.rt_dst, &addrp, sizeof (addrp));
    memcpy(&route.rt_genmask, &mask, sizeof (mask));

    route.rt_dev = ifs;
    //originally was RTF_UP | RTF_HOST | RTF_LOCAL |
    route.rt_flags = RTF_UP | /*RTF_HOST*/ RTF_GATEWAY | RTF_LOCAL | RTF_STATIC;
    route.rt_metric = 0;
    if(0== rtioctl(SIOCADDRT, &route, 0)){
    //ioctl returns -1 on fail - works fine
   // if (ioctl(s, SIOCADDRT, &route) != -1) { - works fine, previous version
        diag_printf("My route added - dst: %s",
                inet_ntoa(((struct sockaddr_in *) &route.rt_dst)->sin_addr));
        diag_printf(", mask: %s",
                inet_ntoa(((struct sockaddr_in *) &route.rt_genmask)->sin_addr));
        diag_printf(", gateway: %s",
                inet_ntoa(((struct sockaddr_in *) &route.rt_gateway)->sin_addr));
        diag_printf(", interface %s\n", ifs);
        /*if (errno != EEXIST) {
            perror("SIOCADDRT 3");
        }*/
    }
    close(s);
}
Esempio n. 4
0
static int bsd_ioctl     (struct CYG_FILE_TAG *fp, CYG_ADDRWORD cmd,
                                CYG_ADDRWORD data)
{
	register struct socket *so = (struct socket *)fp->f_data;
        void *p = 0;

	switch (cmd) {

	case FIONBIO:
		if (*(int *)data)
			so->so_state |= SS_NBIO;
		else
			so->so_state &= ~SS_NBIO;
		return (0);

	case FIOASYNC:
		if (*(int *)data) {
			so->so_state |= SS_ASYNC;
			so->so_rcv.sb_flags |= SB_ASYNC;
			so->so_snd.sb_flags |= SB_ASYNC;
		} else {
			so->so_state &= ~SS_ASYNC;
			so->so_rcv.sb_flags &= ~SB_ASYNC;
			so->so_snd.sb_flags &= ~SB_ASYNC;
		}
		return (0);

	case FIONREAD:
		*(int *)data = so->so_rcv.sb_cc;
		return (0);

	case SIOCATMARK:
		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
		return (0);
	}
	/*
	 * Interface/routing/protocol specific ioctls:
	 * interface and routing ioctls should have a
	 * different entry since a socket's unnecessary
	 */
	if (IOCGROUP(cmd) == 'i')
		return (ifioctl(so, (u_long)cmd, (caddr_t)data, p));
	if (IOCGROUP(cmd) == 'r')
		return (rtioctl((u_long)cmd, (caddr_t)data, p));
	return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 
	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));

}
Esempio n. 5
0
/*
 * MPSAFE
 */
int
soo_ioctl(struct file *fp, u_long cmd, caddr_t data,
	  struct ucred *cred, struct sysmsg *msg)
{
	struct socket *so;
	int error;

	so = (struct socket *)fp->f_data;

	switch (cmd) {
	case FIOASYNC:
		if (*(int *)data) {
			sosetstate(so, SS_ASYNC);
			atomic_set_int(&so->so_rcv.ssb_flags,  SSB_ASYNC);
			atomic_set_int(&so->so_snd.ssb_flags, SSB_ASYNC);
		} else {
			soclrstate(so, SS_ASYNC);
			atomic_clear_int(&so->so_rcv.ssb_flags, SSB_ASYNC);
			atomic_clear_int(&so->so_snd.ssb_flags, SSB_ASYNC);
		}
		error = 0;
		break;
	case FIONREAD:
		*(int *)data = so->so_rcv.ssb_cc;
		error = 0;
		break;
	case FIOSETOWN:
		error = fsetown(*(int *)data, &so->so_sigio);
		break;
	case FIOGETOWN:
		*(int *)data = fgetown(&so->so_sigio);
		error = 0;
		break;
	case SIOCSPGRP:
		error = fsetown(-(*(int *)data), &so->so_sigio);
		break;
	case SIOCGPGRP:
		*(int *)data = -fgetown(&so->so_sigio);
		error = 0;
		break;
	case SIOCATMARK:
		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
		error = 0;
		break;
	default:
		/*
		 * Interface/routing/protocol specific ioctls:
		 * interface and routing ioctls should have a
		 * different entry since a socket's unnecessary
		 */
		if (IOCGROUP(cmd) == 'i') {
			error = ifioctl(so, cmd, data, cred);
		} else if (IOCGROUP(cmd) == 'r') {
			error = rtioctl(cmd, data, cred);
		} else {
			error = so_pru_control_direct(so, cmd, data, NULL);
		}
		break;
	}
	return (error);
}
Esempio n. 6
0
void gwkludge(void)
{
    struct sockaddr_in dst, gate;
    FILE *fp;
    char *type, *dname, *gname, *qual, buf[BUFSIZ];
    struct interface *ifp;
    int metric, n;
    struct rt_entry route;

    fp = fopen(_PATH_GATEWAYS, "r");
    if (fp == NULL)
        return;
    qual = buf;
    dname = buf + 64;
    gname = buf + ((BUFSIZ - 64) / 3);
    type = buf + (((BUFSIZ - 64) * 2) / 3);
    memset(&dst, 0, sizeof (dst));
    memset(&gate, 0, sizeof (gate));
    memset(&route, 0, sizeof(route));
    /* format: {net | host} XX gateway XX metric DD [passive | external]\n */
#define	readentry(fp) \
	fscanf((fp), "%s %s gateway %s metric %d %s\n", \
		type, dname, gname, &metric, qual)
    for (;;) {
        if ((n = readentry(fp)) == EOF)
            break;
        /*
         *	Lusertrap. Vendors should ship the line
         *
         *	CONFIGME CONFIGME gateway CONFIGME metric 1
         *
         */
        if (strcmp(type,"CONFIGME")==0)
        {
            fprintf(stderr,"Not starting gated. Please configure first.\n");
            exit(1);
        }
        if (!getnetorhostname(type, dname, &dst))
            continue;
        if (!gethostnameornumber(gname, &gate))
            continue;
        if (metric == 0)			/* XXX */
            metric = 1;
        if (strcmp(qual, "passive") == 0) {
            /*
             * Passive entries aren't placed in our tables,
             * only the kernel's, so we don't copy all of the
             * external routing information within a net.
             * Internal machines should use the default
             * route to a suitable gateway (like us).
             */
            route.rt_dst = *(struct sockaddr *) &dst;
            route.rt_router = *(struct sockaddr *) &gate;
            route.rt_flags = RTF_UP;
            if (strcmp(type, "host") == 0)
                route.rt_flags |= RTF_HOST;
            if (metric)
                route.rt_flags |= RTF_GATEWAY;
            (void) rtioctl(ADD, &route.rt_rt);
            continue;
        }
        if (strcmp(qual, "external") == 0) {
            /*
             * Entries marked external are handled
             * by other means, e.g. EGP,
             * and are placed in our tables only
             * to prevent overriding them
             * with something else.
             */
            rtadd((struct sockaddr *)&dst,
                  (struct sockaddr *)&gate, metric,
                  RTS_EXTERNAL|RTS_PASSIVE);
            continue;
        }
        /* assume no duplicate entries */
        externalinterfaces++;
        ifp = (struct interface *)malloc(sizeof (*ifp));
        memset(ifp, 0, sizeof (*ifp));
        ifp->int_flags = IFF_REMOTE;
        /* can't identify broadcast capability */
        ifp->int_net = inet_netof_subnet(dst.sin_addr);
        if (strcmp(type, "host") == 0) {
            ifp->int_flags |= IFF_POINTOPOINT;
            ifp->int_dstaddr = *((struct sockaddr *)&dst);
        }
        ifp->int_addr = *((struct sockaddr *)&gate);
        ifp->int_metric = metric;
        ifp->int_next = ifnet;
        ifnet = ifp;
        addrouteforif(ifp);
    }
    fclose(fp);
}
Esempio n. 7
0
__private_extern__ int
soioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
{
	int error = 0;
	int int_arg;

	socket_lock(so, 1);

	/* call the socket filter's ioctl handler anything but ours */
	if (IOCGROUP(cmd) != 'i' && IOCGROUP(cmd) != 'r') {
		switch (cmd) {
		case SIOCGASSOCIDS32:
		case SIOCGASSOCIDS64:
		case SIOCGCONNIDS32:
		case SIOCGCONNIDS64:
		case SIOCGCONNINFO32:
		case SIOCGCONNINFO64:
		case SIOCSCONNORDER:
		case SIOCGCONNORDER:
			/* don't pass to filter */
			break;

		default:
			error = sflt_ioctl(so, cmd, data);
			if (error != 0)
				goto out;
			break;
		}
	}

	switch (cmd) {
	case FIONBIO:			/* int */
		bcopy(data, &int_arg, sizeof (int_arg));
		if (int_arg)
			so->so_state |= SS_NBIO;
		else
			so->so_state &= ~SS_NBIO;

		goto out;

	case FIOASYNC:			/* int */
		bcopy(data, &int_arg, sizeof (int_arg));
		if (int_arg) {
			so->so_state |= SS_ASYNC;
			so->so_rcv.sb_flags |= SB_ASYNC;
			so->so_snd.sb_flags |= SB_ASYNC;
		} else {
			so->so_state &= ~SS_ASYNC;
			so->so_rcv.sb_flags &= ~SB_ASYNC;
			so->so_snd.sb_flags &= ~SB_ASYNC;
		}
		goto out;

	case FIONREAD:			/* int */
		bcopy(&so->so_rcv.sb_cc, data, sizeof (u_int32_t));
		goto out;

	case SIOCSPGRP:			/* int */
		bcopy(data, &so->so_pgid, sizeof (pid_t));
		goto out;

	case SIOCGPGRP:			/* int */
		bcopy(&so->so_pgid, data, sizeof (pid_t));
		goto out;

	case SIOCATMARK:		/* int */
		int_arg = (so->so_state & SS_RCVATMARK) != 0;
		bcopy(&int_arg, data, sizeof (int_arg));
		goto out;

	case SIOCSETOT:			/* int; deprecated */
		error = EOPNOTSUPP;
		goto out;

	case SIOCGASSOCIDS32:		/* so_aidreq32 */
	case SIOCGASSOCIDS64:		/* so_aidreq64 */
	case SIOCGCONNIDS32:		/* so_cidreq32 */
	case SIOCGCONNIDS64:		/* so_cidreq64 */
	case SIOCGCONNINFO32:		/* so_cinforeq32 */
	case SIOCGCONNINFO64:		/* so_cinforeq64 */
	case SIOCSCONNORDER:		/* so_cordreq */
	case SIOCGCONNORDER:		/* so_cordreq */
		error = (*so->so_proto->pr_usrreqs->pru_control)(so,
		    cmd, data, NULL, p);
		goto out;
	}

	/*
	 * Interface/routing/protocol specific ioctls:
	 * interface and routing ioctls should have a
	 * different entry since a socket's unnecessary
	 */
	if (IOCGROUP(cmd) == 'i') {
		error = ifioctllocked(so, cmd, data, p);
	} else {
		if (IOCGROUP(cmd) == 'r')
			error = rtioctl(cmd, data, p);
		else
			error = (*so->so_proto->pr_usrreqs->pru_control)(so,
			    cmd, data, NULL, p);
	}

out:
	socket_unlock(so, 1);

	if (error == EJUSTRETURN)
		error = 0;

	return (error);
}
Esempio n. 8
0
__private_extern__ int
soioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
{
    struct sockopt sopt;
    int error = 0;
    int dropsockref = -1;

    socket_lock(so, 1);

    sopt.sopt_level = cmd;
    sopt.sopt_name = (int)data;
    sopt.sopt_p = p;

    /* Call the socket filter's ioctl handler for most ioctls */
    if (IOCGROUP(cmd) != 'i' && IOCGROUP(cmd) != 'r') {
        int filtered = 0;
        struct socket_filter_entry *filter;

        for (filter = so->so_filt; filter && error == 0;
                filter = filter->sfe_next_onsocket) {
            if (filter->sfe_filter->sf_filter.sf_ioctl) {
                if (filtered == 0) {
                    sflt_use(so);
                    socket_unlock(so, 0);
                    filtered = 1;
                }
                error = filter->sfe_filter->sf_filter.
                        sf_ioctl(filter->sfe_cookie, so, cmd, data);
            }
        }

        if (filtered) {
            socket_lock(so, 0);
            sflt_unuse(so);
        }

        if (error != 0)
            goto out;
    }

    switch (cmd) {

    case FIONBIO:
        if (*(int *)data)
            so->so_state |= SS_NBIO;
        else
            so->so_state &= ~SS_NBIO;

        goto out;

    case FIOASYNC:
        if (*(int *)data) {
            so->so_state |= SS_ASYNC;
            so->so_rcv.sb_flags |= SB_ASYNC;
            so->so_snd.sb_flags |= SB_ASYNC;
        } else {
            so->so_state &= ~SS_ASYNC;
            so->so_rcv.sb_flags &= ~SB_ASYNC;
            so->so_snd.sb_flags &= ~SB_ASYNC;
        }
        goto out;

    case FIONREAD:
        *(int *)data = so->so_rcv.sb_cc;
        goto out;

    case SIOCSPGRP:
        so->so_pgid = *(int *)data;
        goto out;

    case SIOCGPGRP:
        *(int *)data = so->so_pgid;
        goto out;

    case SIOCATMARK:
        *(int *)data = (so->so_state&SS_RCVATMARK) != 0;
        goto out;

    case SIOCSETOT: {
        /*
         * Set socket level options here and then call protocol
         * specific routine.
         */
        struct socket *cloned_so = NULL;
        int cloned_fd = *(int *)data;

        /* let's make sure it's either -1 or a valid file descriptor */
        if (cloned_fd != -1) {
            error = file_socket(cloned_fd, &cloned_so);
            if (error) {
                goto out;
            }
            dropsockref = cloned_fd;
        }

        /* Always set socket non-blocking for OT */
        so->so_state |= SS_NBIO;
        so->so_options |= SO_DONTTRUNC | SO_WANTMORE;
        so->so_flags |= SOF_NOSIGPIPE;

        if (cloned_so && so != cloned_so) {
            /* Flags options */
            so->so_options |=
                cloned_so->so_options & ~SO_ACCEPTCONN;

            /* SO_LINGER */
            if (so->so_options & SO_LINGER)
                so->so_linger = cloned_so->so_linger;

            /* SO_SNDBUF, SO_RCVBUF */
            if (cloned_so->so_snd.sb_hiwat > 0) {
                if (sbreserve(&so->so_snd,
                              cloned_so->so_snd.sb_hiwat) == 0) {
                    error = ENOBUFS;
                    goto out;
                }
            }
            if (cloned_so->so_rcv.sb_hiwat > 0) {
                if (sbreserve(&so->so_rcv,
                              cloned_so->so_rcv.sb_hiwat) == 0) {
                    error = ENOBUFS;
                    goto out;
                }
            }

            /* SO_SNDLOWAT, SO_RCVLOWAT */
            so->so_snd.sb_lowat =
                (cloned_so->so_snd.sb_lowat > so->so_snd.sb_hiwat) ?
                so->so_snd.sb_hiwat : cloned_so->so_snd.sb_lowat;
            so->so_rcv.sb_lowat =
                (cloned_so->so_rcv.sb_lowat > so->so_rcv.sb_hiwat) ?
                so->so_rcv.sb_hiwat : cloned_so->so_rcv.sb_lowat;

            /* SO_SNDTIMEO, SO_RCVTIMEO */
            so->so_snd.sb_timeo = cloned_so->so_snd.sb_timeo;
            so->so_rcv.sb_timeo = cloned_so->so_rcv.sb_timeo;
        }

        error = (*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
                data, 0, p);
        /* Just ignore protocols that do not understand it */
        if (error == EOPNOTSUPP)
            error = 0;

        goto out;
    }
    }
    /*
     * Interface/routing/protocol specific ioctls:
     * interface and routing ioctls should have a
     * different entry since a socket's unnecessary
     */
    if (IOCGROUP(cmd) == 'i') {
        error = ifioctllocked(so, cmd, data, p);
    } else {
        if (IOCGROUP(cmd) == 'r')
            error = rtioctl(cmd, data, p);
        else
            error = (*so->so_proto->pr_usrreqs->pru_control)(so,
                    cmd, data, 0, p);
    }

out:
    if (dropsockref != -1)
        file_drop(dropsockref);
    socket_unlock(so, 1);

    if (error == EJUSTRETURN)
        error = 0;

    return (error);
}
int
soo_ioctl(file_t *fp, u_long cmd, void *data)
{
	struct socket *so = fp->f_data;
	int error = 0;

	switch (cmd) {

	case FIONBIO:
		solock(so);
		if (*(int *)data)
			so->so_state |= SS_NBIO;
		else 
			so->so_state &= ~SS_NBIO; 
		sounlock(so);
		break;

	case FIOASYNC:
		solock(so);
		if (*(int *)data) {
			so->so_state |= SS_ASYNC;
			so->so_rcv.sb_flags |= SB_ASYNC;
			so->so_snd.sb_flags |= SB_ASYNC;
		} else {
			so->so_state &= ~SS_ASYNC;
			so->so_rcv.sb_flags &= ~SB_ASYNC;
			so->so_snd.sb_flags &= ~SB_ASYNC;
		}
		sounlock(so);
		break;

	case FIONREAD:
		*(int *)data = so->so_rcv.sb_cc;
		break;

	case FIONWRITE:
		*(int *)data = so->so_snd.sb_cc;
		break;

	case FIONSPACE:
		/*
		 * See the comment around sbspace()'s definition
		 * in sys/socketvar.h in face of counts about maximum
		 * to understand the following test. We detect overflow
		 * and return zero.
		 */
		solock(so);
		if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc)
		    || (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt))
			*(int *)data = 0;
		else
			*(int *)data = sbspace(&so->so_snd);
		sounlock(so);
		break;

	case SIOCSPGRP:
	case FIOSETOWN:
	case TIOCSPGRP:
		error = fsetown(&so->so_pgid, cmd, data);
		break;

	case SIOCGPGRP:
	case FIOGETOWN:
	case TIOCGPGRP:
		error = fgetown(so->so_pgid, cmd, data);
		break;

	case SIOCATMARK:
		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
		break;

	default:
		/*
		 * Interface/routing/protocol specific ioctls:
		 * interface and routing ioctls should have a
		 * different entry since a socket's unnecessary
		 */
		KERNEL_LOCK(1, NULL);
		if (IOCGROUP(cmd) == 'i')
			error = ifioctl(so, cmd, data, curlwp);
		else if (IOCGROUP(cmd) == 'r')
			error = rtioctl(cmd, data, curlwp);
		else {
			error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
			    (struct mbuf *)cmd, (struct mbuf *)data, NULL,
			     curlwp);
		}
		KERNEL_UNLOCK_ONE(NULL);
		break;
	}


	return error;
}