Exemple #1
0
int uae_slirp_init(void)
{
#if defined(WITH_QEMU_SLIRP)
	if (impl == AUTO_IMPLEMENTATION) {
		impl = check_conf(QEMU_IMPLEMENTATION);
	}
#endif
#if defined(WITH_BUILTIN_SLIRP)
	if (impl == AUTO_IMPLEMENTATION) {
		impl = check_conf(BUILTIN_IMPLEMENTATION);
	}
#endif
	if (impl == AUTO_IMPLEMENTATION) {
		impl = NO_IMPLEMENTATION;
	}

#ifdef WITH_QEMU_SLIRP
	if (impl == QEMU_IMPLEMENTATION) {
		return uae_qemu_uae_init() == NULL;
	}
#endif
#ifdef WITH_BUILTIN_SLIRP
	if (impl == BUILTIN_IMPLEMENTATION) {
		return slirp_init();
	}
#endif
	return -1;
}
Exemple #2
0
int main(int argc, char *argv[])
{	
	co_rc_t rc;
	HANDLE daemon_handle = 0;
	int exit_code = 0;
	co_daemon_handle_t daemon_handle_;
	start_parameters_t start_parameters;
	WSADATA wsad;

	co_debug_start();
	WSAStartup(MAKEWORD(2, 0), &wsad);
	slirp_init();

	rc = handle_paramters(&start_parameters, argc, argv);
	if (!CO_OK(rc)) {
		exit_code = -1;
		goto out;
	}

	co_terminal_print("Slirp initialized\n");

	daemon_parameters = &start_parameters;
	rc = co_os_daemon_pipe_open(daemon_parameters->instance, 
				    CO_MODULE_CONET0 + daemon_parameters->index, &daemon_handle_);
	if (!CO_OK(rc)) {
		co_terminal_print("Error opening a pipe to the daemon\n");
		goto out;
	}

	slirp_mutex = CreateMutex(NULL, FALSE, NULL);
	if (slirp_mutex == NULL) 
		goto out_close;

	co_set_terminal_print_hook(terminal_print_hook_func);

	co_terminal_print("Slirp loop running\n");

	daemon_handle = daemon_handle_->handle;
	exit_code = wait_loop(daemon_handle);

	CloseHandle(slirp_mutex);

out_close:
	co_os_daemon_pipe_close(daemon_handle_);

out:
	co_debug_end();
	return exit_code;
}
Exemple #3
0
void enet_slirp_start(void) {
    struct in_addr guest_addr;
    
    if (!slirp_inited) {
        Log_Printf(LOG_WARN, "Starting SLIRP");
#ifndef _WIN32
        signal(SIGPIPE, SIG_IGN);
#endif
        slirp_init();
        slirpq = QueueCreate();
        slirp_inited=1;
        //host_sleep_ms(500);
        slirp_mutex=SDL_CreateMutex();
        tick_func_handle=SDL_CreateThread(tick_func,"SLiRPTickThread", (void *)NULL);
        inet_aton("10.0.2.15", &guest_addr);
        slirp_redir(0, 42323, guest_addr, 23);
    }
}
Exemple #4
0
SLIRP *sim_slirp_open (const char *args, void *opaque, packet_callback callback, DEVICE *dptr, uint32 dbit)
{
SLIRP *slirp = (SLIRP *)g_malloc0(sizeof(*slirp));
char *targs = g_strdup (args);
const char *tptr = targs;
const char *cptr;
char tbuf[CBUFSIZE], gbuf[CBUFSIZE], abuf[CBUFSIZE];
int err;

slirp_dptr = dptr;
slirp_dbit = dbit;
slirp->args = (char *)g_malloc0(1 + strlen(args));
strcpy (slirp->args, args);
slirp->opaque = opaque;
slirp->callback = callback;
slirp->maskbits = 24;
slirp->dhcpmgmt = 1;
slirp->db_chime = INVALID_SOCKET;
inet_aton(DEFAULT_IP_ADDR,&slirp->vgateway);

err = 0;
while (*tptr && !err) {
    tptr = get_glyph_nc (tptr, tbuf, ',');
    if (!tbuf[0])
        break;
    cptr = tbuf;
    cptr = get_glyph (cptr, gbuf, '=');
    if (0 == MATCH_CMD (gbuf, "DHCP")) {
        slirp->dhcpmgmt = 1;
        if (cptr && *cptr)
            inet_aton (cptr, &slirp->vdhcp_start);
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "TFTP")) {
        if (cptr && *cptr)
            slirp->tftp_path = g_strdup (cptr);
        else {
            sim_printf ("Missing TFTP Path\n");
            err = 1;
            }
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "BOOTFILE")) {
        if (cptr && *cptr)
            slirp->boot_file = g_strdup (cptr);
        else {
            sim_printf ("Missing DHCP Boot file name\n");
            err = 1;
            }
        continue;
        }
    if ((0 == MATCH_CMD (gbuf, "NAMESERVER")) ||
        (0 == MATCH_CMD (gbuf, "DNS"))) {
        if (cptr && *cptr)
            inet_aton (cptr, &slirp->vnameserver);
        else {
            sim_printf ("Missing nameserver\n");
            err = 1;
            }
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "DNSSEARCH")) {
        if (cptr && *cptr) {
            int count = 0;
            char *name;
           
            slirp->dns_search = g_strdup (cptr);
            name = slirp->dns_search;
            do {
                ++count;
                slirp->dns_search_domains = (char **)realloc (slirp->dns_search_domains, (count + 1)*sizeof(char *));
                slirp->dns_search_domains[count] = NULL;
                slirp->dns_search_domains[count-1] = name;
                name = strchr (name, ':');
                if (name) {
                    *name = '\0';
                    ++name;
                    }
                } while (name && *name);
            }
        else {
            sim_printf ("Missing DNS search list\n");
            err = 1;
            }
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "GATEWAY")) {
        if (cptr && *cptr) {
            cptr = get_glyph (cptr, abuf, '/');
            if (cptr && *cptr)
                slirp->maskbits = atoi (cptr);
            inet_aton (abuf, &slirp->vgateway);
            }
        else {
            sim_printf ("Missing host\n");
            err = 1;
            }
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "NETWORK")) {
        if (cptr && *cptr) {
            cptr = get_glyph (cptr, abuf, '/');
            if (cptr && *cptr)
                slirp->maskbits = atoi (cptr);
            inet_aton (abuf, &slirp->vnetwork);
            }
        else {
            sim_printf ("Missing network\n");
            err = 1;
            }
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "NODHCP")) {
        slirp->dhcpmgmt = 0;
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "UDP")) {
        if (cptr && *cptr)
            err = _parse_redirect_port (&slirp->rtcp, cptr, IS_UDP);
        else {
            sim_printf ("Missing UDP port mapping\n");
            err = 1;
            }
        continue;
        }
    if (0 == MATCH_CMD (gbuf, "TCP")) {
        if (cptr && *cptr)
            err = _parse_redirect_port (&slirp->rtcp, cptr, IS_TCP);
        else {
            sim_printf ("Missing TCP port mapping\n");
            err = 1;
            }
        continue;
        }
    sim_printf ("Unexpected NAT argument: %s\n", gbuf);
    err = 1;
    }
