const char *NET_AdrToString(netadr_t a) { static char s[NET_ADDRSTRMAXLEN]; if (a.type == NA_LOOPBACK) { Com_sprintf(s, sizeof(s), "loopback"); } else if (a.type == NA_BOT) { Com_sprintf(s, sizeof(s), "bot"); } else if (a.type == NA_IP) { // Port has to be returned along with ip address because of compatibility Com_sprintf(s, sizeof(s), "%i.%i.%i.%i:%hu", a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port)); } #ifdef FEATURE_IPV6 else if (a.type == NA_IP6) { // FIXME: add port for compatibility // (joining a server through the server browser) struct sockaddr_storage sadr; memset(&sadr, 0, sizeof(sadr)); NetadrToSockadr(&a, (struct sockaddr *) &sadr); Sys_SockaddrToString(s, sizeof(s), (struct sockaddr *) &sadr); } #endif return s; }
std::string AddressToString( const netadr_t& address, bool with_port ) { if ( address.type == netadrtype_t::NA_LOOPBACK ) { return "loopback"; } else if ( address.type == netadrtype_t::NA_BOT ) { return "bot"; } else if ( address.type == netadrtype_t::NA_IP || address.type == netadrtype_t::NA_IP6 || address.type == netadrtype_t::NA_IP_DUAL ) { char s[ NET_ADDR_STR_MAX_LEN ]; sockaddr_storage sadr = {0}; NetadrToSockadr( &address, reinterpret_cast<sockaddr*>(&sadr) ); Sys_SockaddrToString( s, sizeof(s), reinterpret_cast<sockaddr*>(&sadr) ); std::string result = s; if ( with_port ) { if ( NET_IS_IPv6( address.type ) ) { result = '[' + result + ']'; } result += ':' + std::to_string(ntohs(GetPort(address))); } return result; } return ""; }
/* ================== Sys_ShowIP ================== */ void Sys_ShowIP(void) { int i; char addrbuf[NET_ADDRSTRMAXLEN]; for (i = 0; i < numIP; i++) { Sys_SockaddrToString(addrbuf, sizeof (addrbuf), (struct sockaddr *) & localIP[i].addr); if (localIP[i].type == NA_IP) Com_Printf("IP: %s\n", addrbuf); else if (localIP[i].type == NA_IP6) Com_Printf("IP6: %s\n", addrbuf); } }
const char *NET_AdrToString (netadr_t a) { static char s[NET_ADDRSTRMAXLEN]; if (a.type == NA_LOOPBACK) Com_sprintf (s, sizeof(s), "loopback"); else if (a.type == NA_IP || a.type == NA_IP6) { struct sockaddr_storage sadr; memset(&sadr, 0, sizeof(sadr)); NetadrToSockadr(&a, (struct sockaddr *) &sadr); Sys_SockaddrToString(s, sizeof(s), (struct sockaddr *) &sadr); } return s; }
const char *NET_AdrToString(netadr_t a) { static char s[NET_ADDRSTRMAXLEN]; switch (a.type) { case NA_LOOPBACK: Com_sprintf(s, sizeof(s), "loopback"); break; case NA_BOT: Com_sprintf(s, sizeof(s), "bot"); break; case NA_IP: // Port has to be returned along with ip address because of compatibility Com_sprintf(s, sizeof(s), "%i.%i.%i.%i:%hu", a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port)); break; #ifdef FEATURE_IPV6 case NA_IP6: { // FIXME: add port for compatibility // (joining a server through the server browser) // Needs to be [ip]:port since : is a valid entry in ipv6 struct sockaddr_storage sadr; memset(&sadr, 0, sizeof(sadr)); NetadrToSockadr(&a, (struct sockaddr *) &sadr); Sys_SockaddrToString(s, sizeof(s), (struct sockaddr *) &sadr); break; } break; #endif default: Com_Printf("NET_AdrToString: Unknown address type: %i\n", a.type); break; } return s; }
/* ==================== Sys_CreateListenSockets Step 3 - Create the listening sockets ==================== */ qboolean Sys_CreateListenSockets (void) { unsigned int sock_ind; for (sock_ind = 0; sock_ind < nb_sockets; sock_ind++) { listen_socket_t* listen_sock = &listen_sockets[sock_ind]; socket_t crt_sock; int addr_family; addr_family = listen_sock->local_addr.ss_family; crt_sock = socket (addr_family, SOCK_DGRAM, IPPROTO_UDP); if (crt_sock == INVALID_SOCKET) { // If the address family isn't supported but the socket is optional, don't fail! if (Sys_GetLastNetError() == NETERR_AFNOSUPPORT && listen_sock->optional) { Com_Printf (MSG_WARNING, "> WARNING: protocol %s isn't supported\n", (addr_family == AF_INET) ? "IPv4" : ((addr_family == AF_INET6) ? "IPv6" : "UNKNOWN")); if (sock_ind + 1 < nb_sockets) memmove (&listen_sockets[sock_ind], &listen_sockets[sock_ind + 1], (nb_sockets - sock_ind - 2) * sizeof (listen_sockets[0])); sock_ind--; nb_sockets--; continue; } Com_Printf (MSG_ERROR, "> ERROR: socket creation failed (%s)\n", Sys_GetLastNetErrorString ()); Sys_CloseAllSockets (); return false; } if (addr_family == AF_INET6) { // Win32's API only supports it since Windows Vista, but fortunately // the default value is what we want on Win32 anyway (IPV6_V6ONLY = true) #ifdef IPV6_V6ONLY int ipv6_only = 1; if (setsockopt (crt_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&ipv6_only, sizeof(ipv6_only)) != 0) { #ifdef WIN32 // This flag isn't supported before Windows Vista if (Sys_GetLastNetError() != NETERR_NOPROTOOPT) #endif { Com_Printf (MSG_ERROR, "> ERROR: setsockopt(IPV6_V6ONLY) failed (%s)\n", Sys_GetLastNetErrorString ()); Sys_CloseAllSockets (); return false; } } #endif } if (listen_sock->local_addr_name != NULL) { const char* addr_str; addr_str = Sys_SockaddrToString(&listen_sock->local_addr, listen_sock->local_addr_len); Com_Printf (MSG_NORMAL, "> Listening on address %s (%s)\n", listen_sock->local_addr_name, addr_str); } else Com_Printf (MSG_NORMAL, "> Listening on all %s addresses\n", addr_family == AF_INET6 ? "IPv6" : "IPv4"); if (bind (crt_sock, (struct sockaddr*)&listen_sock->local_addr, listen_sock->local_addr_len) != 0) { Com_Printf (MSG_ERROR, "> ERROR: socket binding failed (%s)\n", Sys_GetLastNetErrorString ()); Sys_CloseAllSockets (); return false; } listen_sock->socket = crt_sock; } return true; }