diff options
author | swallace <swallace@FreeBSD.org> | 1995-10-10 07:59:30 +0000 |
---|---|---|
committer | swallace <swallace@FreeBSD.org> | 1995-10-10 07:59:30 +0000 |
commit | 20f13c7a7ed3183879431f56c3761a1c7914af8a (patch) | |
tree | 81a969abda60acfc5b1785850773a90772c8c462 /sys/i386/ibcs2/ibcs2_socksys.c | |
parent | 6c1c648223be1d6caaddff391d1d2946ebc316a2 (diff) | |
download | FreeBSD-src-20f13c7a7ed3183879431f56c3761a1c7914af8a.zip FreeBSD-src-20f13c7a7ed3183879431f56c3761a1c7914af8a.tar.gz |
Remove old files no longer needed.
Add new files created for emulator.
Modify NetBSD import to work with FreeBSD and add new features and
code. The complete emulator is essentially a combination of work/code
implemented by Sean Eric Fagan, Soren Schmidt, Scott Bartram, and myself,
Steven Wallace.
Features of this new emulator system include:
o "clean" code, including strict prototyping.
o Auto-generation of ibcs2 system calls, xenix system calls, isc system
calls. Generation includes system tables, structure definitions,
and prototyping of function calls.
o ibcs2 emulator does not rely on any COMPAT_43 system calls.
o embedded socksys support
o ibcs2 msgsys, semsys, shmsys calls supported if supported in kernel
o alternate /emul/ibcs2 namespace searched first for files in ibcs2
system. Usefull to keep sysv libraries, binaries in /emul/ibcs2.
o many other finer details and functions fixed or implemented.
Diffstat (limited to 'sys/i386/ibcs2/ibcs2_socksys.c')
-rw-r--r-- | sys/i386/ibcs2/ibcs2_socksys.c | 1441 |
1 files changed, 89 insertions, 1352 deletions
diff --git a/sys/i386/ibcs2/ibcs2_socksys.c b/sys/i386/ibcs2/ibcs2_socksys.c index a1a52ad..c95526d 100644 --- a/sys/i386/ibcs2/ibcs2_socksys.c +++ b/sys/i386/ibcs2/ibcs2_socksys.c @@ -1,21 +1,15 @@ -/*- - * Copyright (c) 1994 Mostyn Lewis +/* + * Copyright (c) 1994, 1995 Scott Bartram + * Copyright (c) 1994 Arne H Juul * All rights reserved. * - * This software is based on code which is: - * Copyright (c) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk) - * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -27,1367 +21,110 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id: ibcs2_socksys.c,v 1.2 1994/10/17 22:13:08 sos Exp $ */ #include <sys/param.h> #include <sys/systm.h> -#include <sys/filedesc.h> +#include <sys/proc.h> #include <sys/file.h> -#include <sys/kernel.h> -#include <sys/mbuf.h> -#include <sys/protosw.h> +#include <sys/filedesc.h> +#include <sys/ioctl.h> +#include <sys/termios.h> +#include <sys/tty.h> #include <sys/socket.h> -#include <sys/socketvar.h> #include <sys/ioctl.h> -#include <sys/sockio.h> -#include <sys/proc.h> -#include <sys/exec.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/sysent.h> -#include <sys/malloc.h> -#include <sys/un.h> +#include <sys/sysproto.h> #include <net/if.h> -#include <net/if_arp.h> -#include <net/route.h> -#include <netinet/in.h> -#include <vm/vm.h> -#include <i386/ibcs2/ibcs2.h> -#include <i386/ibcs2/ibcs2_socksys.h> - -/* Socksys pseudo driver entry points */ - -int sockopen (dev_t dev, int mode, int devtype, struct proc *p); -int sockioctl(dev_t dev, int cmd, caddr_t arg, int fflag, struct proc *p); -int sockclose(dev_t dev, int flag, int mode, struct proc *p); -/* Socksys internal functions */ - -static void put_socket_fops(struct proc *p, int fd); -static int ss_fop_close(struct file *fp, struct proc *p); -static int ss_fop_ioctl(struct file*fp, int cmd, caddr_t arg, struct proc *p); -static int ss_syscall(caddr_t arg, struct proc *p); +#include <i386/ibcs2/ibcs2_socksys.h> +#include <i386/ibcs2/ibcs2_util.h> /* - * This structure is setup on first usage. Its address is planted - * into a socket's file structure fileops pointer after a successful - * socket creation or accept. + * iBCS2 socksys calls. */ -static struct fileops ss_socket_fops = { - NULL, /* normal socket read */ - NULL, /* normal socket write */ - NULL, /* socksys ioctl */ - NULL, /* normal socket select */ - NULL, /* socksys close */ -}; - -static int (*close_s)__P((struct file *fp, struct proc *p)); -static int (*ioctl_s)__P((struct file *fp, int cmd, caddr_t data, struct proc *p)); - -int ss_debug = 10; - -static int -ss_syscall(arg, p) - caddr_t arg; - struct proc *p; -{ - int cmd; - int error; - int retval[2]; - - retval[0] = retval[1] = 0; - cmd = ((struct ss_call *)arg)->arg[0]; - - if(ss_debug) { - static char *ss_syscall_strings[] = { - "0?", "accept", "bind", "connect", "getpeername", - "getsockname", "getsockopt", "listen", "recv(from)", - "recvfrom", "send(to)", "sendto", "setsockopt", "shutdown", - "socket", "select", "getipdomain", "setipdomain", - "adjtime", "setreuid", "setregid", "gettimeofday", - "settimeofday", "getitimer", "setitimer", - }; - - printf("ss_syscall: [%d] ",p->p_pid); - if(cmd < 0 || (cmd > CMD_SO_SETITIMER && cmd != CMD_SO_SS_DEBUG) ) - printf("? "); - else { - if(cmd == CMD_SO_SS_DEBUG) - printf("%s ","ss_debug"); - else - printf("%s ",ss_syscall_strings[cmd]); - } - printf("(%d) <0x%x,0x%x,0x%x,0x%x,0x%x,0x%x>\n", - cmd, - ((struct ss_call *)arg)->arg[1], - ((struct ss_call *)arg)->arg[2], - ((struct ss_call *)arg)->arg[3], - ((struct ss_call *)arg)->arg[4], - ((struct ss_call *)arg)->arg[5], - ((struct ss_call *)arg)->arg[6]); - } - - error = 0; - - switch (cmd) { - - case CMD_SO_SS_DEBUG: - - /* ss_debug = ((struct ss_call *)arg)->arg[1]; */ - break; - - case CMD_SO_SOCKET: { /* NO CONV */ - - if(ss_debug > 1) - printf("SO_SOCKET af in %d\n", - ((struct ss_call *)arg)->arg[1]); - ((struct ss_call *)arg)->arg[1] = ss_convert( - af_whatevers, - &(((struct ss_call *)arg)->arg[1]), - 0); - if(ss_debug > 1) { - printf("SO_SOCKET af out %d\n", - ((struct ss_call *)arg)->arg[1]); - - printf("SO_SOCKET type in %d\n", - ((struct ss_call *)arg)->arg[2]); - } - ((struct ss_call *)arg)->arg[2] = ss_convert( - type_whatevers, - &(((struct ss_call *)arg)->arg[2]), - 0); - if(ss_debug > 1) - printf("SO_SOCKET type out %d\n", - ((struct ss_call *)arg)->arg[2]); - - SYSCALL(SYS_socket, 0, 0); - - if(ss_debug) - printf("ss_syscall: [%d] socket fd=%d\n", - p->p_pid, retval[0]); - put_socket_fops(p,retval[0]); - - break; - } - - case CMD_SO_ACCEPT: { /* CONVERSION in arg 2 */ - - SYSCALL(SYS_accept, 2, SS_STRUCT_SOCKADDR); - - if(ss_debug) - printf("ss_syscall: [%d] accept fd=%d\n", - p->p_pid, retval[0]); - put_socket_fops(p,retval[0]); - - break; - } - - case CMD_SO_BIND: - SYSCALL(SYS_bind, 2, SS_STRUCT_SOCKADDR); - break; - - case CMD_SO_CONNECT: { - struct alien_sockaddr *sa; - unsigned short family; - - /* Remap any INADDR_ANY (0.0.0.0) to localhost */ - - sa = (struct alien_sockaddr *)((struct ss_call *)arg)->arg[1]; - if(error = copyin((caddr_t)&sa->sa_family, - (caddr_t)&family, sizeof(short))) - return(error); - if (family == AF_INET) { - unsigned long *addr; - unsigned long saddr; - - addr = &(((struct alien_sockaddr_in *)sa)->sin_addr.s_addr); - if(error = copyin((caddr_t)addr, (caddr_t)&saddr, sizeof(long))) - return(error); - if (saddr == INADDR_ANY) { - /* 0x0100007f is 127.0.0.1 reversed */ - saddr = 0x0100007f; - if(error = copyout((caddr_t)&saddr, - (caddr_t)addr, sizeof(long))) - return(error); - if (ss_debug) - printf("ss_syscall: remapped INADDR_ANY to localhost\n"); - } - } - SYSCALL(SYS_connect, 2, SS_STRUCT_SOCKADDR); - break; - } - - case CMD_SO_GETPEERNAME: - SYSCALL(SYS_getpeername, 2, SS_STRUCT_SOCKADDR); - break; - - case CMD_SO_GETSOCKNAME: - SYSCALL(SYS_getsockname, 2, SS_STRUCT_SOCKADDR); - break; - - case CMD_SO_GETSOCKOPT: - if(error = ss_getsockopt((caddr_t)(((int *)arg) + 1),retval,p)) - return(error); - break; - - case CMD_SO_LISTEN: - SYSCALL(SYS_listen, 0, 0); - break; - - case CMD_SO_RECV: - ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL); - ((struct ss_call *)arg)->arg[6] = 0; - SYSCALL(SYS_recvfrom, 0, 0); - break; - - case CMD_SO_RECVFROM: - SYSCALL(SYS_recvfrom, 5, SS_STRUCT_SOCKADDR); - break; - - case CMD_SO_SEND: - ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL); - ((struct ss_call *)arg)->arg[6] = 0; - SYSCALL(SYS_sendto, 0, 0); - break; - - case CMD_SO_SENDTO: - SYSCALL(SYS_sendto, 5, SS_STRUCT_SOCKADDR); - break; - - case CMD_SO_SETSOCKOPT: - if(error = ss_setsockopt((caddr_t)(((int *)arg) + 1),retval,p)) - return(error); - - case CMD_SO_SHUTDOWN: - SYSCALL(SYS_shutdown, 0, 0); - break; - - case CMD_SO_GETIPDOMAIN: - SYSCALL(SYS_getdomainname, 0, 0); - break; - - case CMD_SO_SETIPDOMAIN: /* Note check on BSD utsname no change? */ - SYSCALL(SYS_setdomainname, 0, 0); - break; - - case CMD_SO_SETREUID: - SYSCALL(126/*SYS_setreuid*/, 0, 0); - break; - - case CMD_SO_SETREGID: - SYSCALL(127/*SYS_setregid*/, 0, 0); - break; - - case CMD_SO_GETTIME: - SYSCALL(SYS_gettimeofday, 0, 0); - break; - - case CMD_SO_SETTIME: - SYSCALL(SYS_settimeofday, 0, 0); - break; - - case CMD_SO_GETITIMER: - SYSCALL(SYS_getitimer, 0, 0); - break; - - case CMD_SO_SETITIMER: - SYSCALL(SYS_setitimer, 0, 0); - break; - - case CMD_SO_SELECT: - SYSCALL(SYS_select, 0, 0); - break; - - case CMD_SO_ADJTIME: - SYSCALL(SYS_adjtime, 0, 0); - break; - - default: - printf("ss_syscall: default 0x%x\n",cmd); - return (EINVAL); - } - IBCS2_MAGIC_RETURN(arg); -} - - -static int -ss_fop_ioctl(fp, cmd, arg, p) - struct file *fp; - int cmd; - caddr_t arg; - struct proc *p; -{ - int error; - int retval[2]; - - if(ss_debug) { - static char **ioctl_strings; - int fd; - struct filedesc *fdp; - unsigned int ioctl_type; - unsigned int ioctl_len; - char cmd_type; - int cmd_ordinal; - - static char *ioctl_type_strings[] = { - "0?", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR" - }; - static char *ioctl_S_strings[] = { - "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT", - "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD", - "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME", - "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO" - }; - static char *ioctl_R_strings[] = { - "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?", - "SIOCADDRT", "SIOCDELRT" - }; - static char *ioctl_I_strings[] = { - "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?", - "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR", - "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS", - "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU", - "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH", - "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV", - "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR", - "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC", - "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP", - "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ", - "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?", - "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?", - "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR", - "SIOCSOCKSYS" - }; - - cmd_type = (cmd >> 8) & 0xff; - cmd_ordinal = cmd & 0xff; - - switch (cmd_type) { - - case 'S': - ioctl_strings = ioctl_S_strings; - if (cmd_ordinal > 15) - cmd_ordinal = -1; - break; - - case 'R': - ioctl_strings = ioctl_R_strings; - if (cmd_ordinal > 10) - cmd_ordinal = -1; - break; - - case 'I': - ioctl_strings = ioctl_I_strings; - if (cmd_ordinal > 66) - cmd_ordinal = -1; - break; - - default: - cmd_type = '?'; - break; - } - fdp = p->p_fd; - fd = -1; - while(++fd < NOFILE) - if ( fp == fdp->fd_ofiles[fd] ) - break; - - ioctl_type = (0xe0000000 & cmd) >> 29; - ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK; - - printf("ss_fop_ioctl: [%d] fd=%d ",p->p_pid, fd); - if(cmd_type != '?'){ - if(cmd_ordinal != -1) - printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal], - ioctl_type_strings[ioctl_type], - cmd_type, - cmd_ordinal, - ioctl_len); - else { - cmd_ordinal = cmd & 0xff; - printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal, - ioctl_type_strings[ioctl_type], - cmd_type, - cmd_ordinal, - ioctl_len); - } - } - else { - printf("? %s('%c',%d,l=%d) ", - ioctl_type_strings[ioctl_type], - cmd_type, - cmd_ordinal, - ioctl_len); - } - - printf("0x%x (0x%x) <0x%x>\n", - fp, cmd, arg); - } - - /* No dogs allowed */ - - if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){ - printf("ss_fop_ioctl: bad magic (sys_generic.c has no socksys mods?)\n"); - return(EINVAL); - } - - if(fp->f_type != DTYPE_SOCKET) - return (ENOTSOCK); - - retval[0] = retval[1] = 0; - - - error = 0; - - switch (cmd) { - case SS_SIOCSOCKSYS: /* ss syscall */ - return ss_syscall(arg, p); - - case SS_SIOCSHIWAT: /* set high watermark */ - case SS_SIOCSLOWAT: /* set low watermark */ - break; /* return value of 0 and no error */ - - case SS_SIOCGHIWAT: /* get high watermark */ - case SS_SIOCGLOWAT: /* get low watermark */ - break; /* return value of 0 and no error */ - - case SS_SIOCATMARK: /* at oob mark */ - IOCTL(SIOCATMARK); - break; - - case SS_SIOCSPGRP: /* set process group */ - IOCTL(SIOCSPGRP); - break; - case SS_SIOCGPGRP: /* get process group */ - IOCTL(SIOCGPGRP); - break; - - case FIONREAD: - case SS_FIONREAD: /* get # bytes to read */ - IOCTL(FIONREAD); - break; - - case SS_FIONBIO: /* set/clear non-blocking i/o */ - IOCTL(FIONBIO); - break; - - case SS_FIOASYNC: /* set/clear async i/o */ - IOCTL(FIOASYNC); - break; - - case SS_SIOCADDRT: /* add route - uses struct ortentry */ - IOCTL(SIOCADDRT); - break; - - case SS_SIOCDELRT: /* delete route - uses struct ortentry */ - IOCTL(SIOCDELRT); - break; - - case SS_SIOCSIFADDR: /* set ifnet address */ - IOCTL(SIOCSIFADDR); - break; - - case SS_SIOCGIFADDR: /* get ifnet address */ - IOCTL(SIOCGIFADDR); - break; - - case SS_SIOCSIFDSTADDR: /* set p-p address */ - IOCTL(SIOCSIFDSTADDR); - break; - - case SS_SIOCGIFDSTADDR: /* get p-p address */ - IOCTL(SIOCGIFDSTADDR); - break; - - case SS_SIOCSIFFLAGS: /* set ifnet flags */ - IOCTL(SIOCSIFFLAGS); - break; - - case SS_SIOCGIFFLAGS: /* get ifnet flags */ - IOCTL(SIOCGIFFLAGS); - break; - - case SS_SIOCGIFCONF: /* get ifnet ltst */ - IOCTL(SIOCGIFCONF); - break; - - case SS_SIOCGIFBRDADDR: /* get broadcast addr */ - IOCTL(SIOCGIFBRDADDR); - break; - - case SS_SIOCSIFBRDADDR: /* set broadcast addr */ - IOCTL(SIOCSIFBRDADDR); - break; - - case SS_SIOCGIFNETMASK: /* get net addr mask */ - IOCTL(SIOCGIFNETMASK); - break; - - case SS_SIOCSIFNETMASK: /* set net addr mask */ - IOCTL(SIOCSIFNETMASK); - break; - - case SS_SIOCGIFMETRIC: /* get IF metric */ - IOCTL(SIOCGIFMETRIC); - break; - - case SS_SIOCSIFMETRIC: /* set IF metric */ - IOCTL(SIOCSIFMETRIC); - break; - -/* FreeBSD 2.0 does not have socket ARPs */ - -#ifdef SIOCSARP - - case SS_SIOCSARP: /* set arp entry */ - IOCTL(SIOCSARP); - break; - - case SS_SIOCGARP: /* get arp entry */ - IOCTL(SIOCGARP); - break; - - case SS_SIOCDARP: /* delete arp entry */ - IOCTL(SIOCDARP); - break; - -#else /* SIOCSARP */ - - case SS_SIOCSARP: /* set arp entry */ - return(EINVAL); - - case SS_SIOCGARP: /* get arp entry */ - return(EINVAL); - - case SS_SIOCDARP: /* delete arp entry */ - return(EINVAL); - -#endif /* SIOCSARP */ - - case SS_SIOCGENADDR: /* Get ethernet addr XXX */ - return (EINVAL); -/* return (error = ioctl_s(fp, SIOCGIFHWADDR, arg, p)); */ - - case SS_SIOCSIFMTU: /* get if_mtu */ - IOCTL(SIOCSIFMTU); - break; - - case SS_SIOCGIFMTU: /* set if_mtu */ - IOCTL(SIOCGIFMTU); - break; - - case SS_SIOCGETNAME: /* getsockname XXX */ - return (EINVAL); -/* return (ioctl_s(fp, SIOCGIFNAME, arg, p)); MMM */ - - case SS_SIOCGETPEER: { /* getpeername */ - struct moose { - int fd; - caddr_t asa; - int *alen; - int compat_43; - } args; - - struct alien_sockaddr uaddr; - struct sockaddr nuaddr; - int nuaddr_len = sizeof(struct sockaddr); - struct filedesc *fdp; - - if(fp->f_type != DTYPE_SOCKET) - return (ENOTSOCK); - - bzero((caddr_t)&nuaddr, sizeof(struct sockaddr)); - fdp = p->p_fd; - args.fd = -1; - while(++args.fd < NOFILE) - if ( fp == fdp->fd_ofiles[args.fd] ) - break; - if(args.fd == NOFILE){ - printf("ss_fop_ioctl: [%d] SS_SIOCGETPEER args.fd > NOFILE\n", p->p_pid); - return(EBADF); - } - args.asa = (caddr_t)&nuaddr; - args.alen = &nuaddr_len; - args.compat_43 = 0; - error = SYSCALLX(SYS_getpeername, &args); - if(error) - return(error); - - bzero((caddr_t)&uaddr, sizeof(struct alien_sockaddr)); - uaddr.sa_family = (unsigned short)nuaddr.sa_family; - bcopy(&nuaddr.sa_data, &uaddr.sa_data, __ALIEN_SOCK_SIZE__ - sizeof(unsigned short)); - - error = copyout((caddr_t)&uaddr, (caddr_t)arg, sizeof(struct alien_sockaddr)); - return error; - } - - default: - printf("ss_fop_ioctl: [%d] %lx unknown ioctl 0x%x, 0x%lx\n", - p->p_pid, (unsigned long)fp, - cmd, (unsigned long)arg); - return (EINVAL); - } - IBCS2_MAGIC_RETURN(arg); -} int -sockioctl(dev, cmd, arg, fflag, p) - dev_t dev; - int cmd; - caddr_t arg; - int fflag; - struct proc *p; +ibcs2_socksys(p, uap, retval) + register struct proc *p; + register struct ibcs2_socksys_args *uap; + int *retval; { + register struct filedesc *fdp = p->p_fd; + register struct file *fp; int error; - int retval[2]; - - if(ss_debug) { - char cmd_type; - int cmd_ordinal; - static char **ioctl_strings; - unsigned int ioctl_type; - unsigned int ioctl_len; - - static char *ioctl_type_strings[] = { - "NIOCxx", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR" - }; - static char *ioctl_S_strings[] = { - "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT", - "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD", - "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME", - "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO" - }; - static char *ioctl_R_strings[] = { - "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?", - "SIOCADDRT", "SIOCDELRT" - }; - static char *ioctl_I_strings[] = { - "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?", - "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR", - "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS", - "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU", - "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH", - "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV", - "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR", - "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC", - "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP", - "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ", - "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?", - "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?", - "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR", - "SIOCSOCKSYS" - }; - static char *ioctl_NIOC_strings[] = { - "0?", "NIOCNFSD", "NIOCOLDGETFH", "NIOCASYNCD", - "NIOCSETDOMNAM", "NIOCGETDOMNAM", "NIOCCLNTHAND", - "NIOCEXPORTFS", "NIOCGETFH", "NIOCLSTAT" - }; - - cmd_ordinal = cmd & 0xff; - cmd_type = (cmd >> 8) & 0xff; - switch (cmd_type) { - - case 0: - ioctl_strings = ioctl_NIOC_strings; - cmd_type = ' '; - if (cmd_ordinal > 9) - cmd_ordinal = -1; - break; - - case 'S': - ioctl_strings = ioctl_S_strings; - if (cmd_ordinal > 15) - cmd_ordinal = -1; - break; - - case 'R': - ioctl_strings = ioctl_R_strings; - if (cmd_ordinal > 10) - cmd_ordinal = -1; - break; - - case 'I': - ioctl_strings = ioctl_I_strings; - if (cmd_ordinal > 66) - cmd_ordinal = -1; - break; - - default: - cmd_type = '?'; - break; - - } - ioctl_type = (0xe0000000 & cmd) >> 29; - ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK; - - printf("sockioctl: [%d] ",p->p_pid); - if(cmd_type != '?'){ - if(cmd_ordinal != -1) - printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal], - ioctl_type_strings[ioctl_type], - cmd_type, - cmd_ordinal, - ioctl_len); - else { - cmd_ordinal = cmd & 0xff; - printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal, - ioctl_type_strings[ioctl_type], - cmd_type, - cmd_ordinal, - ioctl_len); - } - } - else { - printf("? %s('%c',%d,l=%d) ", - ioctl_type_strings[ioctl_type], - cmd_type, - cmd_ordinal, - ioctl_len); - } - - printf("0x%x (0x%x) <0x%x>\n", - dev, cmd, arg); - } - - if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){ - printf("sockioctl: bad magic (sys_generic.c has no socksys mods?)\n"); - return(EINVAL); - } - - switch (cmd) { - - case SS_SIOCSOCKSYS: /* ss syscall */ - return ss_syscall(arg, p); + int realargs[7]; /* 1 for command, 6 for recvfrom */ + void *passargs; - /* NIOCxx: These ioctls are really just integers - * (no other information to go on). + /* + * SOCKET should only be legal on /dev/socksys. + * GETIPDOMAINNAME should only be legal on /dev/socksys ? + * The others are (and should be) only legal on sockets. */ - case NIOCSETDOMNAM: { - struct sgdomarg domargs; - - if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg))) - return(error); - - arg = (caddr_t)&domargs; - SYSCALL_N(SYS_setdomainname, 0, 0); - break; - } - - case NIOCGETDOMNAM: { - struct sgdomarg domargs; - - if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg))) - return(error); - - arg = (caddr_t)&domargs; - SYSCALL_N(SYS_getdomainname, 0, 0); - break; - } - - case NIOCLSTAT: { - struct lstatarg st; - - if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&st, sizeof(struct lstatarg))) - return(error); - - /* DO WE HAVE A FOREIGN LSTAT */ -/* return mumbo_lstat(st.fname, st.statb); */ - return (EINVAL); - } - - case NIOCNFSD: - case NIOCOLDGETFH: - case NIOCASYNCD: - case NIOCCLNTHAND: - case NIOCEXPORTFS: - case NIOCGETFH: - return (EINVAL); - - - case SS_IF_UNITSEL: /* set unit number */ - case SS_SIOCXPROTO: /* empty proto table */ - - case SS_SIOCIFDETACH: /* detach interface */ - case SS_SIOCGENPSTATS: /* get ENP stats */ - - case SS_SIOCSIFNAME: /* set interface name */ - case SS_SIOCGIFONEP: /* get one-packet params */ - case SS_SIOCSIFONEP: /* set one-packet params */ - - case SS_SIOCPROTO: /* link proto */ - case SS_SIOCX25XMT: - case SS_SIOCX25RCV: - case SS_SIOCX25TBL: - - printf("sockioctl: [%d] unsupported ioctl 0x%x , 0x%lx\n", - p->p_pid, - cmd, (unsigned long)arg); - return (EINVAL); - - default: - printf("sockioctl: [%d] unknown ioctl 0x%x , 0x%lx\n", - p->p_pid, - cmd, (unsigned long)arg); - return (EINVAL); - } - IBCS2_MAGIC_RETURN(arg); -} - - -int sockopen(dev, mode, devtype, p) - dev_t dev; - int mode; - int devtype; - struct proc *p; -{ - - if(ss_debug) - printf("sockopen: [%d] 0x%x\n", p->p_pid, dev); - - /* minor = 0 is the socksys device itself. No special handling - * will be needed as it is controlled by the application - * via ioctls. - */ - if (minor(dev) == 0) - return 0; - - /* minor = 1 is the spx device. This is the client side of a - * streams pipe to the X server. Under SCO and friends - * the library code messes around setting the connection - * up itself. We do it ourselves - this means we don't - * need to worry about the implementation of the server - * side (/dev/X0R - which must exist but can be a link - * to /dev/null) nor do we need to actually implement - * getmsg/putmsg. - */ -{ /* SPX */ - int fd, error, args[3]; - int retval[2]; -#define SUN_LEN(su) \ - (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) + 1 - struct sockaddr_un *Xaddr = (struct sockaddr_un *)UA_ALLOC(); - retval[0] = retval[1] = 0; - if(ss_debug) - printf("sockopen: SPX: [%d] opening\n", p->p_pid); - - /* Grab a socket. */ - if(ss_debug) - printf("sockopen: SPX: [%d] get a unix domain socket\n", - p->p_pid); - args[0] = AF_UNIX; - args[1] = SOCK_STREAM; - args[2] = 0; - error = SYSCALLX(SYS_socket, args); - if (error) + if (error = copyin(uap->argsp, (caddr_t)realargs, sizeof(realargs))) return error; - fd = retval[0]; - if(fd < 1) { - printf("sockopen: SPX: [%d] unexpected fd of %d\n", - p->p_pid, fd); - return(EOPNOTSUPP); /* MRL whatever */ - } - - /* Connect the socket to X. */ - if(ss_debug) - printf("sockopen: SPX: [%d] connect to /tmp/X11-unix/X0\n", - p->p_pid); - args[0] = fd; - Xaddr->sun_family = AF_UNIX; - copyout("/tmp/.X11-unix/X0", Xaddr->sun_path, 18); - Xaddr->sun_len = SUN_LEN(Xaddr); - args[1] = (int)Xaddr; - args[2] = sizeof(struct sockaddr_un); - error = SYSCALLX(SYS_connect, args); - if (error) { - (void)SYSCALLX(SYS_close, &fd); - return error; - } - - put_socket_fops(p,fd); - - return 0; -} /* SPX */ -} - - -int sockclose(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - if(ss_debug) - printf("sockclose: [%d] 0x%x\n", p->p_pid, dev); - return(0); -} - -static -int ss_fop_close(struct file *fp, struct proc *p) -{ - -int fd; -struct filedesc *fdp; - - if(ss_debug){ - fdp = p->p_fd; - fd = -1; - while(++fd < NOFILE) - if ( fp == fdp->fd_ofiles[fd] ) - break; - printf("ss_fop_close: [%d] fd=%d ", p->p_pid, fd); - } - - if(fp->f_type == DTYPE_SOCKET) { - if(ss_debug) - printf("is a socket\n"); - return(close_s(fp, p)); - } - else { - if(ss_debug) - printf("is not a socket\n"); - return(ENOTSOCK); - } -} - -void put_socket_fops(struct proc *p, int fd) -{ -struct filedesc *fdp; -struct file *fp; - - fdp = p->p_fd; - fp = fdp->fd_ofiles[fd]; - if (ss_socket_fops.fo_ioctl != fp->f_ops->fo_ioctl) { - bcopy(fp->f_ops, &ss_socket_fops, sizeof(struct fileops)); - ioctl_s = ss_socket_fops.fo_ioctl; /* save standard ioctl */ - close_s = ss_socket_fops.fo_close; /* save standard close */ - ss_socket_fops.fo_ioctl = ss_fop_ioctl; - ss_socket_fops.fo_close = ss_fop_close; - } - fp->f_ops = &ss_socket_fops; - - return; -} - -int ss_SYSCALL(n,convert_arg,indicator,arg,p,retval) - int n; /* syscall ordinal */ - int convert_arg; /* if not 0, argument to convert */ - int indicator; /* type of argument to convert */ - int *arg; /* address of alien arg */ - struct proc *p; - int *retval; -{ -int error; -int rc; - - if(convert_arg){ - if(rc = ss_convert_struct( (caddr_t)*(arg + convert_arg), - indicator, - SS_ALIEN_TO_NATIVE)) - return(rc); - - error = (*sysent[n].sy_call)(p, arg + 1, retval); - rc = ss_convert_struct( (caddr_t)*(arg + convert_arg), - indicator, - SS_NATIVE_TO_ALIEN); - if(ss_debug) - printf("ss_SYSCALL: [%d] error=%d, rc=%d\n", - p->p_pid, error, rc); - } - else { - rc = 0; - error = (*sysent[n].sy_call)(p, arg + 1, retval); - if(ss_debug) - printf("ss_SYSCALL: [%d] error=%d\n",p->p_pid, error); - } - - return(error ? error : rc); -} - -int ss_IOCTL(fp, cmd, arg, p) - struct file *fp; - int cmd; - int *arg; /* address of alien arg */ - struct proc *p; -{ -int error, rc; -int these[2]; -char cmd_type; -int cmd_ordinal; -int indicator; - - cmd_type = (cmd >> 8) & 0xff; - cmd_ordinal = cmd & 0xff; - these[0] = cmd_type; - these[1] = cmd_ordinal; - if(ss_debug > 1) - printf("ss_IOCTL: calling ss_convert with %d(%c) %d\n", - these[0],these[0],these[1]); - indicator = ss_convert( struct_whatevers, these, 0); - if(ss_debug > 1) - printf("ss_IOCTL: ss_convert returns indicator %d\n",indicator); - if(indicator){ - error = ss_convert_struct((caddr_t)*(arg + 2), - indicator, - SS_ALIEN_TO_NATIVE); - if(ss_debug > 1) - printf("ss_IOCTL: ss_convert_struct returns %d\n",error); - if(error) - return(error); - /* change len in ioctl now - in the general case */ - error = ioctl_s(fp, cmd, (caddr_t)arg, p); - rc = ss_convert_struct( (caddr_t)*(arg + 2), - indicator, - SS_NATIVE_TO_ALIEN); - if(ss_debug) - printf("ss_IOCTL: [%d] error=%d, rc=%d\n",p->p_pid, - error, rc); - } - else { - rc = 0; - error = ioctl_s(fp, cmd, (caddr_t)arg, p); - if(ss_debug) - printf("ss_IOCTL: [%d] error=%d\n",p->p_pid, error); - } - - return(error ? error : rc); -} - - -struct ss_socketopt_args { - int s; - int level; - int name; - caddr_t val; - int valsize; -}; - -int -ss_setsockopt(arg, ret, p) - struct ss_socketopt_args *arg; - int *ret; - struct proc *p; -{ - int error, optname; - int retval[2]; - - if (arg->level != 0xffff) /* FreeBSD, SCO and ? */ - return (ENOPROTOOPT); - - optname = ss_convert(sopt_whatevers, &arg->name, 0); - - switch (optname) { - - case SO_ACCEPTCONN: - case SO_BROADCAST: - case SO_DEBUG: - case SO_DONTROUTE: - case SO_LINGER: - case SO_KEEPALIVE: - case SO_OOBINLINE: - case SO_RCVBUF: - case SO_RCVLOWAT: - case SO_RCVTIMEO: - case SO_REUSEADDR: - case SO_SNDBUF: - case SO_SNDLOWAT: - case SO_SNDTIMEO: - case SO_USELOOPBACK: - error = SYSCALLX(SYS_setsockopt, arg); - *ret = retval[0]; - *(ret + 1) = retval[1]; - return(error); - - case SO_ERROR: - case SO_IMASOCKET: - case SO_NO_CHECK: - case SO_ORDREL: - case SO_PRIORITY: - case SO_PROTOTYPE: - case SO_TYPE: - return (ENOPROTOOPT); - - } - - return (ENOPROTOOPT); -} - - -int -ss_getsockopt(arg, ret, p) - struct ss_socketopt_args *arg; - int *ret; - struct proc *p; -{ - int error, optname; - int retval[2]; - - if (arg->level != 0xffff) /* FreeBSD, SCO and ? */ - return (ENOPROTOOPT); - - optname = ss_convert(sopt_whatevers, &arg->name, 0); - - switch (optname) { - - case SO_ACCEPTCONN: - case SO_BROADCAST: - case SO_DEBUG: - case SO_DONTROUTE: - case SO_ERROR: - case SO_KEEPALIVE: - case SO_LINGER: - case SO_OOBINLINE: - case SO_RCVBUF: - case SO_RCVLOWAT: - case SO_RCVTIMEO: - case SO_REUSEADDR: - case SO_SNDBUF: - case SO_SNDLOWAT: - case SO_SNDTIMEO: - case SO_TYPE: - case SO_USELOOPBACK: - error = SYSCALLX(SYS_getsockopt, arg); - *ret = retval[0]; - *(ret + 1) = retval[1]; - return(error); - - - case SO_PROTOTYPE: { - int value = 0; - - error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int)); - return(error); - } - - - case SO_IMASOCKET: { - int value = 1; - - error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int)); - return(error); - } - - case SO_NO_CHECK: - case SO_ORDREL: - case SO_PRIORITY: - return (ENOPROTOOPT); - } - - return (ENOPROTOOPT); -} - -#define SS_CONVERT -int system_type = SS_FREEBSD; /* FreeBSD */ - -int -ss_convert(what, this, otherwise) - struct whatever **what; - int *this; - int otherwise; -{ - struct whatever *specific; - - if(!(specific = what[system_type])) - return *this; - - for (; specific->from != -1; specific++) - if(specific->from <= *this && *this <= specific->to) - if(specific->from == specific->to){ - if(specific->more){ - specific = specific->more; - this++; - continue; - } - else { - return((int)specific->conversion); - } - } - else { - return(specific->conversion ? ( - specific->all_the_same ? (int)specific->conversion : specific->conversion[*this - specific->from] ) : *this); - } - - return otherwise; -} - -/* Returns 0 - no conversion, no pointer modification - 1 - converted, relevant pointer modification - -1 - error - */ -int -ss_convert_struct(alien, indicator, direction) - char *alien; - int indicator; - int direction; -{ -int error, len; - - switch (system_type) { - - case SS_FREEBSD: - return(0); - case SS_SYSVR4: - case SS_SYSVR3: - case SS_SCO_32: - case SS_WYSE_321: - case SS_ISC: - case SS_LINUX: - - switch(direction){ - - case SS_ALIEN_TO_NATIVE: - - error = ss_atn(alien, indicator); - if(ss_debug > 1) - printf("ss_convert: ATN ss_atn error %d\n",error); - return(error); - - case SS_NATIVE_TO_ALIEN: - - error = ss_nta(alien, indicator); - if(ss_debug > 1) - printf("ss_convert: NTA ss_nta error %d\n",error); - return(error); - - } + DPRINTF(("ibcs2_socksys: %08x %08x %08x %08x %08x %08x %08x\n", + realargs[0], realargs[1], realargs[2], realargs[3], + realargs[4], realargs[5], realargs[6])); + + passargs = (void *)(realargs + 1); + switch (realargs[0]) { + case SOCKSYS_ACCEPT: + return accept(p, passargs, retval); + case SOCKSYS_BIND: + return bind(p, passargs, retval); + case SOCKSYS_CONNECT: + return connect(p, passargs, retval); + case SOCKSYS_GETPEERNAME: + return getpeername(p, passargs, retval); + case SOCKSYS_GETSOCKNAME: + return getsockname(p, passargs, retval); + case SOCKSYS_GETSOCKOPT: + return getsockopt(p, passargs, retval); + case SOCKSYS_LISTEN: + return listen(p, passargs, retval); + case SOCKSYS_RECV: + realargs[5] = realargs[6] = 0; + /* FALLTHROUGH */ + case SOCKSYS_RECVFROM: + return recvfrom(p, passargs, retval); + case SOCKSYS_SEND: + realargs[5] = realargs[6] = 0; + /* FALLTHROUGH */ + case SOCKSYS_SENDTO: + return sendto(p, passargs, retval); + case SOCKSYS_SETSOCKOPT: + return setsockopt(p, passargs, retval); + case SOCKSYS_SHUTDOWN: + return shutdown(p, passargs, retval); + case SOCKSYS_SOCKET: + return socket(p, passargs, retval); + case SOCKSYS_SELECT: + return select(p, passargs, retval); + case SOCKSYS_GETIPDOMAIN: + return getdomainname(p, passargs, retval); + case SOCKSYS_SETIPDOMAIN: + return setdomainname(p, passargs, retval); + case SOCKSYS_ADJTIME: + return adjtime(p, passargs, retval); + case SOCKSYS_SETREUID: + return setreuid(p, passargs, retval); + case SOCKSYS_SETREGID: + return setregid(p, passargs, retval); + case SOCKSYS_GETTIME: + return gettimeofday(p, passargs, retval); + case SOCKSYS_SETTIME: + return settimeofday(p, passargs, retval); + case SOCKSYS_GETITIMER: + return getitimer(p, passargs, retval); + case SOCKSYS_SETITIMER: + return setitimer(p, passargs, retval); default: - - printf("ss_convert_struct: not expecting system_type %d\n", system_type); - break; - - } - return(EINVAL); -} - -/* note sockaddr_un linux unsigned short fam, 108 path - BSD uchar , uchar 104 */ -int -ss_atn(alien, indicator) - char *alien; - int indicator; -{ -int error; - - switch (indicator) { - - case SS_STRUCT_ARPREQ: - /* compatible */ - return(0); - - case SS_STRUCT_IFCONF: - /* compatible */ - return(0); - - case SS_STRUCT_IFREQ: - /* length OK - more unions - function dependent */ - return(0); - - case SS_STRUCT_ORTENTRY: - /* compatible */ - return(0); - - case SS_STRUCT_SOCKADDR:{ - struct native_hdr { - u_char len; - u_char family; - }; - union hdr_part { - struct native_hdr native; - u_short alien_family; - } hdr; - - if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr))) - return(error); - if(ss_debug > 1) - printf("ss_atn:copyin 0x%x\n",hdr.alien_family); - - if( hdr.alien_family < AF_MAX){ - hdr.native.family = hdr.alien_family >> 8; /* 386 endianess */ - /* OR LEN FOM A PARAM ? */ - hdr.native.len = sizeof(struct sockaddr); - if(ss_debug > 1) - printf("ss_atn:copyout 0x%x\n",hdr.alien_family); - error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr)); - return(error); - } - else { - printf("ss_atn: sa_family = %d\n", hdr.alien_family); - return(EINVAL); - } - - } - - case SS_STRUCT_SOCKNEWPROTO: - /* don't have */ - printf("ss_atn: not expecting SS_STRUCT_SOCKNEWPROTO\n"); - return(EINVAL); - - default: - printf("ss_atn: not expecting case %d\n",indicator); - return(EINVAL); - - } -} - -/* note sockaddr_un linux unsigned short fam, 108 path - BSD uchar , uchar 104 */ -int -ss_nta(alien, indicator) - char *alien; - int indicator; -{ -int error; - - switch (indicator) { - - case SS_STRUCT_ARPREQ: - /* compatible */ - return(0); - - case SS_STRUCT_IFCONF: - /* compatible */ - return(0); - - case SS_STRUCT_IFREQ: - /* length OK - more unions - function dependent */ - return(0); - - case SS_STRUCT_ORTENTRY: - /* compatible */ - return(0); - - case SS_STRUCT_SOCKADDR:{ - struct native_hdr { - u_char len; - u_char family; - }; - union hdr_part { - struct native_hdr native; - u_short alien_family; - } hdr; - - if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr))) - return(error); - if(ss_debug > 1) - printf("ss_nta:copyin 0x%x\n",hdr.alien_family); - hdr.alien_family = hdr.native.family; - if(ss_debug > 1) - printf("ss_nta:copyout 0x%x\n",hdr.alien_family); - error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr)); - return(error); - } - - case SS_STRUCT_SOCKNEWPROTO: - /* don't have */ - printf("ss_nta: not expecting SS_STRUCT_SOCKNEWPROTO\n"); - return(EINVAL); - - default: - printf("ss_nta: not expecting case %d\n",indicator); - return(EINVAL); - + printf("socksys unknown %08x %08x %08x %08x %08x %08x %08x\n", + realargs[0], realargs[1], realargs[2], realargs[3], + realargs[4], realargs[5], realargs[6]); + return EINVAL; } + /* NOTREACHED */ } |