if (err) {
    sim_slirp_close (slirp);
    g_free (targs);
    return NULL;
    }

slirp->vnetmask.s_addr = htonl(~((1 << (32-slirp->maskbits)) - 1));
slirp->vnetwork.s_addr = slirp->vgateway.s_addr & slirp->vnetmask.s_addr;
if ((slirp->vgateway.s_addr & ~slirp->vnetmask.s_addr) == 0)
    slirp->vgateway.s_addr = htonl(ntohl(slirp->vnetwork.s_addr) | 2);
if ((slirp->vdhcp_start.s_addr == 0) && slirp->dhcpmgmt)
    slirp->vdhcp_start.s_addr = htonl(ntohl(slirp->vnetwork.s_addr) | 15);
if (slirp->vnameserver.s_addr == 0)
    slirp->vnameserver.s_addr = htonl(ntohl(slirp->vnetwork.s_addr) | 3);
slirp->slirp = slirp_init (0, slirp->vnetwork, slirp->vnetmask, slirp->vgateway, 
                           NULL, slirp->tftp_path, slirp->boot_file, 
                           slirp->vdhcp_start, slirp->vnameserver, 
                           (const char **)(slirp->dns_search_domains), (void *)slirp);

if (_do_redirects (slirp->slirp, slirp->rtcp)) {
    sim_slirp_close (slirp);
    slirp = NULL;
    }
