Network.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Copyright 2014 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <optional>
  6. #include <string>
  7. #include <string_view>
  8. #include <type_traits>
  9. #include <vector>
  10. #include "Common/CommonTypes.h"
  11. struct sockaddr_in;
  12. namespace Common
  13. {
  14. enum class MACConsumer
  15. {
  16. BBA,
  17. IOS
  18. };
  19. enum
  20. {
  21. BBA_HARDWARE_TYPE = 1,
  22. MAC_ADDRESS_SIZE = 6,
  23. IPV4_HEADER_TYPE = 8
  24. };
  25. enum DHCPConst
  26. {
  27. MESSAGE_QUERY = 1,
  28. MESSAGE_REPLY = 2
  29. };
  30. using MACAddress = std::array<u8, MAC_ADDRESS_SIZE>;
  31. constexpr std::size_t IPV4_ADDR_LEN = 4;
  32. using IPAddress = std::array<u8, IPV4_ADDR_LEN>;
  33. constexpr IPAddress IP_ADDR_ANY = {0, 0, 0, 0};
  34. constexpr IPAddress IP_ADDR_BROADCAST = {255, 255, 255, 255};
  35. constexpr IPAddress IP_ADDR_SSDP = {239, 255, 255, 250};
  36. constexpr u16 SSDP_PORT = 1900;
  37. constexpr u16 IPV4_ETHERTYPE = 0x800;
  38. constexpr u16 ARP_ETHERTYPE = 0x806;
  39. struct EthernetHeader
  40. {
  41. EthernetHeader();
  42. explicit EthernetHeader(u16 ether_type);
  43. EthernetHeader(const MACAddress& dest, const MACAddress& src, u16 ether_type);
  44. u16 Size() const;
  45. static constexpr std::size_t SIZE = 14;
  46. MACAddress destination = {};
  47. MACAddress source = {};
  48. u16 ethertype = 0;
  49. };
  50. static_assert(sizeof(EthernetHeader) == EthernetHeader::SIZE);
  51. static_assert(std::is_standard_layout_v<EthernetHeader>);
  52. struct IPv4Header
  53. {
  54. IPv4Header();
  55. IPv4Header(u16 data_size, u8 ip_proto, const sockaddr_in& from, const sockaddr_in& to);
  56. u16 Size() const;
  57. u8 DefinedSize() const;
  58. static constexpr std::size_t SIZE = 20;
  59. u8 version_ihl = 0;
  60. u8 dscp_esn = 0;
  61. u16 total_len = 0;
  62. u16 identification = 0;
  63. u16 flags_fragment_offset = 0;
  64. u8 ttl = 0;
  65. u8 protocol = 0;
  66. u16 header_checksum = 0;
  67. IPAddress source_addr{};
  68. IPAddress destination_addr{};
  69. };
  70. static_assert(sizeof(IPv4Header) == IPv4Header::SIZE);
  71. static_assert(std::is_standard_layout_v<IPv4Header>);
  72. struct TCPHeader
  73. {
  74. TCPHeader();
  75. TCPHeader(const sockaddr_in& from, const sockaddr_in& to, u32 seq, const u8* data, u16 length);
  76. TCPHeader(const sockaddr_in& from, const sockaddr_in& to, u32 seq, u32 ack, u16 flags);
  77. u8 GetHeaderSize() const;
  78. u16 Size() const;
  79. u8 IPProto() const;
  80. static constexpr std::size_t SIZE = 20;
  81. u16 source_port = 0;
  82. u16 destination_port = 0;
  83. u32 sequence_number = 0;
  84. u32 acknowledgement_number = 0;
  85. u16 properties = 0;
  86. u16 window_size = 0;
  87. u16 checksum = 0;
  88. u16 urgent_pointer = 0;
  89. };
  90. static_assert(sizeof(TCPHeader) == TCPHeader::SIZE);
  91. static_assert(std::is_standard_layout_v<TCPHeader>);
  92. struct UDPHeader
  93. {
  94. UDPHeader();
  95. UDPHeader(const sockaddr_in& from, const sockaddr_in& to, u16 data_length);
  96. u16 Size() const;
  97. u8 IPProto() const;
  98. static constexpr std::size_t SIZE = 8;
  99. u16 source_port = 0;
  100. u16 destination_port = 0;
  101. u16 length = 0;
  102. u16 checksum = 0;
  103. };
  104. static_assert(sizeof(UDPHeader) == UDPHeader::SIZE);
  105. static_assert(std::is_standard_layout_v<UDPHeader>);
  106. #pragma pack(push, 1)
  107. struct ARPHeader
  108. {
  109. ARPHeader();
  110. ARPHeader(u32 from_ip, const MACAddress& from_mac, u32 to_ip, const MACAddress& to_mac);
  111. u16 Size() const;
  112. static constexpr std::size_t SIZE = 28;
  113. u16 hardware_type = 0;
  114. u16 protocol_type = 0;
  115. u8 hardware_size = 0;
  116. u8 protocol_size = 0;
  117. u16 opcode = 0;
  118. MACAddress sender_address{};
  119. u32 sender_ip = 0;
  120. MACAddress targer_address{};
  121. u32 target_ip = 0;
  122. };
  123. static_assert(sizeof(ARPHeader) == ARPHeader::SIZE);
  124. #pragma pack(pop)
  125. struct DHCPBody
  126. {
  127. DHCPBody();
  128. DHCPBody(u32 transaction, const MACAddress& client_address, u32 new_ip, u32 serv_ip);
  129. static constexpr std::size_t SIZE = 240;
  130. u8 message_type = 0;
  131. u8 hardware_type = 0;
  132. u8 hardware_addr = 0;
  133. u8 hops = 0;
  134. u32 transaction_id = 0;
  135. u16 seconds = 0;
  136. u16 boot_flag = 0;
  137. u32 client_ip = 0;
  138. u32 your_ip = 0;
  139. u32 server_ip = 0;
  140. u32 relay_ip = 0;
  141. MACAddress client_mac{};
  142. unsigned char padding[10]{};
  143. unsigned char hostname[0x40]{};
  144. unsigned char boot_file[0x80]{};
  145. u8 magic_cookie[4] = {0x63, 0x82, 0x53, 0x63};
  146. };
  147. static_assert(sizeof(DHCPBody) == DHCPBody::SIZE);
  148. struct DHCPPacket
  149. {
  150. DHCPPacket();
  151. DHCPPacket(const std::vector<u8>& data);
  152. void AddOption(u8 fnc, const std::vector<u8>& params);
  153. std::vector<u8> Build() const;
  154. DHCPBody body;
  155. std::vector<std::vector<u8>> options;
  156. };
  157. // The compiler might add 2 bytes after EthernetHeader to enforce 16-bytes alignment
  158. #pragma pack(push, 1)
  159. struct ARPPacket
  160. {
  161. ARPPacket();
  162. ARPPacket(const MACAddress& destination, const MACAddress& source);
  163. std::vector<u8> Build() const;
  164. u16 Size() const;
  165. EthernetHeader eth_header;
  166. ARPHeader arp_header;
  167. static constexpr std::size_t SIZE = EthernetHeader::SIZE + ARPHeader::SIZE;
  168. };
  169. static_assert(sizeof(ARPPacket) == ARPPacket::SIZE);
  170. #pragma pack(pop)
  171. struct TCPPacket
  172. {
  173. TCPPacket();
  174. TCPPacket(const MACAddress& destination, const MACAddress& source, const sockaddr_in& from,
  175. const sockaddr_in& to, u32 seq, u32 ack, u16 flags);
  176. std::vector<u8> Build() const;
  177. u16 Size() const;
  178. EthernetHeader eth_header;
  179. IPv4Header ip_header;
  180. TCPHeader tcp_header;
  181. std::vector<u8> ipv4_options;
  182. std::vector<u8> tcp_options;
  183. std::vector<u8> data;
  184. static constexpr std::size_t MIN_SIZE = EthernetHeader::SIZE + IPv4Header::SIZE + TCPHeader::SIZE;
  185. };
  186. struct UDPPacket
  187. {
  188. UDPPacket();
  189. UDPPacket(const MACAddress& destination, const MACAddress& source, const sockaddr_in& from,
  190. const sockaddr_in& to, const std::vector<u8>& payload);
  191. std::vector<u8> Build() const;
  192. u16 Size() const;
  193. EthernetHeader eth_header;
  194. IPv4Header ip_header;
  195. UDPHeader udp_header;
  196. std::vector<u8> ipv4_options;
  197. std::vector<u8> data;
  198. static constexpr std::size_t MIN_SIZE = EthernetHeader::SIZE + IPv4Header::SIZE + UDPHeader::SIZE;
  199. };
  200. class PacketView
  201. {
  202. public:
  203. PacketView(const u8* ptr, std::size_t size);
  204. std::optional<u16> GetEtherType() const;
  205. std::optional<ARPPacket> GetARPPacket() const;
  206. std::optional<u8> GetIPProto() const;
  207. std::optional<TCPPacket> GetTCPPacket() const;
  208. std::optional<UDPPacket> GetUDPPacket() const;
  209. private:
  210. const u8* m_ptr;
  211. std::size_t m_size;
  212. };
  213. struct NetworkErrorState
  214. {
  215. int error;
  216. #ifdef _WIN32
  217. int wsa_error;
  218. #endif
  219. };
  220. MACAddress GenerateMacAddress(MACConsumer type);
  221. std::string MacAddressToString(const MACAddress& mac);
  222. std::optional<MACAddress> StringToMacAddress(std::string_view mac_string);
  223. u16 ComputeNetworkChecksum(const void* data, u16 length, u32 initial_value = 0);
  224. u16 ComputeTCPNetworkChecksum(const IPAddress& from, const IPAddress& to, const void* data,
  225. u16 length, u8 protocol);
  226. NetworkErrorState SaveNetworkErrorState();
  227. void RestoreNetworkErrorState(const NetworkErrorState& state);
  228. const char* DecodeNetworkError(s32 error_code);
  229. const char* StrNetworkError();
  230. } // namespace Common