void ip_filter::add_rule(address first, address last, int flags) { if (first.is_v4()) { assert(last.is_v4()); m_filter4.add_rule(first.to_v4(), last.to_v4(), flags); } else if (first.is_v6()) { assert(last.is_v6()); m_filter6.add_rule(first.to_v6(), last.to_v6(), flags); } else assert(false); }
int ip_filter::access(address const& addr) const { if (addr.is_v4()) return m_filter4.access(addr.to_v4()); assert(addr.is_v6()); return m_filter6.access(addr.to_v6()); }
void ip_filter::add_rule(address first, address last, boost::uint32_t flags) { if (first.is_v4()) { TORRENT_ASSERT(last.is_v4()); m_filter4.add_rule(first.to_v4().to_bytes(), last.to_v4().to_bytes(), flags); } #if TORRENT_USE_IPV6 else if (first.is_v6()) { TORRENT_ASSERT(last.is_v6()); m_filter6.add_rule(first.to_v6().to_bytes(), last.to_v6().to_bytes(), flags); } #endif else TORRENT_ASSERT(false); }
int ip_filter::access(address const& addr) const { if (addr.is_v4()) return m_filter4.access(addr.to_v4().to_bytes()); #if TORRENT_USE_IPV6 TORRENT_ASSERT(addr.is_v6()); return m_filter6.access(addr.to_v6().to_bytes()); #else return 0; #endif }
// returns the number of bits in that differ from the right // between the addresses. int cidr_distance(address const& a1, address const& a2) { if (a1.is_v4() && a2.is_v4()) { // both are v4 address_v4::bytes_type b1 = a1.to_v4().to_bytes(); address_v4::bytes_type b2 = a2.to_v4().to_bytes(); return address_v4::bytes_type::static_size * 8 - common_bits(b1.c_array(), b2.c_array(), b1.size()); } address_v6::bytes_type b1; address_v6::bytes_type b2; if (a1.is_v4()) b1 = address_v6::v4_mapped(a1.to_v4()).to_bytes(); else b1 = a1.to_v6().to_bytes(); if (a2.is_v4()) b2 = address_v6::v4_mapped(a2.to_v4()).to_bytes(); else b2 = a2.to_v6().to_bytes(); return address_v6::bytes_type::static_size * 8 - common_bits(b1.c_array(), b2.c_array(), b1.size()); }
bool in_subnet(address const& addr, ip_interface const& iface) { if (addr.is_v4() != iface.interface_address.is_v4()) return false; // since netmasks seems unreliable for IPv6 interfaces // (MacOS X returns AF_INET addresses as bitmasks) assume // that any IPv6 address belongs to the subnet of any // interface with an IPv6 address if (addr.is_v6()) return true; return (addr.to_v4().to_ulong() & iface.netmask.to_v4().to_ulong()) == (iface.interface_address.to_v4().to_ulong() & iface.netmask.to_v4().to_ulong()); }
// returns the number of bits in that differ from the right // between the addresses. The larger number, the further apart // the IPs are int cidr_distance(address const& a1, address const& a2) { #if LIBED2K_USE_IPV6 if (a1.is_v4() && a2.is_v4()) { #endif // both are v4 address_v4::bytes_type b1 = a1.to_v4().to_bytes(); address_v4::bytes_type b2 = a2.to_v4().to_bytes(); return address_v4::bytes_type().size() * 8 - common_bits(b1.data(), b2.data(), b1.size()); #if LIBED2K_USE_IPV6 } address_v6::bytes_type b1; address_v6::bytes_type b2; if (a1.is_v4()) b1 = address_v6::v4_mapped(a1.to_v4()).to_bytes(); else b1 = a1.to_v6().to_bytes(); if (a2.is_v4()) b2 = address_v6::v4_mapped(a2.to_v4()).to_bytes(); else b2 = a2.to_v6().to_bytes(); return address_v6::bytes_type().size() * 8 - common_bits(b1.data(), b2.data(), b1.size()); #endif }
void write_address(address const& a, OutIt& out) { if (a.is_v4()) { write_uint32(a.to_v4().to_ulong(), out); } else if (a.is_v6()) { address_v6::bytes_type bytes = a.to_v6().to_bytes(); std::copy(bytes.begin(), bytes.end(), out); } }
address mask_address(const address& addrIn, uint8_t prefixLen) { if (addrIn.is_v4()) { prefixLen = std::min<uint8_t>(prefixLen, 32); uint32_t mask = get_subnet_mask_v4(prefixLen); return address_v4(addrIn.to_v4().to_ulong() & mask); } struct in6_addr mask; struct in6_addr addr6; prefixLen = std::min<uint8_t>(prefixLen, 128); compute_ipv6_subnet(addrIn.to_v6(), prefixLen, &mask, &addr6); address_v6::bytes_type data; std::memcpy(data.data(), &addr6, sizeof(addr6)); return address_v6(data); }
std::string address_to_bytes(address const& a) { #if LIBED2K_USE_IPV6 if (a.is_v6()) { address_v6::bytes_type b = a.to_v6().to_bytes(); return std::string((char*)&b[0], b.size()); } else #endif { address_v4::bytes_type b = a.to_v4().to_bytes(); return std::string((char*)&b[0], b.size()); } }
void write_address(address const& a, OutIt&& out) { #if TORRENT_USE_IPV6 if (a.is_v4()) { #endif write_uint32(a.to_v4().to_ulong(), out); #if TORRENT_USE_IPV6 } else if (a.is_v6()) { for (auto b : a.to_v6().to_bytes()) write_uint8(b, out); } #endif }
void write_address(address const& a, OutIt& out) { #if TORRENT_USE_IPV6 if (a.is_v4()) { #endif write_uint32(a.to_v4().to_ulong(), out); #if TORRENT_USE_IPV6 } else if (a.is_v6()) { address_v6::bytes_type bytes = a.to_v6().to_bytes(); std::copy(bytes.begin(), bytes.end(), out); } #endif }
void write_address(address const& a, OutIt& out) { #if TORRENT_USE_IPV6 if (a.is_v4()) { #endif write_uint32(a.to_v4().to_ulong(), out); #if TORRENT_USE_IPV6 } else if (a.is_v6()) { typedef address_v6::bytes_type bytes_t; bytes_t bytes = a.to_v6().to_bytes(); for (bytes_t::iterator i = bytes.begin() , end(bytes.end()); i != end; ++i) write_uint8(*i, out); } #endif }
void natpmp::rebind(address const& listen_interface) try { address_v4 local = address_v4::any(); if (listen_interface.is_v4() && listen_interface != address_v4::any()) { local = listen_interface.to_v4(); } else { local = guess_local_address(m_socket.io_service()); if (local == address_v4::any()) { throw std::runtime_error("local host is probably not on a NATed " "network. disabling NAT-PMP"); } } #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) m_log << time_now_string() << " local ip: " << local.to_string() << std::endl; #endif if (!is_local(local)) { // the local address seems to be an external // internet address. Assume it is not behind a NAT throw std::runtime_error("local IP is not on a local network"); } m_disabled = false; // assume the router is located on the local // network as x.x.x.1 udp::endpoint nat_endpoint( address_v4((local.to_ulong() & 0xffffff00) | 1), 5351); if (nat_endpoint == m_nat_endpoint) return; // TODO: find a better way to figure out the router IP m_nat_endpoint = nat_endpoint; #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) m_log << "assuming router is at: " << m_nat_endpoint.address().to_string() << std::endl; #endif m_socket.open(udp::v4()); m_socket.bind(udp::endpoint(address_v4::any(), 0)); for (int i = 0; i < num_mappings; ++i) { if (m_mappings[i].local_port == 0) continue; refresh_mapping(i); } } catch (std::exception& e) { m_disabled = true; std::stringstream msg; msg << "NAT-PMP disabled: " << e.what(); #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) m_log << msg.str() << std::endl; #endif m_callback(0, 0, msg.str()); };