diff --git a/.travis.yml b/.travis.yml index bfc25b4..1c8a3af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,22 @@ +sudo: required + branches: only: - master language: cpp - -os: - - linux +os: linux +compiler: gcc before_install: - sudo apt-get update --fix-missing - sudo apt-get install build-essential zlib1g-dev libmysqlclient-dev liblua5.1-0-dev + - (cd /tmp && wget http://www.cmake.org/files/v3.1/cmake-3.1.3.tar.gz && tar zxf cmake-3.1.3.tar.gz) + - (cd /tmp/cmake-3.1.3 && cmake . && make && sudo make install) > /dev/null 2>&1 + - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + - sudo apt-get -qq update + - sudo apt-get -qq install g++-5 + - export CXX="g++-5" CC="gcc-5" - mkdir build - cd build @@ -17,4 +24,4 @@ script: - cmake -D WITH_MYSQL=true -D WITH_LUA=true ../ - make - sudo make install - - sudo make uninstall + - sudo make uninstall \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 363ba1b..847bc07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,5 @@ # Required cmake version -cmake_minimum_required(VERSION 2.4.3) - -if(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -endif(COMMAND cmake_policy) +cmake_minimum_required(VERSION 3.1.0) # Put the include dirs which are in the source or build tree # before all other include dirs, so the headers in the sources @@ -11,17 +7,16 @@ endif(COMMAND cmake_policy) # since cmake 2.4.1 set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) -project(pvpgn) +project(pvpgn CXX) option(WITH_BNETD "compile the bnetd target" ON) option(WITH_D2CS "compile the d2cs target" ON) option(WITH_D2DBS "compile the d2dbs target" ON) option(WITH_ANSI "enforce strict ISO C++ conforming" ON) -if(WIN32) - option(WITH_WIN32_GUI "enable GUI building (default on)" ON) -endif(WIN32) - option(WITH_LUA "enable Lua support" OFF) +if(WIN32) + option(WITH_WIN32_GUI "enable GUI building (default on)" ON) +endif(WIN32) #storage backends flags option(WITH_MYSQL "include MySQL user accounts support" OFF) @@ -32,29 +27,22 @@ include(ConfigureChecks.cmake) if (CMAKE_COMPILER_IS_GNUCXX) - # Determine GCC version. - message("Determining GCC version.") - EXEC_PROGRAM(${CMAKE_CXX_COMPILER} - ARGS --version - OUTPUT_VARIABLE _GCC_VERSION) - STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]) .*" "\\1\\2\\3" - _GCC_VERSION ${_GCC_VERSION}) - message(" GCC version is ${_GCC_VERSION}") - - # Add -Wno-longlong if the GCC version is < 4.0.0. Add -pedantic flag - # but disable warnings for variadic macros with GCC >= 4.0.0. Earlier - # versions warn because of anonymous variadic macros in pedantic mode - # but do not have a flag to disable these warnings. - if (400 GREATER _GCC_VERSION) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long") - else (400 GREATER _GCC_VERSION) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wno-variadic-macros") - endif (400 GREATER _GCC_VERSION) - - # Pass CXX flags to flags. - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSEQAN_CXX_FLAGS_=\"${CMAKE_CXX_FLAGS}\"") -endif (CMAKE_COMPILER_IS_GNUCXX) + # Minimum G++ version: 4.8 + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + message(FATAL_ERROR "G++ 4.8 or higher required") + endif() + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wno-variadic-macros") + + # Pass CXX flags to flags. + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSEQAN_CXX_FLAGS_=\"${CMAKE_CXX_FLAGS}\"") +endif () + +if (MSVC) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0) + message(FATAL_ERROR "Visual Studio 2012 or higher required") + endif() +endif () subdirs(src conf man files) if(WITH_LUA) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index e343de7..3383edb 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -9,11 +9,10 @@ set(CMAKE_MODULE_PATH # include used modules include(DefineInstallationPaths) include(CheckIncludeFileCXX) -include(CheckIncludeFilesCXX) include(CheckFunctionExists) include(CheckSymbolExists) +include(CheckTypeSize) include(CheckLibraryExists) -include(CheckTypeSizeCXX) include(CheckCXXCompilerFlag) include(CheckMkdirArgs) @@ -35,9 +34,9 @@ else(WIN32) set(D2DBS_DEFAULT_CONF_FILE "${SYSCONFDIR}/d2dbs.conf") endif(WIN32) +enable_language(C) # library checks find_package(ZLIB REQUIRED) -check_library_exists(pcap pcap_open_offline "" HAVE_LIBPCAP) check_library_exists(nsl gethostbyname "" HAVE_LIBNSL) check_library_exists(socket socket "" HAVE_LIBSOCKET) check_library_exists(resolv inet_aton "" HAVE_LIBRESOLV) @@ -90,66 +89,74 @@ if(WIN32) SET(NETWORK_LIBRARIES ${NETWORK_LIBRARIES} ws2_32) endif(WIN32) -check_include_files_cxx("cassert;cctype;cerrno;cmath;climits;csignal;cstdarg;cstddef;cstdio;cstdlib;cstring;ctime;deque;exception;fstream;iomanip;iostream;limits;list;map;memory;sstream;stdexcept;string;utility;vector" HAVE_STD_HEADERS) -if(NOT HAVE_STD_HEADERS) - MESSAGE(FATAL_ERROR "Standard C90/C++98 header missing, you need a fully standard compliant compiler/enviroment.") -endif(NOT HAVE_STD_HEADERS) -check_include_file_cxx(fcntl.h HAVE_FCNTL_H) -check_include_file_cxx(sys/time.h HAVE_SYS_TIME_H) -check_include_file_cxx(sys/select.h HAVE_SYS_SELECT_H) -check_include_file_cxx(unistd.h HAVE_UNISTD_H) -check_include_file_cxx(sys/utsname.h HAVE_SYS_UTSNAME_H) -check_include_file_cxx(sys/timeb.h HAVE_SYS_TIMEB_H) -check_include_file_cxx(sys/socket.h HAVE_SYS_SOCKET_H) -check_include_file_cxx(sys/param.h HAVE_SYS_PARAM_H) -check_include_file_cxx(netinet/in.h HAVE_NETINET_IN_H) +message(STATUS "Checking POSIX headers") check_include_file_cxx(arpa/inet.h HAVE_ARPA_INET_H) -check_include_file_cxx(netdb.h HAVE_NETDB_H) -check_include_file_cxx(termios.h HAVE_TERMIOS_H) -check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H) -check_include_file_cxx(sys/wait.h HAVE_SYS_WAIT_H) -check_include_file_cxx(sys/ioctl.h HAVE_SYS_IOCTL_H) -check_include_file_cxx(stdint.h HAVE_STDINT_H) -check_include_file_cxx(sys/file.h HAVE_SYS_FILE_H) -check_include_file_cxx(poll.h HAVE_POLL_H) -check_include_file_cxx(sys/poll.h HAVE_SYS_POLL_H) -check_include_file_cxx(sys/stropts.h HAVE_SYS_STROPTS_H) -check_include_file_cxx(sys/stat.h HAVE_SYS_STAT_H) -check_include_file_cxx(pwd.h HAVE_PWD_H) -check_include_file_cxx(grp.h HAVE_GRP_H) -check_include_file_cxx(dir.h HAVE_DIR_H) check_include_file_cxx(dirent.h HAVE_DIRENT_H) -check_include_file_cxx(ndir.h HAVE_NDIR_H) -check_include_file_cxx(sys/ndir.h HAVE_SYS_NDIR_H) -check_include_file_cxx(sys/dir.h HAVE_SYS_DIR_H) -check_include_file_cxx(direct.h HAVE_DIRECT_H) +check_include_file_cxx(grp.h HAVE_GRP_H) +check_include_file_cxx(fcntl.h HAVE_FCNTL_H) +check_include_file_cxx(netdb.h HAVE_NETDB_H) +check_include_file_cxx(netinet/in.h HAVE_NETINET_IN_H) +check_include_file_cxx(poll.h HAVE_POLL_H) +check_include_file_cxx(pwd.h HAVE_PWD_H) check_include_file_cxx(sys/mman.h HAVE_SYS_MMAN_H) -check_include_files_cxx("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H) -check_include_file_cxx(sys/epoll.h HAVE_SYS_EPOLL_H) check_include_file_cxx(sys/resource.h HAVE_SYS_RESOURCE_H) -check_include_file_cxx(pcap.h HAVE_PCAP_H) +check_include_file_cxx(sys/select.h HAVE_SYS_SELECT_H) +check_include_file_cxx(sys/socket.h HAVE_SYS_SOCKET_H) +check_include_file_cxx(sys/stat.h HAVE_SYS_STAT_H) +check_include_file_cxx(sys/time.h HAVE_SYS_TIME_H) +check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H) +check_include_file_cxx(sys/utsname.h HAVE_SYS_UTSNAME_H) +check_include_file_cxx(sys/wait.h HAVE_SYS_WAIT_H) +check_include_file_cxx(termios.h HAVE_TERMIOS_H) +check_include_file_cxx(unistd.h HAVE_UNISTD_H) + +message(STATUS "Checking optional POSIX/required SUS headers") +check_include_file_cxx(sys/timeb.h HAVE_SYS_TIMEB_H) + +message(STATUS "Checking FreeBSD-based headers") +if (HAVE_SYS_TYPES_H) +check_include_file_cxx(sys/event.h HAVE_SYS_EVENT_H) +endif() +check_include_file_cxx(sys/param.h HAVE_SYS_PARAM_H) + +message(STATUS "Checking BSD headers") +check_include_file_cxx(sys/file.h HAVE_SYS_FILE_H) + +message(STATUS "Checking Linux headers") +check_include_file_cxx(sys/epoll.h HAVE_SYS_EPOLL_H) + +message(STATUS "Checking Win32 headers") check_include_file_cxx(windows.h HAVE_WINDOWS_H) check_include_file_cxx(winsock2.h HAVE_WINSOCK2_H) check_include_file_cxx(process.h HAVE_PROCESS_H) -check_type_size_cxx("unsigned char" SIZEOF_UNSIGNED_CHAR) -check_type_size_cxx("unsigned short" SIZEOF_UNSIGNED_SHORT) -check_type_size_cxx("unsigned int" SIZEOF_UNSIGNED_INT) -check_type_size_cxx("unsigned long" SIZEOF_UNSIGNED_LONG) -check_type_size_cxx("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG) -check_type_size_cxx("signed char" SIZEOF_SIGNED_CHAR) -check_type_size_cxx("signed short" SIZEOF_SIGNED_SHORT) -check_type_size_cxx("signed int" SIZEOF_SIGNED_INT) -check_type_size_cxx("signed long" SIZEOF_SIGNED_LONG) -check_type_size_cxx("signed long long" SIZEOF_SIGNED_LONG_LONG) +message(STATUS "Checking other headers") +check_include_file_cxx(dir.h HAVE_DIR_H) +check_include_file_cxx(direct.h HAVE_DIRECT_H) +check_include_file_cxx(ndir.h HAVE_NDIR_H) +check_include_file_cxx(sys/dir.h HAVE_SYS_DIR_H) +check_include_file_cxx(sys/ndir.h HAVE_SYS_NDIR_H) +check_include_file_cxx(sys/poll.h HAVE_SYS_POLL_H) +#Keep for now +check_include_file_cxx(stdint.h HAVE_STDINT_H) + +check_type_size("unsigned char" SIZEOF_UNSIGNED_CHAR) +check_type_size("unsigned short" SIZEOF_UNSIGNED_SHORT) +check_type_size("unsigned int" SIZEOF_UNSIGNED_INT) +check_type_size("unsigned long" SIZEOF_UNSIGNED_LONG) +check_type_size("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG) +check_type_size("signed char" SIZEOF_SIGNED_CHAR) +check_type_size("signed short" SIZEOF_SIGNED_SHORT) +check_type_size("signed int" SIZEOF_SIGNED_INT) +check_type_size("signed long" SIZEOF_SIGNED_LONG) +check_type_size("signed long long" SIZEOF_SIGNED_LONG_LONG) check_function_exists(mmap HAVE_MMAP) check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) check_function_exists(strdup HAVE_STRDUP) check_function_exists(strtoul HAVE_STRTOUL) check_function_exists(uname HAVE_UNAME) -check_function_exists(uname HAVE_UNAME) check_function_exists(fork HAVE_FORK) check_function_exists(getpid HAVE_GETPID) check_function_exists(sigaction HAVE_SIGACTION) @@ -189,9 +196,9 @@ check_function_exists(setitimer HAVE_SETITIMER) check_function_exists(epoll_create HAVE_EPOLL_CREATE) check_function_exists(getrlimit HAVE_GETRLIMIT) check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) -check_function_exists(_vsnprintf HAVE__VSNPRINTF) +check_symbol_exists(_vsnprintf "stdio.h" HAVE__VSNPRINTF) check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) -check_function_exists(_snprintf HAVE__SNPRINTF) +check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF) check_function_exists(setpgrp HAVE_SETPGRP) check_function_exists(inet_aton HAVE_INET_ATON) diff --git a/cmake/Modules/CheckIncludeFilesCXX.cmake b/cmake/Modules/CheckIncludeFilesCXX.cmake deleted file mode 100644 index 68fa117..0000000 --- a/cmake/Modules/CheckIncludeFilesCXX.cmake +++ /dev/null @@ -1,59 +0,0 @@ -# - Check if the files can be included -# -# CHECK_INCLUDE_FILES_CXX(INCLUDE VARIABLE) -# -# INCLUDE - list of files to include -# VARIABLE - variable to return result -# -# The following variables may be set before calling this macro to -# modify the way the check is run: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories - -MACRO(CHECK_INCLUDE_FILES_CXX INCLUDE VARIABLE) - IF("${VARIABLE}" MATCHES "^${VARIABLE}$") - SET(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") - IF(CMAKE_REQUIRED_INCLUDES) - SET(CHECK_INCLUDE_FILES_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}") - ELSE(CMAKE_REQUIRED_INCLUDES) - SET(CHECK_INCLUDE_FILES_CXX_INCLUDE_DIRS) - ENDIF(CMAKE_REQUIRED_INCLUDES) - SET(CHECK_INCLUDE_FILES_CXX_CONTENT "/* */\n") - SET(MACRO_CHECK_INCLUDE_FILES_CXX_FLAGS ${CMAKE_REQUIRED_FLAGS}) - FOREACH(FILE ${INCLUDE}) - SET(CMAKE_CONFIGURABLE_FILE_CONTENT - "${CMAKE_CONFIGURABLE_FILE_CONTENT}#include <${FILE}>\n") - ENDFOREACH(FILE) - SET(CMAKE_CONFIGURABLE_FILE_CONTENT - "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n\nint main(){return 0;}\n") - CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" - "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.cxx" @ONLY IMMEDIATE) - - MESSAGE(STATUS "Looking for include files ${VARIABLE}") - TRY_COMPILE(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.cxx - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} - CMAKE_FLAGS - -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_CXX_FLAGS} - "${CHECK_INCLUDE_FILES_CXX_INCLUDE_DIRS}" - OUTPUT_VARIABLE OUTPUT) - IF(${VARIABLE}) - MESSAGE(STATUS "Looking for include files ${VARIABLE} - found") - SET(${VARIABLE} 1 CACHE INTERNAL "Have include ${VARIABLE}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if files ${INCLUDE} " - "exist passed with the following output:\n" - "${OUTPUT}\n\n") - ELSE(${VARIABLE}) - MESSAGE(STATUS "Looking for include files ${VARIABLE} - not found.") - SET(${VARIABLE} "" CACHE INTERNAL "Have includes ${VARIABLE}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if files ${INCLUDE} " - "exist failed with the following output:\n" - "${OUTPUT}\nSource:\n${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") - ENDIF(${VARIABLE}) - ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$") -ENDMACRO(CHECK_INCLUDE_FILES_CXX) diff --git a/cmake/Modules/DefineInstallationPaths.cmake b/cmake/Modules/DefineInstallationPaths.cmake index fde8c25..ef7a4b9 100644 --- a/cmake/Modules/DefineInstallationPaths.cmake +++ b/cmake/Modules/DefineInstallationPaths.cmake @@ -3,89 +3,63 @@ IF (NOT APPLICATION_NAME) SET(APPLICATION_NAME ${PROJECT_NAME}) ENDIF (NOT APPLICATION_NAME) -# Suffix for Linux -SET(LIB_SUFFIX - CACHE STRING "Define suffix of directory name (32/64)" -) - SET(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Base directory for executables and libraries" FORCE ) -SET(SHARE_INSTALL_PREFIX - "${CMAKE_INSTALL_PREFIX}/share" - CACHE PATH "Base directory for files which go to share/" - FORCE -) + SET(DATA_INSTALL_PREFIX "${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}" - CACHE PATH "The parent directory where applications can install their data" FORCE) - # The following are directories where stuff will be installed to + CACHE PATH "The parent directory where applications can install their data" + FORCE +) SET(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)" FORCE ) + +#***********************************# + +if(WIN32) + SET(LOCALSTATE_INSTALL_DIR + "${EXEC_INSTALL_PREFIX}/var" + CACHE PATH "The ${APPLICATION_NAME} local state install dir (default prefix/var)" + FORCE + ) +else() + SET(LOCALSTATE_INSTALL_DIR + "${EXEC_INSTALL_PREFIX}/var/${APPLICATION_NAME}" + CACHE PATH "The ${APPLICATION_NAME} local state install dir (default prefix/var)" + FORCE + ) +endif() + +SET(MAN_INSTALL_DIR + "${SHARE_INSTALL_PREFIX}/man" + CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)" + FORCE +) + if(WIN32) SET(SBIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}" CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)" FORCE ) -else(WIN32) +else() SET(SBIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/sbin" CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)" FORCE ) -endif(WIN32) -SET(LIB_INSTALL_DIR - "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" - CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)" - FORCE -) -SET(LIBEXEC_INSTALL_DIR - "${EXEC_INSTALL_PREFIX}/libexec" - CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)" - FORCE -) -SET(PLUGIN_INSTALL_DIR - "${LIB_INSTALL_DIR}/${APPLICATION_NAME}" - CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})" - FORCE -) -SET(INCLUDE_INSTALL_DIR - "${CMAKE_INSTALL_PREFIX}/include" - CACHE PATH "The subdirectory to the header prefix (default prefix/include)" - FORCE -) +endif() -SET(DATA_INSTALL_DIR - "${DATA_INSTALL_PREFIX}" - CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})" - FORCE -) -SET(HTML_INSTALL_DIR - "${DATA_INSTALL_PREFIX}/doc/HTML" - CACHE PATH "The HTML install dir for documentation (default data/doc/html)" - FORCE -) -SET(ICON_INSTALL_DIR - "${DATA_INSTALL_PREFIX}/icons" - CACHE PATH "The icon install dir (default data/icons/)" - FORCE -) -SET(SOUND_INSTALL_DIR - "${DATA_INSTALL_PREFIX}/sounds" - CACHE PATH "The install dir for sound files (default data/sounds)" - FORCE -) - -SET(LOCALE_INSTALL_DIR - "${SHARE_INSTALL_PREFIX}/locale" - CACHE PATH "The install dir for translations (default prefix/share/locale)" +SET(SHARE_INSTALL_PREFIX + "${CMAKE_INSTALL_PREFIX}/share" + CACHE PATH "Base directory for files which go to share/" FORCE ) @@ -95,36 +69,10 @@ if(WIN32) CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default conf)" FORCE ) -else(WIN32) +else() SET(SYSCONF_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/etc/${APPLICATION_NAME}" CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)" FORCE ) -endif(WIN32) - -SET(MAN_INSTALL_DIR - "${SHARE_INSTALL_PREFIX}/man" - CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)" - FORCE -) -SET(INFO_INSTALL_DIR - "${SHARE_INSTALL_PREFIX}/info" - CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)" - FORCE -) - -if(WIN32) - SET(LOCALSTATE_INSTALL_DIR - "${EXEC_INSTALL_PREFIX}/var" - CACHE PATH "The ${APPLICATION_NAME} local state install dir (default prefix/var)" - FORCE - ) -else(WIN32) - SET(LOCALSTATE_INSTALL_DIR - "${EXEC_INSTALL_PREFIX}/var/${APPLICATION_NAME}" - CACHE PATH "The ${APPLICATION_NAME} local state install dir (default prefix/var)" - FORCE - ) -endif(WIN32) - +endif() \ No newline at end of file diff --git a/config.h.cmake b/config.h.cmake index 906bb93..b1341a0 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -15,12 +15,10 @@ #cmakedefine HAVE_TERMIOS_H #cmakedefine HAVE_SYS_TYPES_H #cmakedefine HAVE_SYS_WAIT_H -#cmakedefine HAVE_SYS_IOCTL_H #cmakedefine HAVE_STDINT_H #cmakedefine HAVE_SYS_FILE_H #cmakedefine HAVE_POLL_H #cmakedefine HAVE_SYS_POLL_H -#cmakedefine HAVE_SYS_STROPTS_H #cmakedefine HAVE_SYS_STAT_H #cmakedefine HAVE_PWD_H #cmakedefine HAVE_GRP_H @@ -34,7 +32,6 @@ #cmakedefine HAVE_SYS_EVENT_H #cmakedefine HAVE_SYS_EPOLL_H #cmakedefine HAVE_SYS_RESOURCE_H -#cmakedefine HAVE_PCAP_H #cmakedefine HAVE_WINDOWS_H #cmakedefine HAVE_WINSOCK2_H #cmakedefine HAVE_PROCESS_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e59e19..14827fc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -54,10 +54,6 @@ if(WITH_D2DBS) add_subdirectory(d2dbs) endif(WITH_D2DBS) -if(HAVE_PCAP_H AND HAVE_LIBPCAP) - add_subdirectory(bnpcap) -endif(HAVE_PCAP_H AND HAVE_LIBPCAP) - if(CMAKE_TESTING_ENABLED) add_subdirectory(test) endif(CMAKE_TESTING_ENABLED) diff --git a/src/bnetd/i18n.cpp b/src/bnetd/i18n.cpp index 5da0694..f47f2ce 100644 --- a/src/bnetd/i18n.cpp +++ b/src/bnetd/i18n.cpp @@ -69,13 +69,13 @@ namespace pvpgn const char * commonfile = "common.xml"; // filename template, actually file name is "common-{lang}.xml" /* Array with string translations, each string has array with pair language=translation - { - original = { - { language = translate }, - ... - }, - ... - } + { + original = { + { language = translate }, + ... + }, + ... + } */ std::map > translations = std::map >(); @@ -232,7 +232,7 @@ namespace pvpgn // if not found then init //if (it == translations.end()) // translations[original] = std::map(); - + // check if translate string has a reference to another translation if (pugi::xml_attribute attr = node.child("translate").attribute("refid")) @@ -277,8 +277,8 @@ namespace pvpgn try { if (lang = conn_get_gamelang_localized(c)) - if (!(format = _find_string(fmt, lang))) - format = fmt; // if not found use original + if (!(format = _find_string(fmt, lang))) + format = fmt; // if not found use original output = fmt::format(format, args); @@ -314,7 +314,7 @@ namespace pvpgn extern const char * i18n_filename(const char * filename, t_tag gamelang) { // get language string - char lang_str[sizeof(t_tag)+1]; + char lang_str[sizeof(t_tag) + 1]; std::memset(lang_str, 0, sizeof(lang_str)); tag_uint_to_str(lang_str, gamelang); @@ -343,8 +343,8 @@ namespace pvpgn return tag_str_to_uint(countries[0][0]); for (int i = 0; i < (sizeof(countries) / sizeof(*countries)); i++) - if (strcasecmp(code, countries[i][0]) == 0) - return tag_str_to_uint(countries[i][1]); + if (strcasecmp(code, countries[i][0]) == 0) + return tag_str_to_uint(countries[i][1]); return tag_str_to_uint(countries[0][1]); // default } @@ -355,13 +355,13 @@ namespace pvpgn // force localize by user country if (prefs_get_localize_by_country()) - if (const char * country = conn_get_country(c)) - lang = lang_find_by_country(country); + if (const char * country = conn_get_country(c)) + lang = lang_find_by_country(country); // if user set own language if (t_account * a = conn_get_account(c)) - if (const char * l = account_get_userlang(a)) - lang = tag_str_to_uint(l); + if (const char * l = account_get_userlang(a)) + lang = tag_str_to_uint(l); // FIXME: Russian text displays not correctly directly in game in non-russian Starcraft // but most Russians use English Starcraft. @@ -369,10 +369,10 @@ namespace pvpgn // // Return English text in game for Russian if (t_clienttag clienttag = conn_get_clienttag(c)) - if (lang == GAMELANG_RUSSIAN_UINT && conn_get_game(c) && - (clienttag == CLIENTTAG_STARCRAFT_UINT || clienttag == CLIENTTAG_BROODWARS_UINT || clienttag == CLIENTTAG_STARJAPAN_UINT || clienttag == CLIENTTAG_SHAREWARE_UINT || - clienttag == CLIENTTAG_DIABLORTL_UINT || clienttag == CLIENTTAG_DIABLOSHR_UINT || clienttag == CLIENTTAG_WARCIIBNE_UINT)) - lang = GAMELANG_ENGLISH_UINT; + if (lang == GAMELANG_RUSSIAN_UINT && conn_get_game(c) && + (clienttag == CLIENTTAG_STARCRAFT_UINT || clienttag == CLIENTTAG_BROODWARS_UINT || clienttag == CLIENTTAG_STARJAPAN_UINT || clienttag == CLIENTTAG_SHAREWARE_UINT || + clienttag == CLIENTTAG_DIABLORTL_UINT || clienttag == CLIENTTAG_DIABLOSHR_UINT || clienttag == CLIENTTAG_WARCIIBNE_UINT)) + lang = GAMELANG_ENGLISH_UINT; return lang; @@ -437,41 +437,58 @@ namespace pvpgn switch (gamelang) { - case GAMELANG_RUSSIAN_UINT: - // All Blizzard games except Warcraft 3 - if (clienttag == CLIENTTAG_STARCRAFT_UINT || clienttag == CLIENTTAG_BROODWARS_UINT || clienttag == CLIENTTAG_STARJAPAN_UINT || clienttag == CLIENTTAG_SHAREWARE_UINT || - clienttag == CLIENTTAG_DIABLORTL_UINT || clienttag == CLIENTTAG_DIABLOSHR_UINT || clienttag == CLIENTTAG_WARCIIBNE_UINT || - clienttag == CLIENTTAG_DIABLO2DV_UINT || clienttag == CLIENTTAG_DIABLO2XP_UINT) - { - convert_utf8_to_windows1251(buf, buf, MAX_MESSAGE_LEN); - } - // There is an additional conversion in Starcraft and Diablo 2 - if (clienttag == CLIENTTAG_STARCRAFT_UINT || clienttag == CLIENTTAG_BROODWARS_UINT || clienttag == CLIENTTAG_STARJAPAN_UINT || clienttag == CLIENTTAG_SHAREWARE_UINT || - clienttag == CLIENTTAG_DIABLO2DV_UINT || clienttag == CLIENTTAG_DIABLO2XP_UINT) - { - convert_windows1252_to_utf8(buf); - } - break; - - default: - break; + case GAMELANG_RUSSIAN_UINT: + // All Blizzard games except Warcraft 3 + if (clienttag == CLIENTTAG_STARCRAFT_UINT || clienttag == CLIENTTAG_BROODWARS_UINT || clienttag == CLIENTTAG_STARJAPAN_UINT || clienttag == CLIENTTAG_SHAREWARE_UINT || + clienttag == CLIENTTAG_DIABLORTL_UINT || clienttag == CLIENTTAG_DIABLOSHR_UINT || clienttag == CLIENTTAG_WARCIIBNE_UINT || + clienttag == CLIENTTAG_DIABLO2DV_UINT || clienttag == CLIENTTAG_DIABLO2XP_UINT) + { + convert_utf8_to_windows1251(buf, buf, MAX_MESSAGE_LEN); } - return buf; + // There is an additional conversion in Starcraft and Diablo 2 + if (clienttag == CLIENTTAG_STARCRAFT_UINT || clienttag == CLIENTTAG_BROODWARS_UINT || clienttag == CLIENTTAG_STARJAPAN_UINT || clienttag == CLIENTTAG_SHAREWARE_UINT || + clienttag == CLIENTTAG_DIABLO2DV_UINT || clienttag == CLIENTTAG_DIABLO2XP_UINT) + { + convert_windows1252_to_utf8(buf); + } + break; + + default: + break; + } + return buf; } -/* -* Text conversion for Russian text -*/ + /* + * Text conversion for Russian text + */ #ifndef REGION_CONVERT_RUSSIAN - typedef struct ConvLetter { - char win1251; - int unicode; + typedef struct ConvLetter + { + char win1251; + int unicode; } Letter; - static Letter g_letters[] = { { 0x82, 0x201A }, { 0x83, 0x0453 }, { 0x84, 0x201E }, { 0x85, 0x2026 }, { 0x86, 0x2020 }, { 0x87, 0x2021 }, { 0x88, 0x20AC }, { 0x89, 0x2030 }, { 0x8A, 0x0409 }, { 0x8B, 0x2039 }, { 0x8C, 0x040A }, { 0x8D, 0x040C }, { 0x8E, 0x040B }, { 0x8F, 0x040F }, { 0x90, 0x0452 }, { 0x91, 0x2018 }, { 0x92, 0x2019 }, { 0x93, 0x201C }, { 0x94, 0x201D }, { 0x95, 0x2022 }, { 0x96, 0x2013 }, { 0x97, 0x2014 }, { 0x99, 0x2122 }, { 0x9A, 0x0459 }, { 0x9B, 0x203A }, { 0x9C, 0x045A }, { 0x9D, 0x045C }, { 0x9E, 0x045B }, { 0x9F, 0x045F }, { 0xA0, 0x00A0 }, { 0xA1, 0x040E }, { 0xA2, 0x045E }, { 0xA3, 0x0408 }, { 0xA4, 0x00A4 }, { 0xA5, 0x0490 }, { 0xA6, 0x00A6 }, { 0xA7, 0x00A7 }, { 0xA8, 0x0401 }, { 0xA9, 0x00A9 }, { 0xAA, 0x0404 }, { 0xAB, 0x00AB }, { 0xAC, 0x00AC }, { 0xAD, 0x00AD }, { 0xAE, 0x00AE }, { 0xAF, 0x0407 }, { 0xB0, 0x00B0 }, { 0xB1, 0x00B1 }, { 0xB2, 0x0406 }, { 0xB3, 0x0456 }, { 0xB4, 0x0491 }, { 0xB5, 0x00B5 }, { 0xB6, 0x00B6 }, { 0xB7, 0x00B7 }, { 0xB8, 0x0451 }, { 0xB9, 0x2116 }, { 0xBA, 0x0454 }, { 0xBB, 0x00BB }, { 0xBC, 0x0458 }, { 0xBD, 0x0405 }, { 0xBE, 0x0455 }, { 0xBF, 0x0457 } }; - + static Letter g_letters[] = { + { static_cast(0x82), 0x201A }, { static_cast(0x83), 0x0453 }, { static_cast(0x84), 0x201E }, { static_cast(0x85), 0x2026 }, + { static_cast(0x86), 0x2020 }, { static_cast(0x87), 0x2021 }, { static_cast(0x88), 0x20AC }, { static_cast(0x89), 0x2030 }, + { static_cast(0x8A), 0x0409 }, { static_cast(0x8B), 0x2039 }, { static_cast(0x8C), 0x040A }, { static_cast(0x8D), 0x040C }, + { static_cast(0x8E), 0x040B }, { static_cast(0x8F), 0x040F }, { static_cast(0x90), 0x0452 }, { static_cast(0x91), 0x2018 }, + { static_cast(0x92), 0x2019 }, { static_cast(0x93), 0x201C }, { static_cast(0x94), 0x201D }, { static_cast(0x95), 0x2022 }, + { static_cast(0x96), 0x2013 }, { static_cast(0x97), 0x2014 }, { static_cast(0x99), 0x2122 }, { static_cast(0x9A), 0x0459 }, + { static_cast(0x9B), 0x203A }, { static_cast(0x9C), 0x045A }, { static_cast(0x9D), 0x045C }, { static_cast(0x9E), 0x045B }, + { static_cast(0x9F), 0x045F }, { static_cast(0xA0), 0x00A0 }, { static_cast(0xA1), 0x040E }, { static_cast(0xA2), 0x045E }, + { static_cast(0xA3), 0x0408 }, { static_cast(0xA4), 0x00A4 }, { static_cast(0xA5), 0x0490 }, { static_cast(0xA6), 0x00A6 }, + { static_cast(0xA7), 0x00A7 }, { static_cast(0xA8), 0x0401 }, { static_cast(0xA9), 0x00A9 }, { static_cast(0xAA), 0x0404 }, + { static_cast(0xAB), 0x00AB }, { static_cast(0xAC), 0x00AC }, { static_cast(0xAD), 0x00AD }, { static_cast(0xAE), 0x00AE }, + { static_cast(0xAF), 0x0407 }, { static_cast(0xB0), 0x00B0 }, { static_cast(0xB1), 0x00B1 }, { static_cast(0xB2), 0x0406 }, + { static_cast(0xB3), 0x0456 }, { static_cast(0xB4), 0x0491 }, { static_cast(0xB5), 0x00B5 }, { static_cast(0xB6), 0x00B6 }, + { static_cast(0xB7), 0x00B7 }, { static_cast(0xB8), 0x0451 }, { static_cast(0xB9), 0x2116 }, { static_cast(0xBA), 0x0454 }, + { static_cast(0xBB), 0x00BB }, { static_cast(0xBC), 0x0458 }, { static_cast(0xBD), 0x0405 }, { static_cast(0xBE), 0x0455 }, + { static_cast(0xBF), 0x0457 } }; + // https://code.google.com/p/convert-utf8-to-cp1251/ int convert_utf8_to_windows1251(const char* utf8, char* windows1251, size_t n) { diff --git a/src/bnpcap/CMakeLists.txt b/src/bnpcap/CMakeLists.txt deleted file mode 100644 index 59bac28..0000000 --- a/src/bnpcap/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_executable(bnpcap bnpcap.cpp) -target_link_libraries(bnpcap common pcap) - -install(TARGETS bnpcap DESTINATION ${BINDIR}) diff --git a/src/bnpcap/bnpcap.cpp b/src/bnpcap/bnpcap.cpp deleted file mode 100644 index 8c83e2f..0000000 --- a/src/bnpcap/bnpcap.cpp +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright (C) 2001 Marco Ziech (mmz@gmx.net) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include "common/setup_before.h" -#include -#include - -#include - -#include "compat/pgetopt.h" -#include "compat/psock.h" -#include "common/init_protocol.h" -#include "common/bnet_protocol.h" -#include "common/udp_protocol.h" -#include "common/packet.h" -#include "common/eventlog.h" -#include "common/hexdump.h" -#include "common/list.h" -#include "common/version.h" -#include "common/util.h" -#include "common/xalloc.h" -#include "common/setup_after.h" - -using namespace pvpgn; - -/* FIXME: everywhere: add checks for NULL pointers */ - -char *filename = NULL; -pcap_t *pc; -char ebuf[PCAP_ERRBUF_SIZE]; - - -int bnpcap_dodebug = 0; -int bnpcap_beverbose = 0; - -unsigned int listen_port = 6112; - -/********************* CONNECTIONS ********************/ - -typedef enum { - tcp_state_none, - tcp_state_syn, - tcp_state_ack, - tcp_state_ok -} t_tcp_state; - -typedef struct { - /* It's IPV4 */ - unsigned int ip; - unsigned short port; -} t_bnpcap_addr; - -/* To track connections ... */ -typedef struct { - t_bnpcap_addr client; - t_bnpcap_addr server; - t_packet_class cclass; - t_tcp_state tcpstate; - int incomplete; - int clientoff; - t_packet *clientpkt; - int serveroff; - t_packet *serverpkt; - t_list * packets; -} t_bnpcap_conn; - -typedef struct { - t_packet_dir dir; - struct timeval tv; - unsigned int id; - t_packet *p; -} t_bnpcap_packet; - -t_list * conns; -t_list * udppackets; - -struct timeval packettime; - -static unsigned int current_packet_id = 1; - -/*********************** HEADERS **********************/ - -/* FIXME: don't assume that's always true */ -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; - -/************************** TCP ***********************/ - -typedef struct { - u16 sport; - u16 dport; - u32 seqno; - u32 ackno; - u16 stuff; /* Data offset, various flags */ - u16 window; - u16 checksum; - u16 urgp; /* Urgent Pointer (if URG flag set) */ - /* options */ -} t_tcp_header_raw; - -typedef struct { - unsigned short sport; - unsigned short dport; - unsigned int seqno; - unsigned int ackno; - unsigned char doffset; - unsigned short flags; -#define TCP_URG 0x20 /* Urgent pointer field significant */ -#define TCP_ACK 0x10 /* Acknowlegdement field significant */ -#define TCP_PSH 0x08 /* Push function */ -#define TCP_RST 0x04 /* Reset connection */ -#define TCP_SYN 0x02 /* Synchronize sequence numbers */ -#define TCP_FIN 0x01 /* No more data from sender (finish) */ - unsigned short window; - unsigned short checksum; - unsigned short urgp; - /* options */ -} t_tcp_header; - -/******************************** UDP ************************/ - -typedef struct { - u16 sport; - u16 dport; - u16 len; - u16 checksum; -} t_ip_udp_header_raw; - -typedef struct { - unsigned short sport; - unsigned short dport; - unsigned short len; - unsigned short checksum; -} t_ip_udp_header; - -/******************************** IP *************************/ - -typedef struct { - u8 versionihl; - u8 tos; - u16 len; - u16 id; - u16 flagsoffset; - u8 ttl; - u8 protocol; - u16 checksum; - u32 src; - u32 dst; - /* options */ -} t_ip_header_raw; - -typedef struct { - unsigned char version; - unsigned char ihl; - unsigned char tos; - unsigned short len; - unsigned short id; - unsigned char flags; -#define IP_DF 0x02 /* 1 == Don't fragment */ -#define IP_MF 0x01 /* 1 == More fragments */ - unsigned short offset; - unsigned char ttl; - unsigned char protocol; - unsigned short checksum; - unsigned int src; - unsigned int dst; - /* options */ -} t_ip_header; - -/******************************* ETHERNET *****************************/ - -typedef struct { - u8 dst[6]; /* Ethernet hardware address */ - u8 src[6]; /* Ethernet hardware address */ - u16 type; /* Ethernet_II: protocol type */ - /* FIXME: Ethernet [802.2|802.3|SNAP]: maybe something else (eg. length) */ -} t_ether_raw; - -/************************************************************************/ -/************************* CONNECTION FUNCTIONS *************************/ - -static t_bnpcap_conn * bnpcap_conn_new(t_bnpcap_addr const *s, t_bnpcap_addr const *d) -{ - t_bnpcap_conn * c; - - c = (t_bnpcap_conn *)xmalloc(sizeof(t_bnpcap_conn)); /* avoid warning */ - if (!c) { - eventlog(eventlog_level_error, __FUNCTION__, "xalloc failed: %s", std::strerror(errno)); - return NULL; - } - if (d->port == listen_port || d->port == 6200) { /* FIXME: That's dirty: We assume the server is on port 6112 */ - std::memcpy(&c->client, s, sizeof(t_bnpcap_addr)); - std::memcpy(&c->server, d, sizeof(t_bnpcap_addr)); - } - else { - std::memcpy(&c->client, d, sizeof(t_bnpcap_addr)); - std::memcpy(&c->server, s, sizeof(t_bnpcap_addr)); - } - c->cclass = packet_class_init; - c->packets = list_create(); - c->incomplete = 0; - c->tcpstate = tcp_state_none; - c->clientoff = 0; - c->clientpkt = NULL; - c->serveroff = 0; - c->serverpkt = NULL; - return c; -} - -static void bnpcap_conn_set_class(t_bnpcap_conn *c, t_packet_class cclass) -{ - c->cclass = cclass; -} - -static t_packet_class bnpcap_conn_get_class(t_bnpcap_conn *c) -{ - return c->cclass; -} - -static t_bnpcap_conn * bnpcap_conn_find(t_bnpcap_addr const *s, t_bnpcap_addr const *d) -{ - t_elem * curr; - - LIST_TRAVERSE(conns, curr) { - t_bnpcap_conn *c; - - c = (t_bnpcap_conn*)elem_get_data(curr); - if (((c->client.ip == s->ip) && (c->client.port == s->port)) && - ((c->server.ip == d->ip) && (c->server.port == d->port))) { - return c; - } - else if (((c->client.ip == d->ip) && (c->client.port == d->port)) && - ((c->server.ip == s->ip) && (c->server.port == s->port))) { - return c; - } - } - return NULL; -} - -static t_packet_dir bnpcap_conn_get_dir(t_bnpcap_conn const * c, t_bnpcap_addr const *s, t_bnpcap_addr const *d) -{ - if (((c->client.ip == s->ip) && (c->client.port == s->port)) && - ((c->server.ip == d->ip) && (c->server.port == d->port))) - return packet_dir_from_client; - else - return packet_dir_from_server; -} - -static int bnpcap_conn_add_packet(t_bnpcap_conn *c, t_bnpcap_packet *bp) { - eventlog(eventlog_level_debug, __FUNCTION__, "id=%u ", bp->id); - list_append_data(c->packets, bp); - packet_add_ref(bp->p); - return 0; -} - -static int bnpcap_conn_packet(unsigned int sip, unsigned short sport, unsigned int dip, unsigned short dport, unsigned char const * data, unsigned int len) -{ - t_bnpcap_addr s; - t_bnpcap_addr d; - t_bnpcap_conn *c; - t_bnpcap_packet *bp; - - s.ip = sip; - s.port = sport; - d.ip = dip; - d.port = dport; - - if ((c = bnpcap_conn_find(&s, &d))) { - eventlog(eventlog_level_debug, __FUNCTION__, "adding packet to existing connection"); - if (c->tcpstate == tcp_state_ack) { - c->tcpstate = tcp_state_ok; - } - else if (c->tcpstate == tcp_state_syn) { - c->incomplete = 1; /* ACK missing */ - c->tcpstate = tcp_state_ok; - } - } - else { - eventlog(eventlog_level_debug, __FUNCTION__, "adding packet to incomplete connection"); - c = bnpcap_conn_new(&s, &d); - bnpcap_conn_set_class(c, packet_class_raw); /* we don't know the init sequence */ - c->incomplete = 1; - c->tcpstate = tcp_state_ok; - list_append_data(conns, c); - } - if (c->tcpstate != tcp_state_ok) { - eventlog(eventlog_level_warn, __FUNCTION__, "connection got packet in wrong state!"); - } - if (bnpcap_conn_get_class(c) == packet_class_init) { - if (len > 1) { - eventlog(eventlog_level_warn, __FUNCTION__, "init packet larger than 1 byte"); - } - switch (data[0]) { - case CLIENT_INITCONN_CLASS_BNET: - bnpcap_conn_set_class(c, packet_class_bnet); - break; - case CLIENT_INITCONN_CLASS_FILE: - bnpcap_conn_set_class(c, packet_class_file); - break; - case 0xf7: // W3 matchmaking hack - eventlog(eventlog_level_info, __FUNCTION__, "matchmaking packet"); - bnpcap_conn_set_class(c, packet_class_bnet); - break; - default: - bnpcap_conn_set_class(c, packet_class_raw); - } - } - else { - t_packet *p; - unsigned int off; - unsigned char const *datap = data; - int always_complete = 0; - - - if (bnpcap_conn_get_class(c) == packet_class_raw) - always_complete = 1; /* There is no size field */ - if (bnpcap_conn_get_class(c) == packet_class_file) - always_complete = 1; /* Size field isn't always there */ - - if (always_complete) { - /* packet is always complete */ - eventlog(eventlog_level_debug, __FUNCTION__, "packet is always complete (class=%d)", bnpcap_conn_get_class(c)); - bp = (t_bnpcap_packet *)xmalloc(sizeof(t_bnpcap_packet)); /* avoid warning */ - if (!bp) { - eventlog(eventlog_level_error, __FUNCTION__, "xalloc failed: %s", std::strerror(errno)); - return -1; - } - bp->dir = bnpcap_conn_get_dir(c, &s, &d); - bp->p = packet_create(bnpcap_conn_get_class(c)); - bp->id = current_packet_id++; - if (!bp->p) { - eventlog(eventlog_level_error, __FUNCTION__, "packet_create failed"); - return -1; - } - std::memcpy(&bp->tv, &packettime, sizeof(struct timeval)); - packet_set_size(bp->p, len); - std::memcpy(packet_get_raw_data(bp->p, 0), data, len); - bnpcap_conn_add_packet(c, bp); - if ((packet_get_class(bp->p) == packet_class_file) && (packet_get_type(bp->p) == SERVER_FILE_REPLY)) { - eventlog(eventlog_level_debug, __FUNCTION__, "file transfer initiated (setting to raw)"); - bnpcap_conn_set_class(c, packet_class_raw); - } - } - else { - /* read out saved state */ - if (bnpcap_conn_get_dir(c, &s, &d) == packet_dir_from_client) { - p = c->clientpkt; - off = c->clientoff; - } - else { - p = c->serverpkt; - off = c->serveroff; - } - while ((datap - data) < (signed)len) { - if (!p) { - eventlog(eventlog_level_debug, __FUNCTION__, "creating new packet"); - p = packet_create(bnpcap_conn_get_class(c)); - if (!p) { - eventlog(eventlog_level_error, __FUNCTION__, "packet_create failed"); - return -1; - } - packet_set_size(p, packet_get_header_size(p)); /* set it to the minimum for now */ - off = 0; - } - if (off < packet_get_header_size(p)) { - unsigned int l = (packet_get_header_size(p) - off); - /* (len-(datap-data)) : remaining bytes in buffer */ - if ((len - (datap - data)) < l) - l = (len - (datap - data)); - eventlog(eventlog_level_debug, __FUNCTION__, "filling up header (adding %d to %d to get %d)", l, off, packet_get_header_size(p)); - std::memcpy(packet_get_raw_data(p, off), datap, l); - datap = datap + l; - off = off + l; - } - else { - unsigned int l = (packet_get_size(p) - off); - if ((len - (datap - data)) < l) - l = (len - (datap - data)); - eventlog(eventlog_level_debug, __FUNCTION__, "filling up packet (0x%04x:%s) (adding %d to %d to get %d)", packet_get_type(p), packet_get_type_str(p, bnpcap_conn_get_dir(c, &s, &d)), l, off, packet_get_size(p)); - std::memcpy(packet_get_raw_data(p, off), datap, l); - datap = datap + l; - off = off + l; - } - if ((off >= packet_get_header_size(p)) && (off >= packet_get_size(p))) { - /* packet is complete */ - eventlog(eventlog_level_debug, __FUNCTION__, "packet is complete"); - bp = (t_bnpcap_packet *)xmalloc(sizeof(t_bnpcap_packet)); /* avoid warning */ - if (!bp) { - eventlog(eventlog_level_error, __FUNCTION__, "xalloc failed: %s", std::strerror(errno)); - return -1; - } - if ((off != packet_get_size(p)) && (bnpcap_dodebug)) { - eventlog(eventlog_level_warn, __FUNCTION__, "packet size differs (%d != %d) (offset=0x%04lx)", off, packet_get_size(p), datap - data); - hexdump(stderr, data, len); - /* std::memcpy(packet_get_raw_data(p,0),data,packet_get_size(p)); */ - } - bp->dir = bnpcap_conn_get_dir(c, &s, &d); - bp->p = p; - bp->id = current_packet_id++; - std::memcpy(&bp->tv, &packettime, sizeof(struct timeval)); - bnpcap_conn_add_packet(c, bp); - if (packet_get_size(p) == 0) - datap = data + len; /* if size is invalid, drop the rest of the stream packet */ - p = NULL; - off = 0; - } - } /* while */ - /* write back saved state */ - if ((off > 0) && (bnpcap_dodebug)) { - eventlog(eventlog_level_debug, __FUNCTION__, "saving %d bytes in packet buffer (p=0x%08lx)", off, (long)p); - } - if (bnpcap_conn_get_dir(c, &s, &d) == packet_dir_from_client) { - c->clientpkt = p; - c->clientoff = off; - } - else { - c->serverpkt = p; - c->serveroff = off; - } - } /* !always_complete */ - return 0; - } - return 0; -} - - -/************************************************************************/ -/******************************** LAYERS ********************************/ - -/********************************* TCP **********************************/ - -static int bnpcap_tcp2tcp(t_tcp_header * d, t_tcp_header_raw const * s) -{ - d->sport = htons(s->sport); - d->dport = htons(s->dport); - d->seqno = htonl(s->seqno); - d->ackno = htonl(s->ackno); - d->doffset = (htons(s->stuff) & 0xF000) >> 12; - d->flags = (htons(s->stuff) & 0x0FFF); - d->window = htons(s->window); - d->checksum = htons(s->checksum); - d->urgp = htons(s->urgp); - return 0; -} - -static int bnpcap_process_tcp(t_ip_header const * ip, unsigned char const *data, unsigned int len) -{ - t_tcp_header_raw const *raw; - t_tcp_header h; - - raw = (t_tcp_header_raw const *)data; /* avoid warning */ - bnpcap_tcp2tcp(&h, raw); - if (h.doffset < 5) { - eventlog(eventlog_level_warn, __FUNCTION__, "tcp header too small (%u 32-bit words)", h.doffset); - return 1; - } - else { - char fstr[32] = ""; - - if (h.flags & TCP_URG) - std::strcat(fstr, "U"); - if (h.flags & TCP_ACK) - std::strcat(fstr, "A"); - if (h.flags & TCP_PSH) - std::strcat(fstr, "P"); - if (h.flags & TCP_RST) - std::strcat(fstr, "R"); - if (h.flags & TCP_SYN) - std::strcat(fstr, "S"); - if (h.flags & TCP_FIN) - std::strcat(fstr, "F"); - eventlog(eventlog_level_debug, __FUNCTION__, "tcp: sport=%u dport=%u seqno=0x%08x ackno=0x%08x window=0x%08x len=%d (%s)", h.sport, h.dport, h.seqno, h.ackno, h.window, ((signed)len - (h.doffset * 4)), fstr); - if (((signed)len - (h.doffset * 4)) <= 0) { - eventlog(eventlog_level_info, __FUNCTION__, "empty packet (%d)", ((signed)len - (h.doffset * 4))); - /* handle sync packets */ - if (h.flags & TCP_SYN) { - t_bnpcap_addr s, d; - - s.ip = ip->src; s.port = h.sport; - d.ip = ip->dst; d.port = h.dport; - if (h.flags & TCP_ACK) { - t_bnpcap_conn *c = bnpcap_conn_find(&s, &d); - - if (c) { - if (c->tcpstate == tcp_state_syn) - c->tcpstate = tcp_state_ack; - } - } - else { - if (!bnpcap_conn_find(&s, &d)) { - t_bnpcap_conn *c; - - c = bnpcap_conn_new(&s, &d); - c->tcpstate = tcp_state_syn; - list_append_data(conns, c); - eventlog(eventlog_level_debug, __FUNCTION__, "created new connection with SYN"); - } - else { - eventlog(eventlog_level_debug, __FUNCTION__, "got SYN in connection"); - } - } - } - } - else if (((h.sport != listen_port) && (h.dport != listen_port)) && ((h.sport != 6200) && (h.dport != 6200))) { - eventlog(eventlog_level_info, __FUNCTION__, "other packet (%d)", ((signed)len - (h.doffset * 4))); - } - else { - eventlog(eventlog_level_info, __FUNCTION__, "valid packet (%d)", ((signed)len - (h.doffset * 4))); - bnpcap_conn_packet(ip->src, h.sport, ip->dst, h.dport, data + (h.doffset * 4), len - (h.doffset * 4)); - } - return 0; - } -} - -/************************************ UDP ********************************/ - -static int bnpcap_udp2udp(t_ip_udp_header *d, t_ip_udp_header_raw const *s) -{ - d->sport = ntohs(s->sport); - d->dport = ntohs(s->dport); - d->len = ntohs(s->len); - d->checksum = ntohs(s->checksum); - return 0; -} - -static int bnpcap_process_udp(unsigned char const *data, unsigned int len) -{ - t_ip_udp_header_raw const *raw; - t_ip_udp_header h; - t_bnpcap_packet *bp; - - raw = (t_ip_udp_header_raw const *)data; /* avoid warning */ - bnpcap_udp2udp(&h, raw); - - bp = (t_bnpcap_packet *)xmalloc(sizeof(t_bnpcap_packet)); /* avoid warning */ - if (!bp) { - eventlog(eventlog_level_error, __FUNCTION__, "xalloc failed: %s", std::strerror(errno)); - return -1; - } - if (h.dport == listen_port || h.dport == 6200) { - bp->dir = packet_dir_from_client; - } - else { - bp->dir = packet_dir_from_server; - } - eventlog(eventlog_level_debug, __FUNCTION__, "sport=%u dport=%u len=%u(%d)", h.sport, h.dport, h.len, len); - bp->id = current_packet_id++; - std::memcpy(&bp->tv, &packettime, sizeof(struct timeval)); - bp->p = packet_create(packet_class_udp); - if (!bp->p) { - eventlog(eventlog_level_error, __FUNCTION__, "packet_create failed"); - return -1; - } - packet_set_size(bp->p, h.len - sizeof(t_ip_udp_header_raw)); - std::memcpy(packet_get_raw_data(bp->p, 0), data + sizeof(t_ip_udp_header_raw), h.len - sizeof(t_ip_udp_header_raw)); - eventlog(eventlog_level_error, __FUNCTION__, "id=%u ", bp->id); - list_append_data(udppackets, bp); - return 0; -} - -/************************************ IP *********************************/ - -static int bnpcap_ip2ip(t_ip_header * d, t_ip_header_raw const * s) -{ - d->version = ((s->versionihl & 0xf0) >> 4); - d->ihl = s->versionihl & 0x0f; - d->tos = s->tos; - d->len = ntohs(s->len); - d->id = ntohs(s->id); - d->offset = ntohl(s->flagsoffset); - d->flags = ((d->offset & 0xE000) >> 13); - d->offset = ((d->offset & 0x1FFF)); - d->ttl = s->ttl; - d->protocol = s->protocol; - d->checksum = ntohs(s->checksum); - d->src = ntohl(s->src); - d->dst = ntohl(s->dst); - return 0; -} - - -static int bnpcap_process_ip(unsigned char const *data, unsigned int len) -{ - /* FIXME: handle IP fragmentation */ - /* FIXME: use identification field to pass the datagram in the right order */ - t_ip_header_raw const *raw; - t_ip_header h; - - raw = (t_ip_header_raw const *)data; /* avoid warning */ - bnpcap_ip2ip(&h, raw); - if (h.version != 4) { - eventlog(eventlog_level_warn, __FUNCTION__, "ip version %u not supported (ihl=%u, raw=0x%02x)", h.version, h.ihl, raw->versionihl); - return 1; - } - else if (h.ihl < 5) { - /* an IP header must be at least 5 words */ - eventlog(eventlog_level_warn, __FUNCTION__, "ip header to small (%u 32-bit words)", h.ihl); - return 1; - } - else if (h.len > len) { - eventlog(eventlog_level_warn, __FUNCTION__, "ip len larger than packet (%d > %d)", h.len, len); - return 1; - } - else { - char fstr[32] = ""; - - if (h.flags & IP_DF) - std::strcat(fstr, "D"); - if (h.flags & IP_MF) - std::strcat(fstr, "M"); - eventlog(eventlog_level_debug, __FUNCTION__, "ip: len=%u(%u) src=%08x dst=%08x protocol=%u offset=0x%08x id=0x%08x (%s)", h.len, len, h.src, h.dst, h.protocol, h.offset, h.id, fstr); - if (h.protocol == 6) { - /* This is TCP */ - return bnpcap_process_tcp(&h, data + (h.ihl * 4), h.len - (h.ihl * 4)); - } - else if (h.protocol == 17) { - /* This is UDP */ - return bnpcap_process_udp(data + (h.ihl * 4), h.len - (h.ihl * 4)); - } - } - return 0; -} - -/************************************* ETHERNET ******************************/ - -static int bnpcap_process_ether(unsigned char const *data, unsigned int len) -{ /* Well, first parse the ethernet header (I hope you use Ethernet_II :) ... */ - t_ether_raw const *raw; - - raw = (t_ether_raw const *)data; /* avoid warning */ - if (ntohs(raw->type) == 0x0800) { - /* This is IP */ - return bnpcap_process_ip(data + sizeof(t_ether_raw), len - sizeof(t_ether_raw)); - } - else { - eventlog(eventlog_level_warn, __FUNCTION__, "unsupported protocol 0x%04x", ntohs(raw->type)); - return 1; - } -} - -/* If you want to use other hardware protocols like PPP add them here ... */ - -/**************************** PACKET/PCAP *********************************/ - -static void bnpcap_process_packet(u_char * private_, const struct pcap_pkthdr * p, u_char const * data) -{ - unsigned int pl = p->len; - - if (private_) private_ = NULL; // hack to eliminate compiler warning - - std::memcpy(&packettime, &p->ts, sizeof(struct timeval)); - eventlog(eventlog_level_debug, __FUNCTION__, "packet: len=%d caplen=%d", p->len, p->caplen); - /* FIXME: check if it's ethernet */ - bnpcap_process_ether(data, pl); -} - -/**************************************************************************/ - -static void bnpcap_usage(void) { - std::printf("BNPCAP - A tool to convert pcap battle.net dumps to a human-readable format.\n"); - std::printf("Version " PVPGN_VERSION " --- Copyright (c) 2001 Marco Ziech (mmz@gmx.net)\n"); - std::printf("This software makes use of libpcap.\n\n"); - std::printf("Usage: bnpcap [-d] [-v] [-p PORT] \n"); - std::printf(" -d Print out debugging information\n"); - std::printf(" -v Be more verbose\n"); - std::printf(" -p PORT Specify port to process (Default: 6112)\n\n"); -} - -/******************************* MAIN *************************************/ - -int main(int argc, char **argv) { - t_elem * currconn; - t_elem * currudp; - int c; - - while ((c = getopt(argc, argv, "dvp:")) != -1) { - switch (c) { - case 'p': - str_to_uint(optarg, &listen_port); - break; - case 'd': - bnpcap_dodebug = 1; - break; - case 'v': - bnpcap_beverbose = 1; - break; - case '?': - std::printf("unrecognized option '%c'\n", optopt); - break; - default: - std::printf("getopt returned \'%c\'\n", c); - } - } - - if (optind < argc) { - filename = argv[optind]; - } - else { - bnpcap_usage(); - return 1; - } - - pc = pcap_open_offline(filename, ebuf); - if (!pc) { - std::fprintf(stderr, "pcap_open_offline: %s\n", ebuf); - return -1; - } - - eventlog_set(stderr); - eventlog_clear_level(); - if (bnpcap_dodebug) - eventlog_add_level("debug"); - if (bnpcap_beverbose || bnpcap_dodebug) - eventlog_add_level("info"); - eventlog_add_level("warn"); - eventlog_add_level("error"); - eventlog_add_level("fatal"); - - conns = list_create(); - udppackets = list_create(); - pcap_dispatch(pc, 0, bnpcap_process_packet, NULL); - - std::printf("### This packet dump was created by bnpcap.\n"); - LIST_TRAVERSE(conns, currconn) { - t_bnpcap_conn *c; - char cstr[64]; - char sstr[64]; - t_elem * currpacket; - - c = (t_bnpcap_conn*)elem_get_data(currconn); - snprintf(cstr, 64, "%u.%u.%u.%u:%u", ((c->client.ip & 0xFF000000) >> 24), ((c->client.ip & 0x00FF0000) >> 16), ((c->client.ip & 0x0000FF00) >> 8), ((c->client.ip & 0x000000FF)), c->client.port); - snprintf(sstr, 64, "%u.%u.%u.%u:%u", ((c->server.ip & 0xFF000000) >> 24), ((c->server.ip & 0x00FF0000) >> 16), ((c->server.ip & 0x0000FF00) >> 8), ((c->server.ip & 0x000000FF)), c->server.port); - std::printf("## %s connection: client=%s server=%s\n", (c->incomplete ? "incomplete" : "complete"), cstr, sstr); - LIST_TRAVERSE(c->packets, currpacket) { - t_bnpcap_packet * bp; - - bp = (t_bnpcap_packet*)elem_get_data(currpacket); - std::printf("# %u packet from %s: type=0x%04x(%s) length=%d class=%s\n", bp->id/*bp->tv.tv_sec*/, (bp->dir == packet_dir_from_client ? "client" : "server"), packet_get_type(bp->p), packet_get_type_str(bp->p, bp->dir), packet_get_size(bp->p), packet_get_class_str(bp->p)); - hexdump(stdout, packet_get_raw_data(bp->p, 0), packet_get_size(bp->p)); - std::printf("\n"); - } - } - std::printf("## udp packets\n"); - LIST_TRAVERSE(udppackets, currudp) { - t_bnpcap_packet *bp; - - bp = (t_bnpcap_packet*)elem_get_data(currudp); - std::printf("# %u packet from %s: type=0x%04x(%s) length=%d class=%s\n", bp->id/*bp->tv.tv_sec*/, (bp->dir == packet_dir_from_client ? "client" : "server"), packet_get_type(bp->p), packet_get_type_str(bp->p, bp->dir), packet_get_size(bp->p), packet_get_class_str(bp->p)); - hexdump(stdout, packet_get_raw_data(bp->p, 0), packet_get_size(bp->p)); - std::printf("\n"); - } - pcap_close(pc); - return 0; -} diff --git a/src/win32/configwin.h b/src/win32/configwin.h index 28d73da..eb4b24f 100644 --- a/src/win32/configwin.h +++ b/src/win32/configwin.h @@ -416,9 +416,6 @@ # define HAVE_SYS_FILE_H 1 #endif -/* Define if you have the header file. */ -/* #undef HAVE_SYS_IOCTL_H */ - /* Define if you have the header file. */ /* #undef HAVE_SYS_MMAN_H */ @@ -445,9 +442,6 @@ /* Define if you have the header file. */ #define HAVE_SYS_STAT_H 1 -/* Define if you have the header file. */ -/* #undef HAVE_SYS_STROPTS_H */ - /* Define if you have the header file. */ /* #undef HAVE_SYS_TIME_H */ /* MinGW has this header, but confilcts with compat/gettimeofday.h */