1 1.1 christos /* Operations on network stuff. 2 1.1.1.4 christos Copyright (C) 2018-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GDB. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 1.1 christos 19 1.1 christos #include "netstuff.h" 20 1.1 christos #include <algorithm> 21 1.1 christos 22 1.1 christos #ifdef USE_WIN32API 23 1.1 christos #include <ws2tcpip.h> 24 1.1 christos #else 25 1.1 christos #include <netinet/in.h> 26 1.1 christos #include <arpa/inet.h> 27 1.1 christos #include <netdb.h> 28 1.1 christos #include <sys/socket.h> 29 1.1 christos #include <netinet/tcp.h> 30 1.1 christos #endif 31 1.1 christos 32 1.1 christos /* See gdbsupport/netstuff.h. */ 33 1.1 christos 34 1.1 christos scoped_free_addrinfo::~scoped_free_addrinfo () 35 1.1 christos { 36 1.1 christos freeaddrinfo (m_res); 37 1.1 christos } 38 1.1 christos 39 1.1 christos /* See gdbsupport/netstuff.h. */ 40 1.1 christos 41 1.1 christos parsed_connection_spec 42 1.1 christos parse_connection_spec_without_prefix (std::string spec, struct addrinfo *hint) 43 1.1 christos { 44 1.1 christos parsed_connection_spec ret; 45 1.1 christos size_t last_colon_pos = 0; 46 1.1 christos /* We're dealing with IPv6 if: 47 1.1 christos 48 1.1 christos - ai_family is AF_INET6, or 49 1.1 christos - ai_family is not AF_INET, and 50 1.1 christos - spec[0] is '[', or 51 1.1 christos - the number of ':' on spec is greater than 1. */ 52 1.1 christos bool is_ipv6 = (hint->ai_family == AF_INET6 53 1.1 christos || (hint->ai_family != AF_INET 54 1.1 christos && (spec[0] == '[' 55 1.1 christos || std::count (spec.begin (), 56 1.1 christos spec.end (), ':') > 1))); 57 1.1 christos 58 1.1 christos if (is_ipv6) 59 1.1 christos { 60 1.1 christos if (spec[0] == '[') 61 1.1 christos { 62 1.1 christos /* IPv6 addresses can be written as '[ADDR]:PORT', and we 63 1.1 christos support this notation. */ 64 1.1 christos size_t close_bracket_pos = spec.find_first_of (']'); 65 1.1 christos 66 1.1 christos if (close_bracket_pos == std::string::npos) 67 1.1 christos error (_("Missing close bracket in hostname '%s'"), 68 1.1 christos spec.c_str ()); 69 1.1 christos 70 1.1 christos hint->ai_family = AF_INET6; 71 1.1 christos 72 1.1 christos const char c = spec[close_bracket_pos + 1]; 73 1.1 christos 74 1.1 christos if (c == '\0') 75 1.1 christos last_colon_pos = std::string::npos; 76 1.1 christos else if (c != ':') 77 1.1 christos error (_("Invalid cruft after close bracket in '%s'"), 78 1.1 christos spec.c_str ()); 79 1.1 christos 80 1.1 christos /* Erase both '[' and ']'. */ 81 1.1 christos spec.erase (0, 1); 82 1.1 christos spec.erase (close_bracket_pos - 1, 1); 83 1.1 christos } 84 1.1 christos else if (spec.find_first_of (']') != std::string::npos) 85 1.1 christos error (_("Missing open bracket in hostname '%s'"), 86 1.1 christos spec.c_str ()); 87 1.1 christos } 88 1.1 christos 89 1.1 christos if (last_colon_pos == 0) 90 1.1 christos last_colon_pos = spec.find_last_of (':'); 91 1.1 christos 92 1.1 christos /* The length of the hostname part. */ 93 1.1 christos size_t host_len; 94 1.1 christos 95 1.1 christos if (last_colon_pos != std::string::npos) 96 1.1 christos { 97 1.1 christos /* The user has provided a port. */ 98 1.1 christos host_len = last_colon_pos; 99 1.1 christos ret.port_str = spec.substr (last_colon_pos + 1); 100 1.1 christos } 101 1.1 christos else 102 1.1 christos host_len = spec.size (); 103 1.1 christos 104 1.1 christos ret.host_str = spec.substr (0, host_len); 105 1.1 christos 106 1.1 christos /* Default hostname is localhost. */ 107 1.1 christos if (ret.host_str.empty ()) 108 1.1 christos ret.host_str = "localhost"; 109 1.1 christos 110 1.1 christos return ret; 111 1.1 christos } 112 1.1 christos 113 1.1 christos /* See gdbsupport/netstuff.h. */ 114 1.1 christos 115 1.1 christos parsed_connection_spec 116 1.1 christos parse_connection_spec (const char *spec, struct addrinfo *hint) 117 1.1 christos { 118 1.1 christos /* Struct to hold the association between valid prefixes, their 119 1.1 christos family and socktype. */ 120 1.1 christos struct host_prefix 121 1.1 christos { 122 1.1 christos /* The prefix. */ 123 1.1 christos const char *prefix; 124 1.1 christos 125 1.1 christos /* The 'ai_family'. */ 126 1.1 christos int family; 127 1.1 christos 128 1.1 christos /* The 'ai_socktype'. */ 129 1.1 christos int socktype; 130 1.1 christos }; 131 1.1 christos static const struct host_prefix prefixes[] = 132 1.1 christos { 133 1.1 christos { "udp:", AF_UNSPEC, SOCK_DGRAM }, 134 1.1 christos { "tcp:", AF_UNSPEC, SOCK_STREAM }, 135 1.1 christos { "udp4:", AF_INET, SOCK_DGRAM }, 136 1.1 christos { "tcp4:", AF_INET, SOCK_STREAM }, 137 1.1 christos { "udp6:", AF_INET6, SOCK_DGRAM }, 138 1.1 christos { "tcp6:", AF_INET6, SOCK_STREAM }, 139 1.1 christos }; 140 1.1 christos 141 1.1 christos for (const host_prefix prefix : prefixes) 142 1.1 christos if (startswith (spec, prefix.prefix)) 143 1.1 christos { 144 1.1 christos spec += strlen (prefix.prefix); 145 1.1 christos hint->ai_family = prefix.family; 146 1.1 christos hint->ai_socktype = prefix.socktype; 147 1.1 christos hint->ai_protocol 148 1.1 christos = hint->ai_socktype == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP; 149 1.1 christos break; 150 1.1 christos } 151 1.1 christos 152 1.1 christos return parse_connection_spec_without_prefix (spec, hint); 153 1.1 christos } 154