2021-04-06 17:23:13 +08:00
|
|
|
|
#ifndef MS_UTILS_HPP
|
2021-03-24 16:52:41 +08:00
|
|
|
|
#define MS_UTILS_HPP
|
|
|
|
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
#include <winsock2.h>
|
|
|
|
|
#include <ws2tcpip.h>
|
|
|
|
|
#include <Iphlpapi.h>
|
|
|
|
|
#pragma comment (lib, "Ws2_32.lib")
|
|
|
|
|
#pragma comment(lib,"Iphlpapi.lib")
|
|
|
|
|
#else
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <net/if.h>
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <netinet/tcp.h>
|
|
|
|
|
#endif // defined(_WIN32)
|
|
|
|
|
|
|
|
|
|
#include <algorithm>// std::transform(), std::find(), std::min(), std::max()
|
|
|
|
|
#include <cinttypes>// PRIu64, etc
|
|
|
|
|
#include <cmath>
|
|
|
|
|
#include <cstddef>// size_t
|
|
|
|
|
#include <cstdint>// uint8_t, etc
|
|
|
|
|
#include <cstring>// std::memcmp(), std::memcpy()
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <openssl/bio.h>
|
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
#include <openssl/x509.h>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
namespace Utils {
|
|
|
|
|
|
|
|
|
|
class Byte {
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* Getters below get value in Host Byte Order.
|
|
|
|
|
* Setters below set value in Network Byte Order.
|
|
|
|
|
*/
|
|
|
|
|
static uint8_t Get1Byte(const uint8_t *data, size_t i);
|
|
|
|
|
static uint16_t Get2Bytes(const uint8_t *data, size_t i);
|
|
|
|
|
static uint32_t Get3Bytes(const uint8_t *data, size_t i);
|
|
|
|
|
static uint32_t Get4Bytes(const uint8_t *data, size_t i);
|
|
|
|
|
static uint64_t Get8Bytes(const uint8_t *data, size_t i);
|
|
|
|
|
static void Set1Byte(uint8_t *data, size_t i, uint8_t value);
|
|
|
|
|
static void Set2Bytes(uint8_t *data, size_t i, uint16_t value);
|
|
|
|
|
static void Set3Bytes(uint8_t *data, size_t i, uint32_t value);
|
|
|
|
|
static void Set4Bytes(uint8_t *data, size_t i, uint32_t value);
|
|
|
|
|
static void Set8Bytes(uint8_t *data, size_t i, uint64_t value);
|
|
|
|
|
static uint16_t PadTo4Bytes(uint16_t size);
|
|
|
|
|
static uint32_t PadTo4Bytes(uint32_t size);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Inline static methods. */
|
|
|
|
|
|
|
|
|
|
inline uint8_t Byte::Get1Byte(const uint8_t *data, size_t i) { return data[i]; }
|
|
|
|
|
|
|
|
|
|
inline uint16_t Byte::Get2Bytes(const uint8_t *data, size_t i) {
|
|
|
|
|
return uint16_t{data[i + 1]} | uint16_t{data[i]} << 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline uint32_t Byte::Get3Bytes(const uint8_t *data, size_t i) {
|
|
|
|
|
return uint32_t{data[i + 2]} | uint32_t{data[i + 1]} << 8 | uint32_t{data[i]} << 16;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline uint32_t Byte::Get4Bytes(const uint8_t *data, size_t i) {
|
|
|
|
|
return uint32_t{data[i + 3]} | uint32_t{data[i + 2]} << 8 | uint32_t{data[i + 1]} << 16 |
|
|
|
|
|
uint32_t{data[i]} << 24;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline uint64_t Byte::Get8Bytes(const uint8_t *data, size_t i) {
|
|
|
|
|
return uint64_t{Byte::Get4Bytes(data, i)} << 32 | Byte::Get4Bytes(data, i + 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void Byte::Set1Byte(uint8_t *data, size_t i, uint8_t value) { data[i] = value; }
|
|
|
|
|
|
|
|
|
|
inline void Byte::Set2Bytes(uint8_t *data, size_t i, uint16_t value) {
|
|
|
|
|
data[i + 1] = static_cast<uint8_t>(value);
|
|
|
|
|
data[i] = static_cast<uint8_t>(value >> 8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void Byte::Set3Bytes(uint8_t *data, size_t i, uint32_t value) {
|
|
|
|
|
data[i + 2] = static_cast<uint8_t>(value);
|
|
|
|
|
data[i + 1] = static_cast<uint8_t>(value >> 8);
|
|
|
|
|
data[i] = static_cast<uint8_t>(value >> 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void Byte::Set4Bytes(uint8_t *data, size_t i, uint32_t value) {
|
|
|
|
|
data[i + 3] = static_cast<uint8_t>(value);
|
|
|
|
|
data[i + 2] = static_cast<uint8_t>(value >> 8);
|
|
|
|
|
data[i + 1] = static_cast<uint8_t>(value >> 16);
|
|
|
|
|
data[i] = static_cast<uint8_t>(value >> 24);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void Byte::Set8Bytes(uint8_t *data, size_t i, uint64_t value) {
|
|
|
|
|
data[i + 7] = static_cast<uint8_t>(value);
|
|
|
|
|
data[i + 6] = static_cast<uint8_t>(value >> 8);
|
|
|
|
|
data[i + 5] = static_cast<uint8_t>(value >> 16);
|
|
|
|
|
data[i + 4] = static_cast<uint8_t>(value >> 24);
|
|
|
|
|
data[i + 3] = static_cast<uint8_t>(value >> 32);
|
|
|
|
|
data[i + 2] = static_cast<uint8_t>(value >> 40);
|
|
|
|
|
data[i + 1] = static_cast<uint8_t>(value >> 48);
|
|
|
|
|
data[i] = static_cast<uint8_t>(value >> 56);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline uint16_t Byte::PadTo4Bytes(uint16_t size) {
|
|
|
|
|
// If size is not multiple of 32 bits then pad it.
|
|
|
|
|
if (size & 0x03)
|
|
|
|
|
return (size & 0xFFFC) + 4;
|
|
|
|
|
else
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}// namespace Utils
|
|
|
|
|
|
|
|
|
|
#endif
|