抛弃GdCpp*.dll/pdb历史重新建库。libhv和Sqlite的dll保留
This commit is contained in:
329
include/IpHelper.h
Normal file
329
include/IpHelper.h
Normal file
@@ -0,0 +1,329 @@
|
||||
#pragma once
|
||||
|
||||
#include "GdCPP_Exports.h"
|
||||
#include "spdlog/fmt/fmt.h"
|
||||
#include "spdlog/fmt/xchar.h"
|
||||
#include "StringHelper.h"
|
||||
#include <WS2tcpip.h>
|
||||
#include <vector>
|
||||
#include <ifdef.h> //for IF_OPER_STATUS
|
||||
|
||||
/// @brief ipv4地址类,在sockaddr_in基础上增加字符与ip互转的函数
|
||||
struct GDCPP_API ipv4addr
|
||||
: public sockaddr_in
|
||||
{
|
||||
ipv4addr()
|
||||
{
|
||||
zero();
|
||||
}
|
||||
// 复制构造函数
|
||||
ipv4addr(const ipv4addr &src)
|
||||
{
|
||||
memcpy(this, &src, sizeof(sockaddr_in));
|
||||
}
|
||||
|
||||
ipv4addr(const sockaddr_in* src)
|
||||
{
|
||||
if (src) {
|
||||
if (src->sin_family == AF_INET) { //确认src是ipv4地址
|
||||
memcpy(this, src, sizeof(sockaddr_in));
|
||||
return;
|
||||
}
|
||||
}
|
||||
zero();
|
||||
}
|
||||
|
||||
ipv4addr(const sockaddr* src)
|
||||
{
|
||||
if (src) {
|
||||
if (src->sa_family == AF_INET) { //确认src是ipv4地址
|
||||
memcpy(this, src, sizeof(sockaddr_in));
|
||||
return;
|
||||
}
|
||||
}
|
||||
zero();
|
||||
}
|
||||
|
||||
ipv4addr(uint32_t ip, uint16_t port=0)
|
||||
{
|
||||
sin_family = AF_INET;
|
||||
sin_addr.S_un.S_addr = ip;
|
||||
sin_port = htons(port);
|
||||
}
|
||||
ipv4addr(const char* ip, uint16_t port = 0)
|
||||
{
|
||||
sin_family = AF_INET;
|
||||
inet_pton(AF_INET, ip, &sin_addr);
|
||||
sin_port = htons(port);
|
||||
}
|
||||
|
||||
ipv4addr(const std::string& ip, uint16_t port = 0)
|
||||
{
|
||||
sin_family = AF_INET;
|
||||
inet_pton(AF_INET, ip.c_str(), &sin_addr);
|
||||
sin_port = htons(port);
|
||||
}
|
||||
|
||||
/// @brief 设置ipv4地址
|
||||
/// @param ip 192.168.0.1 32位数值是0x0100A8C0,字节循序是C0 A8 00 01
|
||||
/// @param port
|
||||
void set(uint32_t ip, uint16_t port = 0)
|
||||
{
|
||||
sin_family = AF_INET;
|
||||
sin_addr.S_un.S_addr = ip;
|
||||
sin_port = htons(port);
|
||||
}
|
||||
void set(const char* ip, uint16_t port = 0)
|
||||
{
|
||||
sin_family = AF_INET;
|
||||
inet_pton(AF_INET, ip, &sin_addr);
|
||||
sin_port = htons(port);
|
||||
}
|
||||
|
||||
void set(const std::string& ip, uint16_t port = 0)
|
||||
{
|
||||
sin_family = AF_INET;
|
||||
inet_pton(AF_INET, ip.c_str(), &sin_addr);
|
||||
sin_port = htons(port);
|
||||
}
|
||||
|
||||
// 仅设置端口
|
||||
void setPort(uint16_t port)
|
||||
{
|
||||
sin_port = htons(port);
|
||||
}
|
||||
//改成广播地址
|
||||
void toBoradcast() {
|
||||
sin_addr.S_un.S_addr &= 0x00FFFFFF;
|
||||
sin_addr.S_un.S_addr |= 0xFF000000;
|
||||
}
|
||||
|
||||
void toBoradcast(ipv4addr &dst) {
|
||||
dst = *this;
|
||||
dst.toBoradcast();
|
||||
}
|
||||
|
||||
void zero()
|
||||
{
|
||||
sin_family = AF_INET;
|
||||
sin_port = 0;
|
||||
sin_addr.s_addr = 0;
|
||||
for (auto& i : sin_zero) i = 0;
|
||||
}
|
||||
|
||||
uint32_t ip() const { return sin_addr.s_addr; }
|
||||
uint32_t port() const { return htons(sin_port); }
|
||||
|
||||
std::string ipStr() const
|
||||
{
|
||||
const auto& b = sin_addr.S_un.S_un_b;
|
||||
return fmt::format("{:d}.{:d}.{:d}.{:d}", b.s_b1, b.s_b2, b.s_b3, b.s_b4);
|
||||
}
|
||||
|
||||
std::wstring ipWStr() const
|
||||
{
|
||||
const auto& b = sin_addr.S_un.S_un_b;
|
||||
return fmt::format(L"{:d}.{:d}.{:d}.{:d}", b.s_b1, b.s_b2, b.s_b3, b.s_b4);
|
||||
}
|
||||
|
||||
std::string addrStr() const
|
||||
{
|
||||
const auto& b = sin_addr.S_un.S_un_b;
|
||||
return fmt::format("{:d}.{:d}.{:d}.{:d}:{}", b.s_b1, b.s_b2, b.s_b3, b.s_b4, htons(sin_port));
|
||||
}
|
||||
|
||||
std::wstring addrWStr() const
|
||||
{
|
||||
const auto& b = sin_addr.S_un.S_un_b;
|
||||
return fmt::format(L"{:d}.{:d}.{:d}.{:d}:{}", b.s_b1, b.s_b2, b.s_b3, b.s_b4, htons(sin_port));
|
||||
}
|
||||
|
||||
operator const sockaddr* () const {
|
||||
return (const sockaddr*)this;
|
||||
}
|
||||
|
||||
operator sockaddr* () {
|
||||
return (sockaddr*)this;
|
||||
}
|
||||
|
||||
bool operator == (const ipv4addr & src) const {
|
||||
return (src.sin_family== AF_INET && sin_port == src.sin_port && sin_addr.s_addr == src.sin_addr.s_addr);
|
||||
}
|
||||
bool operator != (const ipv4addr& src) const {
|
||||
return !(*this == src);
|
||||
}
|
||||
bool operator < (const ipv4addr& src) const {
|
||||
return (sin_addr.s_addr < src.sin_addr.s_addr) || (sin_addr.s_addr == src.sin_addr.s_addr && sin_port < src.sin_port);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct GDCPP_API sAdapter
|
||||
{
|
||||
IF_OPER_STATUS OperStatus; // 常见IfOperStatusUp,IfOperStatusDown
|
||||
std::wstring Description; // 例:Realtek PCIe GbE Family Controller
|
||||
std::wstring FriendlyName; // 例:WLAN,以太网
|
||||
ipv4addr IpAddr;
|
||||
|
||||
sAdapter(const wchar_t* desc = nullptr, const wchar_t* name = nullptr)
|
||||
: Description(desc == nullptr ? L"" : desc)
|
||||
, FriendlyName(name == nullptr ? L"" : name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
sAdapter(const sAdapter& s)
|
||||
: OperStatus(s.OperStatus)
|
||||
, Description(s.Description)
|
||||
, FriendlyName(s.FriendlyName)
|
||||
, IpAddr(s.IpAddr)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GDCPP_API CAdapterList
|
||||
{
|
||||
public:
|
||||
CAdapterList() = default;
|
||||
|
||||
// 排除ExcludedNetAdpter列举的网卡(蓝牙、vmware等)
|
||||
static std::vector<std::wstring> gExcludedList;
|
||||
|
||||
enum {
|
||||
// 排除Software Loopback Interface 1
|
||||
Exclude_Loopback = 0x00000001,
|
||||
// 排除vmware网卡
|
||||
Exclude_Vmware = 0x00000002,
|
||||
|
||||
// 排除蓝牙网卡
|
||||
Exclude_BlueTeeth = 0x00000004,
|
||||
|
||||
// 排除Microsoft Wi-Fi Direct Virtual Adapter
|
||||
Exclude_MicrosoftWifi = 0x00000008,
|
||||
|
||||
//
|
||||
Exclude_ZeroTier = 0x00000010,
|
||||
|
||||
};
|
||||
|
||||
// 设置排除列表
|
||||
static void _SetExcludedList(std::vector<std::wstring>&list, uint32_t flag)
|
||||
{
|
||||
list.clear();
|
||||
|
||||
if (flag & Exclude_BlueTeeth) {
|
||||
list.push_back(L"Bluetooth Device");
|
||||
}
|
||||
|
||||
if (flag & Exclude_MicrosoftWifi) {
|
||||
list.push_back(L"Microsoft Wi-Fi");
|
||||
}
|
||||
|
||||
|
||||
if (flag & Exclude_Vmware) {
|
||||
list.push_back(L"VMware Virtual");
|
||||
}
|
||||
|
||||
if (flag & Exclude_Loopback) {
|
||||
list.push_back(L"Software Loopback");
|
||||
}
|
||||
if (flag & Exclude_Loopback) {
|
||||
list.push_back(L"ZeroTier");
|
||||
}
|
||||
}
|
||||
|
||||
// 设置全局排除列表
|
||||
static void SetExcludedList(uint32_t flag = Exclude_Loopback | Exclude_Vmware | Exclude_BlueTeeth | Exclude_MicrosoftWifi)
|
||||
{
|
||||
_SetExcludedList(gExcludedList, flag);
|
||||
}
|
||||
|
||||
/// 枚举网卡列表
|
||||
/// @param exclude_flag 在全局排除列表的基础上额外要排除的网卡
|
||||
void Enum(uint32_t exclude_flag);
|
||||
|
||||
/// @brief
|
||||
/// @param box
|
||||
/// @param def
|
||||
//void toComboBox(CComboBox* box, const std::wstring& def);
|
||||
|
||||
const sAdapter* FindIp(uint32_t ip)
|
||||
{
|
||||
for (auto& i : d) {
|
||||
if (i.IpAddr.ip() == ip) {
|
||||
return &i;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const sAdapter* FindName(const std::wstring &name)
|
||||
{
|
||||
for (auto& i : d) {
|
||||
if (i.FriendlyName == name) {
|
||||
return &i;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const sAdapter* FindName(const std::string& name)
|
||||
{
|
||||
auto n = utf8_16(name);
|
||||
for (auto& i : d) {
|
||||
if (i.FriendlyName == n) {
|
||||
return &i;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sAdapter* operator [](uint32_t index) {
|
||||
if (index >= d.size()) return nullptr;
|
||||
return &d[index];
|
||||
}
|
||||
|
||||
bool isUp(uint32_t index) {
|
||||
if (index >= d.size()) return false;
|
||||
return (d[index].OperStatus == IfOperStatusUp);
|
||||
}
|
||||
|
||||
uint32_t size() const { return uint32_t(d.size()); }
|
||||
|
||||
template<typename Func>
|
||||
void forEachAdapter(Func&& func) const {
|
||||
// 使用 const auto& 确保只读访问
|
||||
for (const auto& adapter : d) {
|
||||
func(adapter); // 调用传入的函数,传入 const sAdapter&
|
||||
}
|
||||
}
|
||||
//protected:
|
||||
std::vector<sAdapter> d;
|
||||
};
|
||||
|
||||
|
||||
GDCPP_API int getIPFromHostname(const char* hostname, std::vector<ipv4addr>& foundIp);
|
||||
#ifdef _AFXDLL
|
||||
class CComboBox;
|
||||
static inline void toComboBox(CAdapterList& list, CComboBox* box, const std::wstring& def)
|
||||
{
|
||||
if (box == nullptr) return;
|
||||
|
||||
for (int i = 0; i < list.d.size(); i++) {
|
||||
const auto& b = list.d[i].IpAddr.sin_addr.S_un.S_un_b;
|
||||
|
||||
auto str = fmt::format(L"{}, {:03d}.{:03d}.{:03d}.{:03d}, {}"
|
||||
, list.d[i].OperStatus == IfOperStatusUp ? L"已连接" : L"未连接"
|
||||
, b.s_b1, b.s_b2, b.s_b3, b.s_b4
|
||||
, list.d[i].FriendlyName);
|
||||
|
||||
auto index = box->AddString(str.c_str());
|
||||
box->SetItemData(index, i);
|
||||
if (list.d[i].FriendlyName == def) {
|
||||
box->SetCurSel(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user