diff --git a/Netch.sln b/Netch.sln index 4b753461..ce26dd2d 100644 --- a/Netch.sln +++ b/Netch.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Redirector", "Redirector\Redirector.vcxproj", "{1676DEF3-FBE4-47D2-93A6-8F85EA2F5B74}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RouteHelper", "RouteHelper\RouteHelper.vcxproj", "{7374F7F4-1732-4DED-A603-8335F6704F10}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -26,6 +28,10 @@ Global {1676DEF3-FBE4-47D2-93A6-8F85EA2F5B74}.Debug|x64.Build.0 = Debug|x64 {1676DEF3-FBE4-47D2-93A6-8F85EA2F5B74}.Release|x64.ActiveCfg = Release|x64 {1676DEF3-FBE4-47D2-93A6-8F85EA2F5B74}.Release|x64.Build.0 = Release|x64 + {7374F7F4-1732-4DED-A603-8335F6704F10}.Debug|x64.ActiveCfg = Debug|x64 + {7374F7F4-1732-4DED-A603-8335F6704F10}.Debug|x64.Build.0 = Debug|x64 + {7374F7F4-1732-4DED-A603-8335F6704F10}.Release|x64.ActiveCfg = Release|x64 + {7374F7F4-1732-4DED-A603-8335F6704F10}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RouteHelper/.gitignore b/RouteHelper/.gitignore new file mode 100644 index 00000000..4d0789fe --- /dev/null +++ b/RouteHelper/.gitignore @@ -0,0 +1,3 @@ +/bin +/obj +/*.vcxproj.user diff --git a/RouteHelper/RouteHelper.cpp b/RouteHelper/RouteHelper.cpp new file mode 100644 index 00000000..6c2584e3 --- /dev/null +++ b/RouteHelper/RouteHelper.cpp @@ -0,0 +1,158 @@ +#define _WINSOCK_DEPRECATED_NO_WARNINGS + +#include +#include +#include +#include +#include +#include + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + UNREFERENCED_PARAMETER(hModule); + UNREFERENCED_PARAMETER(lpReserved); + UNREFERENCED_PARAMETER(ul_reason_for_call); + + return TRUE; +} + +BOOL make(PMIB_IPFORWARD_ROW2 rule, USHORT inet, const char* address, UINT8 cidr, const char* gateway, ULONG index, int metric) +{ + rule->InterfaceIndex = index; + rule->DestinationPrefix.PrefixLength = cidr; + + if (AF_INET == inet) + { + rule->DestinationPrefix.Prefix.Ipv4.sin_family = inet; + if (!inet_pton(inet, address, &rule->DestinationPrefix.Prefix.Ipv4.sin_addr)) + { + return FALSE; + } + + if (strlen(gateway)) + { + rule->NextHop.Ipv4.sin_family = inet; + if (!inet_pton(inet, gateway, &rule->NextHop.Ipv4.sin_addr)) + { + return FALSE; + } + } + } + else if (AF_INET6 == inet) + { + rule->DestinationPrefix.Prefix.Ipv6.sin6_family = inet; + if (!inet_pton(inet, address, &rule->DestinationPrefix.Prefix.Ipv6.sin6_addr)) + { + return FALSE; + } + + if (strlen(gateway)) + { + rule->NextHop.Ipv6.sin6_family = inet; + if (!inet_pton(inet, gateway, &rule->NextHop.Ipv6.sin6_addr)) + { + return FALSE; + } + } + } + + rule->ValidLifetime = 0xffffffff; + rule->PreferredLifetime = 0xffffffff; + rule->Metric = metric; + rule->Protocol = MIB_IPPROTO_NETMGMT; + return TRUE; +} + +extern "C" { + __declspec(dllexport) ULONG __cdecl ConvertLuidToIndex(ULONG64 id) + { + NET_LUID luid; + luid.Value = id; + + NET_IFINDEX index = 0; + if (NO_ERROR != ConvertInterfaceLuidToIndex(&luid, &index)) + { + return 0; + } + + return index; + } + + __declspec(dllexport) BOOL __cdecl CreateIPv4(const char* address, const char* netmask, ULONG index) + { + ULONG addr = inet_addr(address); + ULONG mask = inet_addr(netmask); + ULONG ctx = 0; + ULONG inst = 0; + + return (NO_ERROR == AddIPAddress(addr, mask, index, &ctx, &inst)) ? TRUE : FALSE; + } + + __declspec(dllexport) BOOL __cdecl CreateUnicastIP(USHORT inet, const char* address, UINT8 cidr, ULONG index) + { + MIB_UNICASTIPADDRESS_ROW addr; + InitializeUnicastIpAddressEntry(&addr); + + addr.InterfaceIndex = index; + addr.OnLinkPrefixLength = cidr; + + if (AF_INET == inet) + { + addr.Address.Ipv4.sin_family = inet; + if (!inet_pton(inet, address, &addr.Address.Ipv4.sin_addr)) + { + return FALSE; + } + } + else if (AF_INET6 == inet) + { + addr.Address.Ipv6.sin6_family = inet; + if (!inet_pton(inet, address, &addr.Address.Ipv6.sin6_addr)) + { + return FALSE; + } + } + else + { + return FALSE; + } + + return (NO_ERROR == CreateUnicastIpAddressEntry(&addr)) ? TRUE : FALSE; + } + + __declspec(dllexport) BOOL __cdecl RefreshIPTable(USHORT inet, ULONG index) + { + if (NO_ERROR != FlushIpPathTable(inet)) + { + return FALSE; + } + + return (NO_ERROR == FlushIpNetTable2(inet, index)) ? TRUE : FALSE; + } + + __declspec(dllexport) BOOL __cdecl CreateRoute(USHORT inet, const char* address, UINT8 cidr, const char* gateway, ULONG index, int metric = 1) + { + MIB_IPFORWARD_ROW2 rule; + InitializeIpForwardEntry(&rule); + + if (!make(&rule, inet, address, cidr, gateway, index, metric)) + { + return FALSE; + } + + return (NO_ERROR == CreateIpForwardEntry2(&rule)) ? TRUE : FALSE; + } + + __declspec(dllexport) BOOL __cdecl DeleteRoute(USHORT inet, const char* address, UINT8 cidr, const char* gateway, ULONG index, int metric = 1) + { + MIB_IPFORWARD_ROW2 rule; + InitializeIpForwardEntry(&rule); + + if (!make(&rule, inet, address, cidr, gateway, index, metric)) + { + return FALSE; + } + + return (NO_ERROR == DeleteIpForwardEntry2(&rule)) ? TRUE : FALSE; + } +} diff --git a/RouteHelper/RouteHelper.vcxproj b/RouteHelper/RouteHelper.vcxproj new file mode 100644 index 00000000..11d86917 --- /dev/null +++ b/RouteHelper/RouteHelper.vcxproj @@ -0,0 +1,96 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7374f7f4-1732-4ded-a603-8335f6704f10} + RouteHelper + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + true + $(ProjectDir)bin\ + $(ProjectDir)obj\ + + + false + $(ProjectDir)bin\ + $(ProjectDir)obj\ + + + + Level4 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + stdc17 + + + Console + true + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + + + + + Level4 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + stdc17 + + + Console + true + true + true + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + + + + + + + + + \ No newline at end of file diff --git a/RouteHelper/RouteHelper.vcxproj.filters b/RouteHelper/RouteHelper.vcxproj.filters new file mode 100644 index 00000000..e15645d2 --- /dev/null +++ b/RouteHelper/RouteHelper.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source + + + \ No newline at end of file