winws: NLM filter

This commit is contained in:
bol-van 2024-07-12 15:13:18 +03:00
parent 5a6dcb658b
commit 7e2ed880dc
10 changed files with 282 additions and 22 deletions

Binary file not shown.

View File

@ -50,6 +50,8 @@ Task of `iptables` is done inside `winws` through `windivert` filters. `Windiver
--wf-raw=<filter>|@<filename> ; raw windivert filter string or filename --wf-raw=<filter>|@<filename> ; raw windivert filter string or filename
--wf-save=<filename> ; save windivert filter string to a file and exit --wf-save=<filename> ; save windivert filter string to a file and exit
--ssid-filter=ssid1[,ssid2,ssid3,...] ; enable winws only if any of specified wifi SSIDs connected --ssid-filter=ssid1[,ssid2,ssid3,...] ; enable winws only if any of specified wifi SSIDs connected
--nlm-filter=net1[,net2,net3,...] ; enable winws only if any of specified NLM network is connected. names and GUIDs are accepted.
--nlm-list[=all] ; list Network List Manager (NLM) networks. connected only or all.
``` ```
`--wf-l3`, `--wf-tcp`, `--wf-udp` can take multiple comma separated arguments. `--wf-l3`, `--wf-tcp`, `--wf-udp` can take multiple comma separated arguments.
@ -64,6 +66,10 @@ Multiple `winws` processes are allowed. However, it's discouraged to intersect t
SSID names must be written in the same case as the system sees them. This option does not analyze routing and does not detect where traffic actually goes. SSID names must be written in the same case as the system sees them. This option does not analyze routing and does not detect where traffic actually goes.
If multiple connections are available, the only thing that triggers `winws` operation is wifi connection presence. That's why it's a good idea to add also `--wf-iface` filter to not break ethernet, for example. If multiple connections are available, the only thing that triggers `winws` operation is wifi connection presence. That's why it's a good idea to add also `--wf-iface` filter to not break ethernet, for example.
`--nlm-filter` is like `--ssid-filter` but works with names or GUIDs from Network List Manager. NLM names are those you see in Control Panel "Network and Sharing Center".
NLM networks are adapter independent. Usually MAC address of the default router is used to distinugish networks. NLM works with any type of adapters : ethernet, wifi, vpn and others.
That's why NLM is more universal than `ssid-filter`.
`Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`. `Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`.
That's why exists separate standalone version in `binaries/win64/zapret-tpws`. That's why exists separate standalone version in `binaries/win64/zapret-tpws`.
`Cygwin` is required for `blockcheck.sh` support but `winws` itself can be run standalone without cygwin. `Cygwin` is required for `blockcheck.sh` support but `winws` itself can be run standalone without cygwin.

View File

@ -56,7 +56,8 @@ https://learn.microsoft.com/en-us/security-updates/SecurityAdvisories/2015/30339
--wf-raw=<filter>|@<filename> ; задать напрямую фильтр windivert из параметра или из файла. имени файла предшествует символ @. --wf-raw=<filter>|@<filename> ; задать напрямую фильтр windivert из параметра или из файла. имени файла предшествует символ @.
--wf-save=<filename> ; сохранить сконструированный фильтр windivert в файл для последующей правки вручную --wf-save=<filename> ; сохранить сконструированный фильтр windivert в файл для последующей правки вручную
--ssid-filter=ssid1[,ssid2,ssid3,...] ; включать winws только когда подключена любая из указанных wifi сетей --ssid-filter=ssid1[,ssid2,ssid3,...] ; включать winws только когда подключена любая из указанных wifi сетей
--nlm-filter=net1[,net2,net3,...] ; включать winws только когда подключена любая из указанных сетей NLM
--nlm-list[=all] ; вывести список сетей NLM. по умолчанию только подключенных, all - всех.
Параметры --wf-l3, --wf-tcp, --wf-udp могут брать несколько значений через запятую. Параметры --wf-l3, --wf-tcp, --wf-udp могут брать несколько значений через запятую.
Номера интерфейсов можно узнать так : netsh int ip show int. Номера интерфейсов можно узнать так : netsh int ip show int.
@ -80,6 +81,15 @@ winws включается. Это нужно, чтобы можно было п
И это может сломать дурение на ethernet. Поэтому полезно так же будет добавить фильтр --wf-iface на индекс интерфейса wifi адаптера, И это может сломать дурение на ethernet. Поэтому полезно так же будет добавить фильтр --wf-iface на индекс интерфейса wifi адаптера,
чтобы не трогать другой трафик. чтобы не трогать другой трафик.
--nlm-filter аналогичен --ssid-filter, но работает с именами или GUIDами сетей Network List Manager (NLM).
Это те сети, которые вы видите в панели управления в разделе "Центр управления сетями и общим доступом".
Под сетью подразумевается не конкретный адаптер, а именно сетевое окружение конкретного подключения.
Обычно проверяется mac адрес шлюза. К сети можно подключиться через любой адаптер, и она останется той же самой.
Если подключиться, допустим, к разными роутерам по кабелю, то будут разные сети.
А если к одному роутеру через 2 разных сетевых карточки на том же компе - будет одна сеть.
NLM абстрагирует типы сетевых адаптеров. Он работает как с wifi, так и с ethernet и любыми другими.
Поэтому это более универсальный метод, чем ssid фильтр.
Если в путях присутствуют национальные символы, то при вызове winws из cmd или bat кодировку нужно использовать OEM. Если в путях присутствуют национальные символы, то при вызове winws из cmd или bat кодировку нужно использовать OEM.
Для русского языка это 866. Пути с пробелами нужно брать в кавычки. Для русского языка это 866. Пути с пробелами нужно брать в кавычки.

View File

@ -5,7 +5,7 @@ CFLAGS_MAC = -mmacosx-version-min=10.8
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz
LIBS_BSD = -lz LIBS_BSD = -lz
LIBS_CYGWIN = -lz -Lwindivert -lwindivert -lwlanapi LIBS_CYGWIN = -lz -Lwindivert -lwindivert -lwlanapi -lole32 -loleaut32 -luuid
SRC_FILES = *.c crypto/*.c SRC_FILES = *.c crypto/*.c
all: nfqws all: nfqws

View File

@ -16,6 +16,7 @@
#ifdef __CYGWIN__ #ifdef __CYGWIN__
#include <wlanapi.h> #include <wlanapi.h>
#include <netlistmgr.h>
#endif #endif
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment) uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment)
@ -963,10 +964,204 @@ void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_fac
static HANDLE w_filter = NULL; static HANDLE w_filter = NULL;
static OVERLAPPED ovl = { .hEvent = NULL }; static OVERLAPPED ovl = { .hEvent = NULL };
static const struct str_list_head *wlan_filter_ssid = NULL; static const struct str_list_head *wlan_filter_ssid = NULL;
static DWORD wlan_filter_tick=0; static const struct str_list_head *nlm_filter_net = NULL;
static DWORD logical_net_filter_tick=0;
uint32_t w_win32_error=0; uint32_t w_win32_error=0;
INetworkListManager* pNetworkListManager=NULL;
bool wlan_filter_match(const struct str_list_head *ssid_list) static void guid2str(const GUID *guid, char *str)
{
snprintf(str,37, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
}
static bool str2guid(const char* str, GUID *guid)
{
unsigned int u[11],k;
if (11 != sscanf(str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", u+0, u+1, u+2, u+3, u+4, u+5, u+6, u+7, u+8, u+9, u+10))
return false;
guid->Data1 = u[0];
if ((u[1] & 0xFFFF0000) || (u[2] & 0xFFFF0000)) return false;
guid->Data2 = (USHORT)u[1];
guid->Data3 = (USHORT)u[2];
for (k = 0; k < 8; k++)
{
if (u[k+3] & 0xFFFFFF00) return false;
guid->Data4[k] = (UCHAR)u[k+3];
}
return true;
}
bool win_dark_init(const struct str_list_head *ssid_filter, const struct str_list_head *nlm_filter)
{
win_dark_deinit();
wlan_filter_ssid = LIST_EMPTY(ssid_filter) ? NULL : ssid_filter;
nlm_filter_net = LIST_EMPTY(nlm_filter) ? NULL : nlm_filter;
if (nlm_filter_net)
{
if (SUCCEEDED(w_win32_error = CoInitialize(NULL)))
{
if (FAILED(w_win32_error = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, &IID_INetworkListManager, (LPVOID*)&pNetworkListManager)))
{
win_dark_deinit();
return false;
}
}
}
return true;
}
bool win_dark_deinit(void)
{
if (pNetworkListManager)
{
pNetworkListManager->lpVtbl->Release(pNetworkListManager);
pNetworkListManager = NULL;
}
if (nlm_filter_net) CoUninitialize();
wlan_filter_ssid = nlm_filter_net = NULL;
}
bool nlm_list(bool bAll)
{
bool bRet = true;
if (SUCCEEDED(w_win32_error = CoInitialize(NULL)))
{
INetworkListManager* pNetworkListManager;
if (SUCCEEDED(w_win32_error = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, &IID_INetworkListManager, (LPVOID*)&pNetworkListManager)))
{
IEnumNetworks* pEnum;
if (SUCCEEDED(w_win32_error = pNetworkListManager->lpVtbl->GetNetworks(pNetworkListManager, NLM_ENUM_NETWORK_ALL, &pEnum)))
{
INetwork* pNet;
VARIANT_BOOL bIsConnected, bIsConnectedInet;
GUID idNet;
BSTR bstrName;
char Name[128];
int connected;
for (connected = 1; connected >= !bAll; connected--)
{
for (;;)
{
if (FAILED(w_win32_error = pEnum->lpVtbl->Next(pEnum, 1, &pNet, NULL)))
{
bRet = false;
break;
}
if (!pNet) break;
if (SUCCEEDED(w_win32_error = pNet->lpVtbl->get_IsConnected(pNet, &bIsConnected)) &&
SUCCEEDED(w_win32_error = pNet->lpVtbl->get_IsConnectedToInternet(pNet, &bIsConnectedInet)) &&
SUCCEEDED(w_win32_error = pNet->lpVtbl->GetNetworkId(pNet, &idNet)) &&
SUCCEEDED(w_win32_error = pNet->lpVtbl->GetName(pNet, &bstrName)))
{
if (!!bIsConnected == connected)
{
if (WideCharToMultiByte(CP_UTF8, 0, bstrName, -1, Name, sizeof(Name), NULL, NULL))
{
printf("Name : %s", Name);
if (bIsConnected) printf(" (connected)");
if (bIsConnectedInet) printf(" (inet)");
printf("\n");
guid2str(&idNet, Name);
printf("NetID : %s\n", Name);
printf("\n");
}
else
{
w_win32_error = HRESULT_FROM_WIN32(GetLastError());
bRet = false;
}
}
SysFreeString(bstrName);
}
else
bRet = false;
pNet->lpVtbl->Release(pNet);
if (!bRet) break;
}
if (!bRet) break;
pEnum->lpVtbl->Reset(pEnum);
}
pEnum->lpVtbl->Release(pEnum);
}
else
bRet = false;
pNetworkListManager->lpVtbl->Release(pNetworkListManager);
}
else
bRet = false;
}
else
bRet = false;
CoUninitialize();
return bRet;
}
static bool nlm_filter_match(const struct str_list_head *nlm_list)
{
// no filter given. always matches.
if (!nlm_list || LIST_EMPTY(nlm_list))
{
w_win32_error = 0;
return true;
}
bool bRet = true, bMatch = false;
IEnumNetworks* pEnum;
if (SUCCEEDED(w_win32_error = pNetworkListManager->lpVtbl->GetNetworks(pNetworkListManager, NLM_ENUM_NETWORK_ALL, &pEnum)))
{
INetwork* pNet;
VARIANT_BOOL bIsConnected;
GUID idNet,g;
BSTR bstrName;
char Name[128];
struct str_list *nlm;
for (;;)
{
if (FAILED(w_win32_error = pEnum->lpVtbl->Next(pEnum, 1, &pNet, NULL)))
{
bRet = false;
break;
}
if (!pNet) break;
if (SUCCEEDED(w_win32_error = pNet->lpVtbl->get_IsConnected(pNet, &bIsConnected)) &&
SUCCEEDED(w_win32_error = pNet->lpVtbl->GetNetworkId(pNet, &idNet)) &&
SUCCEEDED(w_win32_error = pNet->lpVtbl->GetName(pNet, &bstrName)))
{
if (bIsConnected)
{
if (WideCharToMultiByte(CP_UTF8, 0, bstrName, -1, Name, sizeof(Name), NULL, NULL))
{
LIST_FOREACH(nlm, nlm_list, next)
{
bMatch = !strcmp(Name,nlm->str) || str2guid(nlm->str,&g) && !memcmp(&idNet,&g,sizeof(GUID));
if (bMatch) break;
}
}
else
{
w_win32_error = HRESULT_FROM_WIN32(GetLastError());
bRet = false;
}
}
SysFreeString(bstrName);
}
else
bRet = false;
pNet->lpVtbl->Release(pNet);
if (!bRet || bMatch) break;
}
pEnum->lpVtbl->Release(pEnum);
}
else
bRet = false;
return bRet && bMatch;
}
static bool wlan_filter_match(const struct str_list_head *ssid_list)
{ {
DWORD dwCurVersion; DWORD dwCurVersion;
HANDLE hClient = NULL; HANDLE hClient = NULL;
@ -1031,12 +1226,17 @@ found:
goto ex; goto ex;
} }
static bool wlan_filter_match_rate_limited(void) bool logical_net_filter_match(void)
{
return wlan_filter_match(wlan_filter_ssid) && nlm_filter_match(nlm_filter_net);
}
static bool logical_net_filter_match_rate_limited(void)
{ {
DWORD dwTick = GetTickCount() / 1000; DWORD dwTick = GetTickCount() / 1000;
if (wlan_filter_tick == dwTick) return true; if (logical_net_filter_tick == dwTick) return true;
wlan_filter_tick = dwTick; logical_net_filter_tick = dwTick;
return wlan_filter_match(wlan_filter_ssid); return logical_net_filter_match();
} }
static HANDLE windivert_init_filter(const char *filter, UINT64 flags) static HANDLE windivert_init_filter(const char *filter, UINT64 flags)
@ -1084,9 +1284,8 @@ void rawsend_cleanup(void)
CloseHandle(ovl.hEvent); CloseHandle(ovl.hEvent);
ovl.hEvent=NULL; ovl.hEvent=NULL;
} }
wlan_filter_ssid = NULL;
} }
bool windivert_init(const char *filter, const struct str_list_head *ssid_filter) bool windivert_init(const char *filter)
{ {
rawsend_cleanup(); rawsend_cleanup();
w_filter = windivert_init_filter(filter, 0); w_filter = windivert_init_filter(filter, 0);
@ -1099,7 +1298,6 @@ bool windivert_init(const char *filter, const struct str_list_head *ssid_filter)
rawsend_cleanup(); rawsend_cleanup();
return false; return false;
} }
wlan_filter_ssid = ssid_filter;
return true; return true;
} }
return false; return false;
@ -1117,7 +1315,7 @@ static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_t *len,
errno=EINTR; errno=EINTR;
return false; return false;
} }
if (!wlan_filter_match_rate_limited()) if (!logical_net_filter_match_rate_limited())
{ {
errno=ENODEV; errno=ENODEV;
return false; return false;
@ -1142,7 +1340,7 @@ static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_t *len,
errno=EINTR; errno=EINTR;
return false; return false;
} }
if (!wlan_filter_match_rate_limited()) if (!logical_net_filter_match_rate_limited())
{ {
errno=ENODEV; errno=ENODEV;
return false; return false;

View File

@ -152,10 +152,13 @@ bool tcp_has_fastopen(const struct tcphdr *tcp);
#ifdef __CYGWIN__ #ifdef __CYGWIN__
extern uint32_t w_win32_error; extern uint32_t w_win32_error;
bool windivert_init(const char *filter, const struct str_list_head *ssid_filter); bool win_dark_init(const struct str_list_head *ssid_filter, const struct str_list_head *nlm_filter);
bool win_dark_deinit(void);
bool logical_net_filter_match(void);
bool nlm_list(bool bAll);
bool windivert_init(const char *filter);
bool windivert_recv(uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa); bool windivert_recv(uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa);
bool windivert_send(const uint8_t *packet, size_t len, const WINDIVERT_ADDRESS *wa); bool windivert_send(const uint8_t *packet, size_t len, const WINDIVERT_ADDRESS *wa);
bool wlan_filter_match(const struct str_list_head *ssid_list);
#else #else
// should pre-do it if dropping privileges. otherwise its not necessary // should pre-do it if dropping privileges. otherwise its not necessary
bool rawsend_preinit(bool bind_fix4, bool bind_fix6); bool rawsend_preinit(bool bind_fix4, bool bind_fix6);

View File

@ -7,7 +7,6 @@
#include "hostlist.h" #include "hostlist.h"
#include "conntrack.h" #include "conntrack.h"
#include <unistd.h>
#include <string.h> #include <string.h>

View File

@ -412,9 +412,15 @@ static int win_main(const char *windivert_filter)
pre_desync(); pre_desync();
if (!win_dark_init(&params.ssid_filter, &params.nlm_filter))
{
fprintf(stderr, "win_dark_init failed. win32 error %u (0x%08X)\n", w_win32_error, w_win32_error);
return w_win32_error;
}
for(;;) for(;;)
{ {
if (!wlan_filter_match(&params.ssid_filter)) if (!logical_net_filter_match())
{ {
printf("logical network is not present. waiting it to appear.\n"); printf("logical network is not present. waiting it to appear.\n");
fflush(stdout); fflush(stdout);
@ -423,17 +429,21 @@ static int win_main(const char *windivert_filter)
if (bQuit) if (bQuit)
{ {
DLOG("QUIT requested\n") DLOG("QUIT requested\n")
win_dark_deinit();
return 0; return 0;
} }
usleep(500000); usleep(500000);
} }
while (!wlan_filter_match(&params.ssid_filter)); while (!logical_net_filter_match());
printf("logical network now present\n"); printf("logical network now present\n");
fflush(stdout); fflush(stdout);
} }
if (!windivert_init(windivert_filter, &params.ssid_filter)) if (!windivert_init(windivert_filter))
{
win_dark_deinit();
return w_win32_error; return w_win32_error;
}
printf("windivert initialized. capture is started.\n"); printf("windivert initialized. capture is started.\n");
@ -460,9 +470,11 @@ static int win_main(const char *windivert_filter)
else if (errno==EINTR) else if (errno==EINTR)
{ {
DLOG("QUIT requested\n") DLOG("QUIT requested\n")
win_dark_deinit();
return 0; return 0;
} }
fprintf(stderr, "windivert: recv failed. errno %d\n", errno); fprintf(stderr, "windivert: recv failed. errno %d\n", errno);
win_dark_deinit();
return w_win32_error; return w_win32_error;
} }
*ifout=0; *ifout=0;
@ -504,6 +516,7 @@ static int win_main(const char *windivert_filter)
fflush(stderr); fflush(stderr);
} }
} }
win_dark_deinit();
return 0; return 0;
} }
@ -550,6 +563,7 @@ static void cleanup_params(void)
HostFailPoolDestroy(&params.hostlist_auto_fail_counters); HostFailPoolDestroy(&params.hostlist_auto_fail_counters);
#ifdef __CYGWIN__ #ifdef __CYGWIN__
strlist_destroy(&params.ssid_filter); strlist_destroy(&params.ssid_filter);
strlist_destroy(&params.nlm_filter);
#endif #endif
} }
static void exit_clean(int code) static void exit_clean(int code)
@ -799,6 +813,8 @@ static void exithelp(void)
" --wf-save=<filename>\t\t\t\t; save windivert filter string to a file and exit\n" " --wf-save=<filename>\t\t\t\t; save windivert filter string to a file and exit\n"
"\nLOGICAL NETWORK FILTER:\n" "\nLOGICAL NETWORK FILTER:\n"
" --ssid-filter=ssid1[,ssid2,ssid3,...]\t\t; enable winws only if any of specified wifi SSIDs connected\n" " --ssid-filter=ssid1[,ssid2,ssid3,...]\t\t; enable winws only if any of specified wifi SSIDs connected\n"
" --nlm-filter=net1[,net2,net3,...]\t\t; enable winws only if any of specified NLM network is connected. names and GUIDs are accepted.\n"
" --nlm-list[=all]\t\t\t\t; list Network List Manager (NLM) networks. connected only or all.\n"
#endif #endif
"\nHOSTLIST FILTER:\n" "\nHOSTLIST FILTER:\n"
" --hostlist=<filename>\t\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" " --hostlist=<filename>\t\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
@ -910,7 +926,7 @@ int main(int argc, char **argv)
char windivert_filter[8192], wf_pf_tcp_src[256], wf_pf_tcp_dst[256], wf_pf_udp_src[256], wf_pf_udp_dst[256], wf_save_file[256]; char windivert_filter[8192], wf_pf_tcp_src[256], wf_pf_tcp_dst[256], wf_pf_udp_src[256], wf_pf_udp_dst[256], wf_save_file[256];
bool wf_ipv4=true, wf_ipv6=true; bool wf_ipv4=true, wf_ipv6=true;
unsigned int IfIdx=0, SubIfIdx=0; unsigned int IfIdx=0, SubIfIdx=0;
unsigned int hash_wf_tcp=0,hash_wf_udp=0,hash_wf_raw=0,hash_ssid_filter=0; unsigned int hash_wf_tcp=0,hash_wf_udp=0,hash_wf_raw=0,hash_ssid_filter=0,hash_nlm_filter=0;
*windivert_filter = *wf_pf_tcp_src = *wf_pf_tcp_dst = *wf_pf_udp_src = *wf_pf_udp_dst = *wf_save_file = 0; *windivert_filter = *wf_pf_tcp_src = *wf_pf_tcp_dst = *wf_pf_udp_src = *wf_pf_udp_dst = *wf_save_file = 0;
#endif #endif
@ -959,6 +975,7 @@ int main(int argc, char **argv)
#ifdef __CYGWIN__ #ifdef __CYGWIN__
LIST_INIT(&params.ssid_filter); LIST_INIT(&params.ssid_filter);
LIST_INIT(&params.nlm_filter);
#else #else
if (can_drop_root()) // are we root ? if (can_drop_root()) // are we root ?
{ {
@ -1049,6 +1066,8 @@ int main(int argc, char **argv)
{"wf-raw",required_argument,0,0}, // optidx=56 {"wf-raw",required_argument,0,0}, // optidx=56
{"wf-save",required_argument,0,0}, // optidx=57 {"wf-save",required_argument,0,0}, // optidx=57
{"ssid-filter",required_argument,0,0}, // optidx=58 {"ssid-filter",required_argument,0,0}, // optidx=58
{"nlm-filter",required_argument,0,0}, // optidx=59
{"nlm-list",optional_argument,0,0}, // optidx=60
#endif #endif
{NULL,0,NULL,0} {NULL,0,NULL,0}
}; };
@ -1582,6 +1601,31 @@ int main(int argc, char **argv)
} }
} }
break; break;
case 59: /* nlm-filter */
hash_nlm_filter=hash_jen(optarg,strlen(optarg));
{
char *e,*p = optarg;
while (p)
{
e = strchr(p,',');
if (e) *e++=0;
if (*p && !strlist_add(&params.nlm_filter, p))
{
fprintf(stderr, "strlist_add failed\n");
exit_clean(1);
}
p = e;
}
}
break;
case 60: /* nlm-list */
if (!nlm_list(optarg && !strcmp(optarg,"all")))
{
fprintf(stderr, "could not get list of NLM networks\n");
exit_clean(1);
}
exit_clean(0);
#endif #endif
} }
@ -1630,7 +1674,7 @@ int main(int argc, char **argv)
HANDLE hMutexArg; HANDLE hMutexArg;
{ {
char mutex_name[128]; char mutex_name[128];
snprintf(mutex_name,sizeof(mutex_name),"Global\\winws_arg_%u_%u_%u_%u_%u_%u_%u_%u",hash_wf_tcp,hash_wf_udp,hash_wf_raw,hash_ssid_filter,IfIdx,SubIfIdx,wf_ipv4,wf_ipv6); snprintf(mutex_name,sizeof(mutex_name),"Global\\winws_arg_%u_%u_%u_%u_%u_%u_%u_%u_%u",hash_wf_tcp,hash_wf_udp,hash_wf_raw,hash_ssid_filter,hash_nlm_filter,IfIdx,SubIfIdx,wf_ipv4,wf_ipv6);
hMutexArg = CreateMutexA(NULL,TRUE,mutex_name); hMutexArg = CreateMutexA(NULL,TRUE,mutex_name);
if (hMutexArg && GetLastError()==ERROR_ALREADY_EXISTS) if (hMutexArg && GetLastError()==ERROR_ALREADY_EXISTS)

View File

@ -66,7 +66,7 @@ struct params_s
int udplen_increment; int udplen_increment;
#ifdef __CYGWIN__ #ifdef __CYGWIN__
struct str_list_head ssid_filter; struct str_list_head ssid_filter,nlm_filter;
#else #else
bool droproot; bool droproot;
uid_t uid; uid_t uid;