1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00
ipxwrapper/src/ipxwrapper.c

193 lines
4.4 KiB
C
Raw Normal View History

2008-12-09 21:36:07 +00:00
/* ipxwrapper - Library functions
* Copyright (C) 2008-2014 Daniel Collins <solemnwarning@solemnwarning.net>
2008-12-09 21:36:07 +00:00
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define WINSOCK_API_LINKAGE
2008-12-09 21:36:07 +00:00
#include <winsock2.h>
#include <windows.h>
2008-12-09 21:36:07 +00:00
#include <wsipx.h>
#include <nspapi.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <time.h>
2008-12-09 21:36:07 +00:00
#include "ipxwrapper.h"
2011-08-28 21:27:06 +00:00
#include "common.h"
#include "interface.h"
2011-09-07 20:03:16 +00:00
#include "router.h"
2012-10-20 18:06:11 +00:00
#include "addrcache.h"
2008-12-09 21:36:07 +00:00
extern const char *version_string;
extern const char *compile_time;
struct ipaddr_list {
uint32_t ipaddr;
struct ipaddr_list *next;
};
2008-12-09 21:36:07 +00:00
ipx_socket *sockets = NULL;
2012-10-21 10:26:52 +00:00
main_config_t main_config;
2008-12-09 21:36:07 +00:00
2011-09-08 00:20:34 +00:00
static CRITICAL_SECTION sockets_cs;
typedef ULONGLONG WINAPI (*GetTickCount64_t)(void);
static HMODULE kernel32 = NULL;
2012-10-20 18:06:11 +00:00
static void init_cs(CRITICAL_SECTION *cs)
{
if(!InitializeCriticalSectionAndSpinCount(cs, 0x80000000))
{
2011-11-16 21:32:59 +00:00
log_printf(LOG_ERROR, "Failed to initialise critical section: %s", w32_error(GetLastError()));
2012-10-20 18:06:11 +00:00
abort();
2011-09-08 00:20:34 +00:00
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if(fdwReason == DLL_PROCESS_ATTACH)
{
log_open("ipxwrapper.log");
2008-12-09 21:36:07 +00:00
2011-11-16 21:32:59 +00:00
log_printf(LOG_INFO, "IPXWrapper %s", version_string);
log_printf(LOG_INFO, "Compiled at %s", compile_time);
if(!getenv("SystemRoot"))
{
log_printf(LOG_WARNING, "SystemRoot is not set in the environment");
char env[268] = "SystemRoot=";
GetSystemWindowsDirectory(env+11, 256);
log_printf(LOG_INFO, "Setting SystemRoot to '%s'", env+11);
_putenv(env);
}
2012-10-21 10:26:52 +00:00
main_config = get_main_config();
min_log_level = main_config.log_level;
ipx_use_pcap = main_config.use_pcap;
2012-10-21 10:26:52 +00:00
if(main_config.fw_except)
{
log_printf(LOG_INFO, "Adding exception to Windows Firewall");
add_self_to_firewall();
}
2012-10-20 18:06:11 +00:00
addr_cache_init();
ipx_interfaces_init();
2012-10-20 18:06:11 +00:00
init_cs(&sockets_cs);
2008-12-09 21:36:07 +00:00
WSADATA wsdata;
int err = WSAStartup(MAKEWORD(1,1), &wsdata);
if(err)
{
2011-11-16 21:32:59 +00:00
log_printf(LOG_ERROR, "Failed to initialize winsock: %s", w32_error(err));
2008-12-09 21:36:07 +00:00
return FALSE;
}
router_init();
}
else if(fdwReason == DLL_PROCESS_DETACH)
{
/* When the "lpvReserved" parameter is non-NULL, the process is terminating rather
* than the DLL being unloaded dynamically and any threads will have been terminated
* at unknown points, meaning any global data may be in an inconsistent state and we
* cannot (safely) clean up. MSDN states we should do nothing.
*/
if(lpvReserved != NULL)
{
return TRUE;
}
router_cleanup();
2008-12-09 21:36:07 +00:00
2011-09-08 00:20:34 +00:00
WSACleanup();
2012-10-20 18:06:11 +00:00
DeleteCriticalSection(&sockets_cs);
2011-08-29 13:15:10 +00:00
ipx_interfaces_cleanup();
2012-10-20 18:06:11 +00:00
addr_cache_cleanup();
unload_dlls();
log_close();
if(kernel32)
{
FreeLibrary(kernel32);
kernel32 = NULL;
}
2008-12-09 21:36:07 +00:00
}
return TRUE;
}
/* Lock the sockets table and search for one by file descriptor.
*
* Returns an ipx_socket pointer on success, unlocks the sockets table and
* returns NULL if no match is found.
2008-12-09 21:36:07 +00:00
*/
ipx_socket *get_socket(SOCKET sockfd)
{
2011-09-08 00:20:34 +00:00
lock_sockets();
2008-12-09 21:36:07 +00:00
ipx_socket *sock;
HASH_FIND_INT(sockets, &sockfd, sock);
2008-12-09 21:36:07 +00:00
if(!sock)
{
2011-09-08 00:20:34 +00:00
unlock_sockets();
2008-12-09 21:36:07 +00:00
}
return sock;
2008-12-09 21:36:07 +00:00
}
/* Lock the mutex */
void lock_sockets(void)
{
2011-09-08 00:20:34 +00:00
EnterCriticalSection(&sockets_cs);
2008-12-09 21:36:07 +00:00
}
/* Unlock the mutex */
void unlock_sockets(void)
{
2011-09-08 00:20:34 +00:00
LeaveCriticalSection(&sockets_cs);
2008-12-09 21:36:07 +00:00
}
uint64_t get_ticks(void)
{
static GetTickCount64_t GetTickCount64 = NULL;
if(!kernel32 && (kernel32 = LoadLibrary("kernel32.dll")))
{
GetTickCount64 = (GetTickCount64_t)(GetProcAddress(kernel32, "GetTickCount64"));
}
if(GetTickCount64)
{
return GetTickCount64();
}
else{
return GetTickCount();
}
}