1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/client/plugin/pepper_util.h"
6
7#include "base/callback.h"
8#include "base/logging.h"
9#include "base/sys_byteorder.h"
10#include "ppapi/cpp/module.h"
11#include "ppapi/cpp/net_address.h"
12#include "third_party/webrtc/base/socketaddress.h"
13
14namespace remoting {
15
16bool SocketAddressToPpNetAddressWithPort(
17    const pp::InstanceHandle& instance,
18    const rtc::SocketAddress& address,
19    pp::NetAddress* pp_address,
20    uint16_t port) {
21  switch (address.ipaddr().family()) {
22    case AF_INET: {
23      in_addr ipv4_addr = address.ipaddr().ipv4_address();
24      PP_NetAddress_IPv4 ip_addr;
25      ip_addr.port = base::HostToNet16(port);
26      memcpy(&ip_addr.addr, &ipv4_addr, sizeof(ip_addr.addr));
27      *pp_address = pp::NetAddress(instance, ip_addr);
28      return true;
29    }
30    case AF_INET6: {
31      in6_addr ipv6_addr = address.ipaddr().ipv6_address();
32      PP_NetAddress_IPv6 ip_addr;
33      ip_addr.port = base::HostToNet16(port);
34      memcpy(&ip_addr.addr, &ipv6_addr, sizeof(ip_addr.addr));
35      *pp_address = pp::NetAddress(instance, ip_addr);
36      return true;
37    }
38    default: {
39      LOG(WARNING) << "Unknown address family: " << address.ipaddr().family();
40      return false;
41    }
42  }
43}
44
45bool SocketAddressToPpNetAddress(const pp::InstanceHandle& instance,
46                                 const rtc::SocketAddress& address,
47                                 pp::NetAddress* pp_net_address) {
48  return SocketAddressToPpNetAddressWithPort(instance,
49                                             address,
50                                             pp_net_address,
51                                             address.port());
52}
53
54void PpNetAddressToSocketAddress(const pp::NetAddress& pp_net_address,
55                                 rtc::SocketAddress* address) {
56  switch (pp_net_address.GetFamily()) {
57    case PP_NETADDRESS_FAMILY_IPV4: {
58      PP_NetAddress_IPv4 ipv4_addr;
59      CHECK(pp_net_address.DescribeAsIPv4Address(&ipv4_addr));
60      address->SetIP(rtc::IPAddress(
61                         bit_cast<in_addr>(ipv4_addr.addr)));
62      address->SetPort(base::NetToHost16(ipv4_addr.port));
63      return;
64    }
65    case PP_NETADDRESS_FAMILY_IPV6: {
66      PP_NetAddress_IPv6 ipv6_addr;
67      CHECK(pp_net_address.DescribeAsIPv6Address(&ipv6_addr));
68      address->SetIP(rtc::IPAddress(
69                         bit_cast<in6_addr>(ipv6_addr.addr)));
70      address->SetPort(base::NetToHost16(ipv6_addr.port));
71      return;
72    }
73    case PP_NETADDRESS_FAMILY_UNSPECIFIED: {
74      break;
75    }
76  };
77
78  NOTREACHED();
79  address->Clear();
80}
81
82}  // namespace remoting
83