Apache Mesos
ip.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_WINDOWS_IP_HPP__
14 #define __STOUT_WINDOWS_IP_HPP__
15 
16 #include <string>
17 
18 #include <stout/error.hpp>
19 #include <stout/foreach.hpp>
20 #include <stout/none.hpp>
21 #include <stout/result.hpp>
22 #include <stout/try.hpp>
23 #include <stout/windows.hpp> // For `iphlpapi.h`.
24 
25 
26 namespace net {
27 
29  const std::string& name,
30  int family)
31 {
32  DWORD result;
33  ULONG size = 0;
34 
35  // TODO(josephw): `GetAdaptersInfo` will only return IPv4 results.
36  // To get IPv6 results, we should look into `GetAdaptersAddresses`.
37  if (family != AF_INET) {
38  return Error("Unsupported family type: " + stringify(family));
39  }
40 
41  // Indicates whether the link device is found or not.
42  bool found = false;
43 
44  // Make an initial call to GetAdaptersInfo to get structure size.
45  if (GetAdaptersInfo(nullptr, &size) != ERROR_BUFFER_OVERFLOW) {
46  return WindowsError("Calling GetAdaptersInfo returned unexpected result");
47  }
48 
49  std::vector<IP_ADAPTER_INFO> adapter_info(size / sizeof(IP_ADAPTER_INFO));
50  result = GetAdaptersInfo(
51  static_cast<PIP_ADAPTER_INFO>(adapter_info.data()),
52  &size);
53 
54  if (result != NO_ERROR) {
55  return WindowsError(result, "GetAdaptersInfo failed");
56  }
57 
58  foreach(const IP_ADAPTER_INFO& ip_adapter, adapter_info) {
59  if (!strcmp(ip_adapter.AdapterName, name.c_str())) {
60  found = true;
61 
62  IP address = IP::parse(ip_adapter.IpAddressList.IpAddress.String).get();
63 
64  if (ip_adapter.IpAddressList.IpMask.String[0] != '\0') {
65  IP netmask = IP::parse(ip_adapter.IpAddressList.IpMask.String).get();
66 
67  Try<IP::Network> network = IP::Network::create(address, netmask);
68  if (network.isError()) {
69  return Error(network.error());
70  }
71 
72  return network.get();
73  }
74 
75  // Note that this is the case where netmask is not specified.
76  // We've seen such cases when VPN is used. In that case, a
77  // default /32 prefix for IPv4 and /64 for IPv6 is used.
78  int prefix = (family == AF_INET ? 32 : 64);
79  Try<IP::Network> network = IP::Network::create(address, prefix);
80  if (network.isError()) {
81  return Error(network.error());
82  }
83 
84  return network.get();
85  }
86  }
87 
88  if (!found) {
89  return Error("Cannot find the link device");
90  }
91 
92  return None();
93 }
94 
95 } // namespace net {
96 
97 #endif // __STOUT_WINDOWS_IP_HPP__
IP address() const
Definition: ip.hpp:261
Definition: errorbase.hpp:36
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
T & get()&
Definition: try.hpp:80
Definition: check.hpp:33
Definition: error.hpp:108
static Try< IP > parse(const std::string &value, int family=AF_UNSPEC)
Definition: ip.hpp:417
Definition: check.hpp:30
IP netmask() const
Definition: ip.hpp:263
Definition: ip.hpp:70
static Result< Network > fromLinkDevice(const std::string &name, int family)
Definition: ip.hpp:30
static Try error(const E &e)
Definition: try.hpp:43
static Try< Network > create(const IP &address, const IP &netmask)
Definition: ip.hpp:570
IP(const struct in_addr &_storage)
Definition: ip.hpp:92
Definition: none.hpp:27
bool isError() const
Definition: try.hpp:78
std::string stringify(int flags)
constexpr const char * name
Definition: shell.hpp:41
int prefix() const
Definition: ip.hpp:266