unsigned int read_port_w(unsigned short port) { unsigned int r; int i = find_port(port, IO_READ); int j = find_port(port + 1, IO_READ); #ifdef GUSPNP if (port == 0x324) i = j = 0; #endif /* FIXME: shoudl already be checked. ASSERT if i, j == -1 */ if (i == -1) { i_printf("can't read low-byte of 16 bit port 0x%04x:trying to read high\n", port); return ((read_port(port + 1) << 8) | 0xff); } if (j == -1) { i_printf("can't read hi-byte of 16 bit port 0x%04x:trying to read low\n", port); return (read_port(port) | 0xff00); } if (!video_port_io) enter_priv_on(); if (port <= 0x3fe) { set_ioperm(port, 2, 1); } else priv_iopl(3); if (!video_port_io) leave_priv_setting(); r = port_in_w(port); if (!video_port_io) enter_priv_on(); if (port <= 0x3fe) set_ioperm(port, 2, 0); else priv_iopl(0); if (!video_port_io) leave_priv_setting(); if ( #ifdef GUSPNP i && j && #endif !video_port_io) { r &= (ports[i].andmask | 0xff00); r &= ((ports[j].andmask << 8) | 0xff); r |= (ports[i].ormask & 0xff); r |= ((ports[j].ormask << 8) & 0xff00); } else video_port_io = 0; LOG_IO(port, r, '}', 0xffff); i_printf("read 16 bit port 0x%x gave %04x at %04x:%04x\n", port, r, LWORD(cs), LWORD(eip)); return (r); }
int write_port_w(unsigned int value, unsigned short port) { int i = find_port(port, IO_WRITE); int j = find_port(port + 1, IO_WRITE); #ifdef GUSPNP if (port == 0x324) i = j = 0; #endif if ((i == -1) || (j == -1)) { i_printf("can't write to 16 bit port 0x%04x\n", port); return 0; } if ( #ifdef GUSPNP i && j && #endif !video_port_io) { value &= (ports[i].andmask | 0xff00); value &= ((ports[j].andmask << 8) | 0xff); value |= (ports[i].ormask & 0xff); value |= ((ports[j].ormask << 8) & 0xff00); } i_printf("write 16 bit port 0x%x value %04x at %04x:%04x\n", port, (value & 0xffff), LWORD(cs), LWORD(eip)); LOG_IO(port, value, '{', 0xffff); if (!video_port_io) enter_priv_on(); if (port <= 0x3fe) set_ioperm(port, 2, 1); else priv_iopl(3); if (!video_port_io) leave_priv_setting(); port_out_w(value, port); if (!video_port_io) enter_priv_on(); if (port <= 0x3fe) set_ioperm(port, 2, 0); else priv_iopl(0); if (!video_port_io) leave_priv_setting(); video_port_io = 0; return (1); }
int OpenNetworkLink(char *name, unsigned short netid) { PRIV_SAVE_AREA int s, proto, ret; struct ifreq req; struct sockaddr_ll addr; if (config.vnet == VNET_TYPE_TAP) { receive_mode = 6; return tun_alloc(name); } proto = htons(netid); enter_priv_on(); s = socket(PF_PACKET, SOCK_RAW, proto); leave_priv_setting(); if (s < 0) { if (errno == EPERM) error("Must be root for direct NIC access\n"); return -1; } fcntl(s, F_SETFL, O_NDELAY); strcpy(req.ifr_name, name); if (ioctl(s, SIOCGIFINDEX, &req) < 0) { close(s); return -1; } addr.sll_family = AF_PACKET; addr.sll_protocol = proto; addr.sll_ifindex = req.ifr_ifindex; if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { pd_printf("OpenNetwork: could not bind socket: %s\n", strerror(errno)); close(s); return -1; } enter_priv_on(); ret = ioctl(s, SIOCGIFFLAGS, &req); leave_priv_setting(); if (ret < 0) { close(s); return -1; } receive_mode = (req.ifr_flags & IFF_PROMISC) ? 6 : ((req.ifr_flags & IFF_BROADCAST) ? 3 : 2); return s; }
unsigned char read_port(unsigned short port) { unsigned char r; int i = find_port(port, IO_READ); /* FIXME: stuff does/should check find_port first, so don't waste time checking again! ASSERT!! */ if (i == -1) return (0xff); if (!video_port_io) enter_priv_on(); if (port <= 0x3ff) set_ioperm(port, 1, 1); else priv_iopl(3); if (!video_port_io) leave_priv_setting(); r = port_in(port); if (!video_port_io) enter_priv_on(); if (port <= 0x3ff) set_ioperm(port, 1, 0); else priv_iopl(0); if (!video_port_io) leave_priv_setting(); if (!video_port_io) { r &= ports[i].andmask; r |= ports[i].ormask; } else video_port_io = 0; LOG_IO(port, r, '>', 0xff); i_printf("read port 0x%x gave %02x at %04x:%04x\n", port, r, LWORD(cs), LWORD(eip)); return (r); }
void clear_process_control(void) { struct vt_mode vt_mode; vt_mode.mode = VT_AUTO; enter_priv_on(); ioctl(console_fd, VT_SETMODE, (int) &vt_mode); leave_priv_setting(); signal(SIG_RELEASE, SIG_IGN); signal(SIG_ACQUIRE, SIG_IGN); }
int write_port(unsigned int value, unsigned short port) { int i = find_port(port, IO_WRITE); if (i == -1) return (0); if (!video_port_io) { value &= ports[i].andmask; value |= ports[i].ormask; } i_printf("write port 0x%x value %02x at %04x:%04x\n", port, (value & 0xff), LWORD(cs), LWORD(eip)); LOG_IO(port, value, '<', 0xff); if (!video_port_io) enter_priv_on(); if (port <= 0x3ff) set_ioperm(port, 1, 1); else priv_iopl(3); if (!video_port_io) leave_priv_setting(); port_out(value, port); if (!video_port_io) enter_priv_on(); if (port <= 0x3ff) set_ioperm(port, 1, 0); else priv_iopl(0); if (!video_port_io) leave_priv_setting(); video_port_io = 0; return (1); }
int SDL_priv_init(void) { /* The privs are needed for opening /dev/input/mice. * Unfortunately SDL does not support gpm. * Also, as a bonus, /dev/fb0 can be opened with privs. */ PRIV_SAVE_AREA int ret; assert(pthread_equal(pthread_self(), dosemu_pthread_self)); #ifdef X_SUPPORT preinit_x11_support(); #endif SDL_pre_init(); enter_priv_on(); ret = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_EVENTS); leave_priv_setting(); if (ret < 0) { error("SDL init: %s\n", SDL_GetError()); return -1; } c_printf("VID: initializing SDL plugin\n"); return 0; }
/* * DANG_BEGIN_FUNCTION low_mem_init * * description: * Initializes the lower 1Meg via mmap & sets up the HMA region * * DANG_END_FUNCTION */ void low_mem_init(void) { void *lowmem, *result; #ifdef __i386__ PRIV_SAVE_AREA #endif open_mapping(MAPPING_INIT_LOWRAM); g_printf ("DOS+HMA memory area being mapped in\n"); lowmem = alloc_mapping(MAPPING_INIT_LOWRAM, LOWMEM_SIZE + HMASIZE, -1); if (lowmem == MAP_FAILED) { perror("LOWRAM alloc"); leavedos(98); } #ifdef __i386__ /* we may need root to mmap address 0 */ enter_priv_on(); result = alias_mapping(MAPPING_INIT_LOWRAM, 0, LOWMEM_SIZE + HMASIZE, PROT_READ | PROT_WRITE | PROT_EXEC, lowmem); leave_priv_setting(); if (result == MAP_FAILED && (errno == EPERM || errno == EACCES)) { #ifndef X86_EMULATOR perror ("LOWRAM mmap"); fprintf(stderr, "Cannot map low DOS memory (the first 640k).\n" "You can most likely avoid this problem by running\n" "sysctl -w vm.mmap_min_addr=0\n" "as root, or by changing the vm.mmap_min_addr setting in\n" "/etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n" "If this doesn't help, disable selinux in /etc/selinux/config\n" ); exit(EXIT_FAILURE); #else if (config.cpuemu < 3) { /* switch on vm86-only JIT CPU emulation to with non-zero base */ config.cpuemu = 3; init_emu_cpu(); c_printf("CONF: JIT CPUEMU set to 3 for %d86\n", (int)vm86s.cpu_type); error("Using CPU emulation because vm.mmap_min_addr > 0.\n" "You can most likely avoid this problem by running\n" "sysctl -w vm.mmap_min_addr=0\n" "as root, or by changing the vm.mmap_min_addr setting in\n" "/etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n" "If this doesn't help, disable selinux in /etc/selinux/config\n" ); } result = alias_mapping(MAPPING_INIT_LOWRAM, -1, LOWMEM_SIZE + HMASIZE, PROT_READ | PROT_WRITE | PROT_EXEC, lowmem); #endif } #else result = alias_mapping(MAPPING_INIT_LOWRAM, -1, LOWMEM_SIZE + HMASIZE, PROT_READ | PROT_WRITE | PROT_EXEC, lowmem); if (config.cpuemu < 3) { /* switch on vm86-only JIT CPU emulation to with non-zero base */ config.cpuemu = 3; init_emu_cpu(); c_printf("CONF: JIT CPUEMU set to 3 for %d86\n", (int)vm86s.cpu_type); } #endif if (result == MAP_FAILED) { perror ("LOWRAM mmap"); exit(EXIT_FAILURE); } #ifdef X86_EMULATOR if (result) { warn("WARN: using non-zero memory base address %p.\n" "WARN: You can use the better-tested zero based setup using\n" "WARN: sysctl -w vm.mmap_min_addr=0\n" "WARN: as root, or by changing the vm.mmap_min_addr setting in\n" "WARN: /etc/sysctl.conf or a file in /etc/sysctl.d/ to 0.\n", result); } #endif /* keep conventional memory protected as long as possible to protect NULL pointer dereferences */ mprotect_mapping(MAPPING_LOWMEM, result, config.mem_size * 1024, PROT_NONE); }
static int ipx_bsd_OpenSocket(ipx_socket_t *sk, int port) { int sock; /* sock here means Linux socket handle */ int opt; struct sockaddr_ipx ipxs; uint len; struct sockaddr_ipx ipxs2; /* DANG_FIXTHIS - kludge to support broken linux IPX stack */ /* need to convert dynamic socket open into a real socket number */ /* if (port == 0) { FAIL("IPX: using socket %x\n", nextDynamicSocket); port = nextDynamicSocket++; } */ /* do a socket call, then bind to this port */ sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX); if (sock == -1) { FAIL("IPX: could not open IPX socket.\n"); return -1; } #ifdef DOSEMU opt = 1; /* turn on socket debugging */ if (d.network) { enter_priv_on(); if (setsockopt(sock, SOL_SOCKET, SODBG, &opt, sizeof(opt)) == -1) { leave_priv_setting(); FAIL("IPX: could not set socket option for debugging.\n"); return -1; } leave_priv_setting(); } #endif opt = 1; /* Permit broadcast output */ enter_priv_on(); if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) == -1) { leave_priv_setting(); FAIL("IPX: could not set socket option for broadcast.\n"); return -1; } #ifdef DOSEMU /* allow setting the nType field in the IPX header */ opt = 1; #if 0 /* this seems to be wrong: IPX_TYPE can only be set on level SOL_IPX */ if (setsockopt(sock, SOL_SOCKET, IPX_TYPE, &opt, sizeof(opt)) == -1) { #else /* the socket _is_ an IPX socket, hence it first passes ipx_setsockopt() * in file linux/net/ipx/af_ipx.c. This one handles SOL_IPX itself and * passes SOL_SOCKET-levels down to sock_setsockopt(). * Hence I guess the below is correct (can somebody please verify this?) * -- Hans, June 14 1997 */ if (setsockopt(sock, SOL_IPX, IPX_TYPE, &opt, sizeof(opt)) == -1) { #endif leave_priv_setting(); FAIL("IPX: could not set socket option for nType.\n"); return -1; } #endif ipxs.sipx_family = AF_IPX; ipxs.sipx_network = *reinterpret_cast<uint*> (&ipx_MyAddress[0]); /* ipxs.sipx_network = htonl(MyNetwork); */ bzero(ipxs.sipx_node, 6); /* Please fill in my node name */ ipxs.sipx_port = htons(port); /* now bind to this port */ if (bind(sock, reinterpret_cast<struct sockaddr*> (&ipxs), sizeof(ipxs)) == -1) { FAIL("IPX: could not bind socket to address\n"); close( sock ); leave_priv_setting(); return -1; } if( port==0 ) { len = sizeof(ipxs2); if (getsockname(sock, reinterpret_cast<struct sockaddr*> (&ipxs2), &len) < 0) { FAIL("IPX: could not get socket name in IPXOpenSocket\n"); close( sock ); leave_priv_setting(); return -1; } else { port = htons(ipxs2.sipx_port); FAIL("IPX: opened dynamic socket %04x\n", port); } } leave_priv_setting(); sk->fd = sock; sk->socket = port; return 0; } static void ipx_bsd_CloseSocket(ipx_socket_t *mysock) { /* now close the file descriptor for the socket, and D2_FREE it */ close(mysock->fd); Fail("IPX: closing file descriptor on socket %x\n", mysock->socket); }
/* control the io permissions for ports */ int allow_io(unsigned int start, int size, int permission, int ormask, int andmask, unsigned int portspeed, char *device) { int opendevice = -1; char line[100]; char portname[50]; unsigned int beg, end; FILE *fp; /* find out whether the port address request is available * this way, try to deny uncoordinated acces * * If it is not listed in /proc/ioports, register them * ( we need some syscall to do so bo 960609) * if it is registered, we need the name of a device to open * if we can open it, we disallow to that port */ if ((fp = fopen("/proc/ioports", "r")) == NULL) { i_printf("Ports can't open /proc/ioports\n"); return (0); } while (fgets(line, 100, fp)) { sscanf(line, "%x-%x : %s", &beg, &end, portname); if ((start >= beg) && (start + size - 1 <= end)) { /* ports are occupied, try to open the according device */ i_printf("PORT already registered as %s 0x%04x-0x%04x\n", portname, beg, end); enter_priv_on(); opendevice = open(device, O_RDWR); leave_priv_setting(); if (opendevice == -1) switch (errno) { case EBUSY: i_printf("PORT Device %s already in use\n", device); return (0); case EACCES: i_printf("PORT Device %s , access not allowed\n", device); return (0); case ENOENT: i_printf("PORT No such Device %s\n", device); return (0); } i_printf("PORT Device %s opened successfully\n", device); } } if (opendevice == -1) { /* register it */ i_printf("PORT Syscall to register ports not yet implemented\n"); } #if 0 if ((base + size) < beg || base >= end) continue; else return NULL; /* overlap */ #endif /* first the simplest case...however, this simplest case does * not apply to ports above 0x3ff--the maximum ioperm()able * port under Linux--so we must handle some of that ourselves. * * if we want to log port access below 0x400, don't enter these * ports here with set_ioperm but add them to the list of allowed * ports. That way we get an exception to get out of vm86(0) */ if (permission == IO_RDWR && (ormask == 0 && andmask == 0xFFFF) && portspeed) { if ((start + size - 1) <= 0x3ff) { i_printf("giving fast hardware access to ports 0x%x -> 0x%x\n", start, start + size - 1); set_ioperm(start, size, 1); /* Don't return, but enter it in the list to keep track of the file * descriptor * return (1); */ } /* allow direct I/O to all the ports that *are* below 0x3ff * and add the rest to our list */ else if (start <= 0x3ff) { warn("PORT: s-s: %d %d\n", start, size); i_printf("giving fast hardware access only to ports 0x%x -> 0x3ff\n", start); set_ioperm(start, 0x400 - start, 1); size = start + size - 0x400; start = 0x400; } } /* we'll need to add an entry */ if (ports) { ASSERT(0); /* FIXME XXX */ /* ports = (struct port_struct *) realloc(ports, sizeof(struct port_struct) * (num_ports + 1)); */ } else { ASSERT(0); /* FIXME XXX */ /* ports = (struct port_struct *) malloc(sizeof(struct port_struct) * (num_ports + 1)); */ } num_ports++; if (!ports) { error("allocation error for ports!\n"); num_ports = 0; return (0); } ports[num_ports - 1].start = start; ports[num_ports - 1].size = size; ports[num_ports - 1].permission = permission; ports[num_ports - 1].ormask = ormask; ports[num_ports - 1].andmask = andmask; ports[num_ports - 1].fp = opendevice; i_printf("added port %x size=%d permission=%d ormask=%x andmask=%x\n", start, size, permission, ormask, andmask); return (1); }