else {
    char db_host[32];
    GPollFD pfd;
    int64_t rnd_val = qemu_clock_get_ns ((QEMUClockType)0) / 1000000;

    pthread_mutex_init (&slirp->write_buffer_lock, NULL);
    slirp->gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
    /* setup transmit packet wakeup doorbell */
    do {
        if ((rnd_val & 0xFFFF) == 0)
            ++rnd_val;
        sprintf (db_host, "localhost:%d", (int)(rnd_val & 0xFFFF));
        slirp->db_chime  = sim_connect_sock_ex (db_host, db_host, NULL, NULL, SIM_SOCK_OPT_DATAGRAM);
        } while (slirp->db_chime == INVALID_SOCKET);
    memset (&pfd, 0, sizeof (pfd));
    pfd.fd = slirp->db_chime;
    pfd.events = G_IO_IN;
    g_array_append_val(slirp->gpollfds, pfd);
    slirp->dbit = dbit;
    slirp->dptr = dptr;
    
    sim_slirp_show(slirp, stdout);
    if (sim_log && (sim_log != stdout))
        sim_slirp_show(slirp, sim_log);
    if (sim_deb && (sim_deb != stdout) && (sim_deb != sim_log))
        sim_slirp_show(slirp, sim_deb);
    }
g_free (targs);
return slirp;
}
Exemple #5
0
bool ether_init(void)
{
	char str[256];

	// Do nothing if no Ethernet device specified
	const char *name = PrefsFindString("ether");
	if (name == NULL)
		return false;

	ether_multi_mode = PrefsFindInt32("ethermulticastmode");
	ether_use_permanent = PrefsFindBool("etherpermanentaddress");

	// Determine Ethernet device type
	net_if_type = -1;
	if (PrefsFindBool("routerenabled") || strcmp(name, "router") == 0)
		net_if_type = NET_IF_ROUTER;
	else if (strcmp(name, "slirp") == 0)
		net_if_type = NET_IF_SLIRP;
	else if (strcmp(name, "tap") == 0)
		net_if_type = NET_IF_TAP;
	else
		net_if_type = NET_IF_B2ETHER;

	// Initialize NAT-Router
	if (net_if_type == NET_IF_ROUTER) {
		if (!router_init())
			net_if_type = NET_IF_FAKE;
	}

	// Initialize slirp library
	if (net_if_type == NET_IF_SLIRP) {
		if (slirp_init() < 0) {
			sprintf(str, GetString(STR_SLIRP_NO_DNS_FOUND_WARN));
			WarningAlert(str);
			return false;
		}
	}

	// Open ethernet device
	const char *dev_name;
	switch (net_if_type) {
	case NET_IF_B2ETHER:
		dev_name = PrefsFindString("etherguid");
		if (dev_name == NULL || strcmp(name, "b2ether") != 0)
			dev_name = name;
		break;
	case NET_IF_TAP:
		dev_name = PrefsFindString("etherguid");
		break;
	}
	if (net_if_type == NET_IF_B2ETHER) {
		if (dev_name == NULL) {
			WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
			goto open_error;
		}

		fd = PacketOpenAdapter( dev_name, ether_multi_mode );
		if (!fd) {
			sprintf(str, "Could not open ethernet adapter %s.", dev_name);
			WarningAlert(str);
			goto open_error;
		}

		// Get Ethernet address
		if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) {
			sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name);
			WarningAlert(str);
			goto open_error;
		}
		D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));

		const char *ether_fake_address;
		ether_fake_address = PrefsFindString("etherfakeaddress");
		if(ether_fake_address && strlen(ether_fake_address) == 12) {
			char sm[10];
			strcpy( sm, "0x00" );
			for( int i=0; i<6; i++ ) {
				sm[2] = ether_fake_address[i*2];
				sm[3] = ether_fake_address[i*2+1];
				ether_addr[i] = (uint8)strtoul(sm,0,0);
			}
			D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
		}
	}
	else if (net_if_type == NET_IF_TAP) {
		if (dev_name == NULL) {
			WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
			goto open_error;
		}

		fd = tap_open_adapter(dev_name);
		if (!fd) {
			sprintf(str, "Could not open ethernet adapter %s.", dev_name);
			WarningAlert(str);
			goto open_error;
		}

		if (!tap_check_version(fd)) {
			sprintf(str, "Minimal TAP-Win32 version supported is %d.%d.", TAP_VERSION_MIN_MAJOR, TAP_VERSION_MIN_MINOR);
			WarningAlert(str);
			goto open_error;
		}

		if (!tap_set_status(fd, true)) {
			sprintf(str, "Could not set media status to connected.");
			WarningAlert(str);
			goto open_error;
		}

		if (!tap_get_mac(fd, ether_addr)) {
			sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name);
			WarningAlert(str);
			goto open_error;
		}
		D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));

		const char *ether_fake_address;
		ether_fake_address = PrefsFindString("etherfakeaddress");
		if (ether_fake_address && strlen(ether_fake_address) == 12) {
			char sm[10];
			strcpy( sm, "0x00" );
			for( int i=0; i<6; i++ ) {
				sm[2] = ether_fake_address[i*2];
				sm[3] = ether_fake_address[i*2+1];
				ether_addr[i] = (uint8)strtoul(sm,0,0);
			}
		}
