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; }
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; }
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); } }
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; }
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, ðer_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; }