summaryrefslogtreecommitdiff
path: root/plugins/ProxySwitch/src/ip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ProxySwitch/src/ip.cpp')
-rw-r--r--plugins/ProxySwitch/src/ip.cpp728
1 files changed, 728 insertions, 0 deletions
diff --git a/plugins/ProxySwitch/src/ip.cpp b/plugins/ProxySwitch/src/ip.cpp
new file mode 100644
index 0000000000..abd793e3eb
--- /dev/null
+++ b/plugins/ProxySwitch/src/ip.cpp
@@ -0,0 +1,728 @@
+/*
+proxySwitch
+
+The plugin watches IP address changes, reports them via popups and adjusts
+the proxy settings of Miranda and Internet Explorer accordingly.
+*/
+
+#include "stdafx.h"
+
+//#define IP_DEBUG
+#ifdef IP_DEBUG
+#pragma comment (lib, "user32")
+#pragma comment (lib, "iphlpapi")
+#pragma comment (lib, "ws2_32")
+#define PopupMyIPAddrs(x) printf("PopupMyIPAddrs(%s)\n", x);
+#define GetCurrentProcessId() 13604
+NETWORK_INTERFACE_LIST NIF_List;
+CRITICAL_SECTION csNIF_List;
+char opt_hideIntf[MAX_IPLIST_LENGTH];
+void UpdateInterfacesMenu (void) { }
+PLUGINLINK *pluginLink;
+int main(void) {
+ NETWORK_INTERFACE_LIST list;
+ char opt[200] = "2.252.83.0-2.252.85.0;10.100.0.0/16;2.252.83.32-38;;;32.64.128.0/255.255.255.0";
+ IP_RANGE_LIST range;
+ InitializeCriticalSection(&csNIF_List);
+ lstrcpy(opt_hideIntf, "VMnet*");
+ printf("Started\n");
+ printf("IP Helper procs: %s\n", Load_ExIpHelper_Procedures() ? "Loaded" : "Not found");
+ if ( Create_NIF_List( &list ) >=0 ) {
+ printf("%s\n", Print_NIF_List(list, NULL));
+
+ Create_Range_List( &range, opt, FALSE );
+ printf("'%s' matches: %s\n", opt, Match_Range_List(range, list) ? "yes" : "no" );
+ Free_Range_List( &range );
+
+
+ Free_NIF_List( &list );
+ }
+ DeleteCriticalSection(&csNIF_List);
+ printf("Finished\n");
+ return 0;
+}
+#endif
+
+wchar_t tempstr[MAX_SECONDLINE];
+
+/* ################################################################################ */
+
+#ifndef IP_DEBUG
+void IP_WatchDog (void *arg) {
+ OVERLAPPED overlap;
+ DWORD ret;
+ wchar_t msg[300];
+ HANDLE event_list[2];
+ HANDLE hand = WSACreateEvent();
+ overlap.hEvent = WSACreateEvent();
+
+ for (;;) {
+
+ ret = NotifyAddrChange(&hand, &overlap);
+ if (ret != NO_ERROR && WSAGetLastError() != WSA_IO_PENDING) {
+ wchar_t err[100];
+ mir_snwprintf(err, L"NotifyAddrChange Error: %d/nRestart Miranda IM to restore IP monitor.", WSAGetLastError());
+ ERRORMSG(err);
+ break;
+ }
+
+ event_list[0] = overlap.hEvent;
+ event_list[1] = hEventRebound;
+
+ ret = MsgWaitForMultipleObjectsEx( 2, event_list, INFINITE, 0, MWMO_ALERTABLE );
+ if (ret == WAIT_IO_COMPLETION && Miranda_IsTerminated()) break;
+ if (ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT || ret == (WAIT_OBJECT_0+1) ) {
+ NETWORK_INTERFACE_LIST list;
+
+ if ( Create_NIF_List_Ex( &list ) >=0 ) {
+ int change = INCUPD_INTACT;
+
+ EnterCriticalSection(&csNIF_List);
+ change = IncUpdate_NIF_List(&NIF_List, list);
+ if ( change != INCUPD_INTACT && change != INCUPD_CONN_BIND ) {
+ char proxy = -1;
+ int change_Miranda = 0;
+ int reset_Miranda = 0;
+ int change_IE = 0;
+ int change_Firefox = 0;
+ IP_RANGE_LIST range;
+
+ if ( proxy == -1 ) {
+ Create_Range_List( &range, opt_useProxy, TRUE );
+ if ( Match_Range_List( range, NIF_List ) ) proxy = 1;
+ Free_Range_List( &range );
+ }
+ if ( proxy == -1 ) {
+ Create_Range_List( &range, opt_noProxy, FALSE );
+ if ( Match_Range_List( range, NIF_List ) ) proxy = 0;
+ Free_Range_List( &range );
+ }
+ if ( proxy == -1 ) {
+ Create_Range_List( &range, opt_useProxy, FALSE );
+ if ( Match_Range_List( range, NIF_List ) ) proxy = 1;
+ Free_Range_List( &range );
+ }
+
+ if ( proxy != -1 && proxy != Get_Miranda_Proxy_Status() ) change_Miranda = reset_Miranda = opt_miranda;
+ if ( proxy != -1 && proxy != Get_IE_Proxy_Status() ) change_IE = opt_ie;
+ if ( proxy != -1 && proxy != Get_Firefox_Proxy_Status() ) change_Firefox = opt_firefox;
+ if ( opt_alwayReconnect ) reset_Miranda = 1;
+
+ mir_wstrcpy(msg, L"");
+ if ( opt_showProxyState && change_Miranda ) {
+ mir_wstrcat(msg, TranslateT("\nMiranda "));
+ mir_wstrcat(msg, proxy ? TranslateT("Proxy") : TranslateT("Direct"));
+ }
+ if ( opt_showProxyState && change_IE ) {
+ mir_wstrcat(msg, TranslateT("\nExplorer "));
+ mir_wstrcat(msg, proxy ? TranslateT("Proxy") : TranslateT("Direct"));
+ }
+ if ( opt_showProxyState && change_Firefox ) {
+ mir_wstrcat(msg, TranslateT("\nFirefox "));
+ mir_wstrcat(msg, proxy ? TranslateT("Proxy") : TranslateT("Direct"));
+ }
+ UpdateInterfacesMenu();
+ PopupMyIPAddrs(mir_wstrlen(msg) ? msg : NULL);
+
+ if ( change_IE ) Set_IE_Proxy_Status( proxy );
+ if ( change_Firefox ) Set_Firefox_Proxy_Status( proxy );
+ if ( reset_Miranda ) {
+ PROTO_SETTINGS protocols;
+ Disconnect_All_Protocols( &protocols, change_Miranda );
+ Sleep( 1000 );
+ if ( change_Miranda ) Set_Miranda_Proxy_Status( proxy );
+ Connect_All_Protocols( &protocols );
+ }
+ }
+ LeaveCriticalSection(&csNIF_List);
+
+ Free_NIF_List( &list );
+ }
+ }
+
+ ResetEvent(hEventRebound);
+ WSAResetEvent(hand);
+ WSAResetEvent(overlap.hEvent);
+ }
+
+ WSACloseEvent(hand);
+ WSACloseEvent(overlap.hEvent);
+}
+#endif
+
+/* ################################################################################ */
+
+int Create_NIF_List_Ex (NETWORK_INTERFACE_LIST *list) {
+ UINT delay = 1;
+ int out;
+
+ while ( (out = Create_NIF_List(list)) == -2 && delay < 10 ) {
+ Sleep(delay*50);
+ delay++;
+ }
+ if (out == -2) ERRORMSG(TranslateT("Cannot retrieve IP or Adapter data."));
+ return out < 0 ? -1 : out;
+}
+
+PNETWORK_INTERFACE Find_NIF_IP(NETWORK_INTERFACE_LIST list, const LONG IP) {
+ UCHAR idx = 0;
+ UCHAR i;
+
+ while (idx < list.count) {
+ for (i = 0; i < list.item[idx].IPcount; i++) {
+ if (list.item[idx].IP[i] == IP) return &(list.item[idx]);
+ }
+ idx++;
+ }
+ return NULL;
+}
+
+int Create_NIF_List (NETWORK_INTERFACE_LIST *list) {
+
+ PIP_ADAPTER_INFO pAdapterInfo, pAdapt;
+ PIP_ADDR_STRING pAddrStr;
+ PIP_ADAPTER_ADDRESSES pAddresses, pAddr;
+ PNETWORK_INTERFACE nif;
+ ULONG outBufLen;
+ wchar_t *tmp_opt, *intf, *rest, *name;
+ BOOL skip;
+ DWORD out;
+ UCHAR idx;
+
+ // prepare and load IP_ADAPTER_ADDRESSES
+ outBufLen = 0;
+ if (GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
+ pAddresses = (PIP_ADAPTER_ADDRESSES) malloc(outBufLen);
+ if (pAddresses == NULL) {
+ ERRORMSG(TranslateT("Cannot allocate memory for pAddresses"));
+ return -1;
+ }
+ if ((out = GetAdaptersAddresses(AF_INET, 0, NULL, pAddresses, &outBufLen)) != ERROR_SUCCESS) {
+ free(pAddresses);
+ return -2;
+ }
+ } else {
+ ERRORMSG(TranslateT("GetAdaptersAddresses sizing failed"));
+ return -1;
+ }
+
+ // prepare and load IP_ADAPTER_INFO
+ outBufLen = 0;
+ if (GetAdaptersInfo(NULL, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
+ pAdapterInfo = (PIP_ADAPTER_INFO) malloc(outBufLen);
+ if (pAdapterInfo == NULL) {
+ ERRORMSG(TranslateT("Cannot allocate memory for pAdapterInfo"));
+ free(pAddresses);
+ return -1;
+ }
+ if (GetAdaptersInfo(pAdapterInfo, &outBufLen) != NO_ERROR) {
+ free(pAdapterInfo);
+ free(pAddresses);
+ return -2;
+ }
+ } else {
+ ERRORMSG(TranslateT("GetAdaptersInfo sizing failed"));
+ free(pAddresses);
+ return -1;
+ }
+
+ ZeroMemory(list, sizeof(NETWORK_INTERFACE_LIST));
+
+ pAdapt = pAdapterInfo;
+ while (pAdapt) {
+
+ // add a new interface into the list
+ list->count++;
+ list->item = (PNETWORK_INTERFACE)mir_realloc( list->item, list->count * sizeof(NETWORK_INTERFACE) );
+ nif = &(list->item[list->count - 1]);
+ ZeroMemory(nif, sizeof(NETWORK_INTERFACE));
+
+ // copy AdapterName
+ nif->AdapterName = (char*)mir_alloc(mir_strlen(pAdapt->AdapterName)+4);
+ nif->AdapterName = mir_strdup(pAdapt->AdapterName);
+
+ // find its FriendlyName and copy it
+ pAddr = pAddresses;
+ while(pAddr && mir_strcmp(pAddr->AdapterName, pAdapt->AdapterName)) {
+ pAddr = pAddr->Next;
+ }
+ if ( pAddr ) {
+ nif->FriendlyName = (wchar_t*)mir_alloc(wcslen(pAddr->FriendlyName)+4);
+ nif->FriendlyName = mir_wstrdup(pAddr->FriendlyName);
+ }
+
+ skip = FALSE;
+ tmp_opt = intf = rest = mir_wstrdup( opt_hideIntf );
+ while ( rest && rest[0] && ! skip ) {
+ rest = wcschr( rest, ';' );
+ if ( rest != NULL ) {
+ rest[0] = 0;
+ rest++;
+ }
+ if ( intf[0] ) {
+ if ( intf[mir_wstrlen(intf)-1] == '*' && mir_wstrlen(intf)-1 <= mir_wstrlen(nif->FriendlyName) ) {
+ intf[mir_wstrlen(intf)-1] = 0;
+ name = nif->FriendlyName;
+ skip = TRUE;
+ while ( intf[0] ) {
+ if ( intf[0] != name[0] ) {
+ skip = FALSE;
+ break;
+ }
+ intf++;
+ name++;
+ }
+ }
+ if ( mir_wstrcmp(nif->FriendlyName, intf) == 0 ) {
+ skip = TRUE;
+ }
+ }
+ intf = rest;
+ }
+ free(tmp_opt);
+
+ if ( skip ) {
+ list->count--;
+ list->item = (PNETWORK_INTERFACE)mir_realloc( list->item, list->count * sizeof(NETWORK_INTERFACE) );
+ pAdapt = pAdapt->Next;
+ continue;
+ }
+
+ // get required size for IPstr and IP
+ outBufLen = 0;
+ pAddrStr = &(pAdapt->IpAddressList);
+ while(pAddrStr) {
+ if ( strcmp("0.0.0.0", pAddrStr->IpAddress.String) ) {
+ nif->IPcount++; // count IP addresses
+ outBufLen += strlen(pAddrStr->IpAddress.String); // count length of IPstr
+ }
+ pAddrStr = pAddrStr->Next;
+ if (pAddrStr) outBufLen += 2; // count length of IPstr (add ", ")
+ }
+
+ // create IPstr and IP
+ if ( nif->IPcount ) {
+ nif->IPstr = (char*)mir_alloc( outBufLen+4 );
+ strcpy(nif->IPstr, "");
+ nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) );
+ outBufLen = 0;
+ pAddrStr = &(pAdapt->IpAddressList);
+ while(pAddrStr) {
+ if ( strcmp("0.0.0.0", pAddrStr->IpAddress.String) ) {
+ strcat( nif->IPstr, pAddrStr->IpAddress.String );
+ nif->IP[outBufLen] = inet_addr( pAddrStr->IpAddress.String );
+ outBufLen++;
+ }
+ pAddrStr = pAddrStr->Next;
+ if (pAddrStr) strcat( nif->IPstr, ", ");
+ }
+ nif->IP[outBufLen] = 0L;
+ }
+ pAdapt = pAdapt->Next;
+ }
+
+ free(pAdapterInfo);
+ free(pAddresses);
+
+ EnterCriticalSection(&csConnection_List);
+ for ( idx=0 ; idx < Connection_List.count ; idx++ ) {
+ nif = Find_NIF_IP( *list, Connection_List.item[idx].IP );
+ if ( nif ) {
+ nif->Bound = 1;
+ }
+ }
+ LeaveCriticalSection(&csConnection_List);
+
+ return 0;
+}
+
+/* ################################################################################ */
+
+PNETWORK_INTERFACE Find_NIF_AdapterName ( NETWORK_INTERFACE_LIST list, const char *AdapterName) {
+ UCHAR idx = 0;
+
+ while ( idx < list.count ) {
+ if ( strcmp(list.item[idx].AdapterName, AdapterName) == 0 ) return &(list.item[idx]);
+ idx++;
+ }
+ return NULL;
+}
+
+PNETWORK_INTERFACE Find_NIF_MenuItem ( NETWORK_INTERFACE_LIST list, const HGENMENU MenuItem) {
+ UCHAR idx = 0;
+
+ while ( idx < list.count ) {
+ if ( list.item[idx].MenuItem == MenuItem ) return &(list.item[idx]);
+ idx++;
+ }
+ return NULL;
+}
+
+/* ################################################################################ */
+
+BOOL Compare_NIF_Lists (NETWORK_INTERFACE_LIST list1, NETWORK_INTERFACE_LIST list2) {
+ UCHAR idx = 0;
+
+ if ( list1.count != list2.count ) return 1;
+ while ( idx < list1.count ) {
+ if ( mir_strcmp(list1.item[idx].AdapterName, list2.item[idx].AdapterName) ) return 1;
+ if ( mir_strcmp(list1.item[idx].IPstr, list2.item[idx].IPstr) ) return 1;
+ if ( mir_wstrcmp(list1.item[idx].FriendlyName, list2.item[idx].FriendlyName) ) return 1;
+ idx++;
+ }
+ return 0;
+}
+
+/* ################################################################################ */
+
+int IncUpdate_NIF_List (NETWORK_INTERFACE_LIST *trg, NETWORK_INTERFACE_LIST src) {
+ UCHAR idx;
+ PNETWORK_INTERFACE nif;
+ int change = INCUPD_INTACT;
+
+ for (idx = 0 ; idx < src.count ; idx++) {
+ nif = Find_NIF_AdapterName( *trg, src.item[idx].AdapterName );
+ if ( nif ) {
+ if ( nif->Disabled ) nif->Disabled = 0;
+ if ( strcmp(NVL(nif->IPstr), NVL(src.item[idx].IPstr)) ) {
+ if (nif->IPstr) free(nif->IPstr);
+ nif->IPstr = src.item[idx].IPstr ? mir_strdup( src.item[idx].IPstr ) : NULL;
+ INCUPD(change, INCUPD_UPDATED);
+ }
+ if ( mir_wstrcmp(NVLW(nif->FriendlyName), NVLW(src.item[idx].FriendlyName)) ) {
+ if (nif->FriendlyName) free(nif->FriendlyName);
+ nif->FriendlyName = src.item[idx].FriendlyName ? mir_wstrdup( src.item[idx].FriendlyName ) : NULL;
+ INCUPD(change, INCUPD_UPDATED);
+ }
+ if ( nif->IPcount != src.item[idx].IPcount ) {
+ if ( nif->IPcount > src.item[idx].IPcount && nif->Bound ) {
+ INCUPD(change, INCUPD_CONN_LOST );
+ UnboundConnections( nif->IP, src.item[idx].IP );
+ }
+ nif->IPcount = src.item[idx].IPcount;
+ if (nif->IP) free(nif->IP);
+ if (src.item[idx].IP) {
+ nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) );
+ memcpy( nif->IP, src.item[idx].IP, (nif->IPcount+1) * sizeof(LONG) );
+ } else {
+ nif->IP = NULL;
+ }
+ INCUPD(change, INCUPD_UPDATED);
+ } else {
+ if ( nif->IPcount > 0 && memcmp( nif->IP, src.item[idx].IP, nif->IPcount * sizeof(LONG) ) ) {
+ free(nif->IP);
+ nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) );
+ memcpy( nif->IP, src.item[idx].IP, (nif->IPcount+1) * sizeof(LONG) );
+ INCUPD(change, INCUPD_UPDATED);
+ }
+ }
+ if ( nif->Bound != src.item[idx].Bound ) {
+ nif->Bound = src.item[idx].Bound;
+ INCUPD(change, INCUPD_CONN_BIND);
+ }
+ } else {
+ trg->count++;
+ trg->item = (PNETWORK_INTERFACE)mir_realloc( trg->item, trg->count * sizeof(NETWORK_INTERFACE) );
+ nif = &(trg->item[trg->count - 1]);
+ ZeroMemory(nif, sizeof(NETWORK_INTERFACE));
+ nif->AdapterName = src.item[idx].AdapterName ? mir_strdup( src.item[idx].AdapterName ) : NULL;
+ nif->FriendlyName = src.item[idx].FriendlyName ? mir_wstrdup( src.item[idx].FriendlyName ) : NULL;
+ nif->IPstr = src.item[idx].IPstr ? strdup( src.item[idx].IPstr ) : NULL;
+ nif->IPcount = src.item[idx].IPcount;
+ nif->Bound = src.item[idx].Bound;
+ if ( nif->IPcount > 0 ) {
+ nif->IP = (LONG*)mir_alloc( (nif->IPcount+1) * sizeof(LONG) );
+ memcpy( nif->IP, src.item[idx].IP, (nif->IPcount+1) * sizeof(LONG) );
+ }
+ INCUPD(change, INCUPD_UPDATED);
+ }
+ }
+ for (idx = 0 ; idx < trg->count ; idx++) {
+ if ( trg->item[idx].Disabled ) continue;
+ nif = Find_NIF_AdapterName( src, trg->item[idx].AdapterName );
+ if ( ! nif ) {
+ if ( trg->item[idx].Bound ) {
+ INCUPD(change, INCUPD_CONN_LOST );
+ UnboundConnections( trg->item[idx].IP, NULL );
+ } else {
+ INCUPD(change, INCUPD_UPDATED );
+ }
+ if (trg->item[idx].IPstr) free(trg->item[idx].IPstr);
+ if (trg->item[idx].IP) free(trg->item[idx].IP);
+ trg->item[idx].IPstr = NULL;
+ trg->item[idx].IPcount = 0;
+ trg->item[idx].IP = NULL;
+ trg->item[idx].Bound = FALSE;
+ trg->item[idx].Disabled = 1;
+ }
+ }
+ return change;
+}
+
+/* ################################################################################ */
+
+wchar_t *Print_NIF (PNETWORK_INTERFACE nif) {
+ ZeroMemory( tempstr, sizeof(tempstr) );
+ mir_snwprintf( tempstr, L"%s:\t%s", nif->FriendlyName, nif->IPstr ? _A2T(nif->IPstr) : TranslateT("disconnected"));
+ return tempstr;
+}
+
+wchar_t *Print_NIF_List (NETWORK_INTERFACE_LIST list, wchar_t *msg) {
+ UCHAR idx;
+ int pos = 0;
+
+ ZeroMemory( tempstr, sizeof(tempstr) );
+ for( idx = 0 ; idx < list.count ; idx++ ) {
+ pos += mir_snwprintf( tempstr+pos, _countof(tempstr), L"%s:\t%s%s%s\n",
+ list.item[idx].FriendlyName,
+ list.item[idx].Bound ? L"[u]":L"",
+ list.item[idx].IPstr ? _A2T(list.item[idx].IPstr) : TranslateT("disconnected"),
+ list.item[idx].Bound ? L"[/u]":L""
+ );
+ }
+ if ( msg ) mir_wstrcat(tempstr, msg); else tempstr[mir_wstrlen(tempstr)-1] = 0;
+ return tempstr;
+}
+
+/* ################################################################################ */
+
+void Free_NIF (PNETWORK_INTERFACE nif) {
+ if (nif->AdapterName) free(nif->AdapterName);
+ if (nif->FriendlyName) free(nif->FriendlyName);
+ if (nif->IPstr) free(nif->IPstr);
+ if (nif->IP) free(nif->IP);
+ ZeroMemory(nif, sizeof(NETWORK_INTERFACE));
+}
+
+void Free_NIF_List (NETWORK_INTERFACE_LIST *list) {
+ UCHAR idx;
+
+ for( idx = 0 ; idx < list->count ; idx++ ) {
+ Free_NIF( &(list->item[idx]) );
+ }
+ free( list->item );
+ ZeroMemory(list, sizeof(NETWORK_INTERFACE_LIST));
+}
+
+/* ################################################################################ */
+
+void Parse_Range ( PIP_RANGE range, wchar_t *str, BOOL prioritized ) {
+ wchar_t *ext;
+ unsigned long num;
+
+ range->cmpType = CMP_SKIP;
+
+ if ((str[0] == '!' && ! prioritized) || (str[0] != '!' && prioritized)) {
+ range->mask = range->net = 0L;
+ return;
+ }
+ if (str[0] == '!') str++;
+
+ // ip/mask
+ if ( (ext = wcschr( str, '/' )) != NULL ) {
+ ext[0] = 0; ext++;
+
+ // ip/bits (10.0.0.1/16)
+ if ( wcsspn(ext, DIGITS) == mir_wstrlen(ext) ) {
+ num = _wtol(ext);
+ if ( num >= 0 && num <= 32 && (range->net = inet_addr(_T2A(str))) != INADDR_NONE ) {
+ range->cmpType = CMP_MASK;
+ range->mask = NETORDER(num ? ~(0xFFFFFFFF >> (num)) : ~0);
+ range->net = range->net & range->mask;
+ }
+ } else {
+
+ // ip/subnet (10.0.0.1/255.255.0.0)
+ if ( (range->net = inet_addr(_T2A(str))) != INADDR_NONE && (range->mask = inet_addr(_T2A(ext))) != INADDR_NONE ) {
+ for ( num = 0 ; num < 32 ; num++ ) {
+ if ( range->mask == NETORDER(num ? ~(0xFFFFFFFF >> (32-num)) : ~0)) {
+ range->cmpType = CMP_MASK;
+ range->net = range->net & range->mask;
+ break;
+ }
+ }
+ }}
+ } else {
+
+ // ipbegin-end
+ if ( (ext = wcschr( str, '-' )) != NULL ) {
+ ext[0] = 0; ext++;
+
+ // ipA.B.C.D1-D2 (10.0.0.1-12)
+ if ( wcsspn(ext, DIGITS) == mir_wstrlen(ext) ) {
+ num = _wtol(ext);
+ if ( num > 0 && num <= 255 && (range->loIP = inet_addr(_T2A(str))) != INADDR_NONE && (range->loIP >> 24) <= num ) {
+ range->cmpType = CMP_SPAN;
+ range->hiIP = ((range->loIP & 0x00FFFFFF) | (num << 24));
+ range->loIP = (range->loIP);
+ }
+ } else {
+
+ // ipstart-ipend (10.0.0.1-10.0.10.255)
+ if ( (range->loIP = inet_addr(_T2A(str))) != INADDR_NONE && (range->hiIP = inet_addr(_T2A(ext))) != INADDR_NONE ) {
+
+ range->loIP = (range->loIP);
+ range->hiIP = (range->hiIP);
+ if ( range->loIP <= range->hiIP ) {
+ range->cmpType = CMP_SPAN;
+ }
+ }
+ }} else {
+
+ // ip
+ if ( mir_wstrlen(str) > 0 && (range->net = inet_addr(_T2A(str))) != INADDR_NONE ) {
+ range->cmpType = CMP_MASK;
+ range->mask = 0xFFFFFFFF;
+ }}}
+
+ if ( range->cmpType == CMP_SKIP ) {
+ range->mask = range->net = 0L;
+ }
+}
+
+int Create_Range_List ( IP_RANGE_LIST *list, wchar_t *str, BOOL prioritized ) {
+ wchar_t *range, *rest, *tmp;
+ int size, idx;
+
+ ZeroMemory(list, sizeof(IP_RANGE_LIST));
+
+ // get expected number of ranges
+ range = str;
+ size = mir_wstrlen( range ) > 0 ? 1 : 0;
+ while ( range[0] ) { if ( range[0] == ';') size++; range++; };
+
+ if (size == 0) return 0;
+
+ // alloc required space
+ list->item = (PIP_RANGE)mir_alloc( size * sizeof( IP_RANGE ) );
+ ZeroMemory( list->item, size * sizeof( IP_RANGE ) );
+
+ tmp = range = rest = mir_wstrdup( str );
+ idx = 0;
+ while ( rest && rest[0] ) {
+ rest = wcschr( rest, ';' );
+ if ( rest != NULL ) {
+ rest[0] = 0;
+ rest++;
+ }
+ Parse_Range( &(list->item[idx]), range, prioritized );
+ if ( list->item[idx].cmpType != CMP_SKIP ) idx++;
+ range = rest;
+ }
+
+ list->count = idx;
+ list->item = (PIP_RANGE)mir_realloc( list->item, (idx+1) * sizeof( IP_RANGE ) );
+
+ ZeroMemory( &(list->item[idx]), sizeof( IP_RANGE ) );
+ list->item[idx].cmpType = CMP_END;
+
+ free( tmp );
+
+ return 0;
+}
+
+int Match_Range_List (IP_RANGE_LIST range, NETWORK_INTERFACE_LIST nif) {
+ PIP_RANGE rng;
+ UCHAR idx;
+ ULONG *ip;
+
+ if ( range.count == 0 || nif.count == 0 ) return 0;
+
+ rng = range.item;
+ while( rng->cmpType != CMP_END ) {
+
+ switch ( rng->cmpType ) {
+ case CMP_SKIP:
+ break;
+
+ case CMP_MASK:
+ for ( idx = 0 ; idx < nif.count ; idx++ ) {
+ ip = (ULONG *)nif.item[idx].IP;
+ while (ip && *ip) {
+ if ( (ULONG)(*ip & rng->mask) == rng->net ) return 1;
+ ip++;
+ }
+ }
+ break;
+
+ case CMP_SPAN:
+ for ( idx = 0 ; idx < nif.count ; idx++ ) {
+ ip = (ULONG *)nif.item[idx].IP;
+ while (ip && *ip) {
+ if ( (NETORDER(rng->loIP) <= NETORDER(*ip)) && (NETORDER(*ip) <= NETORDER(rng->hiIP)) ) return 1;
+ ip++;
+ }
+ }
+ break;
+ }
+ rng++;
+ }
+
+ return 0;
+}
+
+void Free_Range_List (IP_RANGE_LIST *list) {
+ if ( list->item ) free( list->item );
+ ZeroMemory(list, sizeof(IP_RANGE_LIST));
+}
+
+
+int ManageConnections (WPARAM wParam,LPARAM lParam) {
+ NETLIBCONNECTIONEVENTINFO *info = (NETLIBCONNECTIONEVENTINFO *)wParam;
+ int found;
+ UCHAR i;
+
+ EnterCriticalSection(&csConnection_List);
+ found = -1;
+ for (i=0 ; i<Connection_List.count ; i++) {
+ if ( Connection_List.item[i].IP == info->local.sin_addr.s_addr && Connection_List.item[i].Port == info->local.sin_port ) {
+ found = i;
+ break;
+ }
+ }
+ if ( (found >= 0 && info->connected) || (found == -1 && !info->connected)) {
+ LeaveCriticalSection(&csConnection_List);
+ return 0;
+ }
+ if ( found >= 0 ) {
+ Connection_List.count--;
+ for( i=found ; i<Connection_List.count ; i++ ) memcpy( &(Connection_List.item[i]), &(Connection_List.item[i+1]), sizeof(ACTIVE_CONNECTION) );
+ } else {
+ if ( Connection_List.count >= Connection_List._alloc ) {
+ Connection_List._alloc += 10;
+ Connection_List.item = (PACTIVE_CONNECTION)mir_realloc( Connection_List.item, Connection_List._alloc * sizeof(ACTIVE_CONNECTION) );
+ }
+ Connection_List.item[Connection_List.count].IP = info->local.sin_addr.s_addr;
+ Connection_List.item[Connection_List.count].Port = info->local.sin_port;
+ Connection_List.count++;
+ }
+ LeaveCriticalSection(&csConnection_List);
+
+ SetEvent( hEventRebound );
+
+ return 0;
+}
+
+void UnboundConnections ( LONG *OldIP, LONG *NewIP ) {
+ UCHAR i, j;
+ LONG *IP;
+
+ while ( OldIP != NULL && *OldIP != 0 ) {
+ IP = NewIP;
+ while ( IP != NULL && *IP != 0 && *IP != *OldIP ) IP++;
+ if ( IP == NULL || *IP != *OldIP ) {
+ EnterCriticalSection(&csConnection_List);
+ i = 0;
+ while ( i < Connection_List.count ) {
+ if (Connection_List.item[i].IP == (ULONG)*OldIP) {
+ Connection_List.count--;
+ for( j=i ; j<Connection_List.count ; j++ ) memcpy( &(Connection_List.item[j]), &(Connection_List.item[j+1]), sizeof(ACTIVE_CONNECTION) );
+ } else {
+ i++;
+ }
+ }
+ LeaveCriticalSection(&csConnection_List);
+ }
+ OldIP++;
+ }
+}