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