#if 1
		/*
		  If we bridge the underlying ethernet connection and the TAP
		  device altogether, we have to use a fake address.
		 */
		else {
			ether_addr[0] = 0x52;
			ether_addr[1] = 0x54;
			ether_addr[2] = 0x00;
		}
#endif
		D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
	}
	else if (net_if_type == NET_IF_SLIRP) {
		ether_addr[0] = 0x52;
		ether_addr[1] = 0x54;
		ether_addr[2] = 0x00;
		ether_addr[3] = 0x12;
		ether_addr[4] = 0x34;
		ether_addr[5] = 0x56;
		D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
	}
	else {
		memcpy( ether_addr, router_mac_addr, 6 );
		D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
	}

	// Start packet reception thread
	int_ack = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_ack) {
		WarningAlert("WARNING: Cannot create int_ack semaphore");
		goto open_error;
	}

	// nonsignaled
	int_sig = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_sig) {
		WarningAlert("WARNING: Cannot create int_sig semaphore");
		goto open_error;
	}

	int_sig2 = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_sig2) {
		WarningAlert("WARNING: Cannot create int_sig2 semaphore");
		goto open_error;
	}

	int_send_now = CreateSemaphore( 0, 0, 1, NULL);
	if(!int_send_now) {
		WarningAlert("WARNING: Cannot create int_send_now semaphore");
		goto open_error;
	}

	init_queue();

	if(!allocate_read_packets()) goto open_error;

	// No need to enter wait state if we can avoid it.
	// These all terminate fast.

	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &fetch_csection, 5000 );
	} else {
		InitializeCriticalSection( &fetch_csection );
	}
	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &queue_csection, 5000 );
	} else {
		InitializeCriticalSection( &queue_csection );
	}
	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &send_csection, 5000 );
	} else {
		InitializeCriticalSection( &send_csection );
	}
	if(pfnInitializeCriticalSectionAndSpinCount) {
		pfnInitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 );
	} else {
		InitializeCriticalSection( &wpool_csection );
	}

	ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, &ether_tid );
	if (!ether_th) {
		D(bug("Failed to create ethernet thread\n"));
		goto open_error;
	}
	thread_active = true;

	unsigned int dummy;
	unsigned int (WINAPI *receive_func)(void *);
	switch (net_if_type) {
	case NET_IF_SLIRP:
	  receive_func = slirp_receive_func;
	  break;
	default:
	  receive_func = ether_thread_get_packets_nt;
	  break;
	}
	ether_th2 = (HANDLE)_beginthreadex( 0, 0, receive_func, 0, 0, &dummy );
	ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy );

	// Everything OK
	return true;

 open_error:
	if (thread_active) {
		TerminateThread(ether_th,0);
		ether_th = 0;
		if (int_ack)
			CloseHandle(int_ack);
		int_ack = 0;
		if(int_sig)
			CloseHandle(int_sig);
		int_sig = 0;
		if(int_sig2)
			CloseHandle(int_sig2);
		int_sig2 = 0;
		if(int_send_now)
			CloseHandle(int_send_now);
		int_send_now = 0;
		thread_active = false;
	}
	if (fd) {
		switch (net_if_type) {
		case NET_IF_B2ETHER:
			PacketCloseAdapter(fd);
			break;
		case NET_IF_TAP:
			tap_close_adapter(fd);
			break;
		}
		fd = 0;
	}
	return false;
}
int ethernet_open (struct netdriverdata *ndd, void *vsd, void *user, ethernet_gotfunc *gotfunc, ethernet_getfunc *getfunc, int promiscuous)
{
	switch (ndd->type)
	{
		case UAENET_SLIRP:
		case UAENET_SLIRP_INBOUND:
		{
			struct ethernet_data *ed = (struct ethernet_data*)vsd;
			ed->gotfunc = gotfunc;
			ed->getfunc = getfunc;
			ed->userdata = user;
			slirp_data = ed;
			uae_sem_init (&slirp_sem1, 0, 1);
			uae_sem_init (&slirp_sem2, 0, 1);
			slirp_init ();
			for (int i = 0; i < MAX_SLIRP_REDIRS; i++) {
				struct slirp_redir *sr = &currprefs.slirp_redirs[i];
				if (sr->proto) {
					struct in_addr a;
					if (sr->srcport == 0) {
					    inet_aton("10.0.2.15", &a);
						slirp_redir (0, sr->dstport, a, sr->dstport);
					} else {
#ifdef HAVE_STRUCT_IN_ADDR_S_UN
						a.S_un.S_addr = sr->addr;
#else
						a.s_addr = sr->addr;
#endif
						slirp_redir (sr->proto == 1 ? 0 : 1, sr->dstport, a, sr->srcport);
					}
				}
			}
			if (ndd->type == UAENET_SLIRP_INBOUND) {
				struct in_addr a;
			    inet_aton("10.0.2.15", &a);
				for (int i = 0; slirp_ports[i]; i++) {
					int port = slirp_ports[i];
					int j;
					for (j = 0; j < MAX_SLIRP_REDIRS; j++) {
						struct slirp_redir *sr = &currprefs.slirp_redirs[j];
						if (sr->proto && sr->dstport == port)
							break;
					}
					if (j == MAX_SLIRP_REDIRS)
						slirp_redir (0, port + SLIRP_PORT_OFFSET, a, port);
				}
			}
			netmode = ndd->type;
			slirp_start ();
		}
		return 1;
#ifdef WITH_UAENET_PCAP
		case UAENET_PCAP:
		if (uaenet_open (vsd, ndd, user, gotfunc, getfunc, promiscuous)) {
			netmode = ndd->type;
			return 1;
		}
		return 0;
#endif
	}
	return 0;
}