Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#pragma once
9
10#include <AK/IPv4Address.h>
11#include <arpa/inet.h>
12#include <netinet/in.h>
13#include <string.h>
14#include <sys/socket.h>
15#include <sys/un.h>
16
17namespace Core {
18
19class SocketAddress {
20public:
21 enum class Type {
22 Invalid,
23 IPv4,
24 Local
25 };
26
27 SocketAddress() = default;
28 SocketAddress(IPv4Address const& address)
29 : m_type(Type::IPv4)
30 , m_ipv4_address(address)
31 {
32 }
33
34 SocketAddress(IPv4Address const& address, u16 port)
35 : m_type(Type::IPv4)
36 , m_ipv4_address(address)
37 , m_port(port)
38 {
39 }
40
41 static SocketAddress local(DeprecatedString const& address)
42 {
43 SocketAddress addr;
44 addr.m_type = Type::Local;
45 addr.m_local_address = address;
46 return addr;
47 }
48
49 Type type() const { return m_type; }
50 bool is_valid() const { return m_type != Type::Invalid; }
51 IPv4Address ipv4_address() const { return m_ipv4_address; }
52 u16 port() const { return m_port; }
53
54 DeprecatedString to_deprecated_string() const
55 {
56 switch (m_type) {
57 case Type::IPv4:
58 return DeprecatedString::formatted("{}:{}", m_ipv4_address, m_port);
59 case Type::Local:
60 return m_local_address;
61 default:
62 return "[SocketAddress]";
63 }
64 }
65
66 Optional<sockaddr_un> to_sockaddr_un() const
67 {
68 VERIFY(type() == Type::Local);
69 sockaddr_un address;
70 address.sun_family = AF_LOCAL;
71 bool fits = m_local_address.copy_characters_to_buffer(address.sun_path, sizeof(address.sun_path));
72 if (!fits)
73 return {};
74 return address;
75 }
76
77 sockaddr_in to_sockaddr_in() const
78 {
79 VERIFY(type() == Type::IPv4);
80 sockaddr_in address {};
81 address.sin_family = AF_INET;
82 address.sin_addr.s_addr = m_ipv4_address.to_in_addr_t();
83 address.sin_port = htons(m_port);
84 return address;
85 }
86
87private:
88 Type m_type { Type::Invalid };
89 IPv4Address m_ipv4_address;
90 u16 m_port { 0 };
91 DeprecatedString m_local_address;
92};
93
94}
95
96template<>
97struct AK::Formatter<Core::SocketAddress> : Formatter<DeprecatedString> {
98 ErrorOr<void> format(FormatBuilder& builder, Core::SocketAddress const& value)
99 {
100 return Formatter<DeprecatedString>::format(builder, value.to_deprecated_string());
101 }
102};