| // Copyright 2019 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/developer/debug/zxdb/common/inet_util.h" | |
| #include "src/lib/fxl/strings/string_number_conversions.h" | |
| namespace zxdb { | |
| Err ParseHostPort(const std::string& in_host, const std::string& in_port, std::string* out_host, | |
| uint16_t* out_port) { | |
| if (in_host.empty()) { | |
| return Err(ErrType::kInput, "No host component specified."); | |
| } | |
| if (in_port.empty()) { | |
| return Err(ErrType::kInput, "No port component specified."); | |
| } | |
| // Trim brackets from the host name for IPv6 addresses. | |
| if (in_host.front() == '[' && in_host.back() == ']') | |
| *out_host = in_host.substr(1, in_host.size() - 2); | |
| else | |
| *out_host = in_host; | |
| uint16_t port; | |
| if (!fxl::StringToNumberWithError(in_port, &port)) { | |
| return Err(ErrType::kInput, "Invalid port number."); | |
| } | |
| if (port == 0) { | |
| return Err(ErrType::kInput, "Port value out of range."); | |
| } | |
| *out_port = port; | |
| return Err(); | |
| } | |
| Err ParseHostPort(const std::string& input, std::string* out_host, uint16_t* out_port) { | |
| // Separate based on the last colon. | |
| size_t colon = input.rfind(':'); | |
| if (colon == std::string::npos) { | |
| return Err(ErrType::kInput, "Expected colon to separate host/port."); | |
| } | |
| // If the host has a colon in it, it could be an IPv6 address. In this case, | |
| // require brackets around it to differentiate the case where people | |
| // supplied an IPv6 address and we just picked out the last component above. | |
| std::string host = input.substr(0, colon); | |
| if (host.empty()) { | |
| return Err(ErrType::kInput, "No host component specified."); | |
| } | |
| if (host.find(':') != std::string::npos) { | |
| if (host.front() != '[' || host.back() != ']') { | |
| return Err(ErrType::kInput, "Missing brackets enclosing IPv6 address, e.g., \"[::1]:1234\"."); | |
| } | |
| } | |
| std::string port = input.substr(colon + 1); | |
| return ParseHostPort(host, port, out_host, out_port); | |
| } | |
| bool Ipv6HostPortIsMissingBrackets(const std::string& input) { | |
| size_t colon = input.rfind(':'); | |
| if (colon == std::string::npos) { | |
| return false; | |
| } | |
| std::string host = input.substr(0, colon); | |
| if (host.empty()) { | |
| return false; | |
| } | |
| if (host.find(':') == std::string::npos) { | |
| return false; | |
| } | |
| return host.front() != '[' || host.back() != ']'; | |
| } | |
| } // namespace zxdb |