blob: 91de6dcfc2d162f3f690673990a49ab6ff9622cf [file] [log] [blame]
// Copyright 2014 The Chromium OS 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 "peerd/dbus_data_serialization.h"
#include <utility>
#include <vector>
#include "peerd/ip_addr.h"
namespace chromeos {
namespace dbus_utils {
// Extend D-Bus serialization mechanism to handle "peerd::ip_addr" structure.
std::string DBusSignature<peerd::ip_addr>::get() {
// Returns "(ayq)".
return GetDBusSignature<std::pair<std::vector<uint8_t>, uint16_t>>();
}
bool AppendValueToWriter(dbus::MessageWriter* writer,
const peerd::ip_addr& value) {
std::vector<uint8_t> address_bytes;
uint16_t port = 0;
if (value.ss_family == AF_INET) {
// IPv4.
address_bytes.resize(sizeof(in_addr));
auto ipv4 = reinterpret_cast<const sockaddr_in*>(&value);
*reinterpret_cast<in_addr*>(address_bytes.data()) = ipv4->sin_addr;
port = ipv4->sin_port;
} else if (value.ss_family == AF_INET6) {
// IPv6.
address_bytes.resize(sizeof(in6_addr));
auto ipv6 = reinterpret_cast<const sockaddr_in6*>(&value);
*reinterpret_cast<in6_addr*>(address_bytes.data()) = ipv6->sin6_addr;
port = ipv6->sin6_port;
} else {
LOG(ERROR) << "Address family " << value.ss_family << " not supported.";
return false;
}
return AppendValueToWriter(writer,
std::make_pair(std::move(address_bytes), port));
}
bool PopValueFromReader(dbus::MessageReader* reader, peerd::ip_addr* value) {
std::pair<std::vector<uint8_t>, uint16_t> addr;
if (!PopValueFromReader(reader, &addr))
return false;
if (addr.first.size() == sizeof(in_addr)) {
// IPv4.
value->ss_family = AF_INET;
auto ipv4 = reinterpret_cast<sockaddr_in*>(value);
ipv4->sin_addr = *reinterpret_cast<const in_addr*>(addr.first.data());
ipv4->sin_port = addr.second;
} else if (addr.first.size() == sizeof(in6_addr)) {
// IPv6.
value->ss_family = AF_INET6;
auto ipv6 = reinterpret_cast<sockaddr_in6*>(value);
ipv6->sin6_addr = *reinterpret_cast<const in6_addr*>(addr.first.data());
ipv6->sin6_port = addr.second;
} else {
LOG(ERROR) << "Unsupported IP address size.";
return false;
}
return true;
}
} // namespace dbus_utils
} // namespace chromeos