diff --git a/ethernet_dhcp b/ethernet_dhcp new file mode 100644 index 0000000..88b45d5 --- /dev/null +++ b/ethernet_dhcp @@ -0,0 +1,11 @@ +Description='A basic dhcp ethernet connection' +Interface=eno1 +Connection=ethernet +IP=dhcp +#DHCPClient=dhcpcd +#DHCPReleaseOnStop=no +## for DHCPv6 +IP6=dhcp +DHCP6Client=dhclient +## for IPv6 autoconfiguration +IP6=stateless diff --git a/ethernet_usb_dhcp b/ethernet_usb_dhcp new file mode 100644 index 0000000..4a846e6 --- /dev/null +++ b/ethernet_usb_dhcp @@ -0,0 +1,11 @@ +Description='A basic dhcp ethernet connection' +Interface=enp0s20u1u3 +Connection=ethernet +IP=dhcp +#DHCPClient=dhcpcd +#DHCPReleaseOnStop=no +## for DHCPv6 +IP6=dhcp +DHCP6Client=dhclient +## for IPv6 autoconfiguration +IP6=stateless diff --git a/install b/install new file mode 100755 index 0000000..87ab71d --- /dev/null +++ b/install @@ -0,0 +1 @@ +sudo pacman -S syncthing alsa alsa-utils pulseaudio pavucontrol i3 xf86-86-video-amdgpu mesa-libgl lib32-mesa-libgl mesa-vdpau lib32-mesa-vdpau firefox openssh flashplugin diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..87ab71d --- /dev/null +++ b/install.sh @@ -0,0 +1 @@ +sudo pacman -S syncthing alsa alsa-utils pulseaudio pavucontrol i3 xf86-86-video-amdgpu mesa-libgl lib32-mesa-libgl mesa-vdpau lib32-mesa-vdpau firefox openssh flashplugin diff --git a/libbtbb-2015-10-R1.tar.gz b/libbtbb-2015-10-R1.tar.gz new file mode 100644 index 0000000..4de0a69 Binary files /dev/null and b/libbtbb-2015-10-R1.tar.gz differ diff --git a/libbtbb-2015-10-R1/.gitignore b/libbtbb-2015-10-R1/.gitignore new file mode 100644 index 0000000..d033927 --- /dev/null +++ b/libbtbb-2015-10-R1/.gitignore @@ -0,0 +1,17 @@ +*.o +*.so.* +*.so +*.pyc + +# Output directory +build/ + +# wireshark plugins +CMakeCache.txt +CMakeFiles +cmake_install.cmake +install_manifest.txt +plugin.c +wireshark/plugins/btatt/Makefile +wireshark/plugins/btle/Makefile +wireshark/plugins/btsm/Makefile diff --git a/libbtbb-2015-10-R1/.travis.yml b/libbtbb-2015-10-R1/.travis.yml new file mode 100644 index 0000000..02f371a --- /dev/null +++ b/libbtbb-2015-10-R1/.travis.yml @@ -0,0 +1,21 @@ +language: c + +cache: apt + +sudo: false + +addons: + apt: + packages: + - libpcap-dev + +compiler: + - clang + - gcc + +before_script: + - mkdir build + - cd build + - CFLAGS="-g -Wall -Wextra -Werror -Wno-zero-length-array" cmake .. + +script: make diff --git a/libbtbb-2015-10-R1/CMakeLists.txt b/libbtbb-2015-10-R1/CMakeLists.txt new file mode 100644 index 0000000..93e6c20 --- /dev/null +++ b/libbtbb-2015-10-R1/CMakeLists.txt @@ -0,0 +1,50 @@ +# +# Copyright 2013 Dominic Spill +# +# This file is part of Libbtbb. +# +# 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, 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +#top level cmake project for libbtbb lib + tools + +cmake_minimum_required(VERSION 2.8) +set(MAJOR_VERSION 0) +set(MINOR_VERSION 3) +project(libbtbb_all) +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) + +set(INSTALL_DEFAULT_BINDIR "bin" CACHE STRING "Appended to CMAKE_INSTALL_PREFIX") + +set( VERSION ${MAJOR_VERSION}.${MINOR_VERSION} ) +add_definitions( -DVERSION="${VERSION}" ) + +# Comment the following out for releases. +set(CMAKE_C_FLAGS "$ENV{CFLAGS}") + +add_subdirectory(lib) +if(NOT DISABLE_PYTHON) + add_subdirectory(python) +endif() + +# Create uninstall target +configure_file( + ${PROJECT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake +@ONLY) + +add_custom_target(uninstall + ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake +) diff --git a/libbtbb-2015-10-R1/README.cmake b/libbtbb-2015-10-R1/README.cmake new file mode 100644 index 0000000..b9cc4ba --- /dev/null +++ b/libbtbb-2015-10-R1/README.cmake @@ -0,0 +1,12 @@ +CMake Settings +============== +The following are flags that may be of use when configuing this project. + + * DISABLE_PYTHON + * A boolean flag for building and installing btaptap python tool. + + * USE_PCAP + * USE_PCAP=ON - Build with pcap support, the build will fail if + libpcap is not found. + * USE_PCAP=OFF - Disable pcap support will be disabled. + * If left undefined pcap support will be enabled if libpcap is present. diff --git a/libbtbb-2015-10-R1/README.md b/libbtbb-2015-10-R1/README.md new file mode 100644 index 0000000..dd36486 --- /dev/null +++ b/libbtbb-2015-10-R1/README.md @@ -0,0 +1,43 @@ +libbtbb +======= + +This is the Bluetooth baseband decoding library, forked from the GR-Bluetooth +project. It can be used to extract Bluetooth packet and piconet information +from Ubertooth devices as well as GR-Bluetooth/USRP. + +This code is incomplete, it is still under active development. Patches and +bug reports should be submitted to the bug tracker on GitHub: +https://github.com/greatscottgadgets/libbtbb/issues + +This software has been developed and tested on Linux, it should work on other +platforms but this has yet to be tested. + + +Build Instructions +================== + +Libbtbb can be built and installed as follows: +``` +$ mkdir build +$ cd build +$ cmake .. +$ make +$ sudo make install +``` + +This will install the library to /usr/local/lib and the headers to +/usr/local/include, to install to different locations use: +``` +$ cmake -DINSTALL_DIR=/path/to/install -DINCLUDE_DIR=/path/to/include .. +``` + +If you have previous versions of libbtbb, libubertooth or the Ubertooth tools +installed, you can use the cleanup script to remove them: +``` +$ sudo cmake/cleanup.sh -d +``` + +To list the installed files without removing them, use: +``` +$ cmake/cleanup.sh +``` diff --git a/libbtbb-2015-10-R1/cmake/cleanup.sh b/libbtbb-2015-10-R1/cmake/cleanup.sh new file mode 100755 index 0000000..a08838d --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/cleanup.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# A quick and dirty script to remove old installs of +# libbtbb, libubertooth and associated Ubertooth tools +# Copyright 2014 Dominic Spill +# License: GPL v2 + +FIND=`which find` + +INSTALL_DIRS="/usr /usr/local" + +LIBS="btbb ubertooth" + +HEADERS="bluetooth_packet.h \ + bluetooth_piconet.h \ + bluetooth_le_packet.h \ + ubertooth_interface.h \ + ubertooth_control.h \ + ubertooth.h \ + " + +if [ "$1" == "-d" ] +then + EXEC="-print -exec rm -f {} ;" + echo "Deleting previous installs:" +else + EXEC=-print + echo 'Installed files, use "sudo cleanup.sh -d" to delete these files' +fi + +for dir in $INSTALL_DIRS; do + for lib in $LIBS; do + $FIND ${dir}/lib -maxdepth 1 -name "lib$lib.so*" $EXEC + done + for header in $HEADERS; do + $FIND ${dir}/include -maxdepth 1 -name "$header" $EXEC + done + $FIND ${dir}/bin -maxdepth 1 -name "ubertooth-*" $EXEC +done diff --git a/libbtbb-2015-10-R1/cmake/cmake_uninstall.cmake.in b/libbtbb-2015-10-R1/cmake/cmake_uninstall.cmake.in new file mode 100644 index 0000000..9ae1ae4 --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,32 @@ +# http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F + +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + IF(EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) + ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) + ELSE(EXISTS "$ENV{DESTDIR}${file}") + MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) diff --git a/libbtbb-2015-10-R1/cmake/modules/CMakeParseArguments.cmake b/libbtbb-2015-10-R1/cmake/modules/CMakeParseArguments.cmake new file mode 100644 index 0000000..406780e --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/modules/CMakeParseArguments.cmake @@ -0,0 +1,138 @@ +# CMAKE_PARSE_ARGUMENTS( args...) +# +# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for +# parsing the arguments given to that macro or function. +# It processes the arguments and defines a set of variables which hold the +# values of the respective options. +# +# The argument contains all options for the respective macro, +# i.e. keywords which can be used when calling the macro without any value +# following, like e.g. the OPTIONAL keyword of the install() command. +# +# The argument contains all keywords for this macro +# which are followed by one value, like e.g. DESTINATION keyword of the +# install() command. +# +# The argument contains all keywords for this macro +# which can be followed by more than one value, like e.g. the TARGETS or +# FILES keywords of the install() command. +# +# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the +# keywords listed in , and +# a variable composed of the given +# followed by "_" and the name of the respective keyword. +# These variables will then hold the respective value from the argument list. +# For the keywords this will be TRUE or FALSE. +# +# All remaining arguments are collected in a variable +# _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether +# your macro was called with unrecognized parameters. +# +# As an example here a my_install() macro, which takes similar arguments as the +# real install() command: +# +# function(MY_INSTALL) +# set(options OPTIONAL FAST) +# set(oneValueArgs DESTINATION RENAME) +# set(multiValueArgs TARGETS CONFIGURATIONS) +# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) +# ... +# +# Assume my_install() has been called like this: +# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) +# +# After the cmake_parse_arguments() call the macro will have set the following +# variables: +# MY_INSTALL_OPTIONAL = TRUE +# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() +# MY_INSTALL_DESTINATION = "bin" +# MY_INSTALL_RENAME = "" (was not used) +# MY_INSTALL_TARGETS = "foo;bar" +# MY_INSTALL_CONFIGURATIONS = "" (was not used) +# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" +# +# You can the continue and process these variables. +# +# Keywords terminate lists of values, e.g. if directly after a one_value_keyword +# another recognized keyword follows, this is interpreted as the beginning of +# the new option. +# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in +# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would +# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. + +#============================================================================= +# Copyright 2010 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) + return() +endif() +set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) + + +function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) + # first set all result variables to empty/FALSE + foreach(arg_name ${_singleArgNames} ${_multiArgNames}) + set(${prefix}_${arg_name}) + endforeach() + + foreach(option ${_optionNames}) + set(${prefix}_${option} FALSE) + endforeach() + + set(${prefix}_UNPARSED_ARGUMENTS) + + set(insideValues FALSE) + set(currentArgName) + + # now iterate over all arguments and fill the result variables + foreach(currentArg ${ARGN}) + list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword + + if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) + if(insideValues) + if("${insideValues}" STREQUAL "SINGLE") + set(${prefix}_${currentArgName} ${currentArg}) + set(insideValues FALSE) + elseif("${insideValues}" STREQUAL "MULTI") + list(APPEND ${prefix}_${currentArgName} ${currentArg}) + endif() + else() + list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) + endif() + else() + if(NOT ${optionIndex} EQUAL -1) + set(${prefix}_${currentArg} TRUE) + set(insideValues FALSE) + elseif(NOT ${singleArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "SINGLE") + elseif(NOT ${multiArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "MULTI") + endif() + endif() + + endforeach() + + # propagate the result variables to the caller: + foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) + set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) + endforeach() + set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) + +endfunction() diff --git a/libbtbb-2015-10-R1/cmake/modules/FindBTBB.cmake b/libbtbb-2015-10-R1/cmake/modules/FindBTBB.cmake new file mode 100644 index 0000000..45ed432 --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/modules/FindBTBB.cmake @@ -0,0 +1,55 @@ +# Try to find the libbtbb library +# +# Once done this defines: +# LIBBTBB_FOUND - system has libbtbb +# LIBBTBB_INCLUDE_DIR - the libbtbb include directory +# LIBBTBB_LIBRARIES - Link these to use libbtbb +# +# Copyright (c) 2013 Dominic Spill + + +if (LIBBTBB_INCLUDE_DIR AND LIBBTBB_LIBRARIES) + + # in cache already + set(LIBBTBB_FOUND TRUE) + +else (LIBBTBB_INCLUDE_DIR AND LIBBTBB_LIBRARIES) + IF (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + find_package(PkgConfig) + pkg_check_modules(PC_LIBBTBB QUIET libbtbb) + ENDIF(NOT WIN32) + + FIND_PATH(LIBBTBB_INCLUDE_DIR + NAMES btbb.h + HINTS $ENV{LIBBTBB_DIR}/include ${PC_LIBBTBB_INCLUDEDIR} + PATHS /usr/include /usr/local/include + /opt/local/include + ${CMAKE_SOURCE_DIR}/../libbtbb/src + ${LIBBTBB_INCLUDE_DIR} + ) + + set(libbtbb_library_names btbb) + + FIND_LIBRARY(LIBBTBB_LIBRARIES + NAMES ${libbtbb_library_names} + HINTS $ENV{LIBBTBB_DIR}/lib ${PC_LIBBTBB_LIBDIR} + PATHS /usr/local/lib /usr/lib /opt/local/lib ${PC_LIBBTBB_LIBDIR} + ${PC_LIBBTBB_LIBRARY_DIRS} ${CMAKE_SOURCE_DIR}/../libbtbb/src + ) + + if(LIBBTBB_INCLUDE_DIR) + set(CMAKE_REQUIRED_INCLUDES ${LIBBTBB_INCLUDE_DIR}) + endif() + + if(LIBBTBB_LIBRARIES) + set(CMAKE_REQUIRED_LIBRARIES ${LIBBTBB_LIBRARIES}) + endif() + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBBTBB DEFAULT_MSG LIBBTBB_LIBRARIES LIBBTBB_INCLUDE_DIR) + + MARK_AS_ADVANCED(LIBBTBB_INCLUDE_DIR LIBBTBB_LIBRARIES) + +endif (LIBBTBB_INCLUDE_DIR AND LIBBTBB_LIBRARIES) \ No newline at end of file diff --git a/libbtbb-2015-10-R1/cmake/modules/FindPCAP.cmake b/libbtbb-2015-10-R1/cmake/modules/FindPCAP.cmake new file mode 100644 index 0000000..512ed78 --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/modules/FindPCAP.cmake @@ -0,0 +1,146 @@ +# +# $Id: FindPCAP.cmake 38372 2011-08-05 18:52:53Z gerald $ +# +################################################################### +# +# Copyright (c) 2006 Frederic Heem, +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the Telsey nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +################################################################### +# - Find pcap +# Find the PCAP includes and library +# http://www.tcpdump.org/ +# +# The environment variable PCAPDIR allows to specficy where to find +# libpcap in non standard location. +# +# PCAP_INCLUDE_DIRS - where to find pcap.h, etc. +# PCAP_LIBRARIES - List of libraries when using pcap. +# PCAP_FOUND - True if pcap found. + + +IF(EXISTS $ENV{PCAPDIR}) + FIND_PATH(PCAP_INCLUDE_DIR + NAMES + pcap/pcap.h + pcap.h + PATHS + $ENV{PCAPDIR} + NO_DEFAULT_PATH + ) + + FIND_LIBRARY(PCAP_LIBRARY + NAMES + pcap + PATHS + $ENV{PCAPDIR} + NO_DEFAULT_PATH + ) + + +ELSE(EXISTS $ENV{PCAPDIR}) + FIND_PATH(PCAP_INCLUDE_DIR + NAMES + pcap/pcap.h + pcap.h + HINTS + /usr/local/opt/libpcap/include + ) + + FIND_LIBRARY(PCAP_LIBRARY + NAMES + pcap + HINTS + /usr/local/opt/libpcap/lib + ) + +ENDIF(EXISTS $ENV{PCAPDIR}) + +SET(PCAP_INCLUDE_DIRS ${PCAP_INCLUDE_DIR}) +SET(PCAP_LIBRARIES ${PCAP_LIBRARY}) + +IF(PCAP_INCLUDE_DIRS) + MESSAGE(STATUS "Pcap include dirs set to ${PCAP_INCLUDE_DIRS}") +ELSE(PCAP_INCLUDE_DIRS) + MESSAGE(FATAL " Pcap include dirs cannot be found") +ENDIF(PCAP_INCLUDE_DIRS) + +IF(PCAP_LIBRARIES) + MESSAGE(STATUS "Pcap library set to ${PCAP_LIBRARIES}") +ELSE(PCAP_LIBRARIES) + MESSAGE(FATAL "Pcap library cannot be found") +ENDIF(PCAP_LIBRARIES) + +#Functions +INCLUDE(CheckFunctionExists) +INCLUDE(CheckVariableExists) +SET(CMAKE_REQUIRED_INCLUDES ${PCAP_INCLUDE_DIRS}) +SET(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARIES}) +CHECK_VARIABLE_EXISTS("pcap_version" HAVE_PCAP_VERSION) +CHECK_FUNCTION_EXISTS("pcap_open_dead" HAVE_PCAP_OPEN_DEAD) +CHECK_FUNCTION_EXISTS("pcap_freecode" HAVE_PCAP_FREECODE) +# +# Note: for pcap_breakloop() and pcap_findalldevs(), the autoconf script +# checks for more than just whether the function exists, it also checks +# for whether pcap.h declares it; Mac OS X software/security updates can +# update libpcap without updating the headers. +# +CHECK_FUNCTION_EXISTS("pcap_breakloop" HAVE_PCAP_BREAKLOOP) +CHECK_FUNCTION_EXISTS("pcap_create" HAVE_PCAP_CREATE) +CHECK_FUNCTION_EXISTS("pcap_datalink_name_to_val" HAVE_PCAP_DATALINK_NAME_TO_VAL) +CHECK_FUNCTION_EXISTS("pcap_datalink_val_to_description" HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION) +CHECK_FUNCTION_EXISTS("pcap_datalink_val_to_name" HAVE_PCAP_DATALINK_VAL_TO_NAME) +CHECK_FUNCTION_EXISTS("pcap_findalldevs" HAVE_PCAP_FINDALLDEVS) +CHECK_FUNCTION_EXISTS("pcap_free_datalinks" HAVE_PCAP_FREE_DATALINKS) +CHECK_FUNCTION_EXISTS("pcap_get_selectable_fd" HAVE_PCAP_GET_SELECTABLE_FD) +CHECK_FUNCTION_EXISTS("pcap_lib_version" HAVE_PCAP_LIB_VERSION) +CHECK_FUNCTION_EXISTS("pcap_list_datalinks" HAVE_PCAP_LIST_DATALINKS) +CHECK_FUNCTION_EXISTS("pcap_set_datalink" HAVE_PCAP_SET_DATALINK) +# Remote pcap checks +CHECK_FUNCTION_EXISTS("pcap_open" H_PCAP_OPEN) +CHECK_FUNCTION_EXISTS("pcap_findalldevs_ex" H_FINDALLDEVS_EX) +CHECK_FUNCTION_EXISTS("pcap_createsrcstr" H_CREATESRCSTR) +if(H_PCAP_OPEN AND H_FINDALLDEVS_EX AND H_CREATESRCSTR) + SET(HAVE_PCAP_REMOTE 1) + SET(HAVE_REMOTE 1) +endif() +# reset vars +SET(CMAKE_REQUIRED_INCLUDES "") +SET(CMAKE_REQUIRED_LIBRARIES "") + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCAP DEFAULT_MSG PCAP_INCLUDE_DIRS PCAP_LIBRARIES) + +MARK_AS_ADVANCED( + PCAP_LIBRARIES + PCAP_INCLUDE_DIRS +) diff --git a/libbtbb-2015-10-R1/cmake/modules/FindPackageHandleStandardArgs.cmake b/libbtbb-2015-10-R1/cmake/modules/FindPackageHandleStandardArgs.cmake new file mode 100644 index 0000000..25d8df3 --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/modules/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,299 @@ +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( ... ) +# +# This function is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED, QUIET and version-related arguments to find_package(). +# It also sets the _FOUND variable. +# The package is considered found if all variables ... listed contain +# valid results, e.g. valid filepaths. +# +# There are two modes of this function. The first argument in both modes is +# the name of the Find-module where it is called (in original casing). +# +# The first simple mode looks like this: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( (DEFAULT_MSG|"Custom failure message") ... ) +# If the variables to are all valid, then _FOUND +# will be set to TRUE. +# If DEFAULT_MSG is given as second argument, then the function will generate +# itself useful success and error messages. You can also supply a custom error message +# for the failure case. This is not recommended. +# +# The second mode is more powerful and also supports version checking: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS ...] +# [VERSION_VAR ] +# [HANDLE_COMPONENTS] +# [CONFIG_MODE] +# [FAIL_MESSAGE "Custom failure message"] ) +# +# As above, if through are all valid, _FOUND +# will be set to TRUE. +# After REQUIRED_VARS the variables which are required for this package are listed. +# Following VERSION_VAR the name of the variable can be specified which holds +# the version of the package which has been found. If this is done, this version +# will be checked against the (potentially) specified required version used +# in the find_package() call. The EXACT keyword is also handled. The default +# messages include information about the required version and the version +# which has been actually found, both if the version is ok or not. +# If the package supports components, use the HANDLE_COMPONENTS option to enable +# handling them. In this case, find_package_handle_standard_args() will report +# which components have been found and which are missing, and the _FOUND +# variable will be set to FALSE if any of the required components (i.e. not the +# ones listed after OPTIONAL_COMPONENTS) are missing. +# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for +# a find_package(... NO_MODULE) call. In this case VERSION_VAR will be set +# to _VERSION and the macro will automatically check whether the +# Config module was found. +# Via FAIL_MESSAGE a custom failure message can be specified, if this is not +# used, the default message will be displayed. +# +# Example for mode 1: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, success will be reported, including the content of . +# On repeated Cmake runs, the same message won't be printed again. +# +# Example for mode 2: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE +# VERSION_VAR BISON_VERSION) +# In this case, BISON is considered to be found if the variable(s) listed +# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case. +# Also the version of BISON will be checked by using the version contained +# in BISON_VERSION. +# Since no FAIL_MESSAGE is given, the default messages will be printed. +# +# Another example for mode 2: +# +# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE) +# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4 NO_MODULE) +# and adds an additional search directory for automoc4. +# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper +# success/error message. + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +include(FindPackageMessage) +include(CMakeParseArguments) + +# internal helper macro +macro(_FPHSA_FAILURE_MESSAGE _msg) + if (${_NAME}_FIND_REQUIRED) + message(FATAL_ERROR "${_msg}") + else () + if (NOT ${_NAME}_FIND_QUIETLY) + message(STATUS "${_msg}") + endif () + endif () +endmacro() + + +# internal helper macro to generate the failure message when used in CONFIG_MODE: +macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: + if(${_NAME}_CONFIG) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") + else() + # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. + # List them all in the error message: + if(${_NAME}_CONSIDERED_CONFIGS) + set(configsText "") + list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) + math(EXPR configsCount "${configsCount} - 1") + foreach(currentConfigIndex RANGE ${configsCount}) + list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) + list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) + set(configsText "${configsText} ${filename} (version ${version})\n") + endforeach() + if (${_NAME}_NOT_FOUND_MESSAGE) + set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") + endif() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") + + else() + # Simple case: No Config-file was found at all: + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") + endif() + endif() +endmacro() + + +function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) + +# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in +# new extended or in the "old" mode: + set(options CONFIG_MODE HANDLE_COMPONENTS) + set(oneValueArgs FAIL_MESSAGE VERSION_VAR) + set(multiValueArgs REQUIRED_VARS) + set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) + list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) + + if(${INDEX} EQUAL -1) + set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) + set(FPHSA_REQUIRED_VARS ${ARGN}) + set(FPHSA_VERSION_VAR) + else() + + CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + if(FPHSA_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT FPHSA_FAIL_MESSAGE) + set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") + endif() + endif() + +# now that we collected all arguments, process them + + if("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") + set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") + endif() + + # In config-mode, we rely on the variable _CONFIG, which is set by find_package() + # when it successfully found the config-file, including version checking: + if(FPHSA_CONFIG_MODE) + list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) + list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) + set(FPHSA_VERSION_VAR ${_NAME}_VERSION) + endif() + + if(NOT FPHSA_REQUIRED_VARS) + message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") + endif() + + list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) + + string(TOUPPER ${_NAME} _NAME_UPPER) + string(TOLOWER ${_NAME} _NAME_LOWER) + + # collect all variables which were not found, so they can be printed, so the + # user knows better what went wrong (#6375) + set(MISSING_VARS "") + set(DETAILS "") + set(${_NAME_UPPER}_FOUND TRUE) + # check if all passed variables are valid + foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) + if(NOT ${_CURRENT_VAR}) + set(${_NAME_UPPER}_FOUND FALSE) + set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") + else() + set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") + endif() + endforeach() + + # component handling + unset(FOUND_COMPONENTS_MSG) + unset(MISSING_COMPONENTS_MSG) + + if(FPHSA_HANDLE_COMPONENTS) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(${_NAME}_${comp}_FOUND) + + if(NOT DEFINED FOUND_COMPONENTS_MSG) + set(FOUND_COMPONENTS_MSG "found components: ") + endif() + set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}") + + else() + + if(NOT DEFINED MISSING_COMPONENTS_MSG) + set(MISSING_COMPONENTS_MSG "missing components: ") + endif() + set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}") + + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_NAME_UPPER}_FOUND FALSE) + set(MISSING_VARS "${MISSING_VARS} ${comp}") + endif() + + endif() + endforeach() + set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") + set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]") + endif() + + # version handling: + set(VERSION_MSG "") + set(VERSION_OK TRUE) + set(VERSION ${${FPHSA_VERSION_VAR}} ) + if (${_NAME}_FIND_VERSION) + + if(VERSION) + + if(${_NAME}_FIND_VERSION_EXACT) # exact version required + if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + endif () + + else() # minimum version specified: + if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") + endif () + endif() + + else() + + # if the package was not found, but a version was given, add that to the output: + if(${_NAME}_FIND_VERSION_EXACT) + set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") + else() + set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") + endif() + + endif() + else () + if(VERSION) + set(VERSION_MSG "(found version \"${VERSION}\")") + endif() + endif () + + if(VERSION_OK) + set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") + else() + set(${_NAME_UPPER}_FOUND FALSE) + endif() + + + # print the result: + if (${_NAME_UPPER}_FOUND) + FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") + else () + + if(FPHSA_CONFIG_MODE) + _FPHSA_HANDLE_FAILURE_CONFIG_MODE() + else() + if(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") + else() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") + endif() + endif() + + endif () + + set(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE) + +endfunction() diff --git a/libbtbb-2015-10-R1/cmake/modules/FindPythonInterp.cmake b/libbtbb-2015-10-R1/cmake/modules/FindPythonInterp.cmake new file mode 100644 index 0000000..7fb65b8 --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/modules/FindPythonInterp.cmake @@ -0,0 +1,141 @@ +# - Find python interpreter +# This module finds if Python interpreter is installed and determines where the +# executables are. This code sets the following variables: +# +# PYTHONINTERP_FOUND - Was the Python executable found +# PYTHON_EXECUTABLE - path to the Python interpreter +# +# PYTHON_VERSION_STRING - Python version found e.g. 2.5.2 +# PYTHON_VERSION_MAJOR - Python major version found e.g. 2 +# PYTHON_VERSION_MINOR - Python minor version found e.g. 5 +# PYTHON_VERSION_PATCH - Python patch version found e.g. 2 +# +# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of +# version numbers that should be taken into account when searching for Python. +# You need to set this variable before calling find_package(PythonInterp). + +#============================================================================= +# Copyright 2005-2010 Kitware, Inc. +# Copyright 2011 Bjoern Ricks +# Copyright 2012 Rolf Eike Beer +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +unset(_Python_NAMES) + +set(_PYTHON1_VERSIONS 1.6 1.5) +set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) +set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0) + +if(PythonInterp_FIND_VERSION) + if(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$") + string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonInterp_FIND_VERSION}") + string(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}") + list(APPEND _Python_NAMES python${_PYTHON_FIND_MAJ_MIN} python${_PYTHON_FIND_MAJ}) + unset(_PYTHON_FIND_OTHER_VERSIONS) + if(NOT PythonInterp_FIND_VERSION_EXACT) + foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS}) + if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) + list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) + endif() + endforeach() + endif() + unset(_PYTHON_FIND_MAJ_MIN) + unset(_PYTHON_FIND_MAJ) + else() + list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION}) + set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION}_VERSIONS}) + endif() +else() + set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS}) +endif() + +list(APPEND _Python_NAMES python) + +# Search for the current active python version first +find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES}) + +# Set up the versions we know about, in the order we will search. Always add +# the user supplied additional versions to the front. +set(_Python_VERSIONS + ${Python_ADDITIONAL_VERSIONS} + ${_PYTHON_FIND_OTHER_VERSIONS} + ) + +unset(_PYTHON_FIND_OTHER_VERSIONS) +unset(_PYTHON1_VERSIONS) +unset(_PYTHON2_VERSIONS) +unset(_PYTHON3_VERSIONS) + +# Search for newest python version if python executable isn't found +if(NOT PYTHON_EXECUTABLE) + foreach(_CURRENT_VERSION ${_Python_VERSIONS}) + set(_Python_NAMES python${_CURRENT_VERSION}) + if(WIN32) + list(APPEND _Python_NAMES python) + endif() + find_program(PYTHON_EXECUTABLE + NAMES ${_Python_NAMES} + PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath] + ) + endforeach() +endif() + +# determine python version string +if(PYTHON_EXECUTABLE) + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c + "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))" + OUTPUT_VARIABLE _VERSION + RESULT_VARIABLE _PYTHON_VERSION_RESULT + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}") + list(GET _VERSION 0 PYTHON_VERSION_MAJOR) + list(GET _VERSION 1 PYTHON_VERSION_MINOR) + list(GET _VERSION 2 PYTHON_VERSION_PATCH) + if(PYTHON_VERSION_PATCH EQUAL 0) + # it's called "Python 2.7", not "2.7.0" + string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}") + endif() + else() + # sys.version predates sys.version_info, so use that + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.version)" + OUTPUT_VARIABLE _VERSION + RESULT_VARIABLE _PYTHON_VERSION_RESULT + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}") + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}") + if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}") + else() + set(PYTHON_VERSION_PATCH "0") + endif() + else() + # sys.version was first documented for Python 1.5, so assume + # this is older. + set(PYTHON_VERSION_STRING "1.4") + set(PYTHON_VERSION_MAJOR "1") + set(PYTHON_VERSION_MAJOR "4") + set(PYTHON_VERSION_MAJOR "0") + endif() + endif() + unset(_PYTHON_VERSION_RESULT) + unset(_VERSION) +endif() + +# handle the QUIETLY and REQUIRED arguments and set PYTHONINTERP_FOUND to TRUE if +# all listed variables are TRUE +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonInterp REQUIRED_VARS PYTHON_EXECUTABLE VERSION_VAR PYTHON_VERSION_STRING) + +mark_as_advanced(PYTHON_EXECUTABLE) diff --git a/libbtbb-2015-10-R1/cmake/modules/GetGitRevisionDescription.cmake b/libbtbb-2015-10-R1/cmake/modules/GetGitRevisionDescription.cmake new file mode 100644 index 0000000..c8d27f2 --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/modules/GetGitRevisionDescription.cmake @@ -0,0 +1,130 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() diff --git a/libbtbb-2015-10-R1/cmake/modules/GetGitRevisionDescription.cmake.in b/libbtbb-2015-10-R1/cmake/modules/GetGitRevisionDescription.cmake.in new file mode 100644 index 0000000..69aa84e --- /dev/null +++ b/libbtbb-2015-10-R1/cmake/modules/GetGitRevisionDescription.cmake.in @@ -0,0 +1,39 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") + configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + set(HEAD_HASH "${HEAD_REF}") + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) + string(SUBSTRING ${HEAD_HASH} 0 7 HEAD_HASH) +endif() diff --git a/libbtbb-2015-10-R1/lib/CMakeLists.txt b/libbtbb-2015-10-R1/lib/CMakeLists.txt new file mode 100644 index 0000000..6fcebf5 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/CMakeLists.txt @@ -0,0 +1,39 @@ +# +# Copyright 2013 Dominic Spill +# +# This file is part of Libbtbb. +# +# 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, 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include(GNUInstallDirs) + +# Based heavily upon the hackrf cmake setup. + +project(libbtbb C) +set(PACKAGE libbtbb) + +add_subdirectory(src) + +CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/libbtbb.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/libbtbb.pc +@ONLY) + +INSTALL( + FILES ${CMAKE_CURRENT_BINARY_DIR}/libbtbb.pc + DESTINATION lib${LIB_SUFFIX}/pkgconfig +) diff --git a/libbtbb-2015-10-R1/lib/libbtbb.pc.in b/libbtbb-2015-10-R1/lib/libbtbb.pc.in new file mode 100644 index 0000000..05d58f7 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/libbtbb.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: Bluetooth Baseband Library +Description: C Utility Library +Version: @VERSION@ +Cflags: -I${includedir}/ @BTBB_PC_CFLAGS@ +Libs: -L${libdir} -lbtbb +Libs.private: @BTBB_PC_LIBS@ diff --git a/libbtbb-2015-10-R1/lib/src/CMakeLists.txt b/libbtbb-2015-10-R1/lib/src/CMakeLists.txt new file mode 100644 index 0000000..2be9c5f --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/CMakeLists.txt @@ -0,0 +1,105 @@ +# +# This file is part of Libbtbb. +# +# 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, 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +# Based slightly upon the hackrf cmake setup. + +# FIXME Set static release version here to avoid pulling from git +set(RELEASE "") +set(DIRTY_FLAG "") + +if ( "${RELEASE}" STREQUAL "" ) + # automatic git version when working out of git + include(GetGitRevisionDescription) + get_git_head_revision(GIT_REFSPEC RELEASE) + + execute_process(COMMAND git status -s --untracked-files=no OUTPUT_VARIABLE DIRTY) + if ( NOT "${DIRTY}" STREQUAL "" ) + set(DIRTY_FLAG "*") + endif() +endif() + +add_definitions( -DRELEASE="${RELEASE}${DIRTY_FLAG}" ) + +# Source +set(c_sources ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_packet.c + ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_piconet.c + ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_le_packet.c + ${CMAKE_CURRENT_SOURCE_DIR}/pcap.c + ${CMAKE_CURRENT_SOURCE_DIR}/pcapng.c + ${CMAKE_CURRENT_SOURCE_DIR}/pcapng-bt.c + CACHE INTERNAL "List of C sources") +set(c_headers ${CMAKE_CURRENT_SOURCE_DIR}/btbb.h + CACHE INTERNAL "List of C headers") + +# For cygwin just force UNIX OFF and WIN32 ON +if( ${CYGWIN} ) + SET(UNIX OFF) + SET(WIN32 ON) +endif( ${CYGWIN} ) + +# FIXME: This may be a hack +# perhaps there should be separate libbtbb and libbtbb-static targets? +if( ${WIN32} ) + # Static library + add_library(btbb STATIC ${c_sources}) + set_target_properties(btbb PROPERTIES OUTPUT_NAME "btbb_static") +else() + # Dynamic library + add_library(btbb SHARED ${c_sources}) + set_target_properties(btbb PROPERTIES VERSION ${MAJOR_VERSION}.${MINOR_VERSION} SOVERSION 0) +endif() + +set_target_properties(btbb PROPERTIES CLEAN_DIRECT_OUTPUT 1) + +# PCAP Support +if( (NOT DEFINED USE_PCAP) OR USE_PCAP ) + find_package(PCAP) + + if( USE_PCAP AND NOT ${PCAP_FOUND} ) + message( FATAL_ERROR + "Cannot find libpcap, which is required for USE_PCAP") + endif() + + if( ${PCAP_FOUND} ) + include_directories(${PCAP_INCLUDE_DIRS}) + target_link_libraries(btbb ${PCAP_LIBRARIES}) + add_definitions( -DENABLE_PCAP ) + endif( ${PCAP_FOUND} ) +endif( (NOT DEFINED USE_PCAP) OR USE_PCAP ) + +if( ${UNIX} ) + install(TARGETS btbb + LIBRARY DESTINATION lib${LIB_SUFFIX} + COMPONENT sharedlibs + ) + install(FILES ${c_headers} + DESTINATION include + COMPONENT headers + ) +endif( ${UNIX} ) + +if( ${WIN32} ) + install(TARGETS btbb + DESTINATION bin + COMPONENT staticlibs + ) + install(FILES ${c_headers} + DESTINATION include + COMPONENT headers + ) +endif( ${WIN32} ) diff --git a/libbtbb-2015-10-R1/lib/src/bluetooth_le_packet.c b/libbtbb-2015-10-R1/lib/src/bluetooth_le_packet.c new file mode 100644 index 0000000..579a7ae --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/bluetooth_le_packet.c @@ -0,0 +1,607 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2012 Mike Ryan, Dominic Spill, Michael Ossmann + * Copyright 2005, 2006 Free Software Foundation, Inc. + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "btbb.h" +#include "bluetooth_le_packet.h" +#include +#include + +/* string representations of advertising packet type */ +static const char *ADV_TYPE_NAMES[] = { + "ADV_IND", "ADV_DIRECT_IND", "ADV_NONCONN_IND", "SCAN_REQ", + "SCAN_RSP", "CONNECT_REQ", "ADV_SCAN_IND", +}; + +/* source clock accuracy in a connect packet */ +static const char *CONNECT_SCA[] = { + "251 ppm to 500 ppm", "151 ppm to 250 ppm", "101 ppm to 150 ppm", + "76 ppm to 100 ppm", "51 ppm to 75 ppm", "31 ppm to 50 ppm", + "21 ppm to 30 ppm", "0 ppm to 20 ppm", +}; + +// count of objects in an array, shamelessly stolen from Chrome +#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + +static uint8_t count_bits(uint32_t n) +{ + uint8_t i = 0; + for (i = 0; n != 0; i++) + n &= n - 1; + return i; +} + +static int aa_access_channel_off_by_one(const uint32_t aa) { + int retval = 0; + if(count_bits(aa ^ LE_ADV_AA) == 1) { + retval = 1; + } + return retval; +} + +/* + * A helper function for filtering bogus packets on data channels. + * + * If a candidate capture packet is random noise we would expect its + * Access Address to be a randomly distributed 32-bit number. An + * exhaustive software analysis reveals that of 4294967296 possible + * 32-bit Access Address values, 2900629660 (67.5%) are acceptable and + * 1394337636 (32.5%) are invalid. This function will identify which + * category a candidate Access Address falls into by returning the + * number of offenses contained. + * + * Refer to BT 4.x, Vol 6, Par B, Section 2.1.2. + * + * The Access Address in data channel packets meet the + * following requirements: + * - It shall have no more than six consecutive zeros or ones. + * - It shall not be the advertising channel packets’ Access Address. + * - It shall not be a sequence that differs from the advertising channel packets’ + * Access Address by only one bit. + * - It shall not have all four octets equal. + * - It shall have no more than 24 transitions. + * - It shall have a minimum of two transitions in the most significant six bits. + */ +static int aa_data_channel_offenses(const uint32_t aa) { + int retval = 0, transitions = 0; + unsigned shift, odd = (unsigned) (aa & 1); + uint8_t aab3, aab2, aab1, aab0 = (uint8_t) (aa & 0xff); + + const uint8_t EIGHT_BIT_TRANSITIONS_EVEN[256] = { + 0, 2, 2, 2, 2, 4, 2, 2, 2, 4, 4, 4, 2, 4, 2, 2, + 2, 4, 4, 4, 4, 6, 4, 4, 2, 4, 4, 4, 2, 4, 2, 2, + 2, 4, 4, 4, 4, 6, 4, 4, 4, 6, 6, 6, 4, 6, 4, 4, + 2, 4, 4, 4, 4, 6, 4, 4, 2, 4, 4, 4, 2, 4, 2, 2, + 2, 4, 4, 4, 4, 6, 4, 4, 4, 6, 6, 6, 4, 6, 4, 4, + 4, 6, 6, 6, 6, 8, 6, 6, 4, 6, 6, 6, 4, 6, 4, 4, + 2, 4, 4, 4, 4, 6, 4, 4, 4, 6, 6, 6, 4, 6, 4, 4, + 2, 4, 4, 4, 4, 6, 4, 4, 2, 4, 4, 4, 2, 4, 2, 2, + 1, 3, 3, 3, 3, 5, 3, 3, 3, 5, 5, 5, 3, 5, 3, 3, + 3, 5, 5, 5, 5, 7, 5, 5, 3, 5, 5, 5, 3, 5, 3, 3, + 3, 5, 5, 5, 5, 7, 5, 5, 5, 7, 7, 7, 5, 7, 5, 5, + 3, 5, 5, 5, 5, 7, 5, 5, 3, 5, 5, 5, 3, 5, 3, 3, + 1, 3, 3, 3, 3, 5, 3, 3, 3, 5, 5, 5, 3, 5, 3, 3, + 3, 5, 5, 5, 5, 7, 5, 5, 3, 5, 5, 5, 3, 5, 3, 3, + 1, 3, 3, 3, 3, 5, 3, 3, 3, 5, 5, 5, 3, 5, 3, 3, + 1, 3, 3, 3, 3, 5, 3, 3, 1, 3, 3, 3, 1, 3, 1, 1 + }; + + const uint8_t EIGHT_BIT_TRANSITIONS_ODD[256] = { + 1, 1, 3, 1, 3, 3, 3, 1, 3, 3, 5, 3, 3, 3, 3, 1, + 3, 3, 5, 3, 5, 5, 5, 3, 3, 3, 5, 3, 3, 3, 3, 1, + 3, 3, 5, 3, 5, 5, 5, 3, 5, 5, 7, 5, 5, 5, 5, 3, + 3, 3, 5, 3, 5, 5, 5, 3, 3, 3, 5, 3, 3, 3, 3, 1, + 3, 3, 5, 3, 5, 5, 5, 3, 5, 5, 7, 5, 5, 5, 5, 3, + 5, 5, 7, 5, 7, 7, 7, 5, 5, 5, 7, 5, 5, 5, 5, 3, + 3, 3, 5, 3, 5, 5, 5, 3, 5, 5, 7, 5, 5, 5, 5, 3, + 3, 3, 5, 3, 5, 5, 5, 3, 3, 3, 5, 3, 3, 3, 3, 1, + 2, 2, 4, 2, 4, 4, 4, 2, 4, 4, 6, 4, 4, 4, 4, 2, + 4, 4, 6, 4, 6, 6, 6, 4, 4, 4, 6, 4, 4, 4, 4, 2, + 4, 4, 6, 4, 6, 6, 6, 4, 6, 6, 8, 6, 6, 6, 6, 4, + 4, 4, 6, 4, 6, 6, 6, 4, 4, 4, 6, 4, 4, 4, 4, 2, + 2, 2, 4, 2, 4, 4, 4, 2, 4, 4, 6, 4, 4, 4, 4, 2, + 4, 4, 6, 4, 6, 6, 6, 4, 4, 4, 6, 4, 4, 4, 4, 2, + 2, 2, 4, 2, 4, 4, 4, 2, 4, 4, 6, 4, 4, 4, 4, 2, + 2, 2, 4, 2, 4, 4, 4, 2, 2, 2, 4, 2, 2, 2, 2, 0 + }; + + transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab0] : EIGHT_BIT_TRANSITIONS_EVEN[aab0] ); + odd = (unsigned) (aab0 & 0x80); + aab1 = (uint8_t) (aa >> 8); + transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab1] : EIGHT_BIT_TRANSITIONS_EVEN[aab1] ); + odd = (unsigned) (aab1 & 0x80); + aab2 = (uint8_t) (aa >> 16); + transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab2] : EIGHT_BIT_TRANSITIONS_EVEN[aab2] ); + odd = (unsigned) (aab2 & 0x80); + aab3 = (uint8_t) (aa >> 24); + transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab3] : EIGHT_BIT_TRANSITIONS_EVEN[aab3] ); + + /* consider excessive transitions as offenses */ + if (transitions > 24) { + retval += (transitions - 24); + } + + const uint8_t AA_MSB6_ALLOWED[64] = { + 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0 + }; + + /* consider excessive transitions in the 6 MSBs as an offense */ + retval += (1 - AA_MSB6_ALLOWED[aab3>>2]); + + /* consider all bytes as being equal an offense */ + retval += (((aab0 == aab1) && (aab0 == aab2) && (aab0 == aab3)) ? 1 : 0); + + /* access-channel address and off-by-ones are illegal */ + retval += ((aa == LE_ADV_AA) ? 1 : 0); + retval += aa_access_channel_off_by_one(aa); + + /* inspect nibble triples for insufficient bit transitions */ + for(shift=0; shift<=20; shift+=4) { + uint16_t twelvebits = (uint16_t) ((aa >> shift) & 0xfff); + switch( twelvebits ) { + /* seven consecutive zeroes */ + case 0x080: case 0x180: case 0x280: case 0x380: case 0x480: + case 0x580: case 0x680: case 0x780: case 0x880: case 0x980: + case 0xa80: case 0xb80: case 0xc80: case 0xd80: case 0xe80: + case 0xf80: case 0x101: case 0x301: case 0x501: case 0x701: + case 0x901: case 0xb01: case 0xd01: case 0xf01: case 0x202: + case 0x602: case 0xa02: case 0xe02: case 0x203: case 0x603: + case 0xa03: case 0xe03: case 0x404: case 0xc04: case 0x405: + case 0xc05: case 0x406: case 0xc06: case 0x407: case 0xc07: + case 0x808: case 0x809: case 0x80a: case 0x80b: case 0x80c: + case 0x80d: case 0x80e: case 0x80f: case 0x010: case 0x011: + case 0x012: case 0x013: case 0x014: case 0x015: case 0x016: + case 0x017: case 0x018: case 0x019: case 0x01a: case 0x01b: + case 0x01c: case 0x01d: case 0x01e: case 0x01f: + /* eight consecutive zeroes */ + case 0x100: case 0x300: case 0x500: case 0x700: case 0x900: + case 0xb00: case 0xd00: case 0xf00: case 0x201: case 0x601: + case 0xa01: case 0xe01: case 0x402: case 0xc02: case 0x403: + case 0xc03: case 0x804: case 0x805: case 0x806: case 0x807: + case 0x008: case 0x009: case 0x00a: case 0x00b: case 0x00c: + case 0x00d: case 0x00e: case 0x00f: + /* nine consecutive zeroes */ + case 0xe00: case 0xc01: case 0x802: case 0x803: case 0x004: + case 0x005: case 0x006: case 0x007: + /* ten consecutive zeroes */ + case 0x400: case 0xc00: case 0x801: case 0x002: case 0x003: + /* eleven consecutive zeroes */ + case 0x800: case 0x001: + /* twelve consecutive zeroes */ + case 0x000: + /* seven consecutive ones */ + case 0x07f: case 0x0fe: case 0x2fe: case 0x4fe: case 0x6fe: + case 0x8fe: case 0xafe: case 0xcfe: case 0xefe: case 0x1fc: + case 0x5fc: case 0x9fc: case 0xdfc: case 0x1fd: case 0x5fd: + case 0x9fd: case 0xdfd: case 0x3f8: case 0xbf8: case 0x3f9: + case 0xbf9: case 0x3fa: case 0xbfa: case 0x3fb: case 0xbfb: + case 0x7f4: case 0x7f5: case 0x7f6: case 0x7f7: case 0xfe0: + /* eight consecutive ones */ + case 0x0ff: case 0x2ff: case 0x4ff: case 0x6ff: case 0x8ff: + case 0xaff: case 0xcff: case 0xeff: case 0x1fe: case 0x5fe: + case 0x9fe: case 0xdfe: case 0x3fc: case 0xbfc: case 0x3fd: + case 0xbfd: case 0x7f8: case 0x7f9: case 0x7fa: case 0x7fb: + case 0xff0: case 0xff1: case 0xff2: case 0xff3: case 0xff4: + case 0xff5: case 0xff6: case 0xff7: + /* nine consecutive ones */ + case 0x1ff: case 0x5ff: case 0x9ff: case 0xdff: case 0x3fe: + case 0xbfe: case 0x7fc: case 0x7fd: case 0xff8: case 0xff9: + case 0xffa: case 0xffb: + /* ten consecutive ones */ + case 0x3ff: case 0xbff: case 0x7fe: case 0xffc: case 0xffd: + /* eleven consecutive ones */ + case 0x7ff: case 0xffe: + /* all ones */ + case 0xfff: + retval++; + break; + default: + break; + } + } + + return retval; +} + +lell_packet * +lell_packet_new(void) +{ + lell_packet *pkt = (lell_packet *)calloc(1, sizeof(lell_packet)); + pkt->refcount = 1; + return pkt; +} + +void +lell_packet_ref(lell_packet *pkt) +{ + pkt->refcount++; +} + +void +lell_packet_unref(lell_packet *pkt) +{ + pkt->refcount--; + if (pkt->refcount == 0) + free(pkt); +} + +static uint8_t le_channel_index(uint16_t phys_channel) { + uint8_t ret; + if (phys_channel == 2402) { + ret = 37; + } else if (phys_channel < 2426) { // 0 - 10 + ret = (phys_channel - 2404) / 2; + } else if (phys_channel == 2426) { + ret = 38; + } else if (phys_channel < 2480) { // 11 - 36 + ret = 11 + (phys_channel - 2428) / 2; + } else { + ret = 39; + } + return ret; +} + +void lell_allocate_and_decode(const uint8_t *stream, uint16_t phys_channel, uint32_t clk100ns, lell_packet **pkt) +{ + *pkt = lell_packet_new( ); + memcpy((*pkt)->symbols, stream, MAX_LE_SYMBOLS); + + (*pkt)->channel_idx = le_channel_index(phys_channel); + (*pkt)->channel_k = (phys_channel-2402)/2; + (*pkt)->clk100ns = clk100ns; + + (*pkt)->access_address = 0; + (*pkt)->access_address |= (*pkt)->symbols[0]; + (*pkt)->access_address |= (*pkt)->symbols[1] << 8; + (*pkt)->access_address |= (*pkt)->symbols[2] << 16; + (*pkt)->access_address |= (*pkt)->symbols[3] << 24; + + if (lell_packet_is_data(*pkt)) { + // data PDU + (*pkt)->length = (*pkt)->symbols[5] & 0x1f; + (*pkt)->access_address_offenses = aa_data_channel_offenses((*pkt)->access_address); + (*pkt)->flags.as_bits.access_address_ok = (*pkt)->access_address_offenses ? 0 : 1; + } else { + // advertising PDU + (*pkt)->length = (*pkt)->symbols[5] & 0x3f; + (*pkt)->adv_type = (*pkt)->symbols[4] & 0xf; + (*pkt)->adv_tx_add = (*pkt)->symbols[4] & 0x40 ? 1 : 0; + (*pkt)->adv_rx_add = (*pkt)->symbols[4] & 0x80 ? 1 : 0; + (*pkt)->flags.as_bits.access_address_ok = ((*pkt)->access_address == 0x8e89bed6); + (*pkt)->access_address_offenses = (*pkt)->flags.as_bits.access_address_ok ? 0 : + (aa_access_channel_off_by_one((*pkt)->access_address) ? 1 : 32); + } +} + +unsigned lell_packet_is_data(const lell_packet *pkt) +{ + return (unsigned) (pkt->channel_idx < 37); +} + +uint32_t lell_get_access_address(const lell_packet *pkt) +{ + return pkt->access_address; +} + +unsigned lell_get_access_address_offenses(const lell_packet *pkt) +{ + return pkt->access_address_offenses; +} + +unsigned lell_get_channel_index(const lell_packet *pkt) +{ + return pkt->channel_idx; +} + +unsigned lell_get_channel_k(const lell_packet *pkt) +{ + return pkt->channel_k; +} + +const char * lell_get_adv_type_str(const lell_packet *pkt) +{ + if (lell_packet_is_data(pkt)) + return NULL; + if (pkt->adv_type < COUNT_OF(ADV_TYPE_NAMES)) + return ADV_TYPE_NAMES[pkt->adv_type]; + return "UNKNOWN"; +} + +static void _dump_addr(const char *name, const uint8_t *buf, int offset, int random) { + int i; + printf(" %s%02x", name, buf[offset+5]); + for (i = 4; i >= 0; --i) + printf(":%02x", buf[offset+i]); + printf(" (%s)\n", random ? "random" : "public"); +} + +static void _dump_8(const char *name, const uint8_t *buf, int offset) { + printf(" %s%02x (%d)\n", name, buf[offset], buf[offset]); +} + +static void _dump_16(const char *name, const uint8_t *buf, int offset) { + uint16_t val = buf[offset+1] << 8 | buf[offset]; + printf(" %s%04x (%d)\n", name, val, val); +} + +static void _dump_24(char *name, const uint8_t *buf, int offset) { + uint32_t val = buf[offset+2] << 16 | buf[offset+1] << 8 | buf[offset]; + printf(" %s%06x\n", name, val); +} + +static void _dump_32(const char *name, const uint8_t *buf, int offset) { + uint32_t val = buf[offset+3] << 24 | + buf[offset+2] << 16 | + buf[offset+1] << 8 | + buf[offset+0]; + printf(" %s%08x\n", name, val); +} + +static void _dump_uuid(const uint8_t *uuid) { + int i; + for (i = 0; i < 4; ++i) + printf("%02x", uuid[i]); + printf("-"); + for (i = 4; i < 6; ++i) + printf("%02x", uuid[i]); + printf("-"); + for (i = 6; i < 8; ++i) + printf("%02x", uuid[i]); + printf("-"); + for (i = 8; i < 10; ++i) + printf("%02x", uuid[i]); + printf("-"); + for (i = 10; i < 16; ++i) + printf("%02x", uuid[i]); +} + +// Refer to pg 1735 of Bluetooth Core Spec 4.0 +static void _dump_scan_rsp_data(const uint8_t *buf, int len) { + int pos = 0; + int sublen, i; + uint8_t type; + uint16_t val; + char *cval; + + while (pos < len) { + sublen = buf[pos]; + ++pos; + if (pos + sublen > len) { + printf("Error: attempt to read past end of buffer (%d + %d > %d)\n", pos, sublen, len); + return; + } + if (sublen == 0) { + printf("Early return due to 0 length\n"); + return; + } + type = buf[pos]; + printf(" Type %02x", type); + switch (type) { + case 0x01: + printf(" (Flags)\n"); + printf(" "); + for (i = 0; i < 8; ++i) + printf("%d", buf[pos+1] & (1 << (7-i)) ? 1 : 0); + printf("\n"); + break; + case 0x06: + printf(" (128-bit Service UUIDs, more available)\n"); + goto print128; + case 0x07: + printf(" (128-bit Service UUIDs)\n"); +print128: + if ((sublen - 1) % 16 == 0) { + uint8_t uuid[16]; + for (i = 0; i < sublen - 1; ++i) { + uuid[15 - (i % 16)] = buf[pos+1+i]; + if ((i & 15) == 15) { + printf(" "); + _dump_uuid(uuid); + printf("\n"); + } + } + } + else { + printf("Wrong length (%d, must be divisible by 16)\n", sublen-1); + } + break; + case 0x09: + printf(" (Complete Local Name)\n"); + printf(" "); + for (i = 1; i < sublen; ++i) + printf("%c", isprint(buf[pos+i]) ? buf[pos+i] : '.'); + printf("\n"); + break; + case 0x0a: + printf(" (Tx Power Level)\n"); + printf(" "); + if (sublen-1 == 1) { + cval = (char *)&buf[pos+1]; + printf("%d dBm\n", *cval); + } else { + printf("Wrong length (%d, should be 1)\n", sublen-1); + } + break; + case 0x12: + printf(" (Slave Connection Interval Range)\n"); + printf(" "); + if (sublen-1 == 4) { + val = (buf[pos+2] << 8) | buf[pos+1]; + printf("(%0.2f, ", val * 1.25); + val = (buf[pos+4] << 8) | buf[pos+3]; + printf("%0.2f) ms\n", val * 1.25); + } + else { + printf("Wrong length (%d, should be 4)\n", sublen-1); + } + break; + case 0x16: + printf(" (Service Data)\n"); + printf(" "); + if (sublen-1 >= 2) { + val = (buf[pos+2] << 8) | buf[pos+1]; + printf("UUID: %02x", val); + if (sublen-1 > 2) { + printf(", Additional:"); + for (i = 3; i < sublen; ++i) + printf(" %02x", buf[pos+i]); + } + printf("\n"); + } + else { + printf("Wrong length (%d, should be >= 2)\n", sublen-1); + } + break; + default: + printf("\n"); + printf(" "); + for (i = 1; i < sublen; ++i) + printf(" %02x", buf[pos+i]); + printf("\n"); + } + pos += sublen; + } +} + +void lell_print(const lell_packet *pkt) +{ + int i, opcode; + if (lell_packet_is_data(pkt)) { + int llid = pkt->symbols[4] & 0x3; + static const char *llid_str[] = { + "Reserved", + "LL Data PDU / empty or L2CAP continuation", + "LL Data PDU / L2CAP start", + "LL Control PDU", + }; + + printf("Data / AA %08x (%s) / %2d bytes\n", pkt->access_address, + pkt->flags.as_bits.access_address_ok ? "valid" : "invalid", + pkt->length); + printf(" Channel Index: %d\n", pkt->channel_idx); + printf(" LLID: %d / %s\n", llid, llid_str[llid]); + printf(" NESN: %d SN: %d MD: %d\n", (pkt->symbols[4] >> 2) & 1, + (pkt->symbols[4] >> 3) & 1, + (pkt->symbols[4] >> 4) & 1); + switch (llid) { + case 3: // LL Control PDU + opcode = pkt->symbols[6]; + static const char *opcode_str[] = { + "LL_CONNECTION_UPDATE_REQ", + "LL_CHANNEL_MAP_REQ", + "LL_TERMINATE_IND", + "LL_ENC_REQ", + "LL_ENC_RSP", + "LL_START_ENC_REQ", + "LL_START_ENC_RSP", + "LL_UNKNOWN_RSP", + "LL_FEATURE_REQ", + "LL_FEATURE_RSP", + "LL_PAUSE_ENC_REQ", + "LL_PAUSE_ENC_RSP", + "LL_VERSION_IND", + "LL_REJECT_IND", + "LL_SLAVE_FEATURE_REQ", + "LL_CONNECTION_PARAM_REQ", + "LL_CONNECTION_PARAM_RSP", + "LL_REJECT_IND_EXT", + "LL_PING_REQ", + "LL_PING_RSP", + "Reserved for Future Use", + }; + printf(" Opcode: %d / %s\n", opcode, opcode_str[(opcode<0x14)?opcode:0x14]); + break; + default: + break; + } + } else { + printf("Advertising / AA %08x (%s)/ %2d bytes\n", pkt->access_address, + pkt->flags.as_bits.access_address_ok ? "valid" : "invalid", + pkt->length); + printf(" Channel Index: %d\n", pkt->channel_idx); + printf(" Type: %s\n", lell_get_adv_type_str(pkt)); + + switch(pkt->adv_type) { + case ADV_IND: + _dump_addr("AdvA: ", pkt->symbols, 6, pkt->adv_tx_add); + if (pkt->length-6 > 0) { + printf(" AdvData:"); + for (i = 0; i < pkt->length - 6; ++i) + printf(" %02x", pkt->symbols[12+i]); + printf("\n"); + _dump_scan_rsp_data(&pkt->symbols[12], pkt->length-6); + } + break; + case SCAN_REQ: + _dump_addr("ScanA: ", pkt->symbols, 6, pkt->adv_tx_add); + _dump_addr("AdvA: ", pkt->symbols, 12, pkt->adv_rx_add); + break; + case SCAN_RSP: + _dump_addr("AdvA: ", pkt->symbols, 6, pkt->adv_tx_add); + printf(" ScanRspData:"); + for (i = 0; i < pkt->length - 6; ++i) + printf(" %02x", pkt->symbols[12+i]); + printf("\n"); + _dump_scan_rsp_data(&pkt->symbols[12], pkt->length-6); + break; + case CONNECT_REQ: + _dump_addr("InitA: ", pkt->symbols, 6, pkt->adv_tx_add); + _dump_addr("AdvA: ", pkt->symbols, 12, pkt->adv_rx_add); + _dump_32("AA: ", pkt->symbols, 18); + _dump_24("CRCInit: ", pkt->symbols, 22); + _dump_8("WinSize: ", pkt->symbols, 25); + _dump_16("WinOffset: ", pkt->symbols, 26); + _dump_16("Interval: ", pkt->symbols, 28); + _dump_16("Latency: ", pkt->symbols, 30); + _dump_16("Timeout: ", pkt->symbols, 32); + + printf(" ChM:"); + for (i = 0; i < 5; ++i) + printf(" %02x", pkt->symbols[34+i]); + printf("\n"); + + printf(" Hop: %d\n", pkt->symbols[39] & 0x1f); + printf(" SCA: %d, %s\n", + pkt->symbols[39] >> 5, + CONNECT_SCA[pkt->symbols[39] >> 5]); + break; + } + } + + printf("\n"); + printf(" Data: "); + for (i = 6; i < 6 + pkt->length; ++i) + printf(" %02x", pkt->symbols[i]); + printf("\n"); + + printf(" CRC: "); + for (i = 0; i < 3; ++i) + printf(" %02x", pkt->symbols[6 + pkt->length + i]); + printf("\n"); +} diff --git a/libbtbb-2015-10-R1/lib/src/bluetooth_le_packet.h b/libbtbb-2015-10-R1/lib/src/bluetooth_le_packet.h new file mode 100644 index 0000000..a16fb0b --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/bluetooth_le_packet.h @@ -0,0 +1,74 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2012 Mike Ryan, Dominic Spill, Michael Ossmann + * Copyright 2005, 2006 Free Software Foundation, Inc. + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_BLUETOOTH_LE_PACKET_H +#define INCLUDED_BLUETOOTH_LE_PACKET_H + +#include +#include +#include + +#define MAX_LE_SYMBOLS 64 + +#define LE_ADV_AA 0x8E89BED6 + +#define ADV_IND 0 +#define ADV_DIRECT_IND 1 +#define ADV_NONCONN_IND 2 +#define SCAN_REQ 3 +#define SCAN_RSP 4 +#define CONNECT_REQ 5 +#define ADV_SCAN_IND 6 + +struct lell_packet { + // raw unwhitened bytes of packet, including access address + uint8_t symbols[MAX_LE_SYMBOLS]; + + uint32_t access_address; + + // channel index + uint8_t channel_idx; + uint8_t channel_k; + + // number of symbols + int length; + + uint32_t clk100ns; + + // advertising packet header info + uint8_t adv_type; + int adv_tx_add; + int adv_rx_add; + + unsigned access_address_offenses; + uint32_t refcount; + + /* flags */ + union { + struct { + uint32_t access_address_ok : 1; + } as_bits; + uint32_t as_word; + } flags; +}; + +#endif /* INCLUDED_BLUETOOTH_LE_PACKET_H */ diff --git a/libbtbb-2015-10-R1/lib/src/bluetooth_packet.c b/libbtbb-2015-10-R1/lib/src/bluetooth_packet.c new file mode 100644 index 0000000..f070ad7 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/bluetooth_packet.c @@ -0,0 +1,1421 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2013 Dominic Spill, Michael Ossmann, Will Code + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "bluetooth_packet.h" +#include "uthash.h" +#include "sw_check_tables.h" + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) + +/* Maximum number of AC errors supported by library. Caller may + * specify any value <= AC_ERROR_LIMIT in btbb_init(). */ +#define AC_ERROR_LIMIT 5 + +/* maximum number of bit errors for known syncwords */ +#define MAX_SYNCWORD_ERRS 5 + +/* maximum number of bit errors in */ +#define MAX_BARKER_ERRORS 1 + +/* default codeword modified for PN sequence and barker code */ +#define DEFAULT_CODEWORD 0xb0000002c7820e7eULL + +/* Default access code, used for calculating syndromes */ +#define DEFAULT_AC 0xcc7b7268ff614e1bULL + +/* index into whitening data array */ +static const uint8_t INDICES[] = {99, 85, 17, 50, 102, 58, 108, 45, 92, 62, 32, 118, 88, 11, 80, 2, 37, 69, 55, 8, 20, 40, 74, 114, 15, 106, 30, 78, 53, 72, 28, 26, 68, 7, 39, 113, 105, 77, 71, 25, 84, 49, 57, 44, 61, 117, 10, 1, 123, 124, 22, 125, 111, 23, 42, 126, 6, 112, 76, 24, 48, 43, 116, 0}; + +/* whitening data */ +static const uint8_t WHITENING_DATA[] = {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1}; + +/* lookup table for barker code hamming distance */ +static const uint8_t BARKER_DISTANCE[] = { + 3,3,3,2,3,2,2,1,2,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,1,2,2,3,2,3,3,3, + 3,2,2,1,2,1,1,0,3,3,3,2,3,2,2,1,3,3,3,2,3,2,2,1,2,3,3,3,3,3,3,2, + 2,3,3,3,3,3,3,2,1,2,2,3,2,3,3,3,1,2,2,3,2,3,3,3,0,1,1,2,1,2,2,3, + 3,3,3,2,3,2,2,1,2,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,1,2,2,3,2,3,3,3}; + +/* string representations of packet type */ +static const char * const TYPE_NAMES[] = { + "NULL", "POLL", "FHS", "DM1", "DH1/2-DH1", "HV1", "HV2/2-EV3", "HV3/EV3/3-EV3", + "DV/3-DH1", "AUX1", "DM3/2-DH3", "DH3/3-DH3", "EV4/2-EV5", "EV5/3-EV5", "DM5/2-DH5", "DH5/3-DH5" +}; + +/* + * generator matrix for sync word (64,30) linear block code + * based on polynomial 0260534236651 + * thanks to http://www.ee.unb.ca/cgi-bin/tervo/polygen.pl + * modified for barker code + */ +static const uint64_t sw_matrix[] = { + 0xfe000002a0d1c014ULL, 0x01000003f0b9201fULL, 0x008000033ae40edbULL, 0x004000035fca99b9ULL, + 0x002000036d5dd208ULL, 0x00100001b6aee904ULL, 0x00080000db577482ULL, 0x000400006dabba41ULL, + 0x00020002f46d43f4ULL, 0x000100017a36a1faULL, 0x00008000bd1b50fdULL, 0x000040029c3536aaULL, + 0x000020014e1a9b55ULL, 0x0000100265b5d37eULL, 0x0000080132dae9bfULL, 0x000004025bd5ea0bULL, + 0x00000203ef526bd1ULL, 0x000001033511ab3cULL, 0x000000819a88d59eULL, 0x00000040cd446acfULL, + 0x00000022a41aabb3ULL, 0x0000001390b5cb0dULL, 0x0000000b0ae27b52ULL, 0x0000000585713da9ULL}; + +static const uint64_t barker_correct[] = { + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, 0x4e00000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, + 0xb000000000000000ULL, 0xb000000000000000ULL, 0xb000000000000000ULL, 0x4e00000000000000ULL}; + +static const uint64_t pn = 0x83848D96BBCC54FCULL; + +static const uint16_t fec23_gen_matrix[] = { + 0x2c01, 0x5802, 0x1c04, 0x3808, 0x7010, + 0x4c20, 0x3440, 0x6880, 0x7d00, 0x5600}; + +typedef struct { + uint64_t syndrome; /* key */ + uint64_t error; + UT_hash_handle hh; +} syndrome_struct; + +static syndrome_struct *syndrome_map = NULL; + +static void add_syndrome(uint64_t syndrome, uint64_t error) +{ + syndrome_struct *s; + s = malloc(sizeof(syndrome_struct)); + s->syndrome = syndrome; + s->error = error; + + HASH_ADD(hh, syndrome_map, syndrome, 8, s); +} + +static syndrome_struct *find_syndrome(uint64_t syndrome) +{ + syndrome_struct *s; + + HASH_FIND(hh, syndrome_map, &syndrome, 8, s); + return s; +} + +static uint64_t gen_syndrome(uint64_t codeword) +{ + uint64_t syndrome = codeword & 0xffffffff; + codeword >>= 32; + syndrome ^= sw_check_table4[codeword & 0xff]; + codeword >>= 8; + syndrome ^= sw_check_table5[codeword & 0xff]; + codeword >>= 8; + syndrome ^= sw_check_table6[codeword & 0xff]; + codeword >>= 8; + syndrome ^= sw_check_table7[codeword & 0xff]; + return syndrome; +} + +static void cycle(uint64_t error, int start, int depth, uint64_t codeword) +{ + uint64_t new_error, syndrome, base; + int i; + base = 1; + depth -= 1; + for (i = start; i < 58; i++) + { + new_error = (base << i); + new_error |= error; + if (depth) + cycle(new_error, i + 1, depth, codeword); + else { + syndrome = gen_syndrome(codeword ^ new_error); + add_syndrome(syndrome, new_error); + } + } +} + +static void gen_syndrome_map(int bit_errors) +{ + int i; + for(i = 1; i <= bit_errors; i++) + cycle(0, 0, i, DEFAULT_AC); +} + +/* Generate Sync Word from an LAP */ +uint64_t btbb_gen_syncword(const int LAP) +{ + int i; + uint64_t codeword = DEFAULT_CODEWORD; + + /* the sync word generated is in host order, not air order */ + for (i = 0; i < 24; i++) + if (LAP & (0x800000 >> i)) + codeword ^= sw_matrix[i]; + + return codeword; +} + +static void init_packet(btbb_packet *pkt, uint32_t lap, uint8_t ac_errors) +{ + pkt->LAP = lap; + pkt->ac_errors = ac_errors; + + pkt->flags = 0; + btbb_packet_set_flag(pkt, BTBB_WHITENED, 1); +} + +/* Convert some number of bits of an air order array to a host order integer */ +static uint8_t air_to_host8(const char *air_order, const int bits) +{ + int i; + uint8_t host_order = 0; + for (i = 0; i < bits; i++) + host_order |= ((uint8_t)air_order[i] << i); + return host_order; +} +static uint16_t air_to_host16(const char *air_order, const int bits) +{ + int i; + uint16_t host_order = 0; + for (i = 0; i < bits; i++) + host_order |= ((uint16_t)air_order[i] << i); + return host_order; +} +static uint32_t air_to_host32(const char *air_order, const int bits) +{ + int i; + uint32_t host_order = 0; + for (i = 0; i < bits; i++) + host_order |= ((uint32_t)air_order[i] << i); + return host_order; +} +static uint64_t air_to_host64(const char *air_order, const int bits) +{ + int i; + uint64_t host_order = 0; + for (i = 0; i < bits; i++) + host_order |= ((uint64_t)air_order[i] << i); + return host_order; +} + +///* Convert some number of bits in a host order integer to an air order array */ +//static void host_to_air(const uint8_t host_order, char *air_order, const int bits) +//{ +// int i; +// for (i = 0; i < bits; i++) +// air_order[i] = (host_order >> i) & 0x01; +//} + +/* count the number of 1 bits in a uint64_t */ +static uint8_t count_bits(uint64_t n) +{ +#ifdef __GNUC__ + return (uint8_t) __builtin_popcountll (n); +#else + uint8_t i = 0; + for (i = 0; n != 0; i++) + n &= n - 1; + return i; +#endif +} + +#ifndef RELEASE +#define RELEASE "unknown" +#endif +char *btbb_get_release(void) { + return RELEASE; +} + +#ifndef VERSION +#define VERSION "unknown" +#endif +char *btbb_get_version(void) { + return VERSION; +} + +int btbb_init(int max_ac_errors) +{ + /* Sanity check max_ac_errors. */ + if ( (max_ac_errors < 0) || (max_ac_errors > AC_ERROR_LIMIT) ) { + fprintf(stderr, "%s: max_ac_errors out of range\n", + __FUNCTION__); + return -1; + } + + if ((syndrome_map == NULL) && (max_ac_errors)) + gen_syndrome_map(max_ac_errors); + + return 0; +} + +btbb_packet * +btbb_packet_new(void) +{ + btbb_packet *pkt = (btbb_packet *)calloc(1, sizeof(btbb_packet)); + if(pkt) + pkt->refcount = 1; + else + fprintf(stderr, "Unable to allocate packet"); + return pkt; +} + +void +btbb_packet_ref(btbb_packet *pkt) +{ + pkt->refcount++; +} + +void +btbb_packet_unref(btbb_packet *pkt) +{ + pkt->refcount--; + if (pkt->refcount == 0) + free(pkt); +} + +uint32_t btbb_packet_get_lap(const btbb_packet *pkt) +{ + return pkt->LAP; +} + +void btbb_packet_set_uap(btbb_packet *pkt, uint8_t uap) +{ + pkt->UAP = uap; + btbb_packet_set_flag(pkt, BTBB_UAP_VALID, 1); +} + +uint8_t btbb_packet_get_uap(const btbb_packet *pkt) +{ + return pkt->UAP; +} + +uint16_t btbb_packet_get_nap(const btbb_packet *pkt) +{ + return pkt->NAP; +} + +uint32_t btbb_packet_get_clkn(const btbb_packet *pkt) { + return pkt->clkn; +} + +uint8_t btbb_packet_get_channel(const btbb_packet *pkt) { + return pkt->channel; +} + +void btbb_packet_set_modulation(btbb_packet *pkt, uint8_t modulation) { + pkt->modulation = modulation; +} + +uint8_t btbb_packet_get_modulation(const btbb_packet *pkt) { + return pkt->modulation; +} + +void btbb_packet_set_transport(btbb_packet *pkt, uint8_t transport) { + pkt->transport = transport; +} + +uint8_t btbb_packet_get_transport(const btbb_packet *pkt) { + return pkt->transport; +} + +uint8_t btbb_packet_get_ac_errors(const btbb_packet *pkt) { + return pkt->ac_errors; +} + +int promiscuous_packet_search(char *stream, int search_length, uint32_t *lap, + int max_ac_errors, uint8_t *ac_errors) { + uint64_t syncword, codeword, syndrome, corrected_barker; + syndrome_struct *errors; + char *symbols; + int count, offset = -1; + + /* Barker code at end of sync word (includes + * MSB of LAP) is used as a rough filter. + */ + uint8_t barker = air_to_host8(&stream[57], 6); + barker <<= 1; + + for (count = 0; count < search_length; count++) { + symbols = &stream[count]; + barker >>= 1; + barker |= (symbols[63] << 6); + if (BARKER_DISTANCE[barker] <= MAX_BARKER_ERRORS) { + // Error correction + syncword = air_to_host64(symbols, 64); + + /* correct the barker code with a simple comparison */ + corrected_barker = barker_correct[(uint8_t)(syncword >> 57)]; + syncword = (syncword & 0x01ffffffffffffffULL) | corrected_barker; + + codeword = syncword ^ pn; + + /* Zero syndrome -> good codeword. */ + syndrome = gen_syndrome(codeword); + *ac_errors = 0; + + /* Try to fix errors in bad codeword. */ + if (syndrome) { + errors = find_syndrome(syndrome); + if (errors != NULL) { + syncword ^= errors->error; + *ac_errors = count_bits(errors->error); + syndrome = 0; + } + else { + *ac_errors = 0xff; // fail + } + } + + if (*ac_errors <= max_ac_errors) { + *lap = (syncword >> 34) & 0xffffff; + offset = count; + break; + } + } + } + return offset; +} + +/* Matching a specific LAP */ +int find_known_lap(char *stream, int search_length, uint32_t lap, + int max_ac_errors, uint8_t *ac_errors) { + uint64_t syncword, ac; + char *symbols; + int count, offset = -1; + + ac = btbb_gen_syncword(lap); + for (count = 0; count < search_length; count++) { + symbols = &stream[count]; + syncword = air_to_host64(symbols, 64); + *ac_errors = count_bits(syncword ^ ac); + + if (*ac_errors <= max_ac_errors) { + offset = count; + break; + } + } + return offset; +} + +/* Looks for an AC in the stream */ +int btbb_find_ac(char *stream, int search_length, uint32_t lap, + int max_ac_errors, btbb_packet **pkt_ptr) { + int offset; + uint8_t ac_errors; + + /* Matching any LAP */ + if (lap == LAP_ANY) + offset = promiscuous_packet_search(stream, search_length, &lap, + max_ac_errors, &ac_errors); + else + offset = find_known_lap(stream, search_length, lap, + max_ac_errors, &ac_errors); + + if (offset >= 0) { + if (*pkt_ptr == NULL) + *pkt_ptr = btbb_packet_new(); + init_packet(*pkt_ptr, lap, ac_errors); + } + + return offset; +} + +/* Copy data (symbols) into packet and set rx data. */ +void btbb_packet_set_data(btbb_packet *pkt, char *data, int length, + uint8_t channel, uint32_t clkn) +{ + int i; + + if (length > MAX_SYMBOLS) + length = MAX_SYMBOLS; + for (i = 0; i < length; i++) + pkt->symbols[i] = data[i]; + + pkt->length = length; + pkt->channel = channel; + pkt->clkn = clkn >> 1; // really CLK1 +} + +void btbb_packet_set_flag(btbb_packet *pkt, int flag, int val) +{ + uint32_t mask = 1L << flag; + pkt->flags &= ~mask; + if (val) + pkt->flags |= mask; +} + +int btbb_packet_get_flag(const btbb_packet *pkt, int flag) +{ + uint32_t mask = 1L << flag; + return ((pkt->flags & mask) != 0); +} + +const char *btbb_get_symbols(const btbb_packet* pkt) +{ + return (const char*) pkt->symbols; +} + +int btbb_packet_get_payload_length(const btbb_packet* pkt) +{ + return pkt->payload_length; +} + +const char *btbb_get_payload(const btbb_packet* pkt) +{ + return (const char*) pkt->payload; +} + +int btbb_get_payload_packed(const btbb_packet* pkt, char *dst) +{ + int i; + for(i=0;ipayload_length;i++) + dst[i] = (char) air_to_host8(&pkt->payload[i*8], 8); + return pkt->payload_length; +} + +uint8_t btbb_packet_get_type(const btbb_packet* pkt) +{ + return pkt->packet_type; +} + +uint8_t btbb_packet_get_lt_addr(const btbb_packet* pkt) +{ + return pkt->packet_lt_addr; +} + +uint8_t btbb_packet_get_header_flags(const btbb_packet* pkt) +{ + return pkt->packet_flags; +} + +uint8_t btbb_packet_get_hec(const btbb_packet* pkt) +{ + return pkt->packet_hec; +} + +uint32_t btbb_packet_get_header_packed(const btbb_packet* pkt) +{ + return air_to_host32(&pkt->packet_header[0], 18); +} + +/* Reverse the bits in a byte */ +static uint8_t reverse(char byte) +{ + return (byte & 0x80) >> 7 | (byte & 0x40) >> 5 | (byte & 0x20) >> 3 | (byte & 0x10) >> 1 | (byte & 0x08) << 1 | (byte & 0x04) << 3 | (byte & 0x02) << 5 | (byte & 0x01) << 7; +} + + +/* Decode 1/3 rate FEC, three like symbols in a row */ +static int unfec13(char *input, char *output, int length) +{ + int a, b, c, i; + int be = 0; /* bit errors */ + + for (i = 0; i < length; i++) { + a = 3 * i; + b = a + 1; + c = a + 2; + output[i] = ((input[a] & input[b]) | (input[b] & input[c]) | + (input[c] & input[a])); + be += ((input[a] ^ input[b]) | (input[b] ^ input[c]) | + (input[c] ^ input[a])); + } + + return (be < (length / 4)); +} + +/* encode 10 bits with 2/3 rate FEC code, a (15,10) shortened Hamming code */ +static uint16_t fec23(uint16_t data) +{ + int i; + uint16_t codeword = 0; + + /* host order, not air order */ + for (i = 0; i < 10; i++) + if (data & (1 << i)) + codeword ^= fec23_gen_matrix[i]; + + return codeword; +} + +/* Decode 2/3 rate FEC, a (15,10) shortened Hamming code */ +static char *unfec23(char *input, int length) +{ + /* input points to the input data + * length is length in bits of the data + * before it was encoded with fec2/3 */ + int iptr, optr, count; + char* output; + uint8_t diff, check; + uint16_t data, codeword; + + diff = length % 10; + // padding at end of data + if(0!=diff) + length += (10 - diff); + + output = (char *) malloc(length); + + for (iptr = 0, optr = 0; optr> 10); + + /* no errors or single bit errors (errors in the parity bit): + * (a strong hint it's a real packet) + * Otherwise we need to corret the output*/ + if (diff & (diff - 1)) { + switch (diff) { + /* comments are the bit that's wrong and the value + * of diff in air order, from the BT spec */ + // 1000000000 11010 + case 0x0b: output[optr] ^= 1; break; + // 0100000000 01101 + case 0x16: output[optr+1] ^= 1; break; + // 0010000000 11100 + case 0x07: output[optr+2] ^= 1; break; + // 0001000000 01110 + case 0x0e: output[optr+3] ^= 1; break; + // 0000100000 00111 + case 0x1c: output[optr+4] ^= 1; break; + // 0000010000 11001 + case 0x13: output[optr+5] ^= 1; break; + // 0000001000 10110 + case 0x0d: output[optr+6] ^= 1; break; + // 0000000100 01011 + case 0x1a: output[optr+7] ^= 1; break; + // 0000000010 11111 + case 0x1f: output[optr+8] ^= 1; break; + // 0000000001 10101 + case 0x15: output[optr+9] ^= 1; break; + /* not one of these errors, probably multiple bit errors + * or maybe not a real packet, safe to drop it? */ + default: free(output); return 0; + } + } + } + return output; +} + + +/* Remove the whitening from an air order array */ +static void unwhiten(char* input, char* output, int clock, int length, int skip, btbb_packet* pkt) +{ + int count, index; + index = INDICES[clock & 0x3f]; + index += skip; + index %= 127; + + for(count = 0; count < length; count++) + { + /* unwhiten if whitened, otherwise just copy input to output */ + output[count] = btbb_packet_get_flag(pkt, BTBB_WHITENED) ? + input[count] ^ WHITENING_DATA[index] : input[count]; + index += 1; + index %= 127; + } +} + +/* Pointer to start of packet, length of packet in bits, UAP */ +static uint16_t crcgen(char *payload, int length, int UAP) +{ + char bit; + uint16_t reg, count; + + reg = (reverse(UAP) << 8) & 0xff00; + for(count = 0; count < length; count++) + { + bit = payload[count]; + + reg = (reg >> 1) | (((reg & 0x0001) ^ (bit & 0x01))<<15); + + /*Bit 5*/ + reg ^= ((reg & 0x8000)>>5); + + /*Bit 12*/ + reg ^= ((reg & 0x8000)>>12); + } + return reg; +} + +/* extract UAP by reversing the HEC computation */ +static uint8_t uap_from_hec(uint16_t data, uint8_t hec) +{ + int i; + + for (i = 9; i >= 0; i--) { + /* 0x65 is xor'd if MSB is 1, else 0x00 (which does nothing) */ + if (hec & 0x80) + hec ^= 0x65; + + hec = (hec << 1) | (((hec >> 7) ^ (data >> i)) & 0x01); + } + return reverse(hec); +} + +/* check if the packet's CRC is correct for a given clock (CLK1-6) */ +int crc_check(int clock, btbb_packet* pkt) +{ + /* + * return value of 1 represents inconclusive result (default) + * return value > 1 represents positive result (e.g. CRC match) + * return value of 0 represents negative result (e.g. CRC failure without + * the possibility that we have assumed the wrong logical transport) + */ + int retval = 1; + + switch(pkt->packet_type) + { + case PACKET_TYPE_FHS: + retval = fhs(clock, pkt); + break; + + case PACKET_TYPE_DV: + case PACKET_TYPE_DM1: + case PACKET_TYPE_DM3: + case PACKET_TYPE_DM5: + retval = DM(clock, pkt); + break; + + case PACKET_TYPE_DH1: + case PACKET_TYPE_DH3: + case PACKET_TYPE_DH5: + retval = DH(clock, pkt); + break; + + case PACKET_TYPE_HV3: /* EV3 */ + retval = EV3(clock, pkt); + break; + case PACKET_TYPE_EV4: + retval = EV4(clock, pkt); + break; + case PACKET_TYPE_EV5: + retval = EV5(clock, pkt); + break; + + case PACKET_TYPE_HV1: + retval = HV(clock, pkt); + break; + + /* some types can't help us */ + default: + break; + } + /* + * never return a zero result unless this is a FHS, DM1, or HV1. any + * other type could have actually been something else (another logical + * transport) + */ + if (retval == 0 && (pkt->packet_type != 2 && pkt->packet_type != 3 && + pkt->packet_type != 5)) + return 1; + + /* EV3 and EV5 have a relatively high false positive rate */ + if (retval > 1 && (pkt->packet_type == 7 || pkt->packet_type == 13)) + return 1; + + return retval; +} + +/* verify the payload CRC */ +static int payload_crc(btbb_packet* pkt) +{ + uint16_t crc; /* CRC calculated from payload data */ + uint16_t check; /* CRC supplied by packet */ + + crc = crcgen(pkt->payload, (pkt->payload_length - 2) * 8, pkt->UAP); + check = air_to_host16(&pkt->payload[(pkt->payload_length - 2) * 8], 16); + + return (crc == check); +} + +int fhs(int clock, btbb_packet* pkt) +{ + /* skip the access code and packet header */ + char *stream = pkt->symbols + 122; + /* number of symbols remaining after access code and packet header */ + int size = pkt->length - 122; + + pkt->payload_length = 20; + + if (size < pkt->payload_length * 12) + return 1; //FIXME should throw exception + + char *corrected = unfec23(stream, pkt->payload_length * 8); + if (!corrected) + return 0; + + /* try to unwhiten with known clock bits */ + unwhiten(corrected, pkt->payload, clock, pkt->payload_length * 8, 18, pkt); + if (payload_crc(pkt)) { + free(corrected); + return 1000; + } + + /* try all 32 possible X-input values instead */ + for (clock = 32; clock < 64; clock++) { + unwhiten(corrected, pkt->payload, clock, pkt->payload_length * 8, 18, pkt); + if (payload_crc(pkt)) { + free(corrected); + return 1000; + } + } + + /* failed to unwhiten */ + free(corrected); + return 0; +} + +/* decode payload header, return value indicates success */ +static int decode_payload_header(char *stream, int clock, int header_bytes, int size, int fec, btbb_packet* pkt) +{ + if(header_bytes == 2) + { + if(size < 16) + return 0; //FIXME should throw exception + if(fec) { + if(size < 30) + return 0; //FIXME should throw exception + char *corrected = unfec23(stream, 16); + if (!corrected) + return 0; + unwhiten(corrected, pkt->payload_header, clock, 16, 18, pkt); + free(corrected); + } else { + unwhiten(stream, pkt->payload_header, clock, 16, 18, pkt); + } + /* payload length is payload body length + 2 bytes payload header + 2 bytes CRC */ + pkt->payload_length = air_to_host16(&pkt->payload_header[3], 10) + 4; + } else { + if(size < 8) + return 0; //FIXME should throw exception + if(fec) { + if(size < 15) + return 0; //FIXME should throw exception + char *corrected = unfec23(stream, 8); + if (!corrected) + return 0; + unwhiten(corrected, pkt->payload_header, clock, 8, 18, pkt); + free(corrected); + } else { + unwhiten(stream, pkt->payload_header, clock, 8, 18, pkt); + } + /* payload length is payload body length + 1 byte payload header + 2 bytes CRC */ + pkt->payload_length = air_to_host8(&pkt->payload_header[3], 5) + 3; + } + /* Try to set the max payload length to a sensible value, + * especially when using strange data + */ + int max_length = 0; + switch(pkt->packet_type) { + case PACKET_TYPE_DM1: + max_length = 20; + break; + case PACKET_TYPE_DH1: + /* assuming DH1 but could be 2-DH1 (58) */ + max_length = 30; + break; + case PACKET_TYPE_DV: + /* assuming DV but could be 3-DH1 (87) */ + max_length = 12; /* + 10bytes of voice data */ + break; + case PACKET_TYPE_DM3: + /* assuming DM3 but could be 2-DH3 (371) */ + max_length = 125; + break; + case PACKET_TYPE_DH3: + /* assuming DH3 but could be 3-DH3 (556) */ + max_length = 187; + break; + case PACKET_TYPE_DM5: + /* assuming DM5 but could be 2-DH5 (683) */ + max_length = 228; + break; + case PACKET_TYPE_DH5: + /* assuming DH5 but could be 3-DH5 (1025) */ + max_length = 343; + break; + } + pkt->payload_length = MIN(pkt->payload_length, max_length); + pkt->payload_llid = air_to_host8(&pkt->payload_header[0], 2); + pkt->payload_flow = air_to_host8(&pkt->payload_header[2], 1); + pkt->payload_header_length = header_bytes; + return 1; +} + +/* DM 1/3/5 packet (and DV)*/ +int DM(int clock, btbb_packet* pkt) +{ + int bitlength; + /* number of bytes in the payload header */ + int header_bytes = 2; + /* maximum payload length */ + int max_length; + /* skip the access code and packet header */ + char *stream = pkt->symbols + 122; + /* number of symbols remaining after access code and packet header */ + int size = pkt->length - 122; + + switch(pkt->packet_type) + { + case PACKET_TYPE_DV: + /* skip 80 voice bits, then treat the rest like a DM1 */ + stream += 80; + size -= 80; + header_bytes = 1; + /* I don't think the length of the voice field ("synchronous data + * field") is included in the length indicated by the payload + * header in the data field ("asynchronous data field"), but I + * could be wrong. + */ + max_length = 12; + break; + case PACKET_TYPE_DM1: + header_bytes = 1; + max_length = 20; + break; + case PACKET_TYPE_DM3: + max_length = 125; + break; + case PACKET_TYPE_DM5: + max_length = 228; + break; + default: /* not a DM1/3/5 or DV */ + return 0; + } + if(!decode_payload_header(stream, clock, header_bytes, size, 1, pkt)) + return 0; + /* check that the length indicated in the payload header is within spec */ + if(pkt->payload_length > max_length) + /* could be encrypted */ + return 1; + bitlength = pkt->payload_length*8; + if(bitlength > size) + return 1; //FIXME should throw exception + + char *corrected = unfec23(stream, bitlength); + if (!corrected) + return 0; + unwhiten(corrected, pkt->payload, clock, bitlength, 18, pkt); + free(corrected); + + if (payload_crc(pkt)) + return 10; + + /* could be encrypted */ + return 2; +} + +/* DH 1/3/5 packet (and AUX1) */ +/* similar to DM 1/3/5 but without FEC */ +int DH(int clock, btbb_packet* pkt) +{ + int bitlength; + /* number of bytes in the payload header */ + int header_bytes = 2; + /* maximum payload length */ + int max_length; + /* skip the access code and packet header */ + char *stream = pkt->symbols + 122; + /* number of symbols remaining after access code and packet header */ + int size = pkt->length - 122; + + switch(pkt->packet_type) + { + case PACKET_TYPE_AUX1: + case PACKET_TYPE_DH1: + header_bytes = 1; + max_length = 30; + break; + case PACKET_TYPE_DH3: + max_length = 187; + break; + case PACKET_TYPE_DH5: + max_length = 343; + break; + default: /* not a DH1/3/5 */ + return 0; + } + if(!decode_payload_header(stream, clock, header_bytes, size, 0, pkt)) + return 0; + /* check that the length indicated in the payload header is within spec */ + if(pkt->payload_length > max_length) + /* could be encrypted */ + return 1; + bitlength = pkt->payload_length*8; + if(bitlength > size) + return 1; //FIXME should throw exception + + unwhiten(stream, pkt->payload, clock, bitlength, 18, pkt); + + /* AUX1 has no CRC */ + if (pkt->packet_type == 9) + return 2; + + if (payload_crc(pkt)) + return 10; + + /* could be encrypted */ + return 2; +} + +int EV3(int clock, btbb_packet* pkt) +{ + /* skip the access code and packet header */ + char *stream = pkt->symbols + 122; + + /* number of symbols remaining after access code and packet header */ + int size = pkt->length - 122; + + /* maximum payload length is 30 bytes + 2 bytes CRC */ + int maxlength = 32; + + /* number of bits we have decoded */ + int bits; + + /* check CRC for any integer byte length up to maxlength */ + for (pkt->payload_length = 0; + pkt->payload_length < maxlength; pkt->payload_length++) { + + bits = pkt->payload_length * 8; + + /* unwhiten next byte */ + if ((bits + 8) > size) + return 1; //FIXME should throw exception + unwhiten(stream, pkt->payload + bits, clock, 8, 18 + bits, pkt); + + if ((pkt->payload_length > 2) && (payload_crc(pkt))) + return 10; + } + return 2; +} + +int EV4(int clock, btbb_packet* pkt) +{ + char *corrected; + + /* skip the access code and packet header */ + char *stream = pkt->symbols + 122; + + /* number of symbols remaining after access code and packet header */ + int size = pkt->length - 122; + + /* + * maximum payload length is 120 bytes + 2 bytes CRC + * after FEC2/3, this results in a maximum of 1470 symbols + */ + int maxlength = 1470; + + /* + * minumum payload length is 1 bytes + 2 bytes CRC + * after FEC2/3, this results in a minimum of 45 symbols + */ + int minlength = 45; + + int syms = 0; /* number of symbols we have decoded */ + int bits = 0; /* number of payload bits we have decoded */ + + pkt->payload_length = 1; + + while (syms < maxlength) { + + /* unfec/unwhiten next block (15 symbols -> 10 bits) */ + if (syms + 15 > size) + return 1; //FIXME should throw exception + corrected = unfec23(stream + syms, 10); + if (!corrected) { + free(corrected); + if (syms < minlength) + return 0; + else + return 1; + } + unwhiten(corrected, pkt->payload + bits, clock, 10, 18 + bits, pkt); + free(corrected); + + /* check CRC one byte at a time */ + while (pkt->payload_length * 8 <= bits) { + if (payload_crc(pkt)) + return 10; + pkt->payload_length++; + } + syms += 15; + bits += 10; + } + return 2; +} + +int EV5(int clock, btbb_packet* pkt) +{ + /* skip the access code and packet header */ + char *stream = pkt->symbols + 122; + + /* number of symbols remaining after access code and packet header */ + int size = pkt->length - 122; + + /* maximum payload length is 180 bytes + 2 bytes CRC */ + int maxlength = 182; + + /* number of bits we have decoded */ + int bits; + + /* check CRC for any integer byte length up to maxlength */ + for (pkt->payload_length = 0; + pkt->payload_length < maxlength; pkt->payload_length++) { + + bits = pkt->payload_length * 8; + + /* unwhiten next byte */ + if ((bits + 8) > size) + return 1; //FIXME should throw exception + unwhiten(stream, pkt->payload + bits, clock, 8, 18 + bits, pkt); + + if ((pkt->payload_length > 2) && (payload_crc(pkt))) + return 10; + } + return 2; +} + +/* HV packet type payload parser */ +int HV(int clock, btbb_packet* pkt) +{ + /* skip the access code and packet header */ + char *stream = pkt->symbols + 122; + /* number of symbols remaining after access code and packet header */ + int size = pkt->length - 122; + + pkt->payload_header_length = 0; + if(size < 240) { + pkt->payload_length = 0; + return 1; //FIXME should throw exception + } + + switch (pkt->packet_type) { + case PACKET_TYPE_HV1: + { + char corrected[80]; + if (!unfec13(stream, corrected, 80)) + return 0; + pkt->payload_length = 10; + btbb_packet_set_flag(pkt, BTBB_HAS_PAYLOAD, 1); + unwhiten(corrected, pkt->payload, clock, pkt->payload_length*8, 18, pkt); + } + break; + case PACKET_TYPE_HV2: + { + char *corrected = unfec23(stream, 160); + if (!corrected) + return 0; + pkt->payload_length = 20; + btbb_packet_set_flag(pkt, BTBB_HAS_PAYLOAD, 1); + unwhiten(corrected, pkt->payload, clock, pkt->payload_length*8, 18, pkt); + free(corrected); + } + break; + case PACKET_TYPE_HV3: + pkt->payload_length = 30; + btbb_packet_set_flag(pkt, BTBB_HAS_PAYLOAD, 1); + unwhiten(stream, pkt->payload, clock, pkt->payload_length*8, 18, pkt); + break; + } + + return 2; +} +/* try a clock value (CLK1-6) to unwhiten packet header, + * sets resultant p->packet_type and p->UAP, returns UAP. + */ +uint8_t try_clock(int clock, btbb_packet* pkt) +{ + /* skip 72 bit access code */ + char *stream = pkt->symbols + 68; + /* 18 bit packet header */ + char header[18]; + char unwhitened[18]; + + if (!unfec13(stream, header, 18)) + return 0; + unwhiten(header, unwhitened, clock, 18, 0, pkt); + uint16_t hdr_data = air_to_host16(unwhitened, 10); + uint8_t hec = air_to_host8(&unwhitened[10], 8); + pkt->UAP = uap_from_hec(hdr_data, hec); + pkt->packet_type = air_to_host8(&unwhitened[3], 4); + + return pkt->UAP; +} + +/* decode the packet header */ +int btbb_decode_header(btbb_packet* pkt) +{ + /* skip 72 bit access code */ + char *stream = pkt->symbols + 68; + /* 18 bit packet header */ + char header[18]; + uint8_t UAP; + + if (btbb_packet_get_flag(pkt, BTBB_CLK6_VALID) && unfec13(stream, header, 18)) { + unwhiten(header, pkt->packet_header, pkt->clock, 18, 0, pkt); + uint16_t hdr_data = air_to_host16(pkt->packet_header, 10); + uint8_t hec = air_to_host8(&pkt->packet_header[10], 8); + UAP = uap_from_hec(hdr_data, hec); + if (UAP == pkt->UAP) { + pkt->packet_lt_addr = air_to_host8(&pkt->packet_header[0], 3); + pkt->packet_type = air_to_host8(&pkt->packet_header[3], 4); + pkt->packet_flags = air_to_host8(&pkt->packet_header[7], 3); + pkt->packet_hec = hec; + return 1; + } + } + + return 0; +} + +int btbb_decode_payload(btbb_packet* pkt) +{ + int rv = 0; + pkt->payload_header_length = 0; + + switch(pkt->packet_type) + { + case PACKET_TYPE_NULL: + /* no payload to decode */ + pkt->payload_length = 0; + rv = 1; + break; + case PACKET_TYPE_POLL: + /* no payload to decode */ + pkt->payload_length = 0; + rv = 1; + break; + case PACKET_TYPE_FHS: + rv = fhs(pkt->clock, pkt); + break; + case PACKET_TYPE_DM1: + rv = DM(pkt->clock, pkt); + break; + case PACKET_TYPE_DH1: + /* assuming DH1 but could be 2-DH1 */ + rv = DH(pkt->clock, pkt); + break; + case PACKET_TYPE_HV1: + rv = HV(pkt->clock, pkt); + break; + case PACKET_TYPE_HV2: + rv = HV(pkt->clock, pkt); + break; + case PACKET_TYPE_HV3: /* HV3/EV3/3-EV3 */ + /* decode as EV3 if CRC checks out */ + if ((rv = EV3(pkt->clock, pkt)) <= 1) + /* otherwise assume HV3 */ + rv = HV(pkt->clock, pkt); + /* don't know how to decode 3-EV3 */ + break; + case PACKET_TYPE_DV: + /* assuming DV but could be 3-DH1 */ + rv = DM(pkt->clock, pkt); + break; + case PACKET_TYPE_AUX1: + rv = DH(pkt->clock, pkt); + break; + case PACKET_TYPE_DM3: + /* assuming DM3 but could be 2-DH3 */ + rv = DM(pkt->clock, pkt); + break; + case PACKET_TYPE_DH3: + /* assuming DH3 but could be 3-DH3 */ + rv = DH(pkt->clock, pkt); + break; + case PACKET_TYPE_EV4: + /* assuming EV4 but could be 2-EV5 */ + rv = EV4(pkt->clock, pkt); + break; + case PACKET_TYPE_EV5: + /* assuming EV5 but could be 3-EV5 */ + rv = EV5(pkt->clock, pkt); + break; + case PACKET_TYPE_DM5: + /* assuming DM5 but could be 2-DH5 */ + rv = DM(pkt->clock, pkt); + break; + case PACKET_TYPE_DH5: + /* assuming DH5 but could be 3-DH5 */ + rv = DH(pkt->clock, pkt); + break; + } + btbb_packet_set_flag(pkt, BTBB_HAS_PAYLOAD, 1); + return rv; +} + +/* print packet information */ +void btbb_print_packet(const btbb_packet* pkt) +{ + if (btbb_packet_get_flag(pkt, BTBB_HAS_PAYLOAD)) { + printf(" Type: %s\n", TYPE_NAMES[pkt->packet_type]); + if (pkt->payload_header_length > 0) { + printf(" LT_ADDR: %d\n", pkt->packet_lt_addr); + printf(" LLID: %d\n", pkt->payload_llid); + printf(" flow: %d\n", pkt->payload_flow); + printf(" payload length: %d\n", pkt->payload_length); + } + if (pkt->payload_length) { + printf(" Data: "); + int i; + for(i=0; ipayload_length; i++) + printf(" %02x", air_to_host8(pkt->payload + 8*i, 8)); + printf("\n"); + } + } +} + +char *tun_format(btbb_packet* pkt) +{ + /* include 6 bytes for meta data, 3 bytes for packet header */ + int length = 9 + pkt->payload_length; + char *tun_format = (char *) malloc(length); + int i; + + /* meta data */ + tun_format[0] = pkt->clock & 0xff; + tun_format[1] = (pkt->clock >> 8) & 0xff; + tun_format[2] = (pkt->clock >> 16) & 0xff; + tun_format[3] = (pkt->clock >> 24) & 0xff; + tun_format[4] = pkt->channel; + tun_format[5] = btbb_packet_get_flag(pkt, BTBB_CLK27_VALID) | + (btbb_packet_get_flag(pkt, BTBB_NAP_VALID) << 1); + + /* packet header modified to fit byte boundaries */ + /* lt_addr and type */ + tun_format[6] = (char) air_to_host8(&pkt->packet_header[0], 7); + /* flags */ + tun_format[7] = (char) air_to_host8(&pkt->packet_header[7], 3); + /* HEC */ + tun_format[8] = (char) air_to_host8(&pkt->packet_header[10], 8); + + for(i=0;ipayload_length;i++) + tun_format[i+9] = (char) air_to_host8(&pkt->payload[i*8], 8); + + return tun_format; +} + +/* check to see if the packet has a header */ +int btbb_header_present(const btbb_packet* pkt) +{ + /* skip to last bit of sync word */ + const char *stream = pkt->symbols + 63; + int be = 0; /* bit errors */ + char msb; /* most significant (last) bit of sync word */ + int a, b, c; + + /* check that we have enough symbols */ + if (pkt->length < 122) + return 0; + + /* check that the AC trailer is correct */ + msb = stream[0]; + be += stream[1] ^ !msb; + be += stream[2] ^ msb; + be += stream[3] ^ !msb; + be += stream[4] ^ msb; + + /* + * Each bit of the 18 bit header is repeated three times. Without + * checking the correctness of any particular bit, just count the + * number of times three symbols in a row don't all agree. + */ + stream += 5; + for (a = 0; a < 54; a += 3) { + b = a + 1; + c = a + 2; + be += ((stream[a] ^ stream[b]) | + (stream[b] ^ stream[c]) | (stream[c] ^ stream[a])); + } + + /* + * Few bit errors indicates presence of a header. Many bit errors + * indicates no header is present (i.e. it is an ID packet). + */ + return (be < ID_THRESHOLD); +} + +/* extract LAP from FHS payload */ +uint32_t lap_from_fhs(btbb_packet* pkt) +{ + /* caller should check got_payload() and get_type() */ + return air_to_host32(&pkt->payload[34], 24); +} + +/* extract UAP from FHS payload */ +uint8_t uap_from_fhs(btbb_packet* pkt) +{ + /* caller should check got_payload() and get_type() */ + return air_to_host8(&pkt->payload[64], 8); +} + +/* extract NAP from FHS payload */ +uint16_t nap_from_fhs(btbb_packet* pkt) +{ + /* caller should check got_payload() and get_type() */ + return air_to_host8(&pkt->payload[72], 16); +} + +/* extract clock from FHS payload */ +uint32_t clock_from_fhs(btbb_packet* pkt) +{ + /* + * caller should check got_payload() and get_type() + * + * This is CLK2-27 (units of 1.25 ms). + * CLK0 and CLK1 are implicitly zero. + */ + return air_to_host32(&pkt->payload[115], 26); +} diff --git a/libbtbb-2015-10-R1/lib/src/bluetooth_packet.h b/libbtbb-2015-10-R1/lib/src/bluetooth_packet.h new file mode 100644 index 0000000..27b2a61 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/bluetooth_packet.h @@ -0,0 +1,147 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2013 Dominic Spill, Michael Ossmann, Will Code + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_BLUETOOTH_PACKET_H +#define INCLUDED_BLUETOOTH_PACKET_H +#include "btbb.h" + +/* maximum number of symbols */ +#define MAX_SYMBOLS 3125 + +/* maximum number of payload bits */ +#define MAX_PAYLOAD_LENGTH 2744 + +/* minimum header bit errors to indicate that this is an ID packet */ +#define ID_THRESHOLD 5 + +#define PACKET_TYPE_NULL 0 +#define PACKET_TYPE_POLL 1 +#define PACKET_TYPE_FHS 2 +#define PACKET_TYPE_DM1 3 +#define PACKET_TYPE_DH1 4 +#define PACKET_TYPE_HV1 5 +#define PACKET_TYPE_HV2 6 +#define PACKET_TYPE_HV3 7 +#define PACKET_TYPE_DV 8 +#define PACKET_TYPE_AUX1 9 +#define PACKET_TYPE_DM3 10 +#define PACKET_TYPE_DH3 11 +#define PACKET_TYPE_EV4 12 +#define PACKET_TYPE_EV5 13 +#define PACKET_TYPE_DM5 14 +#define PACKET_TYPE_DH5 15 + +struct btbb_packet { + + uint32_t refcount; + + uint32_t flags; + + uint8_t channel; /* Bluetooth channel (0-79) */ + uint8_t UAP; /* upper address part */ + uint16_t NAP; /* non-significant address part */ + uint32_t LAP; /* lower address part found in access code */ + + uint8_t modulation; + uint8_t transport; + uint8_t packet_type; + uint8_t packet_lt_addr; /* LLID field of payload header (2 bits) */ + uint8_t packet_flags; /* Flags - FLOW/ARQN/SQEN */ + uint8_t packet_hec; /* Flags - FLOW/ARQN/SQEN */ + + /* packet header, one bit per char */ + char packet_header[18]; + + /* number of payload header bytes: 0, 1, 2, or -1 for + * unknown. payload is one bit per char. */ + int payload_header_length; + char payload_header[16]; + + /* LLID field of payload header (2 bits) */ + uint8_t payload_llid; + + /* flow field of payload header (1 bit) */ + uint8_t payload_flow; + + /* payload length: the total length of the asynchronous data + * in bytes. This does not include the length of synchronous + * data, such as the voice field of a DV packet. If there is a + * payload header, this payload length is payload body length + * (the length indicated in the payload header's length field) + * plus payload_header_length plus 2 bytes CRC (if present). + */ + int payload_length; + + /* The actual payload data in host format + * Ready for passing to wireshark + * 2744 is the maximum length, but most packets are shorter. + * Dynamic allocation would probably be better in the long run but is + * problematic in the short run. + */ + char payload[MAX_PAYLOAD_LENGTH]; + + uint16_t crc; + uint32_t clock; /* CLK1-27 of master */ + uint32_t clkn; /* native (local) clock, CLK0-27 */ + uint8_t ac_errors; /* Number of bit errors in the AC */ + + /* the raw symbol stream (less the preamble), one bit per char */ + //FIXME maybe this should be a vector so we can grow it only + //to the size needed and later shrink it if we find we have + //more symbols than necessary + uint16_t length; /* number of symbols */ + char symbols[MAX_SYMBOLS]; + +}; + +/* type-specific CRC checks and decoding */ +int fhs(int clock, btbb_packet* p); +int DM(int clock, btbb_packet* p); +int DH(int clock, btbb_packet* p); +int EV3(int clock, btbb_packet* p); +int EV4(int clock, btbb_packet* p); +int EV5(int clock, btbb_packet* p); +int HV(int clock, btbb_packet* p); + +/* check if the packet's CRC is correct for a given clock (CLK1-6) */ +int crc_check(int clock, btbb_packet* p); + +/* format payload for tun interface */ +char *tun_format(btbb_packet* p); + +/* try a clock value (CLK1-6) to unwhiten packet header, + * sets resultant d_packet_type and d_UAP, returns UAP. + */ +uint8_t try_clock(int clock, btbb_packet* p); + +/* extract LAP from FHS payload */ +uint32_t lap_from_fhs(btbb_packet* p); + +/* extract UAP from FHS payload */ +uint8_t uap_from_fhs(btbb_packet* p); + +/* extract NAP from FHS payload */ +uint16_t nap_from_fhs(btbb_packet* p); + +/* extract clock from FHS payload */ +uint32_t clock_from_fhs(btbb_packet* p); + +#endif /* INCLUDED_BLUETOOTH_PACKET_H */ diff --git a/libbtbb-2015-10-R1/lib/src/bluetooth_piconet.c b/libbtbb-2015-10-R1/lib/src/bluetooth_piconet.c new file mode 100644 index 0000000..751a34d --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/bluetooth_piconet.c @@ -0,0 +1,953 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2013 Dominic Spill, Michael Ossmann, Will Code + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "bluetooth_packet.h" +#include "bluetooth_piconet.h" +#include "uthash.h" +#include +#include + +int perm_table_initialized = 0; +char perm_table[0x20][0x20][0x200]; + +/* count the number of 1 bits in a uint64_t */ +int count_bits(uint8_t n) +{ + int i = 0; + for (i = 0; n != 0; i++) + n &= n - 1; + return i; +} + +btbb_piconet * +btbb_piconet_new(void) +{ + btbb_piconet *pn = (btbb_piconet *)calloc(1, sizeof(btbb_piconet)); + pn->refcount = 1; + return pn; +} + +void +btbb_piconet_ref(btbb_piconet *pn) +{ + pn->refcount++; +} + +void +btbb_piconet_unref(btbb_piconet *pn) +{ + pn->refcount--; + if (pn->refcount == 0) + free(pn); +} + +/* A bit of a hack? to set survey mode */ +static int survey_mode = 0; +int btbb_init_survey() { + survey_mode = 1; + return 0; +} + +void btbb_init_piconet(btbb_piconet *pn, uint32_t lap) +{ + pn->LAP = lap; + btbb_piconet_set_flag(pn, BTBB_LAP_VALID, 1); +} + +void btbb_piconet_set_flag(btbb_piconet *pn, int flag, int val) +{ + uint32_t mask = 1L << flag; + pn->flags &= ~mask; + if (val) + pn->flags |= mask; +} + +int btbb_piconet_get_flag(const btbb_piconet *pn, const int flag) +{ + uint32_t mask = 1L << flag; + return ((pn->flags & mask) != 0); +} + +void btbb_piconet_set_uap(btbb_piconet *pn, uint8_t uap) +{ + pn->UAP = uap; + btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); +} + +uint8_t btbb_piconet_get_uap(const btbb_piconet *pn) +{ + return pn->UAP; +} + +uint32_t btbb_piconet_get_lap(const btbb_piconet *pn) +{ + return pn->LAP; +} + +uint16_t btbb_piconet_get_nap(const btbb_piconet *pn) +{ + return pn->NAP; +} + +uint64_t btbb_piconet_get_bdaddr(const btbb_piconet *pn) +{ + return ((uint64_t) pn->NAP) << 32 | pn->UAP << 24 | pn->LAP; +} + +int btbb_piconet_get_clk_offset(const btbb_piconet *pn) +{ + return pn->clk_offset; +} + +void btbb_piconet_set_clk_offset(btbb_piconet *pn, int clk_offset) +{ + pn->clk_offset = clk_offset; +} + +void btbb_piconet_set_afh_map(btbb_piconet *pn, uint8_t *afh_map) { + int i; + pn->used_channels = 0; + // DGS: Unroll this? + for(i=0; i<10; i++) { + pn->afh_map[i] = afh_map[i]; + pn->used_channels += count_bits(pn->afh_map[i]); + } + if(btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) + get_hop_pattern(pn); +} + +uint8_t *btbb_piconet_get_afh_map(btbb_piconet *pn) { + return pn->afh_map; +} + +void btbb_piconet_set_channel_seen(btbb_piconet *pn, uint8_t channel) +{ + if(!(pn->afh_map[channel/8] & 0x1 << (channel % 8))) { + pn->afh_map[channel/8] |= 0x1 << (channel % 8); + pn->used_channels++; + if(btbb_piconet_get_flag(pn, BTBB_UAP_VALID) && !survey_mode) + get_hop_pattern(pn); + } +} + +uint8_t btbb_piconet_get_channel_seen(btbb_piconet *pn, uint8_t channel) +{ + if(channel < BT_NUM_CHANNELS) + return ( pn->afh_map[channel/8] & (1 << (channel % 8)) ) != 0; + else + return 1; +} + +/* do all the precalculation that can be done before knowing the address */ +void precalc(btbb_piconet *pn) +{ + int i = 0; + int j = 0; + int chan; + + /* populate frequency register bank*/ + for (i = 0; i < BT_NUM_CHANNELS; i++) { + + /* AFH is used, hopping sequence contains only used channels */ + if(btbb_piconet_get_flag(pn, BTBB_IS_AFH)) { + chan = (i * 2) % BT_NUM_CHANNELS; + if(btbb_piconet_get_channel_seen(pn, chan)) + pn->bank[j++] = chan; + } + + /* all channels are used */ + else { + pn->bank[i] = ((i * 2) % BT_NUM_CHANNELS); + } + } + /* actual frequency is 2402 + pn->bank[i] MHz */ + +} + +/* do precalculation that requires the address */ +void address_precalc(int address, btbb_piconet *pn) +{ + /* precalculate some of single_hop()/gen_hop()'s variables */ + pn->a1 = (address >> 23) & 0x1f; + pn->b = (address >> 19) & 0x0f; + pn->c1 = ((address >> 4) & 0x10) + + ((address >> 3) & 0x08) + + ((address >> 2) & 0x04) + + ((address >> 1) & 0x02) + + (address & 0x01); + pn->d1 = (address >> 10) & 0x1ff; + pn->e = ((address >> 7) & 0x40) + + ((address >> 6) & 0x20) + + ((address >> 5) & 0x10) + + ((address >> 4) & 0x08) + + ((address >> 3) & 0x04) + + ((address >> 2) & 0x02) + + ((address >> 1) & 0x01); +} + +#ifdef WC4 +/* These are optimization experiments, which don't help much for + * x86. Hold on to them to see whether they're useful on ARM. */ + +#ifdef NEVER +#define BUTTERFLY(z,p,c,a,b) \ + if ( ((p&(1<>a)^(z>>b)) & (p>>c)) & 0x1 ) \ + z ^= ((1<> i) & 0x01; + for (i = 0; i < 5; i++) + p[i+9] = (p_high >> i) & 0x01; + + /* bit swapping will be easier with an array of bits */ + for (i = 0; i < 5; i++) + z_bit[i] = (z >> i) & 0x01; + + /* butterfly operations */ + for (i = 13; i >= 0; i--) { + /* swap bits according to index arrays if control signal tells us to */ + if (p[i]) { + tmp = z_bit[index1[i]]; + z_bit[index1[i]] = z_bit[index2[i]]; + z_bit[index2[i]] = tmp; + } + } + + /* reconstruct output from rearranged bits */ + output = 0; + for (i = 0; i < 5; i++) + output += z_bit[i] << i; + + return(output); +} + +void perm_table_init(void) +{ + /* populate perm_table for all possible inputs */ + int z, p_high, p_low; + for (z = 0; z < 0x20; z++) + for (p_high = 0; p_high < 0x20; p_high++) + for (p_low = 0; p_low < 0x200; p_low++) + perm_table[z][p_high][p_low] = perm5(z, p_high, p_low); +} + +/* drop-in replacement for perm5() using lookup table */ +int fast_perm(int z, int p_high, int p_low) +{ + if (!perm_table_initialized) { + perm_table_init(); + perm_table_initialized = 1; + } + + return(perm_table[z][p_high][p_low]); +} + +/* generate the complete hopping sequence */ +static void gen_hops(btbb_piconet *pn) +{ + /* a, b, c, d, e, f, x, y1, y2 are variable names used in section 2.6 of the spec */ + /* b is already defined */ + /* e is already defined */ + int a, c, d, x; + uint32_t base_f, f, f_dash; + int h, i, j, k, c_flipped, perm_in, perm_out; + + /* sequence index = clock >> 1 */ + /* (hops only happen at every other clock value) */ + int index = 0; + base_f = 0; + f = 0; + f_dash = 0; + + /* nested loops for optimization (not recalculating every variable with every clock tick) */ + for (h = 0; h < 0x04; h++) { /* clock bits 26-27 */ + for (i = 0; i < 0x20; i++) { /* clock bits 21-25 */ + a = pn->a1 ^ i; + for (j = 0; j < 0x20; j++) { /* clock bits 16-20 */ + c = pn->c1 ^ j; + c_flipped = c ^ 0x1f; + for (k = 0; k < 0x200; k++) { /* clock bits 7-15 */ + d = pn->d1 ^ k; + for (x = 0; x < 0x20; x++) { /* clock bits 2-6 */ + perm_in = ((x + a) % 32) ^ pn->b; + + /* y1 (clock bit 1) = 0, y2 = 0 */ + perm_out = fast_perm(perm_in, c, d); + if (btbb_piconet_get_flag(pn, BTBB_IS_AFH)) + pn->sequence[index] = pn->bank[(perm_out + pn->e + f_dash) % pn->used_channels]; + else + pn->sequence[index] = pn->bank[(perm_out + pn->e + f) % BT_NUM_CHANNELS]; + + /* y1 (clock bit 1) = 1, y2 = 32 */ + perm_out = fast_perm(perm_in, c_flipped, d); + if (btbb_piconet_get_flag(pn, BTBB_IS_AFH)) + pn->sequence[index + 1] = pn->bank[(perm_out + pn->e + f_dash + 32) % pn->used_channels]; + else + pn->sequence[index + 1] = pn->bank[(perm_out + pn->e + f + 32) % BT_NUM_CHANNELS]; + + index += 2; + } + base_f += 16; + f = base_f % BT_NUM_CHANNELS; + f_dash = f % pn->used_channels; + } + } + } + } +} + +/* Function to calculate piconet hopping patterns and add to hash map */ +void gen_hop_pattern(btbb_piconet *pn) +{ + printf("\nCalculating complete hopping sequence.\n"); + /* this holds the entire hopping sequence */ + pn->sequence = (char*) malloc(SEQUENCE_LENGTH); + + precalc(pn); + address_precalc(((pn->UAP<<24) | pn->LAP) & 0xfffffff, pn); + gen_hops(pn); + + printf("Hopping sequence calculated.\n"); +} + +/* Container for hopping pattern */ +typedef struct { + uint64_t key; /* afh flag + address */ + char *sequence; + UT_hash_handle hh; +} hopping_struct; + +static hopping_struct *hopping_map = NULL; + +/* Function to fetch piconet hopping patterns */ +void get_hop_pattern(btbb_piconet *pn) +{ + hopping_struct *s; + uint64_t key; + + /* Two stages to avoid "left shift count >= width of type" warning */ + key = btbb_piconet_get_flag(pn, BTBB_IS_AFH); + key = (key<<39) | ((uint64_t)pn->used_channels<<32) | (pn->UAP<<24) | pn->LAP; + HASH_FIND(hh, hopping_map, &key, 4, s); + + if (s == NULL) { + gen_hop_pattern(pn); + s = malloc(sizeof(hopping_struct)); + s->key = key; + s->sequence = pn->sequence; + HASH_ADD(hh, hopping_map, key, 4, s); + } else { + printf("\nFound hopping sequence in cache.\n"); + pn->sequence = s->sequence; + } +} + +/* determine channel for a particular hop */ +/* borrowed from ubertooth firmware to support AFH */ +char single_hop(int clock, btbb_piconet *pn) +{ + int a, c, d, x, y1, y2, perm, next_channel; + uint32_t base_f, f, f_dash; + + /* following variable names used in section 2.6 of the spec */ + x = (clock >> 2) & 0x1f; + y1 = (clock >> 1) & 0x01; + y2 = y1 << 5; + a = (pn->a1 ^ (clock >> 21)) & 0x1f; + /* b is already defined */ + c = (pn->c1 ^ (clock >> 16)) & 0x1f; + d = (pn->d1 ^ (clock >> 7)) & 0x1ff; + /* e is already defined */ + base_f = (clock >> 3) & 0x1fffff0; + f = base_f % BT_NUM_CHANNELS; + + perm = fast_perm( + ((x + a) % 32) ^ pn->b, + (y1 * 0x1f) ^ c, + d); + /* hop selection */ + if(btbb_piconet_get_flag(pn, BTBB_IS_AFH)) { + f_dash = base_f % pn->used_channels; + next_channel = pn->bank[(perm + pn->e + f_dash + y2) % pn->used_channels]; + } else { + next_channel = pn->bank[(perm + pn->e + f + y2) % BT_NUM_CHANNELS]; + } + return next_channel; +} + +/* look up channel for a particular hop */ +char hop(int clock, btbb_piconet *pn) +{ + return pn->sequence[clock]; +} + +static char aliased_channel(char channel) +{ + return ((channel + 24) % ALIASED_CHANNELS) + 26; +} + +/* create list of initial candidate clock values (hops with same channel as first observed hop) */ +static int init_candidates(char channel, int known_clock_bits, btbb_piconet *pn) +{ + int i; + int count = 0; /* total number of candidates */ + char observable_channel; /* accounts for aliasing if necessary */ + + /* only try clock values that match our known bits */ + for (i = known_clock_bits; i < SEQUENCE_LENGTH; i += 0x40) { + if (pn->aliased) + observable_channel = aliased_channel(pn->sequence[i]); + else + observable_channel = pn->sequence[i]; + if (observable_channel == channel) + pn->clock_candidates[count++] = i; + //FIXME ought to throw exception if count gets too big + } + return count; +} + +/* initialize the hop reversal process */ +int btbb_init_hop_reversal(int aliased, btbb_piconet *pn) +{ + int max_candidates; + uint32_t clock; + + get_hop_pattern(pn); + + if(aliased) + max_candidates = (SEQUENCE_LENGTH / ALIASED_CHANNELS) / 32; + else + max_candidates = (SEQUENCE_LENGTH / BT_NUM_CHANNELS) / 32; + /* this can hold twice the approximate number of initial candidates */ + pn->clock_candidates = (uint32_t*) malloc(sizeof(uint32_t) * max_candidates); + + clock = (pn->clk_offset + pn->first_pkt_time) & 0x3f; + pn->num_candidates = init_candidates(pn->pattern_channels[0], clock, pn); + pn->winnowed = 0; + btbb_piconet_set_flag(pn, BTBB_HOP_REVERSAL_INIT, 1); + btbb_piconet_set_flag(pn, BTBB_CLK27_VALID, 0); + btbb_piconet_set_flag(pn, BTBB_IS_ALIASED, aliased); + + printf("%d initial CLK1-27 candidates\n", pn->num_candidates); + + return pn->num_candidates; +} + +void try_hop(btbb_packet *pkt, btbb_piconet *pn) +{ + uint8_t filter_uap = pn->UAP; + + /* Decode packet - fixing clock drift in the process */ + btbb_decode(pkt, pn); + + if (btbb_piconet_get_flag(pn, BTBB_HOP_REVERSAL_INIT)) { + //pn->winnowed = 0; + pn->pattern_indices[pn->packets_observed] = + pkt->clkn - pn->first_pkt_time; + pn->pattern_channels[pn->packets_observed] = pkt->channel; + pn->packets_observed++; + pn->total_packets_observed++; + btbb_winnow(pn); + if (btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { + printf("got CLK1-27\n"); + printf("clock offset = %d.\n", pn->clk_offset); + } + } else { + if (btbb_piconet_get_flag(pn, BTBB_CLK6_VALID)) { + btbb_uap_from_header(pkt, pn); + if (btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { + printf("got CLK1-27\n"); + printf("clock offset = %d.\n", pn->clk_offset); + } + } else { + if (btbb_uap_from_header(pkt, pn)) { + if (filter_uap == pn->UAP) { + btbb_init_hop_reversal(0, pn); + btbb_winnow(pn); + } else { + printf("failed to confirm UAP\n"); + } + } + } + } + + if(!btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) { + btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); + pn->UAP = filter_uap; + } +} + +/* return the observable channel (26-50) for a given channel (0-78) */ +/* reset UAP/clock discovery */ +static void reset(btbb_piconet *pn) +{ + //printf("no candidates remaining! starting over . . .\n"); + + if(btbb_piconet_get_flag(pn, BTBB_HOP_REVERSAL_INIT)) { + free(pn->clock_candidates); + pn->sequence = NULL; + } + btbb_piconet_set_flag(pn, BTBB_GOT_FIRST_PACKET, 0); + btbb_piconet_set_flag(pn, BTBB_HOP_REVERSAL_INIT, 0); + btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 0); + btbb_piconet_set_flag(pn, BTBB_CLK6_VALID, 0); + btbb_piconet_set_flag(pn, BTBB_CLK27_VALID, 0); + pn->packets_observed = 0; + + /* + * If we have recently observed two packets in a row on the same + * channel, try AFH next time. If not, don't. + */ + btbb_piconet_set_flag(pn, BTBB_IS_AFH, + btbb_piconet_get_flag(pn, BTBB_LOOKS_LIKE_AFH)); + // btbb_piconet_set_flag(pn, BTBB_LOOKS_LIKE_AFH, 0); + //int i; + //for(i=0; i<10; i++) + // pn->afh_map[i] = 0; +} + +/* narrow a list of candidate clock values based on a single observed hop */ +static int channel_winnow(int offset, char channel, btbb_piconet *pn) +{ + int i; + int new_count = 0; /* number of candidates after winnowing */ + char observable_channel; /* accounts for aliasing if necessary */ + + /* check every candidate */ + for (i = 0; i < pn->num_candidates; i++) { + if (pn->aliased) + observable_channel = aliased_channel(pn->sequence[(pn->clock_candidates[i] + offset) % SEQUENCE_LENGTH]); + else + observable_channel = pn->sequence[(pn->clock_candidates[i] + offset) % SEQUENCE_LENGTH]; + if (observable_channel == channel) { + /* this candidate matches the latest hop */ + /* blow away old list of candidates with new one */ + /* safe because new_count can never be greater than i */ + pn->clock_candidates[new_count++] = pn->clock_candidates[i]; + } + } + pn->num_candidates = new_count; + + if (new_count == 1) { + // Calculate clock offset for CLKN, not CLK1-27 + pn->clk_offset = ((pn->clock_candidates[0]<<1) - (pn->first_pkt_time<<1)); + printf("\nAcquired CLK1-27 = 0x%07x\n", pn->clock_candidates[0]); + btbb_piconet_set_flag(pn, BTBB_CLK27_VALID, 1); + } + else if (new_count == 0) { + reset(pn); + } + //else { + //printf("%d CLK1-27 candidates remaining (channel=%d)\n", new_count, channel); + //} + + return new_count; +} + +/* narrow a list of candidate clock values based on all observed hops */ +int btbb_winnow(btbb_piconet *pn) +{ + int new_count = pn->num_candidates; + int index, last_index; + uint8_t channel, last_channel; + + for (; pn->winnowed < pn->packets_observed; pn->winnowed++) { + index = pn->pattern_indices[pn->winnowed]; + channel = pn->pattern_channels[pn->winnowed]; + new_count = channel_winnow(index, channel, pn); + if (new_count <= 1) + break; + + if (pn->packets_observed > 0) { + last_index = pn->pattern_indices[pn->winnowed - 1]; + last_channel = pn->pattern_channels[pn->winnowed - 1]; + /* + * Two packets in a row on the same channel should only + * happen if adaptive frequency hopping is in use. + * There can be false positives, though, especially if + * there is aliasing. + */ + if (!btbb_piconet_get_flag(pn, BTBB_LOOKS_LIKE_AFH) + && (index == last_index + 1) + && (channel == last_channel)) { + btbb_piconet_set_flag(pn, BTBB_LOOKS_LIKE_AFH, 1); + printf("Hopping pattern appears to be AFH\n"); + } + } + } + + return new_count; +} + +/* use packet headers to determine UAP */ +int btbb_uap_from_header(btbb_packet *pkt, btbb_piconet *pn) +{ + uint8_t UAP; + int count, crc_chk, first_clock = 0; + + int starting = 0; + int remaining = 0; + uint32_t clkn = pkt->clkn; + + if (!btbb_piconet_get_flag(pn, BTBB_GOT_FIRST_PACKET)) + pn->first_pkt_time = clkn; + + // Set afh channel map + btbb_piconet_set_channel_seen(pn, pkt->channel); + + if (pn->packets_observed < MAX_PATTERN_LENGTH) { + pn->pattern_indices[pn->packets_observed] = clkn - pn->first_pkt_time; + pn->pattern_channels[pn->packets_observed] = pkt->channel; + } else { + printf("Oops. More hops than we can remember.\n"); + reset(pn); + return 0; //FIXME ought to throw exception + } + pn->packets_observed++; + pn->total_packets_observed++; + + /* try every possible first packet clock value */ + for (count = 0; count < 64; count++) { + /* skip eliminated candidates unless this is our first time through */ + if (pn->clock6_candidates[count] > -1 + || !btbb_piconet_get_flag(pn, BTBB_GOT_FIRST_PACKET)) { + /* clock value for the current packet assuming count was the clock of the first packet */ + int clock = (count + clkn - pn->first_pkt_time) % 64; + starting++; + UAP = try_clock(clock, pkt); + crc_chk = -1; + + /* if this is the first packet: populate the candidate list */ + /* if not: check CRCs if UAPs match */ + if (!btbb_piconet_get_flag(pn, BTBB_GOT_FIRST_PACKET) + || UAP == pn->clock6_candidates[count]) + crc_chk = crc_check(clock, pkt); + + if (btbb_piconet_get_flag(pn, BTBB_UAP_VALID) && + (UAP != pn->UAP)) + crc_chk = -1; + + switch(crc_chk) { + case -1: /* UAP mismatch */ + case 0: /* CRC failure */ + pn->clock6_candidates[count] = -1; + break; + + case 1: /* inconclusive result */ + case 2: /* Inconclusive, but looks better */ + pn->clock6_candidates[count] = UAP; + /* remember this count because it may be the correct clock of the first packet */ + first_clock = count; + remaining++; + break; + + default: /* CRC success */ + pn->clk_offset = (count - (pn->first_pkt_time & 0x3f)) & 0x3f; + if (!btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) + printf("Correct CRC! UAP = 0x%x found after %d total packets.\n", + UAP, pn->total_packets_observed); + else + printf("Correct CRC! CLK6 = 0x%x found after %d total packets.\n", + pn->clk_offset, pn->total_packets_observed); + pn->UAP = UAP; + btbb_piconet_set_flag(pn, BTBB_CLK6_VALID, 1); + btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); + pn->total_packets_observed = 0; + return 1; + } + } + } + + btbb_piconet_set_flag(pn, BTBB_GOT_FIRST_PACKET, 1); + + //printf("reduced from %d to %d CLK1-6 candidates\n", starting, remaining); + + if (remaining == 1) { + pn->clk_offset = (first_clock - (pn->first_pkt_time & 0x3f)) & 0x3f; + if (!btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) + printf("UAP = 0x%x found after %d total packets.\n", + pn->clock6_candidates[first_clock], pn->total_packets_observed); + else + printf("CLK6 = 0x%x found after %d total packets.\n", + pn->clk_offset, pn->total_packets_observed); + pn->UAP = pn->clock6_candidates[first_clock]; + btbb_piconet_set_flag(pn, BTBB_CLK6_VALID, 1); + btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); + pn->total_packets_observed = 0; + return 1; + } + + if (remaining == 0) { + reset(pn); + } + + return 0; +} + +/* FIXME: comment out enqueue and dequeue because they are + * never used. Try to find out what tey were meant to be + * used for before the next release. + */ +///* add a packet to the queue */ +//static void enqueue(btbb_packet *pkt, btbb_piconet *pn) +//{ +// pkt_queue *head; +// //pkt_queue item; +// +// btbb_packet_ref(pkt); +// pkt_queue item = {pkt, NULL}; +// head = pn->queue; +// +// if (head == NULL) { +// pn->queue = &item; +// } else { +// for(; head->next != NULL; head = head->next) +// ; +// head->next = &item; +// } +//} +// +///* pull the first packet from the queue (FIFO) */ +//static btbb_packet *dequeue(btbb_piconet *pn) +//{ +// btbb_packet *pkt; +// +// if (pn->queue == NULL) { +// pkt = NULL; +// } else { +// pkt = pn->queue->pkt; +// pn->queue = pn->queue->next; +// btbb_packet_unref(pkt); +// } +// +// return pkt; +//} + +/* decode the whole packet */ +int btbb_decode(btbb_packet* pkt, btbb_piconet *pn) +{ + btbb_packet_set_flag(pkt, BTBB_HAS_PAYLOAD, 0); + uint8_t clk6, i, best_clk; + int rv = 0, max_rv = 0; + if (btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { + /* Removing this section until we can more reliably handle AFH */ + //if(pn->sequence == NULL) + // get_hop_pattern(pn); + //clk6 = pkt->clock & 0x3f; + //for(i=0; i<64; i++) { + // pkt->clock = (pkt->clock & 0xffffffc0) | ((clk6 + i) & 0x3f); + // if ((pn->sequence[pkt->clock] == pkt->channel) && (btbb_decode_header(pkt))) { + // rv = btbb_decode_payload(pkt); + // if(rv > max_rv) { + // max_rv = rv; + // best_clk = (clk6 + i) & 0x3f; + // } + // } + //} + + // If we found nothing, try again, ignoring channel + if(max_rv <= 1) { + clk6 = pkt->clock & 0x3f; + for(i=0; i<64; i++) { + pkt->clock = (pkt->clock & 0xffffffc0) | ((clk6 + i) & 0x3f); + if (btbb_decode_header(pkt)) { + rv = btbb_decode_payload(pkt); + if(rv > max_rv) { + //printf("Packet decoded with clock 0x%07x (rv=%d)\n", pkt->clock, rv); + //btbb_print_packet(pkt); + max_rv = rv; + best_clk = (clk6 + i) & 0x3f; + } + } + } + } + } else + if (btbb_decode_header(pkt)) { + for(i=0; i<64; i++) { + pkt->clock = (pkt->clock & 0xffffffc0) | (i & 0x3f); + if (btbb_decode_header(pkt)) { + rv = btbb_decode_payload(pkt); + if(rv > max_rv) { + //printf("Packet decoded with clock 0x%02x (rv=%d)\n", i, rv); + //btbb_print_packet(pkt); + max_rv = rv; + best_clk = i & 0x3f; + } + } + } + } + /* If we were successful, print the packet */ + if(max_rv > 0) { + pkt->clock = (pkt->clock & 0xffffffc0) | (best_clk & 0x3f); + btbb_decode_payload(pkt); + printf("Packet decoded with clock 0x%02x (rv=%d)\n", i, rv); + btbb_print_packet(pkt); + } + + return max_rv; +} + +/* Print AFH map from observed packets */ +void btbb_print_afh_map(btbb_piconet *pn) { + uint8_t *afh_map; + afh_map = pn->afh_map; + + /* Print like hcitool does */ + printf("AFH map: 0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + afh_map[0], afh_map[1], afh_map[2], afh_map[3], afh_map[4], + afh_map[5], afh_map[6], afh_map[7], afh_map[8], afh_map[9]); + + // /* Printed ch78 -> ch0 */ + // printf("\tAFH Map=0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + // afh_map[9], afh_map[8], afh_map[7], afh_map[6], afh_map[5], + // afh_map[4], afh_map[3], afh_map[2], afh_map[1], afh_map[0]); +} + +/* Container for survey piconets */ +typedef struct { + uint32_t key; /* LAP */ + btbb_piconet *pn; + UT_hash_handle hh; +} survey_hash; + +static survey_hash *piconet_survey = NULL; + +/* Check for existing piconets in survey results */ +btbb_piconet *get_piconet(uint32_t lap) +{ + survey_hash *s; + btbb_piconet *pn; + HASH_FIND(hh, piconet_survey, &lap, 4, s); + + if (s == NULL) { + pn = btbb_piconet_new(); + btbb_init_piconet(pn, lap); + + s = malloc(sizeof(survey_hash)); + s->key = lap; + s->pn = pn; + HASH_ADD(hh, piconet_survey, key, 4, s); + } else { + pn = s->pn; + } + return pn; +} + +/* Destructively iterate over survey results */ +btbb_piconet *btbb_next_survey_result() { + btbb_piconet *pn = NULL; + survey_hash *tmp; + + if (piconet_survey != NULL) { + pn = piconet_survey->pn; + tmp = piconet_survey; + piconet_survey = piconet_survey->hh.next; + free(tmp); + } + return pn; +} + +int btbb_process_packet(btbb_packet *pkt, btbb_piconet *pn) { + if (survey_mode) { + pn = get_piconet(btbb_packet_get_lap(pkt)); + btbb_piconet_set_channel_seen(pn, pkt->channel); + if(btbb_header_present(pkt) && !btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) + btbb_uap_from_header(pkt, pn); + return 0; + } + + if(pn) + btbb_piconet_set_channel_seen(pn, pkt->channel); + + /* If piconet structure is given, a LAP is given, and packet + * header is readable, do further analysis. If UAP has not yet + * been determined, attempt to calculate it from headers. Once + * UAP is known, try to determine clk6 and clk27. Once clocks + * are known, follow the piconet. */ + if (pn && btbb_piconet_get_flag(pn, BTBB_LAP_VALID) && + btbb_header_present(pkt)) { + + /* Have LAP/UAP/clocks, now hopping along with the piconet. */ + if (btbb_piconet_get_flag(pn, BTBB_FOLLOWING)) { + btbb_packet_set_uap(pkt, btbb_piconet_get_uap(pn)); + btbb_packet_set_flag(pkt, BTBB_CLK6_VALID, 1); + btbb_packet_set_flag(pkt, BTBB_CLK27_VALID, 1); + + if(btbb_decode(pkt, pn)) + btbb_print_packet(pkt); + else + printf("Failed to decode packet\n"); + } + + /* Have LAP/UAP, need clocks. */ + else if (btbb_piconet_get_uap(pn)) { + try_hop(pkt, pn); + if (btbb_piconet_get_flag(pn, BTBB_CLK6_VALID) && + btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { + btbb_piconet_set_flag(pn, BTBB_FOLLOWING, 1); + return -1; + } + } + + /* Have LAP, need UAP. */ + else { + btbb_uap_from_header(pkt, pn); + } + } + return 0; +} diff --git a/libbtbb-2015-10-R1/lib/src/bluetooth_piconet.h b/libbtbb-2015-10-R1/lib/src/bluetooth_piconet.h new file mode 100644 index 0000000..3652a33 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/bluetooth_piconet.h @@ -0,0 +1,131 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2013 Dominic Spill, Michael Ossmann, Will Code + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_BLUETOOTH_PICONET_H +#define INCLUDED_BLUETOOTH_PICONET_H +#include "btbb.h" + +/* maximum number of hops to remember */ +#define MAX_PATTERN_LENGTH 1000 + +/* number of channels in use */ +#define BT_NUM_CHANNELS 79 + +struct btbb_piconet { + + uint32_t refcount; + + uint32_t flags; + + /* true if using a particular aliased receiver implementation */ + int aliased; + + /* AFH channel map - either read or derived from observed packets */ + uint8_t afh_map[10]; + + /* Number of used channel derived from AFH channel map */ + uint8_t used_channels; + + /* lower address part (of master's BD_ADDR) */ + uint32_t LAP; + + /* upper address part (of master's BD_ADDR) */ + uint8_t UAP; + + /* non-significant address part (of master's BD_ADDR) */ + uint16_t NAP; + + /* CLK1-27 candidates */ + uint32_t *clock_candidates; + + /* these values for hop() can be precalculated */ + int b, e; + + /* these values for hop() can be precalculated in part (e.g. a1 is the + * precalculated part of a) */ + int a1, c1, d1; + + /* frequency register bank */ + int bank[BT_NUM_CHANNELS]; + + /* this holds the entire hopping sequence */ + char *sequence; + + /* number of candidates for CLK1-27 */ + int num_candidates; + + /* number of packets observed during one attempt at UAP/clock discovery */ + int packets_observed; + + /* total number of packets observed */ + int total_packets_observed; + + /* number of observed packets that have been used to winnow the candidates */ + int winnowed; + + /* CLK1-6 candidates */ + int clock6_candidates[64]; + + /* remember patterns of observed hops */ + int pattern_indices[MAX_PATTERN_LENGTH]; + uint8_t pattern_channels[MAX_PATTERN_LENGTH]; + + /* offset between CLKN (local) and CLK of piconet */ + int clk_offset; + + /* local clock (clkn) at time of first packet */ + uint32_t first_pkt_time; + + /* queue of packets to be decoded */ + pkt_queue *queue; +}; + +/* number of hops in the hopping sequence (i.e. number of possible values of CLK1-27) */ +#define SEQUENCE_LENGTH 134217728 + +/* number of aliased channels received */ +#define ALIASED_CHANNELS 25 + +/* do all the precalculation that can be done before knowing the address */ +void precalc(btbb_piconet *pnet); + +/* do precalculation that requires the address */ +void address_precalc(int address, btbb_piconet *pnet); + +/* drop-in replacement for perm5() using lookup table */ +int fast_perm(int z, int p_high, int p_low); + +/* 5 bit permutation */ +/* assumes z is constrained to 5 bits, p_high to 5 bits, p_low to 9 bits */ +int perm5(int z, int p_high, int p_low); + +/* determine channel for a particular hop */ +/* replaced with gen_hops() for a complete sequence but could still come in handy */ +char single_hop(int clock, btbb_piconet *pnet); + +/* look up channel for a particular hop */ +char hop(int clock, btbb_piconet *pnet); + +void try_hop(btbb_packet *pkt, btbb_piconet *pn); + +void get_hop_pattern(btbb_piconet *pn); + +#endif /* INCLUDED_BLUETOOTH_PICONET_H */ diff --git a/libbtbb-2015-10-R1/lib/src/btbb.h b/libbtbb-2015-10-R1/lib/src/btbb.h new file mode 100644 index 0000000..154775c --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/btbb.h @@ -0,0 +1,288 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2013 Dominic Spill, Michael Ossmann, Will Code + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_BTBB_H +#define INCLUDED_BTBB_H + +#include + +#define BTBB_WHITENED 0 +#define BTBB_NAP_VALID 1 +#define BTBB_UAP_VALID 2 +#define BTBB_LAP_VALID 3 +#define BTBB_CLK6_VALID 4 +#define BTBB_CLK27_VALID 5 +#define BTBB_CRC_CORRECT 6 +#define BTBB_HAS_PAYLOAD 7 +#define BTBB_IS_EDR 8 + +#define BTBB_HOP_REVERSAL_INIT 9 +#define BTBB_GOT_FIRST_PACKET 10 +#define BTBB_IS_AFH 11 +#define BTBB_LOOKS_LIKE_AFH 12 +#define BTBB_IS_ALIASED 13 +#define BTBB_FOLLOWING 14 + +/* Payload modulation */ +#define BTBB_MOD_UNKNOWN 0x00 +#define BTBB_MOD_GFSK 0x01 +#define BTBB_MOD_PI_OVER_2_DQPSK 0x02 +#define BTBB_MOD_8DPSK 0x03 + +/* Transport types */ +#define BTBB_TRANSPORT_ANY 0x00 +#define BTBB_TRANSPORT_SCO 0x01 +#define BTBB_TRANSPORT_ESCO 0x02 +#define BTBB_TRANSPORT_ACL 0x03 +#define BTBB_TRANSPORT_CSB 0x04 + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* BT BR/EDR support */ + +typedef struct btbb_packet btbb_packet; + +/* Initialize the library. Compute the syndrome. Return 0 on success, + * negative on error. + * + * The library limits max_ac_errors to 5. Using a larger value will + * take up a lot of memory (several GB), without decoding many useful + * packets. Even a limit of 5 results in a syndrome table of several + * hundred MB and lots of noise. For embedded targets, a value of 2 is + * reasonable. */ +int btbb_init(int max_ac_errors); + +char *btbb_get_release(void); +char *btbb_get_version(void); + +btbb_packet *btbb_packet_new(void); +void btbb_packet_ref(btbb_packet *pkt); +void btbb_packet_unref(btbb_packet *pkt); + +/* Search for a packet with specified LAP (or LAP_ANY). The stream + * must be at least of length serch_length + 72. Limit to + * 'max_ac_errors' bit errors. + * + * Returns offset into 'stream' at which packet was found. If no + * packet was found, returns a negative number. If LAP_ANY was + * specified, fills lap. 'ac_errors' must be set as an input, replaced + * by actual number of errors on output. */ +int btbb_find_ac(char *stream, + int search_length, + uint32_t lap, + int max_ac_errors, + btbb_packet **pkt); +#define LAP_ANY 0xffffffffUL +#define UAP_ANY 0xff + +void btbb_packet_set_flag(btbb_packet *pkt, int flag, int val); +int btbb_packet_get_flag(const btbb_packet *pkt, int flag); + +uint32_t btbb_packet_get_lap(const btbb_packet *pkt); +void btbb_packet_set_uap(btbb_packet *pkt, uint8_t uap); +uint8_t btbb_packet_get_uap(const btbb_packet *pkt); +uint16_t btbb_packet_get_nap(const btbb_packet *pkt); + +void btbb_packet_set_modulation(btbb_packet *pkt, uint8_t modulation); +void btbb_packet_set_transport(btbb_packet *pkt, uint8_t transport); +uint8_t btbb_packet_get_modulation(const btbb_packet *pkt); +uint8_t btbb_packet_get_transport(const btbb_packet *pkt); + +uint8_t btbb_packet_get_channel(const btbb_packet *pkt); +uint8_t btbb_packet_get_ac_errors(const btbb_packet *pkt); +uint32_t btbb_packet_get_clkn(const btbb_packet *pkt); +uint32_t btbb_packet_get_header_packed(const btbb_packet* pkt); + +void btbb_packet_set_data(btbb_packet *pkt, + char *syms, // Symbol data + int length, // Number of symbols + uint8_t channel, // Bluetooth channel 0-79 + uint32_t clkn); // 312.5us clock (CLK27-0) + +/* Get a pointer to packet symbols. */ +const char *btbb_get_symbols(const btbb_packet* pkt); + +int btbb_packet_get_payload_length(const btbb_packet* pkt); + +/* Get a pointer to payload. */ +const char *btbb_get_payload(const btbb_packet* pkt); + +/* Pack the payload in to bytes */ +int btbb_get_payload_packed(const btbb_packet* pkt, char *dst); + +uint8_t btbb_packet_get_type(const btbb_packet* pkt); +uint8_t btbb_packet_get_lt_addr(const btbb_packet* pkt); +uint8_t btbb_packet_get_header_flags(const btbb_packet* pkt); +uint8_t btbb_packet_get_hec(const btbb_packet *pkt); + +/* Generate Sync Word from an LAP */ +uint64_t btbb_gen_syncword(const int LAP); + +/* decode the packet header */ +int btbb_decode_header(btbb_packet* pkt); + +/* decode the packet header */ +int btbb_decode_payload(btbb_packet* pkt); + +/* print packet information */ +void btbb_print_packet(const btbb_packet* pkt); + +/* check to see if the packet has a header */ +int btbb_header_present(const btbb_packet* pkt); + +/* Packet queue (linked list) */ +typedef struct pkt_queue { + btbb_packet *pkt; + + struct pkt_queue *next; + +} pkt_queue; + +typedef struct btbb_piconet btbb_piconet; + +btbb_piconet *btbb_piconet_new(void); +void btbb_piconet_ref(btbb_piconet *pn); +void btbb_piconet_unref(btbb_piconet *pn); + +/* initialize the piconet struct */ +void btbb_init_piconet(btbb_piconet *pn, uint32_t lap); + +void btbb_piconet_set_uap(btbb_piconet *pn, uint8_t uap); +uint8_t btbb_piconet_get_uap(const btbb_piconet *pn); +uint32_t btbb_piconet_get_lap(const btbb_piconet *pn); +uint16_t btbb_piconet_get_nap(const btbb_piconet *pn); +uint64_t btbb_piconet_get_bdaddr(const btbb_piconet *pn); + +int btbb_piconet_get_clk_offset(const btbb_piconet *pn); +void btbb_piconet_set_clk_offset(btbb_piconet *pn, int clk_offset); + +void btbb_piconet_set_flag(btbb_piconet *pn, int flag, int val); +int btbb_piconet_get_flag(const btbb_piconet *pn, int flag); + +void btbb_piconet_set_channel_seen(btbb_piconet *pn, uint8_t channel); +void btbb_piconet_set_afh_map(btbb_piconet *pn, uint8_t *afh_map); +uint8_t *btbb_piconet_get_afh_map(btbb_piconet *pn); + +/* Extract as much information (LAP/UAP/CLK) as possible from received packet */ +int btbb_process_packet(btbb_packet *pkt, btbb_piconet *pn); + +/* use packet headers to determine UAP */ +int btbb_uap_from_header(btbb_packet *pkt, btbb_piconet *pn); + +/* Print hexadecimal representation of the derived AFH map */ +void btbb_print_afh_map(btbb_piconet *pn); + +/* decode a whole packet from the given piconet */ +int btbb_decode(btbb_packet* pkt, btbb_piconet *pn); + + +/* initialize the hop reversal process */ +/* returns number of initial candidates for CLK1-27 */ +int btbb_init_hop_reversal(int aliased, btbb_piconet *pn); + +/* narrow a list of candidate clock values based on all observed hops */ +int btbb_winnow(btbb_piconet *pn); + +int btbb_init_survey(void); +/* Destructively iterate over survey results - optionally remove elements */ +btbb_piconet *btbb_next_survey_result(void); + +typedef struct btbb_pcapng_handle btbb_pcapng_handle; +/* create a PCAPNG file for BREDR captures */ +int btbb_pcapng_create_file(const char *filename, const char *interface_desc, btbb_pcapng_handle ** ph); +/* save a BREDR packet to PCAPNG capture file */ +int btbb_pcapng_append_packet(btbb_pcapng_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t reflap, const uint8_t refuap, + const btbb_packet *pkt); +/* record a BDADDR to PCAPNG capture file */ +int btbb_pcapng_record_bdaddr(btbb_pcapng_handle * h, const uint64_t bdaddr, + const uint8_t uapmask, const uint8_t napvalid); +/* record BT CLOCK to PCAPNG capture file */ +int btbb_pcapng_record_btclock(btbb_pcapng_handle * h, const uint64_t bdaddr, + const uint64_t ns, const uint32_t clk, const uint32_t clkmask); +int btbb_pcapng_close(btbb_pcapng_handle * h); + + +/* BLE support */ +typedef struct lell_packet lell_packet; +/* decode and allocate LE packet */ +void lell_allocate_and_decode(const uint8_t *stream, uint16_t phys_channel, uint32_t clk100ns, lell_packet **pkt); +lell_packet *lell_packet_new(void); +void lell_packet_ref(lell_packet *pkt); +void lell_packet_unref(lell_packet *pkt); +uint32_t lell_get_access_address(const lell_packet *pkt); +unsigned lell_get_access_address_offenses(const lell_packet *pkt); +unsigned lell_packet_is_data(const lell_packet *pkt); +unsigned lell_get_channel_index(const lell_packet *pkt); +unsigned lell_get_channel_k(const lell_packet *pkt); +const char * lell_get_adv_type_str(const lell_packet *pkt); +void lell_print(const lell_packet *pkt); + +typedef struct lell_pcapng_handle lell_pcapng_handle; +/* create a PCAPNG file for LE captures */ +int lell_pcapng_create_file(const char *filename, const char *interface_desc, lell_pcapng_handle ** ph); +/* save an LE packet to PCAPNG capture file */ +int lell_pcapng_append_packet(lell_pcapng_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t refAA, const lell_packet *pkt); +/* record LE CONNECT_REQ parameters to PCAPNG capture file */ +int lell_pcapng_record_connect_req(lell_pcapng_handle * h, const uint64_t ns, const uint8_t * pdu); +int lell_pcapng_close(lell_pcapng_handle *h); + + +/* PCAP Support */ +#if defined(ENABLE_PCAP) +typedef struct btbb_pcap_handle btbb_pcap_handle; +/* create a PCAP file for BREDR captures with LINKTYPE_BLUETOOTH_BREDR_BB */ +int btbb_pcap_create_file(const char *filename, btbb_pcap_handle ** ph); +/* write a BREDR packet to PCAP file */ +int btbb_pcap_append_packet(btbb_pcap_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t reflap, const uint8_t refuap, + const btbb_packet *pkt); +int btbb_pcap_close(btbb_pcap_handle * h); + +typedef struct lell_pcap_handle lell_pcap_handle; +/* create a PCAP file for LE captures using LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR */ +int lell_pcap_create_file(const char *filename, lell_pcap_handle ** ph); +/* create a PCAP file for LE captures using LINKTYPE_PPI */ +int lell_pcap_ppi_create_file(const char *filename, int btle_ppi_version, lell_pcap_handle ** ph); +/* save an LE packet to PCAP capture file */ +int lell_pcap_append_packet(lell_pcap_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t refAA, const lell_packet *pkt); +int lell_pcap_append_ppi_packet(lell_pcap_handle * h, const uint64_t ns, + const uint8_t clkn_high, + const int8_t rssi_min, const int8_t rssi_max, + const int8_t rssi_avg, const uint8_t rssi_count, + const lell_packet *pkt); +int lell_pcap_close(lell_pcap_handle *h); +#endif // ENABLE_PCAP + +#ifdef __cplusplus +} // __cplusplus defined. +#endif + +#endif /* INCLUDED_BTBB_H */ diff --git a/libbtbb-2015-10-R1/lib/src/pcap-common.h b/libbtbb-2015-10-R1/lib/src/pcap-common.h new file mode 100644 index 0000000..29856f6 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/pcap-common.h @@ -0,0 +1,129 @@ +/* -*- c -*- */ +/* + * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef PCAP_COMMON_DOT_H +#define PCAP_COMMON_DOT_H + +/* pull definitions for BT DLTs and pseudoheaders from libpcap, if possible */ +#if defined(ENABLE_PCAP) +#include +#include +#endif /* ENABLE_PCAP */ + +#if defined( __APPLE__ ) +#include +#define htobe32 EndianU32_NtoB +#define be32toh EndianU32_BtoN +#define le32toh EndianU32_LtoN +#define htobe64 EndianU64_NtoB +#define be64toh EndianU64_BtoN +#define htole16 EndianU16_NtoL +#define htole32 EndianU32_NtoL +#else +#include +#endif + +#if !defined( htole16 ) /* will be defined under Linux when endian.h already included */ +#if defined( __GNUC__ ) +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +inline uint16_t htole16(uint16_t host_16bits) { return host_16bits; } +inline uint16_t le16toh(uint16_t little_endian_16bits) { return little_endian_16bits; } +inline uint32_t htole32(uint32_t host_32bits) { return host_32bits; } +inline uint32_t le32toh(uint32_t little_endian_32bits) { return little_endian_32bits; } +inline uint64_t htole64(uint64_t host_64bits) { return host_64bits; } +inline uint64_t le64toh(uint64_t little_endian_64bits) { return little_endian_64bits; } +#else +#error "FIXME: need to support big-endian under GNU" +#endif /* __BYTE_ORDER__ */ +#else /* not GNU C */ +#error "FIXME: need to support non-GNU compiler" +#endif /* __GNUC__ */ +#endif /* htole16 */ + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) + +/* --------------------------------- BR/EDR ----------------------------- */ + +#if !defined( DLT_BLUETOOTH_BREDR_BB ) +#define DLT_BLUETOOTH_BREDR_BB 255 +#endif +typedef struct __attribute__((packed)) _pcap_bluetooth_bredr_bb_header { + uint8_t rf_channel; + int8_t signal_power; + int8_t noise_power; + uint8_t access_code_offenses; + uint8_t payload_transport_rate; + uint8_t corrected_header_bits; + int16_t corrected_payload_bits; + uint32_t lap; + uint32_t ref_lap_uap; + uint32_t bt_header; + uint16_t flags; + uint8_t br_edr_payload[0]; +} pcap_bluetooth_bredr_bb_header; + +#define BREDR_DEWHITENED 0x0001 +#define BREDR_SIGPOWER_VALID 0x0002 +#define BREDR_NOISEPOWER_VALID 0x0004 +#define BREDR_PAYLOAD_DECRYPTED 0x0008 +#define BREDR_REFLAP_VALID 0x0010 +#define BREDR_PAYLOAD_PRESENT 0x0020 +#define BREDR_CHANNEL_ALIASED 0x0040 +#define BREDR_REFUAP_VALID 0x0080 +#define BREDR_HEC_CHECKED 0x0100 +#define BREDR_HEC_VALID 0x0200 +#define BREDR_CRC_CHECKED 0x0400 +#define BREDR_CRC_VALID 0x0800 +#define BREDR_MIC_CHECKED 0x1000 +#define BREDR_MIC_VALID 0x2000 + +#define BREDR_MAX_PAYLOAD 400 + +/* --------------------------------- Low Energy ---------------------------- */ + +#if !defined( DLT_BLUETOOTH_LE_LL_WITH_PHDR ) +#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 +#endif +typedef struct __attribute__((packed)) _pcap_bluetooth_le_ll_header { + uint8_t rf_channel; + int8_t signal_power; + int8_t noise_power; + uint8_t access_address_offenses; + uint32_t ref_access_address; + uint16_t flags; + uint8_t le_packet[0]; +} pcap_bluetooth_le_ll_header; + +#define LE_DEWHITENED 0x0001 +#define LE_SIGPOWER_VALID 0x0002 +#define LE_NOISEPOWER_VALID 0x0004 +#define LE_PACKET_DECRYPTED 0x0008 +#define LE_REF_AA_VALID 0x0010 +#define LE_AA_OFFENSES_VALID 0x0020 +#define LE_CHANNEL_ALIASED 0x0040 +#define LE_CRC_CHECKED 0x0400 +#define LE_CRC_VALID 0x0800 +#define LE_MIC_CHECKED 0x1000 +#define LE_MIC_VALID 0x2000 + +#define LE_MAX_PAYLOAD 48 + +#endif /* PCAP_COMMON_DOT_H */ diff --git a/libbtbb-2015-10-R1/lib/src/pcap.c b/libbtbb-2015-10-R1/lib/src/pcap.c new file mode 100644 index 0000000..77da261 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/pcap.c @@ -0,0 +1,422 @@ +/* -*- c -*- */ +/* + * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#include "bluetooth_le_packet.h" +#include "bluetooth_packet.h" +#include "btbb.h" +#include "pcap-common.h" + +#include +#include + +typedef enum { + PCAP_OK = 0, + PCAP_INVALID_HANDLE, + PCAP_FILE_NOT_ALLOWED, + PCAP_NO_MEMORY, +} PCAP_RESULT; + +#if defined(ENABLE_PCAP) + +/* BT BR/EDR support */ + +struct btbb_pcap_handle { + pcap_t * pcap; + pcap_dumper_t * dumper; +}; + +int +btbb_pcap_create_file(const char *filename, btbb_pcap_handle ** ph) +{ + int retval = 0; + btbb_pcap_handle * handle = malloc( sizeof(btbb_pcap_handle) ); + if (handle) { + memset(handle, 0, sizeof(*handle)); +#ifdef PCAP_TSTAMP_PRECISION_NANO + handle->pcap = pcap_open_dead_with_tstamp_precision(DLT_BLUETOOTH_BREDR_BB, + BREDR_MAX_PAYLOAD, + PCAP_TSTAMP_PRECISION_NANO); +#else + handle->pcap = pcap_open_dead(DLT_BLUETOOTH_BREDR_BB, BREDR_MAX_PAYLOAD); +#endif + if (handle->pcap) { + handle->dumper = pcap_dump_open(handle->pcap, filename); + if (handle->dumper) { + *ph = handle; + } + else { + pcap_perror(handle->pcap, "PCAP error:"); + retval = -PCAP_FILE_NOT_ALLOWED; + goto fail; + } + } + else { + retval = -PCAP_INVALID_HANDLE; + goto fail; + } + } + else { + retval = -PCAP_NO_MEMORY; + goto fail; + } + return retval; +fail: + (void) btbb_pcap_close( handle ); + return retval; +} + +typedef struct { + struct pcap_pkthdr pcap_header; + pcap_bluetooth_bredr_bb_header bredr_bb_header; + uint8_t bredr_payload[BREDR_MAX_PAYLOAD]; +} pcap_bredr_packet; + +static void +assemble_pcapng_bredr_packet( pcap_bredr_packet * pkt, + const uint32_t interface_id __attribute__((unused)), + const uint64_t ns, + const uint32_t caplen, + const uint8_t rf_channel, + const int8_t signal_power, + const int8_t noise_power, + const uint8_t access_code_offenses, + const uint8_t payload_transport, + const uint8_t payload_rate, + const uint8_t corrected_header_bits, + const int16_t corrected_payload_bits, + const uint32_t lap, + const uint32_t ref_lap, + const uint8_t ref_uap, + const uint32_t bt_header, + const uint16_t flags, + const uint8_t * payload ) +{ + uint32_t pcap_caplen = sizeof(pcap_bluetooth_bredr_bb_header)+caplen; + uint32_t reflapuap = (ref_lap&0xffffff) | (ref_uap<<24); + + pkt->pcap_header.ts.tv_sec = ns / 1000000000ull; + pkt->pcap_header.ts.tv_usec = ns % 1000000000ull; + pkt->pcap_header.caplen = pcap_caplen; + pkt->pcap_header.len = pcap_caplen; + + pkt->bredr_bb_header.rf_channel = rf_channel; + pkt->bredr_bb_header.signal_power = signal_power; + pkt->bredr_bb_header.noise_power = noise_power; + pkt->bredr_bb_header.access_code_offenses = access_code_offenses; + pkt->bredr_bb_header.payload_transport_rate = + (payload_transport << 4) | payload_rate; + pkt->bredr_bb_header.corrected_header_bits = corrected_header_bits; + pkt->bredr_bb_header.corrected_payload_bits = htole16( corrected_payload_bits ); + pkt->bredr_bb_header.lap = htole32( lap ); + pkt->bredr_bb_header.ref_lap_uap = htole32( reflapuap ); + pkt->bredr_bb_header.bt_header = htole16( bt_header ); + pkt->bredr_bb_header.flags = htole16( flags ); + if (caplen) { + (void) memcpy( &pkt->bredr_payload[0], payload, caplen ); + } + else { + pkt->bredr_bb_header.flags &= htole16( ~BREDR_PAYLOAD_PRESENT ); + } +} + +int +btbb_pcap_append_packet(btbb_pcap_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t reflap, const uint8_t refuap, + const btbb_packet *pkt) +{ + if (h && h->dumper) { + uint16_t flags = BREDR_DEWHITENED | BREDR_SIGPOWER_VALID | + ((noisedbm < sigdbm) ? BREDR_NOISEPOWER_VALID : 0) | + ((reflap != LAP_ANY) ? BREDR_REFLAP_VALID : 0) | + ((refuap != UAP_ANY) ? BREDR_REFUAP_VALID : 0); + uint32_t caplen = (uint32_t) btbb_packet_get_payload_length(pkt); + uint8_t payload_bytes[caplen]; + btbb_get_payload_packed( pkt, (char *) &payload_bytes[0] ); + caplen = MIN(BREDR_MAX_PAYLOAD, caplen); + pcap_bredr_packet pcap_pkt; + assemble_pcapng_bredr_packet( &pcap_pkt, + 0, + ns, + caplen, + btbb_packet_get_channel(pkt), + sigdbm, + noisedbm, + btbb_packet_get_ac_errors(pkt), + btbb_packet_get_transport(pkt), + btbb_packet_get_modulation(pkt), + 0, /* TODO: corrected header bits */ + 0, /* TODO: corrected payload bits */ + btbb_packet_get_lap(pkt), + reflap, + refuap, + btbb_packet_get_header_packed(pkt), + flags, + payload_bytes ); + pcap_dump((u_char *)h->dumper, &pcap_pkt.pcap_header, (u_char *)&pcap_pkt.bredr_bb_header); + return 0; + } + return -PCAP_INVALID_HANDLE; +} + +int +btbb_pcap_close(btbb_pcap_handle * h) +{ + if (h && h->dumper) { + pcap_dump_close(h->dumper); + } + if (h && h->pcap) { + pcap_close(h->pcap); + } + if (h) { + free(h); + return 0; + } + return -PCAP_INVALID_HANDLE; +} + +/* BTLE support */ + +struct lell_pcap_handle { + pcap_t * pcap; + pcap_dumper_t * dumper; + int dlt; + uint8_t btle_ppi_version; +}; + +static int +lell_pcap_create_file_dlt(const char *filename, int dlt, lell_pcap_handle ** ph) +{ + int retval = 0; + lell_pcap_handle * handle = malloc( sizeof(lell_pcap_handle) ); + if (handle) { + memset(handle, 0, sizeof(*handle)); +#ifdef PCAP_TSTAMP_PRECISION_NANO + handle->pcap = pcap_open_dead_with_tstamp_precision(dlt, + BREDR_MAX_PAYLOAD, + PCAP_TSTAMP_PRECISION_NANO); +#else + handle->pcap = pcap_open_dead(dlt, BREDR_MAX_PAYLOAD); +#endif + if (handle->pcap) { + handle->dumper = pcap_dump_open(handle->pcap, filename); + if (handle->dumper) { + handle->dlt = dlt; + *ph = handle; + } + else { + retval = -PCAP_FILE_NOT_ALLOWED; + goto fail; + } + } + else { + retval = -PCAP_INVALID_HANDLE; + goto fail; + } + } + else { + retval = -PCAP_NO_MEMORY; + goto fail; + } + return retval; +fail: + (void) lell_pcap_close( handle ); + return retval; +} + +int +lell_pcap_create_file(const char *filename, lell_pcap_handle ** ph) +{ + return lell_pcap_create_file_dlt(filename, DLT_BLUETOOTH_LE_LL_WITH_PHDR, ph); +} + +int +lell_pcap_ppi_create_file(const char *filename, int btle_ppi_version, + lell_pcap_handle ** ph) +{ + int retval = lell_pcap_create_file_dlt(filename, DLT_PPI, ph); + if (!retval) { + (*ph)->btle_ppi_version = btle_ppi_version; + } + return retval; +} + +typedef struct { + struct pcap_pkthdr pcap_header; + pcap_bluetooth_le_ll_header le_ll_header; + uint8_t le_packet[LE_MAX_PAYLOAD]; +} pcap_le_packet; + +static void +assemble_pcapng_le_packet( pcap_le_packet * pkt, + const uint32_t interface_id __attribute__((unused)), + const uint64_t ns, + const uint32_t caplen, + const uint8_t rf_channel, + const int8_t signal_power, + const int8_t noise_power, + const uint8_t access_address_offenses, + const uint32_t ref_access_address, + const uint16_t flags, + const uint8_t * lepkt ) +{ + uint32_t pcap_caplen = sizeof(pcap_bluetooth_le_ll_header)+caplen; + + pkt->pcap_header.ts.tv_sec = ns / 1000000000ull; + pkt->pcap_header.ts.tv_usec = ns % 1000000000ull; + pkt->pcap_header.caplen = pcap_caplen; + pkt->pcap_header.len = pcap_caplen; + + pkt->le_ll_header.rf_channel = rf_channel; + pkt->le_ll_header.signal_power = signal_power; + pkt->le_ll_header.noise_power = noise_power; + pkt->le_ll_header.access_address_offenses = access_address_offenses; + pkt->le_ll_header.ref_access_address = htole32( ref_access_address ); + pkt->le_ll_header.flags = htole16( flags ); + (void) memcpy( &pkt->le_packet[0], lepkt, caplen ); +} + +int +lell_pcap_append_packet(lell_pcap_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t refAA, const lell_packet *pkt) +{ + if (h && h->dumper && + (h->dlt == DLT_BLUETOOTH_LE_LL_WITH_PHDR)) { + uint16_t flags = LE_DEWHITENED | LE_AA_OFFENSES_VALID | + LE_SIGPOWER_VALID | + ((noisedbm < sigdbm) ? LE_NOISEPOWER_VALID : 0) | + (lell_packet_is_data(pkt) ? 0 : LE_REF_AA_VALID); + pcap_le_packet pcap_pkt; + assemble_pcapng_le_packet( &pcap_pkt, + 0, + ns, + 9+pkt->length, + pkt->channel_k, + sigdbm, + noisedbm, + pkt->access_address_offenses, + refAA, + flags, + &pkt->symbols[0] ); + pcap_dump((u_char *)h->dumper, &pcap_pkt.pcap_header, (u_char *)&pcap_pkt.le_ll_header); + return 0; + } + return -PCAP_INVALID_HANDLE; +} + +#define PPI_BTLE 30006 + +typedef struct __attribute__((packed)) { + uint8_t pph_version; + uint8_t pph_flags; + uint16_t pph_len; + uint32_t pph_dlt; +} ppi_packet_header_t; + +typedef struct __attribute__((packed)) { + uint16_t pfh_type; + uint16_t pfh_datalen; +} ppi_fieldheader_t; + +typedef struct __attribute__((packed)) { + uint8_t btle_version; + uint16_t btle_channel; + uint8_t btle_clkn_high; + uint32_t btle_clk100ns; + int8_t rssi_max; + int8_t rssi_min; + int8_t rssi_avg; + uint8_t rssi_count; +} ppi_btle_t; + +typedef struct __attribute__((packed)) { + struct pcap_pkthdr pcap_header; + ppi_packet_header_t ppi_packet_header; + ppi_fieldheader_t ppi_fieldheader; + ppi_btle_t le_ll_ppi_header; + uint8_t le_packet[LE_MAX_PAYLOAD]; +} pcap_ppi_le_packet; + +int +lell_pcap_append_ppi_packet(lell_pcap_handle * h, const uint64_t ns, + const uint8_t clkn_high, + const int8_t rssi_min, const int8_t rssi_max, + const int8_t rssi_avg, const uint8_t rssi_count, + const lell_packet *pkt) +{ + const uint16_t ppi_packet_header_sz = sizeof(ppi_packet_header_t); + const uint16_t ppi_fieldheader_sz = sizeof(ppi_fieldheader_t); + const uint16_t le_ll_ppi_header_sz = sizeof(ppi_btle_t); + + if (h && h->dumper && + (h->dlt == DLT_PPI)) { + pcap_ppi_le_packet pcap_pkt; + uint32_t pcap_caplen = + ppi_packet_header_sz+ppi_fieldheader_sz+le_ll_ppi_header_sz+pkt->length+9; + uint16_t MHz = 2402 + 2*lell_get_channel_k(pkt); + + pcap_pkt.pcap_header.ts.tv_sec = ns / 1000000000ull; + pcap_pkt.pcap_header.ts.tv_usec = ns % 1000000000ull; + pcap_pkt.pcap_header.caplen = pcap_caplen; + pcap_pkt.pcap_header.len = pcap_caplen; + + pcap_pkt.ppi_packet_header.pph_version = 0; + pcap_pkt.ppi_packet_header.pph_flags = 0; + pcap_pkt.ppi_packet_header.pph_len = htole16(ppi_packet_header_sz+ppi_fieldheader_sz+le_ll_ppi_header_sz); + pcap_pkt.ppi_packet_header.pph_dlt = htole32(DLT_USER0); + + pcap_pkt.ppi_fieldheader.pfh_type = htole16(PPI_BTLE); + pcap_pkt.ppi_fieldheader.pfh_datalen = htole16(le_ll_ppi_header_sz); + + pcap_pkt.le_ll_ppi_header.btle_version = h->btle_ppi_version; + pcap_pkt.le_ll_ppi_header.btle_channel = htole16(MHz); + pcap_pkt.le_ll_ppi_header.btle_clkn_high = clkn_high; + pcap_pkt.le_ll_ppi_header.btle_clk100ns = htole32(pkt->clk100ns); + pcap_pkt.le_ll_ppi_header.rssi_max = rssi_max; + pcap_pkt.le_ll_ppi_header.rssi_min = rssi_min; + pcap_pkt.le_ll_ppi_header.rssi_avg = rssi_avg; + pcap_pkt.le_ll_ppi_header.rssi_count = rssi_count; + (void) memcpy( &pcap_pkt.le_packet[0], &pkt->symbols[0], pkt->length + 9 ); // FIXME where does the 9 come from? + pcap_dump((u_char *)h->dumper, &pcap_pkt.pcap_header, (u_char *)&pcap_pkt.ppi_packet_header); + pcap_dump_flush(h->dumper); + return 0; + } + return -PCAP_INVALID_HANDLE; +} + +int +lell_pcap_close(lell_pcap_handle *h) +{ + if (h && h->dumper) { + pcap_dump_close(h->dumper); + } + if (h && h->pcap) { + pcap_close(h->pcap); + } + if (h) { + free(h); + return 0; + } + return -PCAP_INVALID_HANDLE; +} + +#endif /* ENABLE_PCAP */ diff --git a/libbtbb-2015-10-R1/lib/src/pcapng-bt.c b/libbtbb-2015-10-R1/lib/src/pcapng-bt.c new file mode 100644 index 0000000..b969a6a --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/pcapng-bt.c @@ -0,0 +1,522 @@ +/* -*- c -*- */ +/* + * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "btbb.h" +#include "bluetooth_le_packet.h" +#include "bluetooth_packet.h" +#include "pcapng-bt.h" +#include +#include +#include +#include +#include +#include + +/* generic section options indicating libbtbb */ +const struct { + struct { + option_header hdr; + char libname[8]; + } libopt; + struct { + option_header hdr; + } termopt; +} libbtbb_section_options = { + .libopt = { + .hdr = { + .option_code = SHB_USERAPPL, + .option_length = 7 }, + .libname = "libbtbb" + }, + .termopt = { + .hdr = { + .option_code = OPT_ENDOFOPT, + .option_length = 0 + } + } +}; + +static PCAPNG_RESULT +check_and_fix_tsresol( PCAPNG_HANDLE * handle, + const option_header * interface_options ) +{ + PCAPNG_RESULT retval = PCAPNG_OK; + int got_tsresol = 0; + + while( !got_tsresol && + interface_options && + interface_options->option_code && + interface_options->option_length) { + if (interface_options->option_code == IF_TSRESOL) { + got_tsresol = 1; + } + else { + size_t step = 4+4*((interface_options->option_length+3)/4); + uint8_t * next = &((uint8_t *)interface_options)[step]; + interface_options = (const option_header *) next; + } + } + + if (!got_tsresol) { + const struct { + option_header hdr; + uint8_t resol; + } tsresol = { + .hdr = { + .option_code = IF_TSRESOL, + .option_length = 1, + }, + .resol = 9 /* 10^-9 is nanoseconds */ + }; + + retval = pcapng_append_interface_option( handle, + (const option_header *) &tsresol ); + } + + return retval; +} + +/* --------------------------------- BR/EDR ----------------------------- */ + +static PCAPNG_RESULT +create_bredr_capture_file_single_interface( PCAPNG_HANDLE * handle, + const char * filename, + const option_header * interface_options ) +{ + PCAPNG_RESULT retval = PCAPNG_OK; + + retval = pcapng_create( handle, + filename, + (const option_header *) &libbtbb_section_options, + (size_t) getpagesize( ), + DLT_BLUETOOTH_BREDR_BB, + BREDR_MAX_PAYLOAD, + interface_options, + (size_t) getpagesize( ) ); + + if (retval == PCAPNG_OK) { + /* if there is no timestamp resolution alread in the + interface options, record nanosecond resolution */ + retval = check_and_fix_tsresol( handle, interface_options ); + + if (retval != PCAPNG_OK) { + (void) pcapng_close( handle ); + } + } + + return retval; +} + +int btbb_pcapng_create_file( const char *filename, + const char *interface_desc, + btbb_pcapng_handle ** ph ) +{ + int retval = PCAPNG_OK; + PCAPNG_HANDLE * handle = malloc( sizeof(PCAPNG_HANDLE) ); + if (handle) { + const option_header * popt = NULL; + struct { + option_header header; + char desc[256]; + } ifopt = { + .header = { + .option_code = IF_DESCRIPTION, + } + }; + if (interface_desc) { + (void) strncpy( &ifopt.desc[0], interface_desc, 256 ); + ifopt.desc[255] = '\0'; + ifopt.header.option_length = strlen( ifopt.desc ); + popt = (const option_header *) &ifopt; + } + + retval = -create_bredr_capture_file_single_interface( handle, + filename, + popt ); + if (retval == PCAPNG_OK) { + *ph = (btbb_pcapng_handle *) handle; + } + else { + free( handle ); + } + } + else { + retval = -PCAPNG_NO_MEMORY; + } + return retval; +} + +static PCAPNG_RESULT +append_bredr_packet( PCAPNG_HANDLE * handle, + pcapng_bredr_packet * pkt ) +{ + return pcapng_append_packet( handle, ( const enhanced_packet_block *) pkt ); +} + +static void +assemble_pcapng_bredr_packet( pcapng_bredr_packet * pkt, + const uint32_t interface_id, + const uint64_t ns, + const uint32_t caplen, + const uint8_t rf_channel, + const int8_t signal_power, + const int8_t noise_power, + const uint8_t access_code_offenses, + const uint8_t payload_transport, + const uint8_t payload_rate, + const uint8_t corrected_header_bits, + const int16_t corrected_payload_bits, + const uint32_t lap, + const uint32_t ref_lap, + const uint8_t ref_uap, + const uint32_t bt_header, + const uint16_t flags, + const char * payload ) +{ + uint32_t pcapng_caplen = sizeof(pcap_bluetooth_bredr_bb_header)+caplen; + uint32_t block_length = 4*((36+pcapng_caplen+3)/4); + uint32_t reflapuap = (ref_lap&0xffffff) | (ref_uap<<24); + + pkt->blk_header.block_type = BLOCK_TYPE_ENHANCED_PACKET; + pkt->blk_header.block_total_length = block_length; + pkt->blk_header.interface_id = interface_id; + pkt->blk_header.timestamp_high = (uint32_t) (ns >> 32); + pkt->blk_header.timestamp_low = (uint32_t) (ns & 0x0ffffffffull); + pkt->blk_header.captured_len = pcapng_caplen; + pkt->blk_header.packet_len = pcapng_caplen; + pkt->bredr_bb_header.rf_channel = rf_channel; + pkt->bredr_bb_header.signal_power = signal_power; + pkt->bredr_bb_header.noise_power = noise_power; + pkt->bredr_bb_header.access_code_offenses = access_code_offenses; + pkt->bredr_bb_header.payload_transport_rate = + (payload_transport << 4) | payload_rate; + pkt->bredr_bb_header.corrected_header_bits = corrected_header_bits; + pkt->bredr_bb_header.corrected_payload_bits = htole16( corrected_payload_bits ); + pkt->bredr_bb_header.lap = htole32( lap ); + pkt->bredr_bb_header.ref_lap_uap = htole32( reflapuap ); + pkt->bredr_bb_header.bt_header = htole16( bt_header ); + pkt->bredr_bb_header.flags = htole16( flags ); + if (caplen) { + (void) memcpy( &pkt->bredr_payload[0], payload, caplen ); + } + else { + pkt->bredr_bb_header.flags &= htole16( ~BREDR_PAYLOAD_PRESENT ); + } + ((uint32_t *)pkt)[block_length/4-2] = 0x00000000; /* no-options */ + ((uint32_t *)pkt)[block_length/4-1] = block_length; +} + +int btbb_pcapng_append_packet(btbb_pcapng_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t reflap, const uint8_t refuap, + const btbb_packet *pkt) +{ + uint16_t flags = BREDR_DEWHITENED | BREDR_SIGPOWER_VALID | + ((noisedbm < sigdbm) ? BREDR_NOISEPOWER_VALID : 0) | + ((reflap != LAP_ANY) ? BREDR_REFLAP_VALID : 0) | + ((refuap != UAP_ANY) ? BREDR_REFUAP_VALID : 0); + int caplen = btbb_packet_get_payload_length(pkt); + char payload_bytes[caplen]; + btbb_get_payload_packed( pkt, &payload_bytes[0] ); + caplen = MIN(BREDR_MAX_PAYLOAD, caplen); + pcapng_bredr_packet pcapng_pkt; + assemble_pcapng_bredr_packet( &pcapng_pkt, + 0, + ns, + caplen, + btbb_packet_get_channel(pkt), + sigdbm, + noisedbm, + btbb_packet_get_ac_errors(pkt), + btbb_packet_get_transport(pkt), + btbb_packet_get_modulation(pkt), + 0, /* TODO: corrected header bits */ + 0, /* TODO: corrected payload bits */ + btbb_packet_get_lap(pkt), + reflap, + refuap, + btbb_packet_get_header_packed(pkt), + flags, + payload_bytes ); + return -append_bredr_packet( (PCAPNG_HANDLE *)h, &pcapng_pkt ); +} + +static PCAPNG_RESULT +record_bd_addr_info( PCAPNG_HANDLE * handle, + const uint64_t bd_addr, + const uint8_t uap_mask, + const uint8_t nap_valid ) +{ + const bredr_br_addr_option bdopt = { + .header = { + .option_code = PCAPNG_BREDR_OPTION_BD_ADDR, + .option_length = sizeof(bredr_br_addr_option), + }, + .bd_addr_info = { + .bd_addr = { + ((bd_addr>>0) & 0xff), + ((bd_addr>>8) & 0xff), + ((bd_addr>>16) & 0xff), + ((bd_addr>>24) & 0xff), + ((bd_addr>>32) & 0xff), + ((bd_addr>>40) & 0xff) + }, + .uap_mask = uap_mask, + .nap_valid = nap_valid, + } + }; + return pcapng_append_interface_option( handle, + (const option_header *) &bdopt ); +} + +int btbb_pcapng_record_bdaddr(btbb_pcapng_handle * h, const uint64_t bdaddr, + const uint8_t uapmask, const uint8_t napvalid) +{ + return -record_bd_addr_info( (PCAPNG_HANDLE *) h, + bdaddr, uapmask, napvalid ); +} + +static PCAPNG_RESULT +record_bredr_master_clock_info( PCAPNG_HANDLE * handle, + const uint64_t bd_addr, + const uint64_t ns, + const uint32_t clk, + const uint32_t clk_mask) +{ + const bredr_clk_option mcopt = { + .header = { + .option_code = PCAPNG_BREDR_OPTION_MASTER_CLOCK_INFO, + .option_length = sizeof(bredr_clk_option) + }, + .clock_info = { + .ts = ns, + .lap_uap = htole32(bd_addr & 0xffffffff), + .clk = clk, + .clk_mask = clk_mask + } + }; + return pcapng_append_interface_option( handle, + (const option_header *) &mcopt ); +} + +int btbb_pcapng_record_btclock(btbb_pcapng_handle * h, const uint64_t bdaddr, + const uint64_t ns, const uint32_t clk, + const uint32_t clkmask) +{ + return -record_bredr_master_clock_info( (PCAPNG_HANDLE *) h, + bdaddr, ns, clk, clkmask ); +} + +int btbb_pcapng_close(btbb_pcapng_handle * h) +{ + pcapng_close( (PCAPNG_HANDLE *) h ); + if (h) { + free( h ); + } + return -PCAPNG_INVALID_HANDLE; +} + +/* --------------------------------- Low Energy ---------------------------- */ + +static PCAPNG_RESULT +create_le_capture_file_single_interface( PCAPNG_HANDLE * handle, + const char * filename, + const option_header * interface_options ) +{ + PCAPNG_RESULT retval = PCAPNG_OK; + + retval = pcapng_create( handle, + filename, + (const option_header *) &libbtbb_section_options, + (size_t) getpagesize( ), + DLT_BLUETOOTH_LE_LL_WITH_PHDR, + 64, + interface_options, + (size_t) getpagesize( ) ); + + if (retval == PCAPNG_OK) { + /* if there is no timestamp resolution alread in the + interface options, record nanosecond resolution */ + retval = check_and_fix_tsresol( handle, interface_options ); + + if (retval != PCAPNG_OK) { + (void) pcapng_close( handle ); + } + } + + return retval; +} + +int +lell_pcapng_create_file(const char *filename, const char *interface_desc, + lell_pcapng_handle ** ph) +{ + int retval = PCAPNG_OK; + PCAPNG_HANDLE * handle = malloc( sizeof(PCAPNG_HANDLE) ); + if (handle) { + const option_header * popt = NULL; + struct { + option_header header; + char desc[256]; + } ifopt = { + .header = { + .option_code = IF_DESCRIPTION, + } + }; + if (interface_desc) { + (void) strncpy( &ifopt.desc[0], interface_desc, 256 ); + ifopt.desc[255] = '\0'; + ifopt.header.option_length = strlen( ifopt.desc ); + popt = (const option_header *) &ifopt; + } + + retval = -create_le_capture_file_single_interface( handle, + filename, + popt ); + if (retval == PCAPNG_OK) { + *ph = (lell_pcapng_handle *) handle; + } + else { + free( handle ); + } + } + else { + retval = -PCAPNG_NO_MEMORY; + } + return retval; +} + +static PCAPNG_RESULT +append_le_packet( PCAPNG_HANDLE * handle, + pcapng_le_packet * pkt ) +{ + return pcapng_append_packet( handle, ( const enhanced_packet_block *) pkt ); +} + +/* Size of a PCAPNG enhanced packet block with no packet data. + NOTE: The pcap_bluetooth_le_ll_header is part of the packet data of + the enhanced block. */ +#define PCAPNG_ENHANCED_BLK_SZ 36 + +static void +assemble_pcapng_le_packet( pcapng_le_packet * pkt, + const uint32_t interface_id, + const uint64_t ns, + const uint32_t caplen, + const uint8_t rf_channel, + const int8_t signal_power, + const int8_t noise_power, + const uint8_t access_address_offenses, + const uint32_t ref_access_address, + const uint16_t flags, + const uint8_t * lepkt ) +{ + uint32_t pcapng_caplen = sizeof(pcap_bluetooth_le_ll_header)+caplen; + uint32_t block_length = 4*((PCAPNG_ENHANCED_BLK_SZ+pcapng_caplen+3)/4); + + assert(caplen <= LE_MAX_PAYLOAD); + + pkt->blk_header.block_type = BLOCK_TYPE_ENHANCED_PACKET; + pkt->blk_header.block_total_length = block_length; + pkt->blk_header.interface_id = interface_id; + pkt->blk_header.timestamp_high = (uint32_t) (ns >> 32); + pkt->blk_header.timestamp_low = (uint32_t) (ns & 0x0ffffffffull); + pkt->blk_header.captured_len = pcapng_caplen; + pkt->blk_header.packet_len = pcapng_caplen; + pkt->le_ll_header.rf_channel = rf_channel; + pkt->le_ll_header.signal_power = signal_power; + pkt->le_ll_header.noise_power = noise_power; + pkt->le_ll_header.access_address_offenses = access_address_offenses; + pkt->le_ll_header.ref_access_address = htole32( ref_access_address ); + pkt->le_ll_header.flags = htole16( flags ); + (void) memcpy( &pkt->le_packet[0], lepkt, caplen ); + ((uint32_t *)pkt)[block_length/4-2] = 0x00000000; /* no-options */ + ((uint32_t *)pkt)[block_length/4-1] = block_length; +} + +int +lell_pcapng_append_packet(lell_pcapng_handle * h, const uint64_t ns, + const int8_t sigdbm, const int8_t noisedbm, + const uint32_t refAA, const lell_packet *pkt) +{ + uint16_t flags = LE_DEWHITENED | LE_AA_OFFENSES_VALID | + LE_SIGPOWER_VALID | + ((noisedbm < sigdbm) ? LE_NOISEPOWER_VALID : 0) | + (lell_packet_is_data(pkt) ? 0 : LE_REF_AA_VALID); + pcapng_le_packet pcapng_pkt; + + /* The extra 9 bytes added to the packet length are for: + 4 bytes for Access Address + 2 bytes for PDU header + 3 bytes for CRC */ + assemble_pcapng_le_packet( &pcapng_pkt, + 0, + ns, + 9+pkt->length, + pkt->channel_k, + sigdbm, + noisedbm, + pkt->access_address_offenses, + refAA, + flags, + &pkt->symbols[0] ); + int retval = -append_le_packet( (PCAPNG_HANDLE *) h, &pcapng_pkt ); + if ((retval == 0) && !lell_packet_is_data(pkt) && (pkt->adv_type == CONNECT_REQ)) { + (void) lell_pcapng_record_connect_req(h, ns, &pkt->symbols[0]); + } + return retval; +} + +static PCAPNG_RESULT +record_le_connect_req_info( PCAPNG_HANDLE * handle, + const uint64_t ns, + const uint8_t * pdu ) +{ + le_ll_connection_info_option cropt = { + .header = { + .option_code = PCAPNG_LE_LL_CONNECTION_INFO, + .option_length = sizeof(le_ll_connection_info_option) + }, + .connection_info = { + .ns = ns + } + }; + (void) memcpy( &cropt.connection_info.pdu.bytes[0], pdu, 34 ); + return pcapng_append_interface_option( handle, + (const option_header *) &cropt ); +} + +int +lell_pcapng_record_connect_req(lell_pcapng_handle * h, const uint64_t ns, + const uint8_t * pdu) +{ + return -record_le_connect_req_info( (PCAPNG_HANDLE *) h, ns, pdu ); +} + +int lell_pcapng_close(lell_pcapng_handle *h) +{ + pcapng_close( (PCAPNG_HANDLE *) h ); + if (h) { + free( h ); + } + return -PCAPNG_INVALID_HANDLE; +} diff --git a/libbtbb-2015-10-R1/lib/src/pcapng-bt.h b/libbtbb-2015-10-R1/lib/src/pcapng-bt.h new file mode 100644 index 0000000..3d13758 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/pcapng-bt.h @@ -0,0 +1,120 @@ +/* -*- c -*- */ +/* + * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef PCAPNG_BT_DOT_H +#define PCAPNG_BT_DOT_H + +#include "pcap-common.h" +#include "pcapng.h" + +typedef struct __attribute__((packed)) { + uint32_t centre_freq; + uint32_t analog_bandwidth; + int32_t intermediate_freq; + uint32_t sampling_bandwidth; +} bt_wideband_rf_info; + +typedef struct __attribute__((packed)) { + option_header header; + bt_wideband_rf_info wideband_rf_info; +} bt_wideband_rf_option; + +#define PCAPNG_BT_WIDEBAND_RF_INFO 0xd300 + +/* --------------------------------- BR/EDR ----------------------------- */ + +typedef struct __attribute__((packed)) { + enhanced_packet_block blk_header; + pcap_bluetooth_bredr_bb_header bredr_bb_header; + uint8_t bredr_payload[BREDR_MAX_PAYLOAD]; +} pcapng_bredr_packet; + +typedef struct __attribute__((packed)) { + uint8_t bd_addr[6]; + uint8_t uap_mask; + uint8_t nap_valid; +} bredr_bd_addr_info; + +typedef struct __attribute__((packed)) { + option_header header; + bredr_bd_addr_info bd_addr_info; +} bredr_br_addr_option; + +typedef struct __attribute__((packed)) { + uint64_t ts; + uint32_t lap_uap; + uint32_t clk; + uint32_t clk_mask; +} bredr_clk_info; + +typedef struct __attribute__((packed)) { + option_header header; + bredr_clk_info clock_info; +} bredr_clk_option; + +#define PCAPNG_BREDR_OPTION_BD_ADDR 0xd340 +#define PCAPNG_BREDR_OPTION_MASTER_CLOCK_INFO 0xd341 + +/* --------------------------------- Low Energy ---------------------------- */ + +typedef struct __attribute__((packed)) { + enhanced_packet_block blk_header; + pcap_bluetooth_le_ll_header le_ll_header; + uint8_t le_packet[LE_MAX_PAYLOAD]; + + /* Force 32 bit alignment for options and blk_tot_length. */ + uint8_t pad[2]; + + /* Add space for OPTIONS and BLOCK_TOTAL_LENGTH at end of + block. These won't be at this position in the structure unless + the LE PDU is the full 39 bytes. */ + uint32_t options; + uint32_t blk_tot_length; +} pcapng_le_packet; + +typedef struct __attribute__((packed)) { + uint64_t ns; + union { + struct { + uint8_t InitA[6]; + uint8_t AdvA[6]; + uint8_t AA[4]; + uint8_t CRCInit[3]; + uint8_t WinSize; + uint8_t WinOffset[2]; + uint8_t Interval[2]; + uint8_t Latency[2]; + uint8_t Timeout[2]; + uint8_t ChM[5]; + uint8_t HopSCA; + } fields; + uint8_t bytes[0]; + } pdu; +} le_ll_connection_info; + +typedef struct __attribute__((packed)) { + option_header header; + le_ll_connection_info connection_info; +} le_ll_connection_info_option; + +#define PCAPNG_LE_LL_CONNECTION_INFO 0xd380 + +#endif /* PCAPNG_BT_DOT_H */ diff --git a/libbtbb-2015-10-R1/lib/src/pcapng.c b/libbtbb-2015-10-R1/lib/src/pcapng.c new file mode 100644 index 0000000..dbe61d8 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/pcapng.c @@ -0,0 +1,323 @@ +/* -*- c -*- */ +/* + * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "pcapng.h" + +#include +#include +#include +#include +#include +#include +#include + +static option_header padopt = { + .option_code = 0xffff, +}; + +PCAPNG_RESULT pcapng_create( PCAPNG_HANDLE * handle, + const char * filename, + const option_header * section_options, + const size_t section_options_space, + const uint16_t link_type, + const uint32_t snaplen, + const option_header * interface_options, + const size_t interface_options_space ) +{ + PCAPNG_RESULT retval = PCAPNG_OK; + int PGSZ = getpagesize( ); + size_t zeroes = 0; + ssize_t result = -1; + + handle->section_header = NULL; + handle->interface_description = NULL; + handle->section_header_size = handle->next_section_option_offset = + handle->interface_description_size = + handle->next_interface_option_offset = 0; + + handle->fd = open( filename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP ); + if (handle->fd == -1) { + switch( errno ) { + case EEXIST: + retval = PCAPNG_FILE_EXISTS; + break; + case EMFILE: + case ENFILE: + retval = PCAPNG_TOO_MANY_FILES_OPEN; + break; + case ENOMEM: + case ENOSPC: + retval = PCAPNG_NO_MEMORY; + break; + default: + retval = PCAPNG_FILE_NOT_ALLOWED; + } + } + + if (retval == PCAPNG_OK) { + /* section header */ + const section_header_block shb = { + .block_type = BLOCK_TYPE_SECTION_HEADER, + .block_total_length = 28, + .byte_order_magic = SECTION_HEADER_BYTE_ORDER_MAGIC, + .major_version = 1, + .minor_version = 0, + .section_length = (uint64_t) -1, + }; + handle->section_header_size = sizeof( shb ); + result = write( handle->fd, &shb, sizeof( shb ) ); + /* write initial section options */ + while ((result != -1) && + section_options && + section_options->option_code && + section_options->option_length) { + size_t paddedsz = 4*((section_options->option_length+3)/4); + zeroes = paddedsz - section_options->option_length; + result = write( handle->fd, section_options, 4+section_options->option_length ); + while ((zeroes > 0) && (result != -1)) { + result = write( handle->fd, "\0", 1 ); + zeroes--; + } + section_options = (const option_header *) &((uint8_t *)section_options)[4+paddedsz]; + handle->section_header_size += (4+paddedsz); + } + handle->next_section_option_offset = handle->section_header_size; + } + + if (result == -1) { + retval = PCAPNG_FILE_WRITE_ERROR; + } + else { + /* determine the size of section header with desired space */ + zeroes = (size_t) PGSZ*((handle->section_header_size + 4 + + section_options_space + PGSZ - 1)/PGSZ) - + handle->section_header_size; + handle->section_header_size += zeroes; + while ((zeroes > 0) && (result != -1)) { + result = write( handle->fd, "\0", 1 ); + zeroes--; + } + + /* mmap the section header */ + handle->section_header = mmap( NULL, handle->section_header_size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + handle->fd, 0 ); + } + + if (retval == PCAPNG_OK) { + if (result == -1) { + retval = PCAPNG_FILE_WRITE_ERROR; + } + else if (handle->section_header == MAP_FAILED) { + retval = PCAPNG_MMAP_FAILED; + } + else { + /* write the interface header */ + const interface_description_block idb = { + .block_type = BLOCK_TYPE_INTERFACE, + .block_total_length = 0, + .link_type = link_type, + .snaplen = snaplen + }; + handle->interface_description_size = sizeof( idb ); + result = write( handle->fd, &idb, sizeof( idb ) ); + + /* write interface options */ + while ((result != -1) && + interface_options && + interface_options->option_code && + interface_options->option_length) { + size_t paddedsz = 4*((interface_options->option_length+3)/4); + zeroes = paddedsz - interface_options->option_length; + result = write( handle->fd, interface_options, 4+interface_options->option_length ); + while ((zeroes > 0) && (result != -1)) { + result = write( handle->fd, "\0", 1 ); + zeroes--; + } + interface_options = (const option_header *) &((uint8_t *)interface_options)[4+paddedsz]; + handle->interface_description_size += (4+paddedsz); + } + handle->next_interface_option_offset = handle->interface_description_size; + } + } + + if (retval == PCAPNG_OK) { + if (result == -1) { + retval = PCAPNG_FILE_WRITE_ERROR; + } + else { + /* determine the size of interface description with desired space */ + zeroes = (size_t) PGSZ*((handle->interface_description_size + 4 + + interface_options_space + PGSZ - 1)/PGSZ) - + handle->interface_description_size; + handle->interface_description_size += zeroes; + while ((zeroes > 0) && (result != -1)) { + result = write( handle->fd, "\0", 1 ); + zeroes--; + } + + /* mmap the interface description */ + handle->interface_description = mmap( NULL, handle->interface_description_size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + handle->fd, + handle->section_header_size ); + } + } + + if (retval == PCAPNG_OK) { + if (result == -1) { + retval = PCAPNG_FILE_WRITE_ERROR; + } + else if (handle->interface_description == MAP_FAILED) { + retval = PCAPNG_MMAP_FAILED; + } + else { + uint8_t * dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset]; + padopt.option_length = handle->section_header_size - + handle->next_section_option_offset - 12; + + /* Add padding options, update the header sizes. */ + (void) memcpy( dest, &padopt, sizeof( padopt ) ); + handle->section_header->block_total_length = + (uint32_t) handle->section_header_size; + ((uint32_t*)handle->section_header)[handle->section_header_size/4-1] = + (uint32_t) handle->section_header_size; + + padopt.option_length = handle->interface_description_size - + handle->next_interface_option_offset - 12; + dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset]; + (void) memcpy( dest, &padopt, sizeof( padopt ) ); + handle->interface_description->block_total_length = + (uint32_t) handle->interface_description_size; + ((uint32_t*)handle->interface_description)[handle->interface_description_size/4-1] = + (uint32_t) handle->interface_description_size; + + handle->section_header->section_length = (uint64_t) handle->interface_description_size; + } + } + + if (retval != PCAPNG_OK) { + (void) pcapng_close( handle ); + } + + return retval; +} + +PCAPNG_RESULT pcapng_append_section_option( PCAPNG_HANDLE * handle, + const option_header * section_option ) +{ + PCAPNG_RESULT retval = PCAPNG_OK; + if (handle && (handle->fd != -1)) { + if (handle->section_header && + (handle->section_header != MAP_FAILED) && + handle->next_section_option_offset && + section_option) { + size_t copysz = 4+section_option->option_length; + uint8_t * dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset]; + (void) memcpy( dest, section_option, copysz ); + handle->next_section_option_offset += 4*((copysz+3)/4); + + /* update padding option */ + dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset]; + padopt.option_length = handle->section_header_size - + handle->next_section_option_offset - 12; + (void) memcpy( dest, &padopt, sizeof( padopt ) ); + } + else { + retval = PCAPNG_NO_MEMORY; + } + } + else { + retval = PCAPNG_INVALID_HANDLE; + } + return retval; +} + +PCAPNG_RESULT pcapng_append_interface_option( PCAPNG_HANDLE * handle, + const option_header * interface_option ) +{ + PCAPNG_RESULT retval = PCAPNG_OK; + if (handle && (handle->fd != -1)) { + if (handle->interface_description && + (handle->interface_description != MAP_FAILED) && + handle->next_interface_option_offset && + interface_option) { + size_t copysz = 4+interface_option->option_length; + uint8_t * dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset]; + (void) memcpy( dest, interface_option, copysz ); + handle->next_interface_option_offset += 4*((copysz+3)/4); + + /* update padding option */ + dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset]; + padopt.option_length = handle->interface_description_size - + handle->next_interface_option_offset - 12; + (void) memcpy( dest, &padopt, sizeof( padopt ) ); + } + else { + retval = PCAPNG_NO_MEMORY; + } + } + else { + retval = PCAPNG_INVALID_HANDLE; + } + return retval; +} + +PCAPNG_RESULT pcapng_append_packet( PCAPNG_HANDLE * handle, + const enhanced_packet_block * packet ) +{ + PCAPNG_RESULT retval = PCAPNG_OK; + if (handle && (handle->fd != -1)) { + size_t writesz = packet->block_total_length; + ssize_t result = write( handle->fd, packet, writesz ); + if (result == -1) { + result = PCAPNG_FILE_WRITE_ERROR; + } + else { + handle->section_header->section_length += writesz; + } + } + else { + retval = PCAPNG_INVALID_HANDLE; + } + return retval; +} + +PCAPNG_RESULT pcapng_close( PCAPNG_HANDLE * handle ) +{ + if (handle->interface_description && + (handle->interface_description != MAP_FAILED)) { + (void) munmap( handle->interface_description, + handle->interface_description_size ); + } + if (handle->section_header && + (handle->section_header != MAP_FAILED)) { + (void) munmap( handle->section_header, + handle->section_header_size ); + } + if (handle->fd != -1) { + (void) close( handle->fd ); + } + return PCAPNG_OK; +} diff --git a/libbtbb-2015-10-R1/lib/src/pcapng.h b/libbtbb-2015-10-R1/lib/src/pcapng.h new file mode 100644 index 0000000..da2caf4 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/pcapng.h @@ -0,0 +1,198 @@ +/* -*- c -*- */ +/* + * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef PCAPNG_DOT_H +#define PCAPNG_DOT_H + +#include +#include + +typedef struct __attribute__((packed)) { + uint16_t option_code; + uint16_t option_length; + uint32_t option_value[0]; +} option_header; + +#define OPT_ENDOFOPT 0 +#define OPT_COMMENT 1 + +typedef struct __attribute__((packed)) { + uint32_t block_type; + uint32_t block_total_length; + uint32_t byte_order_magic; + uint16_t major_version; + uint16_t minor_version; + uint64_t section_length; + option_header options[0]; +} section_header_block; + +#define SECTION_HEADER_BYTE_ORDER_MAGIC 0x1a2b3c4d + +#define SHB_HARDWARE 2 +#define SHB_OS 3 +#define SHB_USERAPPL 4 + +typedef struct __attribute__((packed)) { + uint32_t block_type; + uint32_t block_total_length; + uint16_t link_type; + uint16_t reserved; + uint32_t snaplen; + option_header options[0]; +} interface_description_block; + +#define IF_NAME 2 +#define IF_DESCRIPTION 3 +#define IF_IPV4ADDR 4 +#define IF_IPV6ADDR 5 +#define IF_MACADDR 6 +#define IF_EUIADDR 7 +#define IF_SPEED 8 +#define IF_TSRESOL 9 +#define IF_TZONE 10 +#define IF_FILTER 11 +#define IF_OS 12 +#define IF_FCSLEN 13 +#define IF_TSOFFSET 14 + +typedef struct __attribute__((packed)) { + uint32_t block_type; + uint32_t block_total_length; + uint32_t interface_id; + uint32_t timestamp_high; + uint32_t timestamp_low; + uint32_t captured_len; + uint32_t packet_len; + uint32_t packet_data[0]; +} enhanced_packet_block; + +#define EPB_FLAGS 2 +#define EPB_HASH 3 +#define EPB_DROPCOUNT 4 + +typedef struct __attribute__((packed)) { + uint32_t block_type; + uint32_t block_total_length; + uint32_t packet_len; + uint32_t packet_data[0]; +} simple_packet_block; + +typedef struct __attribute__((packed)) { + uint32_t block_type; + uint32_t block_total_length; + uint16_t record_type; + uint16_t record_length; + uint32_t record_value[0]; +} name_resolution_block; + +#define NRES_ENDOFRECORD 0 +#define NRES_IP4RECORD 1 +#define NRES_IP6RECORD 2 + +#define NS_DNSNAME 2 +#define NS_DNSIP4ADDR 3 +#define NS_DNSIP6ADDR 4 + +typedef struct __attribute__((packed)) { + uint32_t block_type; + uint32_t block_total_length; + uint32_t interface_id; + uint32_t timestamp_high; + uint32_t timestamp_low; + option_header options[0]; +} interface_statistics_block; + +#define ISB_STARTTIME 2 +#define ISB_ENDTIME 3 +#define ISB_IFRECV 4 +#define ISB_IFDROP 5 +#define ISB_FILTERACCEPT 6 +#define ISB_OSDROP 7 +#define ISB_USRDELIV 8 + +#define BLOCK_TYPE_INTERFACE 0x00000001 +#define BLOCK_TYPE_SIMPLE_PACKET 0x00000003 +#define BLOCK_TYPE_NAME_RESOLUTION 0x00000004 +#define BLOCK_TYPE_INTERFACE_STATISTICS 0x00000005 +#define BLOCK_TYPE_ENHANCED_PACKET 0x00000006 +#define BLOCK_TYPE_SECTION_HEADER 0x0a0d0d0a + +typedef struct { + int fd; + section_header_block * section_header; + size_t section_header_size; + size_t next_section_option_offset; + interface_description_block * interface_description; + size_t interface_description_size; + size_t next_interface_option_offset; +} PCAPNG_HANDLE; + +typedef enum { + PCAPNG_OK = 0, + PCAPNG_INVALID_HANDLE, + PCAPNG_FILE_NOT_ALLOWED, + PCAPNG_FILE_EXISTS, + PCAPNG_TOO_MANY_FILES_OPEN, + PCAPNG_NO_MEMORY, + PCAPNG_FILE_WRITE_ERROR, + PCAPNG_MMAP_FAILED, +} PCAPNG_RESULT; + +/** + * Create a new PCAP-NG file and set aside space in the section and + * interface headers for options to be recorded/added while packets + * are captured. + * + * @param handle pointer to a handle that is populated by this call + * @param filename file to create + * @param section_options list of initial section options, can be NULL + * @param section_options_space size in bytes dedicated to storing extra section + * options; will be rounded up so section header + * is an integer number of memory pages + * @param link_type + * @param snaplen + * @param interface_options list of initial interface options, can be NULL + * @param interface_options_space size in bytes dedicated to storing extra interface + * options; will be rounded up so interface header + * is an integer number of memory pages + * @returns 0 on success, non zero result code otherwisex + */ +PCAPNG_RESULT pcapng_create( PCAPNG_HANDLE * handle, + const char * filename, + const option_header * section_options, + const size_t section_options_space, + const uint16_t link_type, + const uint32_t snaplen, + const option_header * interface_options, + const size_t interface_options_space ); + +PCAPNG_RESULT pcapng_append_section_option( PCAPNG_HANDLE * handle, + const option_header * section_option ); + +PCAPNG_RESULT pcapng_append_interface_option( PCAPNG_HANDLE * handle, + const option_header * interface_option ); + +PCAPNG_RESULT pcapng_append_packet( PCAPNG_HANDLE * handle, + const enhanced_packet_block * packet ); + +PCAPNG_RESULT pcapng_close( PCAPNG_HANDLE * handle ); + +#endif /* PCAPNG_DOT_H */ diff --git a/libbtbb-2015-10-R1/lib/src/sw_check_tables.h b/libbtbb-2015-10-R1/lib/src/sw_check_tables.h new file mode 100644 index 0000000..62874b2 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/sw_check_tables.h @@ -0,0 +1,4 @@ +static const uint64_t sw_check_table4[] = {0x000000000ULL, 0x100000000ULL, 0x200000000ULL, 0x300000000ULL, 0x185713da9ULL, 0x085713da9ULL, 0x385713da9ULL, 0x285713da9ULL, 0x30ae27b52ULL, 0x20ae27b52ULL, 0x10ae27b52ULL, 0x00ae27b52ULL, 0x28f9346fbULL, 0x38f9346fbULL, 0x08f9346fbULL, 0x18f9346fbULL, 0x390b5cb0dULL, 0x290b5cb0dULL, 0x190b5cb0dULL, 0x090b5cb0dULL, 0x215c4f6a4ULL, 0x315c4f6a4ULL, 0x015c4f6a4ULL, 0x115c4f6a4ULL, 0x09a57b05fULL, 0x19a57b05fULL, 0x29a57b05fULL, 0x39a57b05fULL, 0x11f268df6ULL, 0x01f268df6ULL, 0x31f268df6ULL, 0x21f268df6ULL, 0x2a41aabb3ULL, 0x3a41aabb3ULL, 0x0a41aabb3ULL, 0x1a41aabb3ULL, 0x3216b961aULL, 0x2216b961aULL, 0x1216b961aULL, 0x0216b961aULL, 0x1aef8d0e1ULL, 0x0aef8d0e1ULL, 0x3aef8d0e1ULL, 0x2aef8d0e1ULL, 0x02b89ed48ULL, 0x12b89ed48ULL, 0x22b89ed48ULL, 0x32b89ed48ULL, 0x134af60beULL, 0x034af60beULL, 0x334af60beULL, 0x234af60beULL, 0x0b1de5d17ULL, 0x1b1de5d17ULL, 0x2b1de5d17ULL, 0x3b1de5d17ULL, 0x23e4d1becULL, 0x33e4d1becULL, 0x03e4d1becULL, 0x13e4d1becULL, 0x3bb3c2645ULL, 0x2bb3c2645ULL, 0x1bb3c2645ULL, 0x0bb3c2645ULL, 0x0cd446acfULL, 0x1cd446acfULL, 0x2cd446acfULL, 0x3cd446acfULL, 0x148355766ULL, 0x048355766ULL, 0x348355766ULL, 0x248355766ULL, 0x3c7a6119dULL, 0x2c7a6119dULL, 0x1c7a6119dULL, 0x0c7a6119dULL, 0x242d72c34ULL, 0x342d72c34ULL, 0x042d72c34ULL, 0x142d72c34ULL, 0x35df1a1c2ULL, 0x25df1a1c2ULL, 0x15df1a1c2ULL, 0x05df1a1c2ULL, 0x2d8809c6bULL, 0x3d8809c6bULL, 0x0d8809c6bULL, 0x1d8809c6bULL, 0x05713da90ULL, 0x15713da90ULL, 0x25713da90ULL, 0x35713da90ULL, 0x1d262e739ULL, 0x0d262e739ULL, 0x3d262e739ULL, 0x2d262e739ULL, 0x2695ec17cULL, 0x3695ec17cULL, 0x0695ec17cULL, 0x1695ec17cULL, 0x3ec2ffcd5ULL, 0x2ec2ffcd5ULL, 0x1ec2ffcd5ULL, 0x0ec2ffcd5ULL, 0x163bcba2eULL, 0x063bcba2eULL, 0x363bcba2eULL, 0x263bcba2eULL, 0x0e6cd8787ULL, 0x1e6cd8787ULL, 0x2e6cd8787ULL, 0x3e6cd8787ULL, 0x1f9eb0a71ULL, 0x0f9eb0a71ULL, 0x3f9eb0a71ULL, 0x2f9eb0a71ULL, 0x07c9a37d8ULL, 0x17c9a37d8ULL, 0x27c9a37d8ULL, 0x37c9a37d8ULL, 0x2f3097123ULL, 0x3f3097123ULL, 0x0f3097123ULL, 0x1f3097123ULL, 0x376784c8aULL, 0x276784c8aULL, 0x176784c8aULL, 0x076784c8aULL, 0x19a88d59eULL, 0x09a88d59eULL, 0x39a88d59eULL, 0x29a88d59eULL, 0x01ff9e837ULL, 0x11ff9e837ULL, 0x21ff9e837ULL, 0x31ff9e837ULL, 0x2906aaeccULL, 0x3906aaeccULL, 0x0906aaeccULL, 0x1906aaeccULL, 0x3151b9365ULL, 0x2151b9365ULL, 0x1151b9365ULL, 0x0151b9365ULL, 0x20a3d1e93ULL, 0x30a3d1e93ULL, 0x00a3d1e93ULL, 0x10a3d1e93ULL, 0x38f4c233aULL, 0x28f4c233aULL, 0x18f4c233aULL, 0x08f4c233aULL, 0x100df65c1ULL, 0x000df65c1ULL, 0x300df65c1ULL, 0x200df65c1ULL, 0x085ae5868ULL, 0x185ae5868ULL, 0x285ae5868ULL, 0x385ae5868ULL, 0x33e927e2dULL, 0x23e927e2dULL, 0x13e927e2dULL, 0x03e927e2dULL, 0x2bbe34384ULL, 0x3bbe34384ULL, 0x0bbe34384ULL, 0x1bbe34384ULL, 0x03470057fULL, 0x13470057fULL, 0x23470057fULL, 0x33470057fULL, 0x1b10138d6ULL, 0x0b10138d6ULL, 0x3b10138d6ULL, 0x2b10138d6ULL, 0x0ae27b520ULL, 0x1ae27b520ULL, 0x2ae27b520ULL, 0x3ae27b520ULL, 0x12b568889ULL, 0x02b568889ULL, 0x32b568889ULL, 0x22b568889ULL, 0x3a4c5ce72ULL, 0x2a4c5ce72ULL, 0x1a4c5ce72ULL, 0x0a4c5ce72ULL, 0x221b4f3dbULL, 0x321b4f3dbULL, 0x021b4f3dbULL, 0x121b4f3dbULL, 0x157ccbf51ULL, 0x057ccbf51ULL, 0x357ccbf51ULL, 0x257ccbf51ULL, 0x0d2bd82f8ULL, 0x1d2bd82f8ULL, 0x2d2bd82f8ULL, 0x3d2bd82f8ULL, 0x25d2ec403ULL, 0x35d2ec403ULL, 0x05d2ec403ULL, 0x15d2ec403ULL, 0x3d85ff9aaULL, 0x2d85ff9aaULL, 0x1d85ff9aaULL, 0x0d85ff9aaULL, 0x2c779745cULL, 0x3c779745cULL, 0x0c779745cULL, 0x1c779745cULL, 0x3420849f5ULL, 0x2420849f5ULL, 0x1420849f5ULL, 0x0420849f5ULL, 0x1cd9b0f0eULL, 0x0cd9b0f0eULL, 0x3cd9b0f0eULL, 0x2cd9b0f0eULL, 0x048ea32a7ULL, 0x148ea32a7ULL, 0x248ea32a7ULL, 0x348ea32a7ULL, 0x3f3d614e2ULL, 0x2f3d614e2ULL, 0x1f3d614e2ULL, 0x0f3d614e2ULL, 0x276a7294bULL, 0x376a7294bULL, 0x076a7294bULL, 0x176a7294bULL, 0x0f9346fb0ULL, 0x1f9346fb0ULL, 0x2f9346fb0ULL, 0x3f9346fb0ULL, 0x17c455219ULL, 0x07c455219ULL, 0x37c455219ULL, 0x27c455219ULL, 0x06363dfefULL, 0x16363dfefULL, 0x26363dfefULL, 0x36363dfefULL, 0x1e612e246ULL, 0x0e612e246ULL, 0x3e612e246ULL, 0x2e612e246ULL, 0x36981a4bdULL, 0x26981a4bdULL, 0x16981a4bdULL, 0x06981a4bdULL, 0x2ecf09914ULL, 0x3ecf09914ULL, 0x0ecf09914ULL, 0x1ecf09914ULL}; +static const uint64_t sw_check_table5[] = {0x000000000ULL, 0x33511ab3cULL, 0x3ef526bd1ULL, 0x0da43c0edULL, 0x25bd5ea0bULL, 0x16ec44137ULL, 0x1b48781daULL, 0x281962ae6ULL, 0x132dae9bfULL, 0x207cb4283ULL, 0x2dd88826eULL, 0x1e8992952ULL, 0x3690f03b4ULL, 0x05c1ea888ULL, 0x0865d6865ULL, 0x3b34cc359ULL, 0x265b5d37eULL, 0x150a47842ULL, 0x18ae7b8afULL, 0x2bff61393ULL, 0x03e603975ULL, 0x30b719249ULL, 0x3d13252a4ULL, 0x0e423f998ULL, 0x3576f3ac1ULL, 0x0627e91fdULL, 0x0b83d5110ULL, 0x38d2cfa2cULL, 0x10cbad0caULL, 0x239ab7bf6ULL, 0x2e3e8bb1bULL, 0x1d6f91027ULL, 0x14e1a9b55ULL, 0x27b0b3069ULL, 0x2a148f084ULL, 0x194595bb8ULL, 0x315cf715eULL, 0x020deda62ULL, 0x0fa9d1a8fULL, 0x3cf8cb1b3ULL, 0x07cc072eaULL, 0x349d1d9d6ULL, 0x39392193bULL, 0x0a683b207ULL, 0x2271598e1ULL, 0x1120433ddULL, 0x1c847f330ULL, 0x2fd56580cULL, 0x32baf482bULL, 0x01ebee317ULL, 0x0c4fd23faULL, 0x3f1ec88c6ULL, 0x1707aa220ULL, 0x2456b091cULL, 0x29f28c9f1ULL, 0x1aa3962cdULL, 0x21975a194ULL, 0x12c640aa8ULL, 0x1f627ca45ULL, 0x2c3366179ULL, 0x042a04b9fULL, 0x377b1e0a3ULL, 0x3adf2204eULL, 0x098e38b72ULL, 0x29c3536aaULL, 0x1a9249d96ULL, 0x173675d7bULL, 0x24676f647ULL, 0x0c7e0dca1ULL, 0x3f2f1779dULL, 0x328b2b770ULL, 0x01da31c4cULL, 0x3aeefdf15ULL, 0x09bfe7429ULL, 0x041bdb4c4ULL, 0x374ac1ff8ULL, 0x1f53a351eULL, 0x2c02b9e22ULL, 0x21a685ecfULL, 0x12f79f5f3ULL, 0x0f980e5d4ULL, 0x3cc914ee8ULL, 0x316d28e05ULL, 0x023c32539ULL, 0x2a2550fdfULL, 0x19744a4e3ULL, 0x14d07640eULL, 0x27816cf32ULL, 0x1cb5a0c6bULL, 0x2fe4ba757ULL, 0x2240867baULL, 0x11119cc86ULL, 0x3908fe660ULL, 0x0a59e4d5cULL, 0x07fdd8db1ULL, 0x34acc268dULL, 0x3d22fadffULL, 0x0e73e06c3ULL, 0x03d7dc62eULL, 0x3086c6d12ULL, 0x189fa47f4ULL, 0x2bcebecc8ULL, 0x266a82c25ULL, 0x153b98719ULL, 0x2e0f54440ULL, 0x1d5e4ef7cULL, 0x10fa72f91ULL, 0x23ab684adULL, 0x0bb20ae4bULL, 0x38e310577ULL, 0x35472c59aULL, 0x061636ea6ULL, 0x1b79a7e81ULL, 0x2828bd5bdULL, 0x258c81550ULL, 0x16dd9be6cULL, 0x3ec4f948aULL, 0x0d95e3fb6ULL, 0x0031dff5bULL, 0x3360c5467ULL, 0x08540973eULL, 0x3b0513c02ULL, 0x36a12fcefULL, 0x05f0357d3ULL, 0x2de957d35ULL, 0x1eb84d609ULL, 0x131c716e4ULL, 0x204d6bdd8ULL, 0x0bd1b50fdULL, 0x3880afbc1ULL, 0x352493b2cULL, 0x067589010ULL, 0x2e6cebaf6ULL, 0x1d3df11caULL, 0x1099cd127ULL, 0x23c8d7a1bULL, 0x18fc1b942ULL, 0x2bad0127eULL, 0x26093d293ULL, 0x1558279afULL, 0x3d4145349ULL, 0x0e105f875ULL, 0x03b463898ULL, 0x30e5793a4ULL, 0x2d8ae8383ULL, 0x1edbf28bfULL, 0x137fce852ULL, 0x202ed436eULL, 0x0837b6988ULL, 0x3b66ac2b4ULL, 0x36c290259ULL, 0x05938a965ULL, 0x3ea746a3cULL, 0x0df65c100ULL, 0x0052601edULL, 0x33037aad1ULL, 0x1b1a18037ULL, 0x284b02b0bULL, 0x25ef3ebe6ULL, 0x16be240daULL, 0x1f301cba8ULL, 0x2c6106094ULL, 0x21c53a079ULL, 0x129420b45ULL, 0x3a8d421a3ULL, 0x09dc58a9fULL, 0x047864a72ULL, 0x37297e14eULL, 0x0c1db2217ULL, 0x3f4ca892bULL, 0x32e8949c6ULL, 0x01b98e2faULL, 0x29a0ec81cULL, 0x1af1f6320ULL, 0x1755ca3cdULL, 0x2404d08f1ULL, 0x396b418d6ULL, 0x0a3a5b3eaULL, 0x079e67307ULL, 0x34cf7d83bULL, 0x1cd61f2ddULL, 0x2f87059e1ULL, 0x22233990cULL, 0x117223230ULL, 0x2a46ef169ULL, 0x1917f5a55ULL, 0x14b3c9ab8ULL, 0x27e2d3184ULL, 0x0ffbb1b62ULL, 0x3caaab05eULL, 0x310e970b3ULL, 0x025f8db8fULL, 0x2212e6657ULL, 0x1143fcd6bULL, 0x1ce7c0d86ULL, 0x2fb6da6baULL, 0x07afb8c5cULL, 0x34fea2760ULL, 0x395a9e78dULL, 0x0a0b84cb1ULL, 0x313f48fe8ULL, 0x026e524d4ULL, 0x0fca6e439ULL, 0x3c9b74f05ULL, 0x1482165e3ULL, 0x27d30cedfULL, 0x2a7730e32ULL, 0x19262a50eULL, 0x0449bb529ULL, 0x3718a1e15ULL, 0x3abc9def8ULL, 0x09ed875c4ULL, 0x21f4e5f22ULL, 0x12a5ff41eULL, 0x1f01c34f3ULL, 0x2c50d9fcfULL, 0x176415c96ULL, 0x24350f7aaULL, 0x299133747ULL, 0x1ac029c7bULL, 0x32d94b69dULL, 0x018851da1ULL, 0x0c2c6dd4cULL, 0x3f7d77670ULL, 0x36f34fd02ULL, 0x05a25563eULL, 0x0806696d3ULL, 0x3b5773defULL, 0x134e11709ULL, 0x201f0bc35ULL, 0x2dbb37cd8ULL, 0x1eea2d7e4ULL, 0x25dee14bdULL, 0x168ffbf81ULL, 0x1b2bc7f6cULL, 0x287add450ULL, 0x0063bfeb6ULL, 0x3332a558aULL, 0x3e9699567ULL, 0x0dc783e5bULL, 0x10a812e7cULL, 0x23f908540ULL, 0x2e5d345adULL, 0x1d0c2ee91ULL, 0x35154c477ULL, 0x064456f4bULL, 0x0be06afa6ULL, 0x38b17049aULL, 0x0385bc7c3ULL, 0x30d4a6cffULL, 0x3d709ac12ULL, 0x0e218072eULL, 0x2638e2dc8ULL, 0x1569f86f4ULL, 0x18cdc4619ULL, 0x2b9cded25ULL}; +static const uint64_t sw_check_table6[] = {0x000000000ULL, 0x17a36a1faULL, 0x2f46d43f4ULL, 0x38e5be20eULL, 0x06dabba41ULL, 0x1179d1bbbULL, 0x299c6f9b5ULL, 0x3e3f0584fULL, 0x0db577482ULL, 0x1a161d578ULL, 0x22f3a3776ULL, 0x3550c968cULL, 0x0b6fccec3ULL, 0x1ccca6f39ULL, 0x242918d37ULL, 0x338a72ccdULL, 0x1b6aee904ULL, 0x0cc9848feULL, 0x342c3aaf0ULL, 0x238f50b0aULL, 0x1db055345ULL, 0x0a133f2bfULL, 0x32f6810b1ULL, 0x2555eb14bULL, 0x16df99d86ULL, 0x017cf3c7cULL, 0x39994de72ULL, 0x2e3a27f88ULL, 0x1005227c7ULL, 0x07a64863dULL, 0x3f43f6433ULL, 0x28e09c5c9ULL, 0x36d5dd208ULL, 0x2176b73f2ULL, 0x1993091fcULL, 0x0e3063006ULL, 0x300f66849ULL, 0x27ac0c9b3ULL, 0x1f49b2bbdULL, 0x08ead8a47ULL, 0x3b60aa68aULL, 0x2cc3c0770ULL, 0x14267e57eULL, 0x038514484ULL, 0x3dba11ccbULL, 0x2a197bd31ULL, 0x12fcc5f3fULL, 0x055fafec5ULL, 0x2dbf33b0cULL, 0x3a1c59af6ULL, 0x02f9e78f8ULL, 0x155a8d902ULL, 0x2b658814dULL, 0x3cc6e20b7ULL, 0x04235c2b9ULL, 0x138036343ULL, 0x200a44f8eULL, 0x37a92ee74ULL, 0x0f4c90c7aULL, 0x18effad80ULL, 0x26d0ff5cfULL, 0x317395435ULL, 0x09962b63bULL, 0x1e35417c1ULL, 0x35fca99b9ULL, 0x225fc3843ULL, 0x1aba7da4dULL, 0x0d1917bb7ULL, 0x3326123f8ULL, 0x248578202ULL, 0x1c60c600cULL, 0x0bc3ac1f6ULL, 0x3849ded3bULL, 0x2feab4cc1ULL, 0x170f0aecfULL, 0x00ac60f35ULL, 0x3e936577aULL, 0x29300f680ULL, 0x11d5b148eULL, 0x0676db574ULL, 0x2e96470bdULL, 0x39352d147ULL, 0x01d093349ULL, 0x1673f92b3ULL, 0x284cfcafcULL, 0x3fef96b06ULL, 0x070a28908ULL, 0x10a9428f2ULL, 0x23233043fULL, 0x34805a5c5ULL, 0x0c65e47cbULL, 0x1bc68e631ULL, 0x25f98be7eULL, 0x325ae1f84ULL, 0x0abf5fd8aULL, 0x1d1c35c70ULL, 0x032974bb1ULL, 0x148a1ea4bULL, 0x2c6fa0845ULL, 0x3bccca9bfULL, 0x05f3cf1f0ULL, 0x1250a500aULL, 0x2ab51b204ULL, 0x3d16713feULL, 0x0e9c03f33ULL, 0x193f69ec9ULL, 0x21dad7cc7ULL, 0x3679bdd3dULL, 0x0846b8572ULL, 0x1fe5d2488ULL, 0x27006c686ULL, 0x30a30677cULL, 0x18439a2b5ULL, 0x0fe0f034fULL, 0x37054e141ULL, 0x20a6240bbULL, 0x1e99218f4ULL, 0x093a4b90eULL, 0x31dff5b00ULL, 0x267c9fafaULL, 0x15f6ed637ULL, 0x0255877cdULL, 0x3ab0395c3ULL, 0x2d1353439ULL, 0x132c56c76ULL, 0x048f3cd8cULL, 0x3c6a82f82ULL, 0x2bc9e8e78ULL, 0x33ae40edbULL, 0x240d2af21ULL, 0x1ce894d2fULL, 0x0b4bfecd5ULL, 0x3574fb49aULL, 0x22d791560ULL, 0x1a322f76eULL, 0x0d9145694ULL, 0x3e1b37a59ULL, 0x29b85dba3ULL, 0x115de39adULL, 0x06fe89857ULL, 0x38c18c018ULL, 0x2f62e61e2ULL, 0x1787583ecULL, 0x002432216ULL, 0x28c4ae7dfULL, 0x3f67c4625ULL, 0x07827a42bULL, 0x1021105d1ULL, 0x2e1e15d9eULL, 0x39bd7fc64ULL, 0x0158c1e6aULL, 0x16fbabf90ULL, 0x2571d935dULL, 0x32d2b32a7ULL, 0x0a370d0a9ULL, 0x1d9467153ULL, 0x23ab6291cULL, 0x3408088e6ULL, 0x0cedb6ae8ULL, 0x1b4edcb12ULL, 0x057b9dcd3ULL, 0x12d8f7d29ULL, 0x2a3d49f27ULL, 0x3d9e23eddULL, 0x03a126692ULL, 0x14024c768ULL, 0x2ce7f2566ULL, 0x3b449849cULL, 0x08ceea851ULL, 0x1f6d809abULL, 0x27883eba5ULL, 0x302b54a5fULL, 0x0e1451210ULL, 0x19b73b3eaULL, 0x2152851e4ULL, 0x36f1ef01eULL, 0x1e11735d7ULL, 0x09b21942dULL, 0x3157a7623ULL, 0x26f4cd7d9ULL, 0x18cbc8f96ULL, 0x0f68a2e6cULL, 0x378d1cc62ULL, 0x202e76d98ULL, 0x13a404155ULL, 0x04076e0afULL, 0x3ce2d02a1ULL, 0x2b41ba35bULL, 0x157ebfb14ULL, 0x02ddd5aeeULL, 0x3a386b8e0ULL, 0x2d9b0191aULL, 0x0652e9762ULL, 0x11f183698ULL, 0x29143d496ULL, 0x3eb75756cULL, 0x008852d23ULL, 0x172b38cd9ULL, 0x2fce86ed7ULL, 0x386decf2dULL, 0x0be79e3e0ULL, 0x1c44f421aULL, 0x24a14a014ULL, 0x3302201eeULL, 0x0d3d259a1ULL, 0x1a9e4f85bULL, 0x227bf1a55ULL, 0x35d89bbafULL, 0x1d3807e66ULL, 0x0a9b6df9cULL, 0x327ed3d92ULL, 0x25ddb9c68ULL, 0x1be2bc427ULL, 0x0c41d65ddULL, 0x34a4687d3ULL, 0x230702629ULL, 0x108d70ae4ULL, 0x072e1ab1eULL, 0x3fcba4910ULL, 0x2868ce8eaULL, 0x1657cb0a5ULL, 0x01f4a115fULL, 0x39111f351ULL, 0x2eb2752abULL, 0x30873456aULL, 0x27245e490ULL, 0x1fc1e069eULL, 0x08628a764ULL, 0x365d8ff2bULL, 0x21fee5ed1ULL, 0x191b5bcdfULL, 0x0eb831d25ULL, 0x3d32431e8ULL, 0x2a9129012ULL, 0x12749721cULL, 0x05d7fd3e6ULL, 0x3be8f8ba9ULL, 0x2c4b92a53ULL, 0x14ae2c85dULL, 0x030d469a7ULL, 0x2beddac6eULL, 0x3c4eb0d94ULL, 0x04ab0ef9aULL, 0x130864e60ULL, 0x2d376162fULL, 0x3a940b7d5ULL, 0x0271b55dbULL, 0x15d2df421ULL, 0x2658ad8ecULL, 0x31fbc7916ULL, 0x091e79b18ULL, 0x1ebd13ae2ULL, 0x2082162adULL, 0x37217c357ULL, 0x0fc4c2159ULL, 0x1867a80a3ULL}; +static const uint64_t sw_check_table7[] = {0x000000000ULL, 0x3f0b9201fULL, 0x264037d97ULL, 0x194ba5d88ULL, 0x14d77c687ULL, 0x2bdcee698ULL, 0x32974bb10ULL, 0x0d9cd9b0fULL, 0x29aef8d0eULL, 0x16a56ad11ULL, 0x0feecf099ULL, 0x30e55d086ULL, 0x3d7984b89ULL, 0x027216b96ULL, 0x1b39b361eULL, 0x243221601ULL, 0x0b0ae27b5ULL, 0x3401707aaULL, 0x2d4ad5a22ULL, 0x124147a3dULL, 0x1fdd9e132ULL, 0x20d60c12dULL, 0x399da9ca5ULL, 0x06963bcbaULL, 0x22a41aabbULL, 0x1daf88aa4ULL, 0x04e42d72cULL, 0x3befbf733ULL, 0x367366c3cULL, 0x0978f4c23ULL, 0x1033511abULL, 0x2f38c31b4ULL, 0x1615c4f6aULL, 0x291e56f75ULL, 0x3055f32fdULL, 0x0f5e612e2ULL, 0x02c2b89edULL, 0x3dc92a9f2ULL, 0x24828f47aULL, 0x1b891d465ULL, 0x3fbb3c264ULL, 0x00b0ae27bULL, 0x19fb0bff3ULL, 0x26f099fecULL, 0x2b6c404e3ULL, 0x1467d24fcULL, 0x0d2c77974ULL, 0x3227e596bULL, 0x1d1f268dfULL, 0x2214b48c0ULL, 0x3b5f11548ULL, 0x045483557ULL, 0x09c85ae58ULL, 0x36c3c8e47ULL, 0x2f886d3cfULL, 0x1083ff3d0ULL, 0x34b1de5d1ULL, 0x0bba4c5ceULL, 0x12f1e9846ULL, 0x2dfa7b859ULL, 0x2066a2356ULL, 0x1f6d30349ULL, 0x062695ec1ULL, 0x392d07edeULL, 0x2c2b89ed4ULL, 0x13201becbULL, 0x0a6bbe343ULL, 0x35602c35cULL, 0x38fcf5853ULL, 0x07f76784cULL, 0x1ebcc25c4ULL, 0x21b7505dbULL, 0x0585713daULL, 0x3a8ee33c5ULL, 0x23c546e4dULL, 0x1cced4e52ULL, 0x11520d55dULL, 0x2e599f542ULL, 0x37123a8caULL, 0x0819a88d5ULL, 0x27216b961ULL, 0x182af997eULL, 0x01615c4f6ULL, 0x3e6ace4e9ULL, 0x33f617fe6ULL, 0x0cfd85ff9ULL, 0x15b620271ULL, 0x2abdb226eULL, 0x0e8f9346fULL, 0x318401470ULL, 0x28cfa49f8ULL, 0x17c4369e7ULL, 0x1a58ef2e8ULL, 0x25537d2f7ULL, 0x3c18d8f7fULL, 0x03134af60ULL, 0x3a3e4d1beULL, 0x0535df1a1ULL, 0x1c7e7ac29ULL, 0x2375e8c36ULL, 0x2ee931739ULL, 0x11e2a3726ULL, 0x08a906aaeULL, 0x37a294ab1ULL, 0x1390b5cb0ULL, 0x2c9b27cafULL, 0x35d082127ULL, 0x0adb10138ULL, 0x0747c9a37ULL, 0x384c5ba28ULL, 0x2107fe7a0ULL, 0x1e0c6c7bfULL, 0x3134af60bULL, 0x0e3f3d614ULL, 0x177498b9cULL, 0x287f0ab83ULL, 0x25e3d308cULL, 0x1ae841093ULL, 0x03a3e4d1bULL, 0x3ca876d04ULL, 0x189a57b05ULL, 0x2791c5b1aULL, 0x3eda60692ULL, 0x01d1f268dULL, 0x0c4d2bd82ULL, 0x3346b9d9dULL, 0x2a0d1c015ULL, 0x15068e00aULL, 0x000000001ULL, 0x3f0b9201eULL, 0x264037d96ULL, 0x194ba5d89ULL, 0x14d77c686ULL, 0x2bdcee699ULL, 0x32974bb11ULL, 0x0d9cd9b0eULL, 0x29aef8d0fULL, 0x16a56ad10ULL, 0x0feecf098ULL, 0x30e55d087ULL, 0x3d7984b88ULL, 0x027216b97ULL, 0x1b39b361fULL, 0x243221600ULL, 0x0b0ae27b4ULL, 0x3401707abULL, 0x2d4ad5a23ULL, 0x124147a3cULL, 0x1fdd9e133ULL, 0x20d60c12cULL, 0x399da9ca4ULL, 0x06963bcbbULL, 0x22a41aabaULL, 0x1daf88aa5ULL, 0x04e42d72dULL, 0x3befbf732ULL, 0x367366c3dULL, 0x0978f4c22ULL, 0x1033511aaULL, 0x2f38c31b5ULL, 0x1615c4f6bULL, 0x291e56f74ULL, 0x3055f32fcULL, 0x0f5e612e3ULL, 0x02c2b89ecULL, 0x3dc92a9f3ULL, 0x24828f47bULL, 0x1b891d464ULL, 0x3fbb3c265ULL, 0x00b0ae27aULL, 0x19fb0bff2ULL, 0x26f099fedULL, 0x2b6c404e2ULL, 0x1467d24fdULL, 0x0d2c77975ULL, 0x3227e596aULL, 0x1d1f268deULL, 0x2214b48c1ULL, 0x3b5f11549ULL, 0x045483556ULL, 0x09c85ae59ULL, 0x36c3c8e46ULL, 0x2f886d3ceULL, 0x1083ff3d1ULL, 0x34b1de5d0ULL, 0x0bba4c5cfULL, 0x12f1e9847ULL, 0x2dfa7b858ULL, 0x2066a2357ULL, 0x1f6d30348ULL, 0x062695ec0ULL, 0x392d07edfULL, 0x2c2b89ed5ULL, 0x13201becaULL, 0x0a6bbe342ULL, 0x35602c35dULL, 0x38fcf5852ULL, 0x07f76784dULL, 0x1ebcc25c5ULL, 0x21b7505daULL, 0x0585713dbULL, 0x3a8ee33c4ULL, 0x23c546e4cULL, 0x1cced4e53ULL, 0x11520d55cULL, 0x2e599f543ULL, 0x37123a8cbULL, 0x0819a88d4ULL, 0x27216b960ULL, 0x182af997fULL, 0x01615c4f7ULL, 0x3e6ace4e8ULL, 0x33f617fe7ULL, 0x0cfd85ff8ULL, 0x15b620270ULL, 0x2abdb226fULL, 0x0e8f9346eULL, 0x318401471ULL, 0x28cfa49f9ULL, 0x17c4369e6ULL, 0x1a58ef2e9ULL, 0x25537d2f6ULL, 0x3c18d8f7eULL, 0x03134af61ULL, 0x3a3e4d1bfULL, 0x0535df1a0ULL, 0x1c7e7ac28ULL, 0x2375e8c37ULL, 0x2ee931738ULL, 0x11e2a3727ULL, 0x08a906aafULL, 0x37a294ab0ULL, 0x1390b5cb1ULL, 0x2c9b27caeULL, 0x35d082126ULL, 0x0adb10139ULL, 0x0747c9a36ULL, 0x384c5ba29ULL, 0x2107fe7a1ULL, 0x1e0c6c7beULL, 0x3134af60aULL, 0x0e3f3d615ULL, 0x177498b9dULL, 0x287f0ab82ULL, 0x25e3d308dULL, 0x1ae841092ULL, 0x03a3e4d1aULL, 0x3ca876d05ULL, 0x189a57b04ULL, 0x2791c5b1bULL, 0x3eda60693ULL, 0x01d1f268cULL, 0x0c4d2bd83ULL, 0x3346b9d9cULL, 0x2a0d1c014ULL, 0x15068e00bULL}; diff --git a/libbtbb-2015-10-R1/lib/src/uthash.h b/libbtbb-2015-10-R1/lib/src/uthash.h new file mode 100644 index 0000000..d2255b1 --- /dev/null +++ b/libbtbb-2015-10-R1/lib/src/uthash.h @@ -0,0 +1,960 @@ +/* +Copyright (c) 2003-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#include /* memcmp,strlen */ +#include /* ptrdiff_t */ +#include /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#define DECLTYPE(x) +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while(0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while(0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined (_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#else +#include +#endif + +#define UTHASH_VERSION 1.9.9 + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhe */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + out=NULL; \ + if (head) { \ + unsigned _hf_bkt,_hf_hashv; \ + HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ + keyptr,keylen,out); \ + } \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0 +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while(0) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + replaced=NULL; \ + HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \ + if (replaced!=NULL) { \ + HASH_DELETE(hh,head,replaced); \ + } \ + HASH_ADD(hh,head,fieldname,keylen_in,add); \ +} while(0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.next = NULL; \ + (add)->hh.key = (char*)(keyptr); \ + (add)->hh.keylen = (unsigned)(keylen_in); \ + if (!(head)) { \ + head = (add); \ + (head)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh,head); \ + } else { \ + (head)->hh.tbl->tail->next = (add); \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail = &((add)->hh); \ + } \ + (head)->hh.tbl->num_items++; \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ + (add)->hh.hashv, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ + HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ + HASH_FSCK(hh,head); \ +} while(0) + +#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1)); \ +} while(0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + unsigned _hd_bkt; \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev) { \ + ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next) { \ + ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count; \ + char *_prev; \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %u, actual %u\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hb_keylen=keylen; \ + char *_hb_key=(char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen--) { (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; } \ + bkt = (hashv) & (num_bkts-1); \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _sx_i; \ + char *_hs_key=(char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + bkt = hashv & (num_bkts-1); \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _fn_i; \ + char *_hf_key=(char*)(key); \ + hashv = 2166136261UL; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619; \ + } \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _ho_i; \ + char *_ho_key=(char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned char *_hj_key=(unsigned char*)(key); \ + hashv = 0xfeedbeef; \ + _hj_i = _hj_j = 0x9e3779b9; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12; \ + } \ + hashv += keylen; \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ + case 5: _hj_j += _hj_key[4]; \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned char *_sfh_key=(unsigned char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = keylen; \ + \ + int _sfh_rem = _sfh_len & 3; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabe; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6b; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35l; \ + _h ^= _h >> 16; \ +} while(0) + +#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353; \ + uint32_t _mur_c1 = 0xcc9e2d51; \ + uint32_t _mur_c2 = 0x1b873593; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = _mur_h1*5+0xe6546b64; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ + _mur_k1=0; \ + switch((keylen) & 3) { \ + case 3: _mur_k1 ^= _mur_tail[2] << 16; \ + case 2: _mur_k1 ^= _mur_tail[1] << 8; \ + case 1: _mur_k1 ^= _mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ + bkt = hashv & (num_bkts-1); \ +} while(0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* key comparison function; return 0 if keys equal */ +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +do { \ + if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ + else out=NULL; \ + while (out) { \ + if ((out)->hh.keylen == keylen_in) { \ + if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ + } \ + if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ + else out = NULL; \ + } \ +} while(0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ + && (addhh)->tbl->noexpand != 1) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while(0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ + ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ + _he_thh; \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1) : 0; \ + if (tbl->ineff_expands > 1) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while(0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) break; \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ + if (_hs_psize == 0) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail ) { \ + _hs_tail->next = ((_hs_e) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e) { \ + _hs_e->prev = ((_hs_tail) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail){ \ + _hs_tail->next = NULL; \ + } \ + if ( _hs_nmerges <= 1 ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ + if (!dst) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while(0) + +#define HASH_OVERHEAD(hh,head) \ + ((head) ? ( \ + (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + (sizeof(UT_hash_table)) + \ + (HASH_BLOOM_BYTELEN)))) : 0) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1 +#define HASH_BLOOM_SIGNATURE 0xb12220f2 + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + char bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/libbtbb-2015-10-R1/packaging/Portfile b/libbtbb-2015-10-R1/packaging/Portfile new file mode 100644 index 0000000..4001cd1 --- /dev/null +++ b/libbtbb-2015-10-R1/packaging/Portfile @@ -0,0 +1,34 @@ +# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4 +# $Id$ + +PortSystem 1.0 +PortGroup cmake 1.0 +PortGroup github 1.0 + +github.setup greatscottgadgets libbtbb 2014-02-R2 +categories net security +platforms darwin +maintainers gmail.com:dominicgs +license GPL-2+ + +description Bluetooth Baseband Decoding Library + +long_description \ + LibBTBB is a Bluetooth Baseband processing library that supports Basic \ + Rate and Bluetooth Smart (BLE) packets. It is used by the Ubertooth and \ + gr-bluetooth packet sniffer implementations. + +homepage https://github.com/greatscottgadgets/libbtbb + +checksums rmd160 0adc5d59e611509cdcf8959be8b6e31704529e48 \ + sha256 04a187b6f17836437e5f9deecb0b643c75ec0eafce671e373d1d4c13fc104984 + +configure.dir ${workpath}/build +build.dir ${configure.dir} + +post-extract { + file mkdir ${configure.dir} +} + +configure.post_args ../${name}-${version} +configure.args-append -DPACKAGE_MANAGER=1 \ No newline at end of file diff --git a/libbtbb-2015-10-R1/packaging/libbtbb.rb b/libbtbb-2015-10-R1/packaging/libbtbb.rb new file mode 100644 index 0000000..6a905d4 --- /dev/null +++ b/libbtbb-2015-10-R1/packaging/libbtbb.rb @@ -0,0 +1,26 @@ +require "formula" + +class Libbtbb < Formula + homepage "https://github.com/greatscottgadgets/libbtbb" + url "https://github.com/greatscottgadgets/libbtbb/archive/2014-02-R2.tar.gz" + sha1 "aa94b7d92465704aa647123f11e906491a26d090" + version "2014-02-R2" + + head "https://github.com/greatscottgadgets/libbtbb.git" + + option :universal + + depends_on "cmake" => :build + depends_on :python + + def install + if build.universal? + ENV.universal_binary + ENV["CMAKE_OSX_ARCHITECTURES"] = Hardware::CPU.universal_archs.as_cmake_arch_flags + end + mkdir "build" do + system "cmake", "..", *std_cmake_args + system "make", "install" + end + end +end diff --git a/libbtbb-2015-10-R1/packaging/libbtbb.spec b/libbtbb-2015-10-R1/packaging/libbtbb.spec new file mode 100644 index 0000000..fff4233 --- /dev/null +++ b/libbtbb-2015-10-R1/packaging/libbtbb.spec @@ -0,0 +1,64 @@ +# +#Copyright 2013 Dominic Spill +# +#This file is part of libbtbb +# +#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, 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 libbtbb; see the file COPYING. If not, write to +#the Free Software Foundation, Inc., 51 Franklin Street, +#Boston, MA 02110-1301, USA. +# + +Summary: Bluetooth baseband library +Name: libbtbb +Version: 2013.06 +Release: 1 +Summary: A Bluetooth basebad decoding library +License: GPLv2 +URL: http://mooedit.sourceforge.net/ +Source: %{name}-%{version}.tar.gz + +BuildRequires: cmake gcc python + +Autoreqprov: on + +%description +A library for decoding and processing Bluetooth baseband packets. +It can be used with any raw bitstream receiver, such as Ubertooth or +gr-bluetooth. + +%prep +%setup -q +%build +cmake -DCMAKE_SKIP_RPATH=ON \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DBUILD_ROOT=%{buildroot} + +%{__make} %{?jobs:-j%jobs} + +%install +%{__make} DESTDIR=%{buildroot} install + +%files +%{_prefix}/lib/libbtbb.so +%{_prefix}/lib/libbtbb.so.0 +%{_prefix}/lib/libbtbb.so.0.2.0 +%{_prefix}/lib/python* +%{_bindir}/btaptap +%{_libdir}/../include/libbtbb/bluetooth_le_packet.h +%{_libdir}/../include/libbtbb/btbb.h +%doc COPYING README.md + +%changelog +* Thu Jun 06 2013 Dominic Spill - 0.2.0 +- First binary release diff --git a/libbtbb-2015-10-R1/python/CMakeLists.txt b/libbtbb-2015-10-R1/python/CMakeLists.txt new file mode 100644 index 0000000..3422394 --- /dev/null +++ b/libbtbb-2015-10-R1/python/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright 2013 Dominic Spill +# +# This file is part of Libbtbb +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +project(btbb-python) + +# Check for python installation +find_package(PythonInterp) +if(NOT PYTHONINTERP_FOUND) + return() +else() + add_subdirectory(pcaptools) +endif() + +# Create uninstall target +if(NOT libbtbb_all_SOURCE_DIR) + configure_file( + ${PROJECT_SOURCE_DIR}/../cmake/cmake_uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake + @ONLY) + + add_custom_target(uninstall + ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake + ) +endif() diff --git a/libbtbb-2015-10-R1/python/pcaptools/CMakeLists.txt b/libbtbb-2015-10-R1/python/pcaptools/CMakeLists.txt new file mode 100644 index 0000000..78cfec9 --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright 2013 Dominic Spill +# +# This file is part of Libbtbb (pcapdump) +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +set(SETUP_PY_IN ${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in) +set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py) +set(DEPS ${CMAKE_CURRENT_SOURCE_DIR}/pcapdump/__init__.py + ${CMAKE_CURRENT_SOURCE_DIR}/pcapdump/pcapdump.py) +set(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/build) + +configure_file(${SETUP_PY_IN} ${SETUP_PY}) + +add_custom_command(OUTPUT ${OUTPUT}/timestamp + COMMAND ${PYTHON_EXECUTABLE} setup.py build + COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}/timestamp + DEPENDS ${DEPS}) + +add_custom_target(pcapdump ALL DEPENDS ${OUTPUT}/timestamp) +install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build -b ${OUTPUT} install --prefix=${BUILD_ROOT}/${CMAKE_INSTALL_PREFIX})") + +add_custom_target(btaptap ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/btaptap) +install(PROGRAMS btaptap DESTINATION ${INSTALL_DEFAULT_BINDIR}) + diff --git a/libbtbb-2015-10-R1/python/pcaptools/Makefile b/libbtbb-2015-10-R1/python/pcaptools/Makefile new file mode 100644 index 0000000..f76569e --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/Makefile @@ -0,0 +1,39 @@ +# Copyright 2012 Michael Ossmann, Dominic Spill +# +# This file is part of Project Ubertooth. +# +# 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, 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +INSTALL ?= /usr/bin/install +PYTHON ?= /usr/bin/env python + +INSTALL_DIR ?= /usr/bin + +EXECUTABLE_FILES = btaptap + +all: pcapdump + +pcapdump: + $(PYTHON) setup.py build + +clean: + rm -rf build + +install: pcapdump + $(PYTHON) setup.py install + $(INSTALL) -m 0755 $(EXECUTABLE_FILES) $(INSTALL_DIR) + +.PHONY: all clean install pcapdump diff --git a/libbtbb-2015-10-R1/python/pcaptools/README b/libbtbb-2015-10-R1/python/pcaptools/README new file mode 100644 index 0000000..9c79bf5 --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/README @@ -0,0 +1,20 @@ +This directory contains supplemental tools for working with pcap files produced +by libbtbb. (Actually libbtbb doesn't produce such files by itself at this +time, but you can produce them with the Ubertooth tools. + +These tools are not automatically installed as part of the libbtbb +installation but can be used right out of this directory or manually installed. + +pcapdump: a Python module for pcap + +Pcapdump us used by btaptap to read and write pcap files. It should work with +python 2.4 and above (python 3 support requires using the 2to3 tool). + + +btaptap: a Bluetooth keyboard sniffer + +Many Bluetooth keyboards operate by default in "boot mode" which features +simplified HID messaging that can be interpreted, for example, by a PC BIOS. +Some of those keyboards also transmit these messages over unencrypted +Bluetooth. This tool can be used to extract keystrokes from such +transmissions. diff --git a/libbtbb-2015-10-R1/python/pcaptools/btaptap b/libbtbb-2015-10-R1/python/pcaptools/btaptap new file mode 100755 index 0000000..67b6f25 --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/btaptap @@ -0,0 +1,520 @@ +#!/usr/bin/env python +# +# Copyright 2009 Joshua Wright, Michael Ossmann +# +# This file is part of gr-bluetooth +# +# gr-bluetooth 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, or (at your option) +# any later version. +# +# gr-bluetooth 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 gr-bluetooth; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +import sys +import struct +import time +from pcapdump.pcapdump import * + +DLT_EN10MB = 1 +DLT_BLUETOOTH_HCI_H4 = 187 +ELLISYS_CSV_HDR = "\"Depth\",\"Time\",\"Name\",\"Data\"\x0d\x0a" +ELLISYS_HID_INPUT = "HID Input 1" +USBHID_MAP = { + 0x04 : "a", + 0x05 : "b", + 0x06 : "c", + 0x07 : "d", + 0x08 : "e", + 0x09 : "f", + 0x0A : "g", + 0x0B : "h", + 0x0C : "i", + 0x0D : "j", + 0x0E : "k", + 0x0F : "l", + 0x10 : "m", + 0x11 : "n", + 0x12 : "o", + 0x13 : "p", + 0x14 : "q", + 0x15 : "r", + 0x16 : "s", + 0x17 : "t", + 0x18 : "u", + 0x19 : "v", + 0x1A : "w", + 0x1B : "x", + 0x1C : "y", + 0x1D : "z", + 0x1E : "1", + 0x1F : "2", + 0x20 : "3", + 0x21 : "4", + 0x22 : "5", + 0x23 : "6", + 0x24 : "7", + 0x25 : "8", + 0x26 : "9", + 0x27 : "0", + 0x28 : "[Return]\n", + 0x29 : "[Esc]", + 0x2A : "[Backspace]", + 0x2B : "[Tab]\t", + 0x2C : " ", + 0x2D : "-", + 0x2E : "=", + 0x2F : "[", + 0x30 : "]", + 0x31 : "\\", + 0x32 : "#", + 0x33 : ";", + 0x34 : "'", + 0x35 : "[Grave Accent]", + 0x36 : ",", + 0x37 : ".", + 0x38 : "/", + 0x39 : "[Caps Lock]", + 0x3A : "[F1]", + 0x3B : "[F2]", + 0x3C : "[F3]", + 0x3D : "[F4]", + 0x3E : "[F5]", + 0x3F : "[F6]", + 0x40 : "[F7]", + 0x41 : "[F8]", + 0x42 : "[F9]", + 0x43 : "[F10]", + 0x44 : "[F11]", + 0x45 : "[F12]", + 0x46 : "[PrintScreen]", + 0x47 : "[Scroll]", + 0x48 : "[Pause]", + 0x49 : "[Insert]", + 0x4A : "[Home]", + 0x4B : "[PageUp]", + 0x4C : "[Delete]", + 0x4D : "[End]", + 0x4E : "[PageDown]", + 0x4F : "[RightArrow]", + 0x50 : "[LeftArrow]", + 0x51 : "[DownArrow]", + 0x52 : "[UpArrow]", + 0x53 : "[Keypad Num Lock and Clear]", + 0x54 : "[Keypad /]", + 0x55 : "[Keypad *]", + 0x56 : "[Keypad -]", + 0x57 : "[Keypad +]", + 0x58 : "[Keypad Enter]\n", + 0x59 : "[Keypad 1 and End]", + 0x5A : "[Keypad 2 and Down Arrow]", + 0x5B : "[Keypad 3 and PageDn]", + 0x5C : "[Keypad 4 and Left Arrow]", + 0x5D : "[Keypad 5]", + 0x5E : "[Keypad 6 and Right Arrow]", + 0x5F : "[Keypad 7 and Home]", + 0x60 : "[Keypad 8 and Up Arrow]", + 0x61 : "[Keypad 9 and PageUp]", + 0x62 : "[Keypad 0 and Insert]", + 0x63 : "[Keypad . and Delete]", + 0x64 : "\\", + 0x65 : "[WinKey]", + 0x66 : "[Power9]", + 0x67 : "[Keypad =]", + 0x68 : "[F13]", + 0x69 : "[F14]", + 0x6A : "[F15]", + 0x6B : "[F16]", + 0x6C : "[F17]", + 0x6D : "[F18]", + 0x6E : "[F19]", + 0x6F : "[F20]", + 0x70 : "[F21]", + 0x71 : "[F22]", + 0x72 : "[F23]", + 0x73 : "[F24]", + 0x74 : "[Execute]", + 0x75 : "[Help]", + 0x76 : "[Menu]", + 0x77 : "[Select]", + 0x78 : "[Stop]", + 0x79 : "[Again]", + 0x7A : "[Undo]", + 0x7B : "[Cut]", + 0x7C : "[Copy]", + 0x7D : "[Paste]", + 0x7E : "[Find]", + 0x7F : "[Mute]", + 0x80 : "[Volume Up]", + 0x81 : "[Volume Down]", + 0x82 : "[Locking Caps Lock]", + 0x83 : "[Locking Num Lock]", + 0x84 : "[Locking Scroll Lock]", + 0x85 : "[Keypad Comma]", + 0x86 : "[Keypad Equal]", + 0x87 : "[International1]", + 0x88 : "[International2]", + 0x89 : "[International3]", + 0x8A : "[International4]", + 0x8B : "[International5]", + 0x8C : "[International6]", + 0x8D : "[International7]", + 0x8E : "[International8]", + 0x8F : "[International9]", + 0x90 : "[LANG1]", + 0x91 : "[LANG2]", + 0x92 : "[LANG3]", + 0x93 : "[LANG4]", + 0x94 : "[LANG5]", + 0x95 : "[LANG6]", + 0x96 : "[LANG7]", + 0x97 : "[LANG8]", + 0x98 : "[LANG9]", + 0x99 : "[Alternate Erase]", + 0x9A : "[SysReq/Attention]", + 0x9B : "[Cancel]", + 0x9C : "[Clear]", + 0x9D : "[Prior]", + 0x9E : "[Return]\n", + 0x9F : "[Separator]", + 0xA0 : "[Out]", + 0xA1 : "[Oper]", + 0xA2 : "[Clear/Again]", + 0xA3 : "[CrSel/Props]", + 0xA4 : "[ExSel]", + 0xB0 : "[Keypad 00]", + 0xB1 : "[Keypad 000]", + 0xB2 : "[Thousands Separator]", + 0xB3 : "[Decimal Separator]", + 0xB4 : "[Currency Unit]", + 0xB5 : "[Currency Sub-unit]", + 0xB6 : "[Keypad (]", + 0xB7 : "[Keypad )]", + 0xB8 : "[Keypad {]", + 0xB9 : "[Keypad }]", + 0xBA : "[Keypad Tab]\t", + 0xBB : "[Keypad Backspace]", + 0xBC : "[Keypad A]", + 0xBD : "[Keypad B]", + 0xBE : "[Keypad C]", + 0xBF : "[Keypad D]", + 0xC0 : "[Keypad E]", + 0xC1 : "[Keypad F]", + 0xC2 : "[Keypad XOR]", + 0xC3 : "[Keypad ^]", + 0xC4 : "[Keypad %]", + 0xC5 : "[Keypad <]", + 0xC6 : "[Keypad >]", + 0xC7 : "[Keypad &]", + 0xC8 : "[Keypad &&]", + 0xC9 : "[Keypad |]", + 0xCA : "[Keypad ||]", + 0xCB : "[Keypad :]", + 0xCC : "[Keypad #]", + 0xCD : "[Keypad Space]", + 0xCE : "[Keypad @]", + 0xCF : "[Keypad !]", + 0xD0 : "[Keypad Memory Store]", + 0xD1 : "[Keypad Memory Recall]", + 0xD2 : "[Keypad Memory Clear]", + 0xD3 : "[Keypad Memory Add]", + 0xD4 : "[Keypad Memory Subtract]", + 0xD5 : "[Keypad Memory Multiply]", + 0xD6 : "[Keypad Memory Divide]", + 0xD7 : "[Keypad +/-]", + 0xD8 : "[Keypad Clear]", + 0xD9 : "[Keypad Clear Entry]", + 0xDA : "[Keypad Binary]", + 0xDB : "[Keypad Octal]", + 0xDC : "[Keypad Decimal]", + 0xDD : "[Keypad Hexadecimal]", + 0xE0 : "[LeftControl]", + 0xE1 : "[LeftShift]", + 0xE2 : "[LeftAlt]", + 0xE3 : "[LeftWinKey]", + 0xE4 : "[RightControl]", + 0xE5 : "[RightShift]", + 0xE6 : "[RightAlt]", + 0xE7 : "[RightWinKey]" +} + +# some keycodes represent different things when Shift is held down +USBHID_SHIFT_MAP = { + 0x04 : "A", + 0x05 : "B", + 0x06 : "C", + 0x07 : "D", + 0x08 : "E", + 0x09 : "F", + 0x0A : "G", + 0x0B : "H", + 0x0C : "I", + 0x0D : "J", + 0x0E : "K", + 0x0F : "L", + 0x10 : "M", + 0x11 : "N", + 0x12 : "O", + 0x13 : "P", + 0x14 : "Q", + 0x15 : "R", + 0x16 : "S", + 0x17 : "T", + 0x18 : "U", + 0x19 : "V", + 0x1A : "W", + 0x1B : "X", + 0x1C : "Y", + 0x1D : "Z", + 0x1E : "!", + 0x1F : "@", + 0x20 : "#", + 0x21 : "$", + 0x22 : "%", + 0x23 : "^", + 0x24 : "&", + 0x25 : "*", + 0x26 : "(", + 0x27 : ")", + 0x2D : "_", + 0x2E : "+", + 0x2F : "{", + 0x30 : "}", + 0x31 : "|", + 0x32 : "~", + 0x33 : ":", + 0x34 : "\"", + 0x35 : "~", + 0x36 : "<", + 0x37 : ">", + 0x38 : "?", + 0x64 : "|" +} + +# global variable to track currently depressed keys +active_keys = [] + +def hid2ascii(scancode, shift): + ''' + Convert the specified scancode value to the ASCII equivalent using the + USBHID_MAP list. + ''' + if shift: + try: + code = USBHID_SHIFT_MAP[scancode] + return code + except KeyError: + pass + try: + code = USBHID_MAP[scancode] + except KeyError: + return "[Reserved]" + return code + +def usage(): + print >>sys.stderr, "Usage: btaptap [-r pcapfile.pcap | -e ellisysfile.csv] [-c count] [-h]\n" + sys.exit(0) + +def parse_l2cap_keydata(l2cappkt): + global active_keys + + TRANS_HDR_IN_DATA = 0xA1 + REPORT_ID_KEYBOARD = 0x01 + CTRL = 1 + SHIFT = 2 + ALT = 4 + GUI = 8 + + # Keyboard keystrokes are only seen in L2CAP packets at least 10 bytes long + l2clen = (ord(l2cappkt[1]) << 8) | ord(l2cappkt[0]) + if l2clen < 10: + return + + # Keyboard keystrokes are only carried by Channel ID >= 0x40 + cid = (ord(l2cappkt[3]) << 8) | ord(l2cappkt[2]) + if cid < 0x40: + return + # Ideally we would check for the particular CID for the HID_INTERRUPT + # channel, but we don't handle the negotiation (and may not have even + # seen it). + + # Transaction Header should indicate input data + thdr = ord(l2cappkt[4]) + if thdr != TRANS_HDR_IN_DATA: + return + + # Report ID should indicate this is a keyboard + rid = ord(l2cappkt[5]) + if rid != REPORT_ID_KEYBOARD: + return + + # This byte describes modifier key status (one bit per key) + mod = ord(l2cappkt[6]) + + # We don't care whether left or right modifier keys are pressed, so we + # combine the status bits. + leftmod = mod & 0x0f + rightmod = (mod & 0xf0) >> 4 + mod = leftmod | rightmod + + # up to six keys can be reported at once + keycodes = [] + #for byte in range(8,14): + for byte in range(8,11): + keystroke = ord(l2cappkt[byte]) + if keystroke != 0x00: + keycodes.append(keystroke) + + for keystroke in keycodes: + # don't repeat keys that are still held down + if active_keys.count(keystroke) == 0: + + if (mod & CTRL): + sys.stdout.write("CTRL^") + if (mod & ALT): + sys.stdout.write("ALT^") + if (mod & GUI): # e.g. Windows key + sys.stdout.write("GUI^") + + sys.stdout.write(hid2ascii(keystroke, mod & SHIFT)) + + active_keys = keycodes + +def parse_ellisys_export(exportfile): + try: + cap = open(exportfile, "r") + except (OSError, IOError) as e: + print >>sys.stderr, "Unable to open Ellisys capture file." + return + + # Check to make sure the CSV file header matches out expectations + hdr=cap.readline() + if (hdr != ELLISYS_CSV_HDR): + print >>sys.stderr, "Invalid CSV file (does not match Ellisys export format)" + return + + for packetline in cap.xreadlines(): + try: + (edepth, etime, ename, edata) = packetline.replace('"', '').strip().split(",") + except ValueError: + continue + + # We are only interedted in HID Input data + if (ename != ELLISYS_HID_INPUT): continue + + parse_ellisys_keydata(edata) + +def parse_ellisys_keydata(payload): + TRANS_HDR_IN_DATA = "\xA1" + DEST_CHANNEL_ID = "\x06\x03" + + # Convert space-separated hex into string + payload = payload.replace(' ','').decode("hex") + + # The Ellisys CSV file format doesn't give us the L2CAP data, so we fake it here by adding + # a 2-byte length field, destination CID, and transaction header + packet = chr(len(payload)+1) + "\x00" + DEST_CHANNEL_ID + TRANS_HDR_IN_DATA + payload + parse_l2cap_keydata(packet) + +def parse_bb_keydata(packet): + + BTBBHDR_TYPE_MASK = 0x78 + BTBBHDR_TYPE_SHIFT = 3 + BTBBHDR_TYPE_DM1 = 3 + BTBBPAYLOADHDR_LLID_MASK = 0x03 + BTBBPAYLOADHDR_LLID_SHIFT = 0 + BTBBPAYLOADHDR_LEN_MASK = 0xF8 + BTBBPAYLOADHDR_LEN_SHIFT = 3 + LLID_L2CAP = 2 + + # Keyboard keystrokes are only seen in frames at least 40 bytes long + if len(packet) < 40: + return + + # Keyboard keystrokes are only seen in DM1 frames + btbbhdr = packet[20:23] + type = (ord(btbbhdr[0]) & BTBBHDR_TYPE_MASK) >> BTBBHDR_TYPE_SHIFT + if type != BTBBHDR_TYPE_DM1: + return + + # Keyboard keystrokes are only seen in L2CAP packets 14 bytes long + btbbpayloadhdr = ord(packet[23]) + llid = btbbpayloadhdr & (BTBBPAYLOADHDR_LLID_MASK) >> BTBBPAYLOADHDR_LLID_SHIFT + l2clen = (btbbpayloadhdr & BTBBPAYLOADHDR_LEN_MASK) >> BTBBPAYLOADHDR_LEN_SHIFT + #print "Debug btbbpayloadhdr 0x%02x, llid %d, l2clen %d"%(btbbpayloadhdr, llid, l2clen) + if llid != LLID_L2CAP or l2clen < 14: + return + + parse_l2cap_keydata(packet[24:38]) + +def parse_hci_keydata(packet): + + HCI_TYPE_ACL_DATA = 2 + + # Keyboard keystrokes are only seen in frames at least 19 bytes long + if len(packet) < 19: + return + + # Keyboard keystrokes are only seen in ACL Data frames + type = ord(packet[0]) + if type != HCI_TYPE_ACL_DATA: + return + + parse_l2cap_keydata(packet[5:]) + +if __name__ == '__main__': + + arg_pcapfile = None + arg_ellisysfile = None + arg_count = -1 + packetcount = 0 + + while len(sys.argv) > 1: + op = sys.argv.pop(1) + if op == '-r': + arg_pcapfile = sys.argv.pop(1) + if op == '-c': + arg_count = int(sys.argv.pop(1)) + if op == '-e': + arg_ellisysfile = sys.argv.pop(1) + if op == '-h': + usage() + sys.exit(0) + + if (arg_ellisysfile == None and arg_pcapfile == None): + print >>sys.stderr, "Must specify a libpcap capture or an Ellisys CSV file" + usage() + sys.exit(0) + + if arg_pcapfile != None: + cap = PcapReader(arg_pcapfile) + + while arg_count != packetcount: + try: + (pheader, packet) = cap.pnext() + pkttime = pheader[0] + packetcount+=1 + + if cap.datalink() == DLT_EN10MB: + parse_bb_keydata(packet) + elif cap.datalink() == DLT_BLUETOOTH_HCI_H4: + parse_hci_keydata(packet) + else: + print >>sys.stderr, "Unsupported libpcap data link layer: %d\n" % cap.datalink() + except TypeError: # raised when pnext returns Null (end of capture) + break + + cap.close() + + if arg_ellisysfile != None: + parse_ellisys_export(arg_ellisysfile) + + print diff --git a/libbtbb-2015-10-R1/python/pcaptools/pcapdump/__init__.py b/libbtbb-2015-10-R1/python/pcaptools/pcapdump/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/libbtbb-2015-10-R1/python/pcaptools/pcapdump/pcapdump.py b/libbtbb-2015-10-R1/python/pcaptools/pcapdump/pcapdump.py new file mode 100644 index 0000000..647fc60 --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/pcapdump/pcapdump.py @@ -0,0 +1,193 @@ +# Copyright 2009 Joshua Wright +# +# This file is part of gr-bluetooth +# +# gr-bluetooth 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, or (at your option) +# any later version. +# +# gr-bluetooth 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 gr-bluetooth; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +import struct +import time + +PCAPH_MAGIC_NUM = 0xa1b2c3d4 +PCAPH_VER_MAJOR = 2 +PCAPH_VER_MINOR = 4 +PCAPH_THISZONE = 0 +PCAPH_SIGFIGS = 0 +PCAPH_SNAPLEN = 65535 + +class PcapReader: + + def __init__(self, savefile): + ''' + Opens the specified file, validates a libpcap header is present. + @type savefile: String + @param savefile: Input libpcap filename to open + @rtype: None + ''' + PCAPH_LEN = 24 + self.__fh = open(savefile, mode='rb') + self._pcaphsnaplen = 0 + header = self.__fh.read(PCAPH_LEN) + + # Read the first 4 bytes for the magic number, determine endianness + magicnum = struct.unpack("I", header[0:4])[0] + if magicnum != 0xd4c3b2a1: + # Little endian + self.__endflag = "<" + elif magicnum == 0xa1b2c3d4: + # Big endign + self.__endflag = ">" + else: + raise Exception('Specified file is not a libpcap capture') + + pcaph = struct.unpack("%sIHHIIII"%self.__endflag, header) + if pcaph[1] != PCAPH_VER_MAJOR and pcaph[2] != PCAPH_VER_MINOR \ + and pcaph[3] != PCAPH_THISZONE and pcaph[4] != PCAPH_SIGFIGS \ + and pcaph[5] != PCAPH_SNAPLEN: + raise Exception('Unsupported pcap header format or version') + + self._pcaphsnaplen = pcaph[5] + self._datalink = pcaph[6] + + def datalink(self): + return self._datalink + + def close(self): + ''' + Closes the output packet capture; wrapper for pcap_close(). + @rtype: None + ''' + self.pcap_close() + + def pcap_close(self): + ''' + Closes the output packet capture. + @rtype: None + ''' + self.__fh.close() + + def pnext(self): + ''' + Wrapper for pcap_next to mimic method for Daintree SNA + ''' + return self.pcap_next() + + def pcap_next(self): + ''' + Retrieves the next packet from the capture file. Returns a list of + [Hdr, packet] where Hdr is a list of [timestamp, snaplen, plen] and + packet is a string of the payload content. Returns None at the end + of the packet capture. + @rtype: List + ''' + # Read the next header block + PCAPH_RECLEN = 16 + rechdrdata = self.__fh.read(PCAPH_RECLEN) + + try: + rechdrtmp = struct.unpack("%sIIII"%self.__endflag, rechdrdata) + except struct.error: + return [None,None] + + rechdr = [ + float("%s.%s"%(rechdrtmp[0],rechdrtmp[1])), + rechdrtmp[2], + rechdrtmp[3] + ] + if rechdr[1] > rechdr[2] or rechdr[1] > self._pcaphsnaplen or rechdr[2] > self._pcaphsnaplen: + raise Exception('Corrupted or invalid libpcap record header (included length exceeds actual length)') + + # Read the included packet length + frame = self.__fh.read(rechdr[1]) + return [rechdr, frame] + + +class PcapDumper: + + def __init__(self, datalink, savefile): + ''' + Creates a libpcap file using the specified datalink type. + @type datalink: Integer + @param datalink: Datalink type, one of DLT_* defined in pcap-bpf.h + @type savefile: String + @param savefile: Output libpcap filename to open + @rtype: None + ''' + self.__fh = open(savefile, mode='wb') + self.__fh.write(''.join([ + struct.pack("I", PCAPH_MAGIC_NUM), + struct.pack("H", PCAPH_VER_MAJOR), + struct.pack("H", PCAPH_VER_MINOR), + struct.pack("I", PCAPH_THISZONE), + struct.pack("I", PCAPH_SIGFIGS), + struct.pack("I", PCAPH_SNAPLEN), + struct.pack("I", datalink) + ])) + + def pcap_dump(self, packet, ts_sec=None, ts_usec=None, orig_len=None): + ''' + Appends a new packet to the libpcap file. Optionally specify ts_sec + and tv_usec for timestamp information, otherwise the current time is + used. Specify orig_len if your snaplen is smaller than the entire + packet contents. + @type ts_sec: Integer + @param ts_sec: Timestamp, number of seconds since Unix epoch. Default + is the current timestamp. + @type ts_usec: Integer + @param ts_usec: Timestamp microseconds. Defaults to current timestamp. + @type orig_len: Integer + @param orig_len: Length of the original packet, used if the packet you + are writing is smaller than the original packet. Defaults to the + specified packet's length. + @type packet: String + @param packet: Packet contents + @rtype: None + ''' + + if ts_sec == None or ts_usec == None: + # There must be a better way here that I don't know -JW + s_sec, s_usec = str(time.time()).split(".") + ts_sec = int(s_sec) + ts_usec = int(s_usec) + + if orig_len == None: + orig_len = len(packet) + + plen = len(packet) + + self.__fh.write(''.join([ + struct.pack("I", ts_sec), + struct.pack("I", ts_usec), + struct.pack("I", orig_len), + struct.pack("I", plen), + packet + ])) + + return + + + def close(self): + ''' + Closes the output packet capture; wrapper for pcap_close(). + @rtype: None + ''' + self.pcap_close() + + def pcap_close(self): + ''' + Closed the output packet capture. + @rtype: None + ''' + self.__fh.close() diff --git a/libbtbb-2015-10-R1/python/pcaptools/setup.py b/libbtbb-2015-10-R1/python/pcaptools/setup.py new file mode 100755 index 0000000..bd7a928 --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/setup.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +""" +pcapdump setup + +Install script for pcapdump + +Usage: python setup.py install + +This file is part of libbtbb +Copyright 2012 Dominic Spill +""" + +from distutils.core import setup + +setup( + name = "pcapdump", + version = "0.8", + description = "A reader and dump utility for Pcap files", + author = "Joshua Wright", + url = "https://sourceforge.net/projects/libbtbb/", + license = "GPL", + packages = ['pcapdump'], + classifiers=[ + 'Development Status :: 5 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU General Public License (GPL)', + 'Programming Language :: Python', + 'Operating System :: OS Independent', + 'Topic :: System :: Networking :: Monitoring', + ], +) diff --git a/libbtbb-2015-10-R1/python/pcaptools/setup.py.in b/libbtbb-2015-10-R1/python/pcaptools/setup.py.in new file mode 100755 index 0000000..79196d0 --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/setup.py.in @@ -0,0 +1,32 @@ +#!/usr/bin/env python +""" +pcapdump setup + +Install script for pcapdump + +Usage: python setup.py install + +This file is part of libbtbb +Copyright 2012-2013 Dominic Spill +""" + +from distutils.core import setup + +setup( + name = "pcapdump", + description = "A reader and dump utility for Pcap files", + author = "Joshua Wright", + url = "https://sourceforge.net/projects/libbtbb/", + license = "GPL", + version = '${PACKAGE_VERSION}', + package_dir = { '': '${CMAKE_CURRENT_SOURCE_DIR}' }, + packages = ['pcapdump'], + classifiers=[ + 'Development Status :: 5 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU General Public License (GPL)', + 'Programming Language :: Python', + 'Operating System :: OS Independent', + 'Topic :: System :: Networking :: Monitoring', + ], +) diff --git a/libbtbb-2015-10-R1/python/pcaptools/tests/ellysis-keyboard.csv b/libbtbb-2015-10-R1/python/pcaptools/tests/ellysis-keyboard.csv new file mode 100644 index 0000000..3c53b2b --- /dev/null +++ b/libbtbb-2015-10-R1/python/pcaptools/tests/ellysis-keyboard.csv @@ -0,0 +1,866 @@ +"Depth","Time","Name","Data" +"0","7.248613000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","7.249863000","HID Input 1","01 00 00 28 00 00 00 00 00" +"0","7.251113000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","10.646359000","HID Input 1","01 00 00 28 00 00 00 00 00" +"0","10.658858750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","10.681358750","HID Input 1","01 00 00 28 00 00 00 00 00" +"0","10.758865000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","10.893876750","HID Input 1","01 00 00 28 00 00 00 00 00" +"0","10.983884250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","12.558997750","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","13.009032500","HID Input 1","01 02 00 08 00 00 00 00 00" +"0","13.144044625","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","13.189048625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","13.324059500","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","13.414067500","HID Input 1","01 00 00 11 17 00 00 00 00" +"0","13.459070500","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","13.504074375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","13.549077875","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","13.594078750","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","13.684083375","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","13.729087500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","13.774091625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","13.864099125","HID Input 1","01 00 00 2C 17 00 00 00 00" +"0","13.865349125","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","13.954107375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","13.955357375","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","13.999108000","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","14.044112125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","14.089117000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","14.134119250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","14.269131375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","14.270381375","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","14.404141250","HID Input 1","01 02 00 17 00 00 00 00 00" +"0","14.449145125","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","14.584155625","HID Input 1","01 02 00 06 00 00 00 00 00" +"0","14.674164250","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","14.675414250","HID Input 1","01 02 00 13 00 00 00 00 00" +"0","14.809176000","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","14.854179250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","14.855429250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","14.944184000","HID Input 1","01 00 00 2C 16 00 00 00 00" +"0","14.989186250","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","15.034189500","HID Input 1","01 00 00 16 08 00 00 00 00" +"0","15.079194375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","15.169201125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","15.214205250","HID Input 1","01 00 00 14 00 00 00 00 00" +"0","15.349217625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","15.350467625","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","15.394222125","HID Input 1","01 00 00 18 08 00 00 00 00" +"0","15.439224500","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","15.484228000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","15.619238750","HID Input 1","01 00 00 11 06 00 00 00 00" +"0","15.620488750","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","15.709246125","HID Input 1","01 00 00 06 08 00 00 00 00" +"0","15.710496125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","15.754250625","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","15.799253375","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","15.844256875","HID Input 1","01 00 00 2C 11 00 00 00 00" +"0","15.889262250","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","15.934265375","HID Input 1","01 00 00 11 18 00 00 00 00" +"0","15.979269125","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","16.024272875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","16.114280375","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","16.249286750","HID Input 1","01 00 00 10 05 00 00 00 00" +"0","16.294289875","HID Input 1","01 00 00 05 00 00 00 00 00" +"0","16.295540000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","16.384296125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","16.474304000","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","16.519306375","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","16.564310750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","16.834333625","HID Input 1","01 20 00 00 00 00 00 00 00" +"0","16.924341375","HID Input 1","01 20 00 33 00 00 00 00 00" +"0","17.014348625","HID Input 1","01 00 00 33 00 00 00 00 00" +"0","17.059353250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","17.194365625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","17.329375625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","17.330625625","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","17.419381000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","17.420631000","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","17.509384500","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","17.510634375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","17.554388500","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","17.599393125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","17.689399750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","17.734403750","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","17.869416125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","17.870666125","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","17.959421875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","18.004424875","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","18.184440500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","18.185690625","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","18.274448625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","18.319453375","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","18.409461000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","18.454464375","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","18.544471500","HID Input 1","01 00 00 06 12 00 00 00 00" +"0","18.545721500","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","18.634478875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","18.724483000","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","18.814490375","HID Input 1","01 00 00 0F 2C 00 00 00 00" +"0","18.859493750","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","18.949501375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","18.994505500","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","19.129516125","HID Input 1","01 00 00 18 16 00 00 00 00" +"0","19.130766250","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","19.219524125","HID Input 1","01 00 00 16 08 00 00 00 00" +"0","19.220773875","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","19.309531000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","19.354534125","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","19.444542000","HID Input 1","01 00 00 16 2C 00 00 00 00" +"0","19.445792000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","19.579553625","HID Input 1","01 00 00 2C 16 00 00 00 00" +"0","19.580803625","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","19.669561125","HID Input 1","01 00 00 16 08 00 00 00 00" +"0","19.714563625","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","19.759568375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","19.850826125","HID Input 1","01 00 00 14 00 00 00 00 00" +"0","19.939581000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","19.940831125","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","20.029584250","HID Input 1","01 00 00 18 08 00 00 00 00" +"0","20.074588375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","20.075838500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","20.164594500","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","20.209599125","HID Input 1","01 00 00 11 06 00 00 00 00" +"0","20.254602250","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","20.299605750","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","20.344609375","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","20.390862750","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","20.479621250","HID Input 1","01 00 00 2C 11 00 00 00 00" +"0","20.480871250","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","20.524623750","HID Input 1","01 00 00 11 18 00 00 00 00" +"0","20.569627750","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","20.614630625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","20.659633750","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","20.794646250","HID Input 1","01 00 00 10 05 00 00 00 00" +"0","20.839650500","HID Input 1","01 00 00 05 00 00 00 00 00" +"0","20.840900375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","20.929658125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","20.974661000","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","21.019666125","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","21.109672625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","21.110922625","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","21.199678625","HID Input 1","01 00 00 16 2C 00 00 00 00" +"0","21.244683250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","21.289683500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","21.334685625","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","21.379689625","HID Input 1","01 00 00 17 12 00 00 00 00" +"0","21.424694000","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","21.425944125","HID Input 1","01 00 00 12 2C 00 00 00 00" +"0","21.514699625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","21.515949625","HID Input 1","01 00 00 2C 04 00 00 00 00" +"0","21.604709125","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","21.605959125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","21.694713500","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","21.784722750","HID Input 1","01 00 00 06 0E 00 00 00 00" +"0","21.785972625","HID Input 1","01 00 00 0E 00 00 00 00 00" +"0","21.829726625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","22.009742500","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","22.010992625","HID Input 1","01 00 00 11 12 00 00 00 00" +"0","22.054743875","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","22.144752500","HID Input 1","01 00 00 12 1A 00 00 00 00" +"0","22.146002500","HID Input 1","01 00 00 1A 00 00 00 00 00" +"0","22.189756125","HID Input 1","01 00 00 1A 08 00 00 00 00" +"0","22.191006125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","22.234757000","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","22.414772750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","22.416022875","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","22.549782750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","23.269841500","HID Input 1","01 00 00 0A 00 00 00 00 00" +"0","23.359849625","HID Input 1","01 00 00 0A 08 00 00 00 00" +"0","23.404853625","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","23.494860375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","23.629872625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","23.764884000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","23.809888500","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","23.899893375","HID Input 1","01 00 00 17 0B 00 00 00 00" +"0","23.901143375","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","23.944895500","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","23.989898500","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","24.034901500","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","24.036151500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","24.079906625","HID Input 1","01 00 00 2C 15 00 00 00 00" +"0","24.169913375","HID Input 1","01 00 00 2C 15 08 00 00 00" +"0","24.171163250","HID Input 1","01 00 00 2C 08 00 00 00 00" +"0","24.214916375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","24.216166375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","24.259920750","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","24.394933000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","24.439935000","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","24.574946625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","24.619951625","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","24.754963125","HID Input 1","01 00 00 13 17 00 00 00 00" +"0","24.756213125","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","24.844968875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","24.979979750","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","25.024984125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","25.610031625","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","25.700039125","HID Input 1","01 00 00 12 09 00 00 00 00" +"0","25.745042375","HID Input 1","01 00 00 09 00 00 00 00 00" +"0","25.790047750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","25.880054250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","26.015066000","HID Input 1","01 00 00 2C 07 00 00 00 00" +"0","26.016316000","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","26.105073000","HID Input 1","01 00 00 07 04 00 00 00 00" +"0","26.150076625","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","26.240083250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","26.330091750","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","26.375095000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","26.465100250","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","26.555108125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","26.600111000","HID Input 1","01 00 00 37 00 00 00 00 00" +"0","26.690120000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","26.735123625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","26.825130625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","26.915137500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","26.960140750","HID Input 1","01 02 00 2C 00 00 00 00 00" +"0","27.005146375","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","27.095152500","HID Input 1","01 02 00 0C 00 00 00 00 00" +"0","27.140156250","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","27.185160250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","27.230164000","HID Input 1","01 00 00 09 00 00 00 00 00" +"0","27.275166750","HID Input 1","01 00 00 09 2C 00 00 00 00" +"0","27.276416875","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","27.365174625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","27.366424625","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","27.410178500","HID Input 1","01 00 00 17 0B 00 00 00 00" +"0","27.455182125","HID Input 1","01 00 00 17 0B 08 00 00 00" +"0","27.456432125","HID Input 1","01 00 00 08 0B 00 00 00 00" +"0","27.500184375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","27.545187375","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","27.546437375","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","27.635196750","HID Input 1","01 00 00 2C 04 00 00 00 00" +"0","27.680197375","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","27.725198625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","27.815207125","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","27.860210750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","27.950218375","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","28.040226500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","28.085229750","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","28.220240875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","28.221490750","HID Input 1","01 00 00 0E 00 00 00 00 00" +"0","28.400254625","HID Input 1","01 00 00 0E 08 00 00 00 00" +"0","28.445259750","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","28.446509750","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","28.535264375","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","28.536514250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","28.580269250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","28.715280625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","28.716530750","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","28.805287875","HID Input 137","89 CA 52 04 12 00 00 00 00" +"0","28.850291125","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","28.851541125","HID Input 1","01 00 00 12 18 00 00 00 00" +"0","28.895294250","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","28.985298125","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","29.030302250","HID Input 1","01 00 00 0F 07 00 00 00 00" +"0","29.120309375","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","29.121559375","HID Input 1","01 00 00 07 2C 00 00 00 00" +"0","29.165310625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","29.210314625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","29.211564625","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","29.256569625","HID Input 1","01 00 00 13 15 00 00 00 00" +"0","29.300324125","HID Input 1","01 00 00 13 15 08 00 00 00" +"0","29.345327500","HID Input 1","01 00 00 13 08 00 00 00 00" +"0","29.390330125","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","29.391580000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","29.480336875","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","29.525340750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","29.570344125","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","29.615347125","HID Input 1","01 00 00 0C 06 00 00 00 00" +"0","29.705355375","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","29.706605375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","29.795362750","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","29.885371250","HID Input 1","01 00 00 17 2C 00 00 00 00" +"0","29.886621250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","29.975376500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","30.021631000","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","30.065381000","HID Input 1","01 00 00 17 0B 00 00 00 00" +"0","30.066631000","HID Input 1","01 00 00 17 0B 08 00 00 00" +"0","30.110383625","HID Input 1","01 00 00 08 0B 00 00 00 00" +"0","30.111633625","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","30.155388250","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","30.156638250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","30.290395125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","30.650425125","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","30.740433125","HID Input 1","01 00 00 16 08 00 00 00 00" +"0","30.741683125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","30.830439500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","30.875442375","HID Input 1","01 00 00 14 00 00 00 00 00" +"0","30.965450250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","30.966700250","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","31.055458375","HID Input 1","01 00 00 18 08 00 00 00 00" +"0","31.056708375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","31.100461875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","31.190469125","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","31.235472500","HID Input 1","01 00 00 11 06 00 00 00 00" +"0","31.236722375","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","31.280477250","HID Input 1","01 00 00 06 08 00 00 00 00" +"0","31.325481000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","31.326731000","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","31.370482500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","31.460490375","HID Input 1","01 00 00 2C 11 00 00 00 00" +"0","31.461740375","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","31.550493750","HID Input 1","01 00 00 11 18 00 00 00 00" +"0","31.595498000","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","31.640501250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","31.685504375","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","31.820516875","HID Input 1","01 00 00 10 05 00 00 00 00" +"0","31.865519750","HID Input 1","01 00 00 05 00 00 00 00 00" +"0","31.866769750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","31.955528625","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","32.000532625","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","32.090540250","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","32.091790000","HID Input 1","01 00 00 15 2C 00 00 00 00" +"0","32.135542000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","32.180545000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","32.225548750","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","32.270553125","HID Input 1","01 00 00 12 09 00 00 00 00" +"0","32.315557250","HID Input 1","01 00 00 12 09 2C 00 00 00" +"0","32.360559375","HID Input 1","01 00 00 12 2C 00 00 00 00" +"0","32.361809375","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","32.450569375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","32.451819250","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","32.495570750","HID Input 1","01 00 00 17 0B 00 00 00 00" +"0","32.540573375","HID Input 1","01 00 00 17 0B 08 00 00 00" +"0","32.541823375","HID Input 1","01 00 00 08 0B 00 00 00 00" +"0","32.585578375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","32.586828500","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","32.630580250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","32.675584750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","32.765592000","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","32.810591375","HID Input 1","01 00 00 13 04 00 00 00 00" +"0","32.900599250","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","32.901849250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","32.945604375","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","32.990608125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","33.035611125","HID Input 1","01 00 00 0E 00 00 00 00 00" +"0","33.125619250","HID Input 1","01 00 00 0E 08 00 00 00 00" +"0","33.170623500","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","33.171873500","HID Input 1","01 00 00 08 17 00 00 00 00" +"0","33.215623875","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","33.260627625","HID Input 1","01 00 00 17 2C 00 00 00 00" +"0","33.261877625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","33.395640500","HID Input 1","01 00 00 2C 05 00 00 00 00" +"0","33.396890500","HID Input 1","01 00 00 05 00 00 00 00 00" +"0","33.440643625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","33.485647375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","33.575654500","HID Input 1","01 00 00 08 0C 00 00 00 00" +"0","33.576904375","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","33.620658000","HID Input 1","01 00 00 0C 11 00 00 00 00" +"0","33.665661500","HID Input 1","01 00 00 0C 11 0A 00 00 00" +"0","33.666911500","HID Input 1","01 00 00 0A 11 00 00 00 00" +"0","33.755668250","HID Input 1","01 00 00 0A 00 00 00 00 00" +"0","33.756918125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","33.800673125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","33.845676250","HID Input 1","01 00 00 2C 16 00 00 00 00" +"0","33.890680625","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","33.935684125","HID Input 1","01 00 00 16 08 00 00 00 00" +"0","33.980687375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","34.025691500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","34.026941500","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","34.115695000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","34.116945000","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","34.205701875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","34.206951875","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","34.295709250","HID Input 1","01 00 00 2C 09 00 00 00 00" +"0","34.340712875","HID Input 1","01 00 00 09 00 00 00 00 00" +"0","34.385717250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","34.430721000","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","34.520728875","HID Input 1","01 00 00 15 12 00 00 00 00" +"0","34.521978750","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","34.565731750","HID Input 1","01 00 00 12 10 00 00 00 00" +"0","34.610734500","HID Input 1","01 00 00 12 10 2C 00 00 00" +"0","34.700742750","HID Input 1","01 00 00 12 2C 00 00 00 00" +"0","34.701992750","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","34.745747375","HID Input 1","01 00 00 2C 17 00 00 00 00" +"0","34.746997375","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","34.790748375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","34.791998250","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","34.835752125","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","34.925760250","HID Input 1","01 00 00 0B 08 2C 00 00 00" +"0","34.927010125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","35.060771625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","35.062021500","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","35.105775000","HID Input 1","01 00 00 00 70 20 06 2C 00" +"0","35.195782250","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","35.285790375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","35.330794375","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","35.375792625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","35.465801500","HID Input 1","01 00 00 0A 00 00 00 00 00" +"0","35.555808750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","35.600812000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","35.645815375","HID Input 1","01 00 00 08 17 00 00 00 00" +"0","35.690818625","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","35.735823875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","35.737074000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","35.825830875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","35.870835125","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","35.915839250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","35.960841500","HID Input 1","01 00 00 1C 00 00 00 00 00" +"0","36.005846000","HID Input 1","01 00 00 1C 16 00 00 00 00" +"0","36.050850500","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","36.095853625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","36.140856625","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","36.230864750","HID Input 1","01 00 00 17 08 00 00 00 00" +"0","36.232114750","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","36.275867250","HID Input 1","01 00 00 08 10 00 00 00 00" +"0","36.320869875","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","36.365874125","HID Input 1","01 00 00 10 2C 00 00 00 00" +"0","36.410877625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","36.500885125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","36.502135125","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","36.545889500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","36.590893875","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","36.635894625","HID Input 1","01 00 00 12 2C 00 00 00 00" +"0","36.680895625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","36.682145625","HID Input 1","01 00 00 2C 17 00 00 00 00" +"0","36.725899500","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","36.770904625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","36.815908250","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","36.860910750","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","36.905914625","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","36.907164500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","36.950917500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","36.995921250","HID Input 1","01 00 00 2C 15 00 00 00 00" +"0","37.040924750","HID Input 1","01 00 00 2C 15 08 00 00 00" +"0","37.085929000","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","37.087179000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","37.130933125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","37.220940750","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","37.265944250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","37.310947000","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","37.355951750","HID Input 1","01 00 00 0F 2C 00 00 00 00" +"0","37.445958625","HID Input 1","01 00 00 0F 2C 16 00 00 00" +"0","37.447208625","HID Input 1","01 00 00 16 2C 00 00 00 00" +"0","37.490961375","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","37.535965375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","37.580968750","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","37.625971750","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","37.670975375","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","37.672225500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","37.760984625","HID Input 1","01 00 00 19 00 00 00 00 00" +"0","37.805989000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","37.850992125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","37.940995250","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","37.985997750","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","37.987247625","HID Input 1","01 00 00 15 2C 00 00 00 00" +"0","38.031002125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","38.121009750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","38.122259750","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","38.166013250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","38.167263250","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","38.256020625","HID Input 1","01 00 00 18 15 00 00 00 00" +"0","38.302274625","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","38.346028500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","38.391031375","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","38.436035125","HID Input 1","01 00 00 0C 11 00 00 00 00" +"0","38.481040125","HID Input 1","01 00 00 0C 11 0A 00 00 00" +"0","38.482290125","HID Input 1","01 00 00 0C 11 0A 2C 00 00" +"0","38.526041625","HID Input 1","01 00 00 0C 11 2C 00 00 00" +"0","38.527291500","HID Input 1","01 00 00 2C 11 00 00 00 00" +"0","38.571045500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","38.616049125","HID Input 1","01 00 00 2C 17 00 00 00 00" +"0","38.617299125","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","38.661052375","HID Input 1","01 00 00 17 0B 00 00 00 00" +"0","38.706055375","HID Input 1","01 00 00 17 0B 08 00 00 00" +"0","38.707306500","HID Input 1","01 00 00 08 0B 00 00 00 00" +"0","38.751058750","HID Input 1","01 00 00 08 0B 2C 00 00 00" +"0","38.796062750","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","38.797312875","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","38.886069250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","38.931073625","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","38.976077250","HID Input 1","01 00 00 0C 11 00 00 00 00" +"0","39.066085000","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","39.156092000","HID Input 1","01 00 00 11 0C 00 00 00 00" +"0","39.157342000","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","39.246096250","HID Input 1","01 00 00 0C 17 00 00 00 00" +"0","39.247346125","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","39.291099375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","39.336103000","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","39.426111000","HID Input 1","01 00 00 0C 04 00 00 00 00" +"0","39.427361000","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","39.516119250","HID Input 1","01 00 00 04 0F 00 00 00 00" +"0","39.517369250","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","39.606125250","HID Input 1","01 00 00 0F 2C 00 00 00 00" +"0","39.607375250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","39.651128500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","39.741136750","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","39.831143875","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","39.876147375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","39.921152375","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","39.966155750","HID Input 1","01 00 00 11 07 00 00 00 00" +"0","40.056163750","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","40.057413750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","40.146169625","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","40.236177500","HID Input 1","01 00 00 16 0B 00 00 00 00" +"0","40.237427500","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","40.327434250","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","40.461194250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","40.506195750","HID Input 1","01 00 00 0E 00 00 00 00 00" +"0","40.597453125","HID Input 1","01 00 00 0E 08 00 00 00 00" +"0","40.641202375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","40.731211125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","40.866222125","HID Input 1","01 00 00 36 00 00 00 00 00" +"0","40.956230125","HID Input 1","01 00 00 36 2C 00 00 00 00" +"0","41.001234000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","41.091241000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","41.226251750","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","41.316260625","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","41.317510625","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","41.361262875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","41.406265375","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","41.496272500","HID Input 1","01 00 00 2C 06 00 00 00 00" +"0","41.497522625","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","41.541277000","HID Input 1","01 00 00 06 12 00 00 00 00" +"0","41.586280625","HID Input 1","01 00 00 06 12 18 00 00 00" +"0","41.587530750","HID Input 1","01 00 00 18 12 00 00 00 00" +"0","41.631283125","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","41.721291500","HID Input 1","01 00 00 18 0F 00 00 00 00" +"0","41.722541500","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","41.766292625","HID Input 1","01 00 00 0F 07 00 00 00 00" +"0","41.811293250","HID Input 1","01 00 00 0F 07 2C 00 00 00" +"0","41.812543250","HID Input 1","01 00 00 0F 2C 00 00 00 00" +"0","41.856297750","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","41.946305125","HID Input 1","01 00 00 2C 06 00 00 00 00" +"0","41.947555125","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","42.037562000","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","42.081317000","HID Input 1","01 00 00 12 10 00 00 00 00" +"0","42.171324125","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","42.216328625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","42.261330625","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","42.351339750","HID Input 1","01 00 00 13 0F 00 00 00 00" +"0","42.396343375","HID Input 1","01 00 00 13 0F 08 00 00 00" +"0","42.441346125","HID Input 1","01 00 00 08 0F 00 00 00 00" +"0","42.486349500","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","42.487599500","HID Input 1","01 00 00 08 17 00 00 00 00" +"0","42.531352875","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","42.576356000","HID Input 1","01 00 00 17 08 00 00 00 00" +"0","42.621359000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","42.666363000","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","42.711367125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","42.756371250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","42.757621250","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","42.801376000","HID Input 1","01 00 00 17 0B 00 00 00 00" +"0","42.891383500","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","42.892633500","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","42.936384375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","42.937634250","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","42.981389000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","43.071391375","HID Input 1","01 00 00 2C 13 00 00 00 00" +"0","43.072641375","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","43.161397250","HID Input 1","01 00 00 13 15 00 00 00 00" +"0","43.162647250","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","43.206403125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","43.251407000","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","43.296409250","HID Input 1","01 00 00 12 06 00 00 00 00" +"0","43.386418125","HID Input 1","01 00 00 01 01 01 01 01 01" +"0","43.521429125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","43.522679000","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","43.611434875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","43.701442750","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","43.746447250","HID Input 1","01 00 00 16 2C 00 00 00 00" +"0","43.791449250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","43.881458500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","43.926462125","HID Input 1","01 00 00 05 00 00 00 00 00" +"0","43.971464750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","43.972714875","HID Input 1","01 00 00 1C 00 00 00 00 00" +"0","44.061472625","HID Input 1","01 00 00 1C 2C 00 00 00 00" +"0","44.106478000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","44.151481875","HID Input 1","01 00 00 2C 16 00 00 00 00" +"0","44.197735250","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","44.241489250","HID Input 1","01 00 00 16 08 00 00 00 00" +"0","44.242739250","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","44.286490000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","44.331490375","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","44.376494750","HID Input 1","01 00 00 11 07 00 00 00 00" +"0","44.421498625","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","44.466501000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","44.511505000","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","44.556509375","HID Input 1","01 00 00 0C 11 00 00 00 00" +"0","44.646516375","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","44.691520375","HID Input 1","01 00 00 11 0A 00 00 00 00" +"0","44.692770500","HID Input 1","01 00 00 0A 00 00 00 00 00" +"0","44.736524875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","44.826532500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","44.961543750","HID Input 1","01 00 00 2C 04 00 00 00 00" +"0","44.962793625","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","45.096553625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","45.097803625","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","45.186561250","HID Input 1","01 00 00 11 2C 00 00 00 00" +"0","45.231566000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","45.232815875","HID Input 1","01 00 00 2C 04 00 00 00 00" +"0","45.276568500","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","45.321572375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","45.411580125","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","45.501587625","HID Input 1","01 00 00 06 0E 00 00 00 00" +"0","45.502837625","HID Input 1","01 00 00 0E 00 00 00 00 00" +"0","45.546591000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","45.681598375","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","45.771605625","HID Input 1","01 00 00 11 12 00 00 00 00" +"0","45.816608750","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","45.861612250","HID Input 1","01 00 00 1A 00 00 00 00 00" +"0","45.951621250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","45.996624125","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","46.041626750","HID Input 1","01 00 00 0F 08 00 00 00 00" +"0","46.086630500","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","46.131635875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","46.176639250","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","46.266646625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","46.356654375","HID Input 1","01 00 00 0A 00 00 00 00 00" +"0","46.446661000","HID Input 1","01 00 00 0A 08 00 00 00 00" +"0","46.491665000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","46.536668125","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","46.581671750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","46.626677000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","46.716683375","HID Input 1","01 00 00 08 11 00 00 00 00" +"0","46.717933375","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","46.806691875","HID Input 1","01 00 00 11 17 00 00 00 00" +"0","46.807942000","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","46.896693500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","46.941697625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","47.031705000","HID Input 1","01 00 00 2C 13 00 00 00 00" +"0","47.032955125","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","47.121712625","HID Input 1","01 00 00 13 04 00 00 00 00" +"0","47.211720625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","47.257972500","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","47.346731500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","47.347981500","HID Input 1","01 00 00 0E 00 00 00 00 00" +"0","47.481743250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","47.482993250","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","47.526745000","HID Input 1","01 00 00 08 17 00 00 00 00" +"0","47.571747750","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","47.616752750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","47.618002625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","47.751763625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","47.753013625","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","47.841771250","HID Input 1","01 02 00 25 00 00 00 00 00" +"0","47.976783000","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","48.246801750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","48.606832750","HID Input 1","01 00 00 2A 00 00 00 00 00" +"0","48.786848750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","48.876855500","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","49.011866500","HID Input 1","01 02 00 26 00 00 00 00 00" +"0","49.146879125","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","49.236886750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","49.371897125","HID Input 1","01 00 00 1A 00 00 00 00 00" +"0","49.461902125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","49.506905750","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","49.551908500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","49.596913250","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","49.641917250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","49.686919375","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","49.731923125","HID Input 1","01 00 00 0B 2C 00 00 00 00" +"0","49.821930625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","49.823180750","HID Input 1","01 00 00 2C 17 00 00 00 00" +"0","49.866936000","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","49.911939750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","49.913189750","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","49.956941750","HID Input 1","01 00 00 0B 08 00 00 00 00" +"0","50.001945000","HID Input 1","01 00 00 0B 08 2C 00 00 00" +"0","50.003194750","HID Input 1","01 00 00 2C 08 00 00 00 00" +"0","50.046949875","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","50.136957125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","50.183211125","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","50.226962625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","50.271965625","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","50.361975125","HID Input 1","01 00 00 12 15 00 00 00 00" +"0","50.406978625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","50.541989125","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","50.543239125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","50.631998250","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","50.677001500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","50.767003000","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","50.857010125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","50.948268375","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","51.037021125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","51.038271125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","51.172032125","HID Input 1","01 00 00 2C 16 00 00 00 00" +"0","51.217036750","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","51.218286625","HID Input 1","01 00 00 16 08 00 00 00 00" +"0","51.262039000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","51.352046625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","51.397049375","HID Input 1","01 00 00 14 00 00 00 00 00" +"0","51.487058500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","51.532061875","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","51.577066000","HID Input 1","01 00 00 18 08 00 00 00 00" +"0","51.622069125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","51.667073000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","51.712076250","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","51.802084625","HID Input 1","01 00 00 11 06 00 00 00 00" +"0","51.847088000","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","51.892091125","HID Input 1","01 00 00 06 08 00 00 00 00" +"0","51.893341250","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","51.982098250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","51.983348375","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","52.072100750","HID Input 1","01 00 00 2C 11 00 00 00 00" +"0","52.117105250","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","52.162109125","HID Input 1","01 00 00 11 18 00 00 00 00" +"0","52.207111750","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","52.252116125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","52.342123375","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","52.432130625","HID Input 1","01 00 00 10 05 00 00 00 00" +"0","52.477135375","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","52.478385250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","52.567143250","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","52.612147125","HID Input 1","01 00 00 08 15 00 00 00 00" +"0","52.657151250","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","52.747158125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","52.837166000","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","53.467215875","HID Input 1","01 02 00 26 00 00 00 00 00" +"0","53.468465875","HID Input 1","01 02 00 26 27 00 00 00 00" +"0","53.512220250","HID Input 1","01 02 00 26 00 00 00 00 00" +"0","53.557222375","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","53.872250500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","54.007262250","HID Input 1","01 00 00 2A 00 00 00 00 00" +"0","54.142273375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","54.277285625","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","54.457299750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","54.502303750","HID Input 1","01 00 00 2A 00 00 00 00 00" +"0","54.637311625","HID Input 1","01 02 00 2A 00 00 00 00 00" +"0","54.638561625","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","54.773573375","HID Input 1","01 02 00 27 00 00 00 00 00" +"0","54.862331375","HID Input 1","01 02 00 00 00 00 00 00 00" +"0","55.042347000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","55.222360250","HID Input 1","01 00 00 36 00 00 00 00 00" +"0","55.312369125","HID Input 1","01 00 00 36 2C 00 00 00 00" +"0","55.402376500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","55.492384125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","55.493634125","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","55.582389375","HID Input 1","01 00 00 04 11 00 00 00 00" +"0","55.627393375","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","55.672398250","HID Input 1","01 00 00 11 07 00 00 00 00" +"0","55.673648250","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","55.762406250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","55.763656000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","55.942415000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","55.943665000","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","55.987417000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","56.077425250","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","56.167432250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","56.302444625","HID Unknown","" +"0","56.392451875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","56.437456375","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","56.527463625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","56.662474625","HID Input 1","01 00 00 05 00 00 00 00 00" +"0","56.707480000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","56.708729875","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","56.797485375","HID Input 1","01 00 00 0F 0C 00 00 00 00" +"0","56.842489625","HID Input 1","01 00 00 0F 00 00 00 00 00" +"0","56.887493250","HID Input 1","01 00 00 0F 16 00 00 00 00" +"0","56.888743250","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","56.977502000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","57.022503625","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","57.067507500","HID Input 1","01 00 00 0B 2C 00 00 00 00" +"0","57.112511500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","57.157510875","HID Input 1","01 00 00 2C 04 00 00 00 00" +"0","57.158760750","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","57.247519000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","57.292522125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","57.382531000","HID Input 1","01 00 00 2C 06 00 00 00 00" +"0","57.517541500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","57.518791500","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","57.607548750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","57.652552250","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","57.742559750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","57.832567250","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","57.877572375","HID Input 1","01 00 00 11 08 00 00 00 00" +"0","57.922575875","HID Input 1","01 00 00 11 00 00 00 00 00" +"0","57.967580250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","58.012583250","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","58.102590750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","58.192599000","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","58.282606625","HID Input 1","01 00 00 17 0C 00 00 00 00" +"0","58.327609125","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","58.372612500","HID Input 1","01 00 00 0C 12 00 00 00 00" +"0","58.373862500","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","58.462618125","HID Input 1","01 00 00 12 11 00 00 00 00" +"0","58.507622375","HID Input 1","01 00 00 12 11 2C 00 00 00" +"0","58.508872375","HID Input 1","01 00 00 2C 11 00 00 00 00" +"0","58.552624250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","58.597627500","HID Input 1","01 00 00 2C 04 00 00 00 00" +"0","58.642631250","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","58.687634750","HID Input 1","01 00 00 04 13 00 00 00 00" +"0","58.688884625","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","58.732638750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","58.822646125","HID Input 1","01 00 00 13 00 00 00 00 00" +"0","58.912654125","HID Input 1","01 00 00 13 08 00 00 00 00" +"0","59.002661500","HID Input 1","01 00 00 13 08 04 00 00 00" +"0","59.003911500","HID Input 1","01 00 00 13 04 00 00 00 00" +"0","59.047665000","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","59.092668625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","59.137671250","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","59.227679750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","59.272683500","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","59.407694500","HID Input 1","01 00 00 0C 11 0A 00 00 00" +"0","59.452698250","HID Input 1","01 00 00 0A 11 00 00 00 00" +"0","59.453948250","HID Input 1","01 00 00 0A 00 00 00 00 00" +"0","59.497703125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","59.498953125","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","59.632713000","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","59.633963000","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","59.722715250","HID Input 1","01 00 00 17 12 00 00 00 00" +"0","59.723965250","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","59.767718375","HID Input 1","01 00 00 12 2C 00 00 00 00" +"0","59.857727375","HID Input 1","01 00 00 12 2C 05 00 00 00" +"0","59.902730250","HID Input 1","01 00 00 05 2C 00 00 00 00" +"0","59.903980250","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","59.947732125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","59.992735500","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","60.037739000","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","60.082743625","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","60.172751000","HID Input 1","01 00 00 2C 09 00 00 00 00" +"0","60.174001000","HID Input 1","01 00 00 09 00 00 00 00 00" +"0","60.262759500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","60.307763625","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","60.397771000","HID Input 1","01 00 00 15 12 00 00 00 00" +"0","60.399021000","HID Input 1","01 00 00 12 00 00 00 00 00" +"0","60.442772250","HID Input 1","01 00 00 12 10 00 00 00 00" +"0","60.487776000","HID Input 1","01 00 00 12 10 2C 00 00 00" +"0","60.577784000","HID Input 1","01 00 00 12 2C 00 00 00 00" +"0","60.579033875","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","60.622788500","HID Input 1","01 00 00 2C 17 00 00 00 00" +"0","60.624038625","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","60.667791250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","60.712794375","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","60.714044500","HID Input 1","01 00 00 08 0B 00 00 00 00" +"0","60.802801875","HID Input 1","01 00 00 08 0B 2C 00 00 00" +"0","60.804052000","HID Input 1","01 00 00 08 2C 00 00 00 00" +"0","60.847804000","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","60.937812125","HID Input 1","01 00 00 2C 17 00 00 00 00" +"0","60.939062375","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","60.982813125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","61.072820000","HID Input 1","01 00 00 15 00 00 00 00 00" +"0","61.162828125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","61.207832375","HID Input 1","01 00 00 18 00 00 00 00 00" +"0","61.252834500","HID Input 1","01 00 00 18 16 00 00 00 00" +"0","61.344092625","HID Input 1","01 00 00 16 00 00 00 00 00" +"0","61.387843500","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","61.432846875","HID Input 1","01 00 00 17 00 00 00 00 00" +"0","61.522854875","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","61.567857750","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","61.657865625","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","61.702869375","HID Input 1","01 00 00 07 00 00 00 00 00" +"0","61.837880125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","62.332919500","HID Input 1","01 00 00 2C 00 00 00 00 00" +"0","62.422927500","HID Input 1","01 00 00 2C 10 00 00 00 00" +"0","62.424177500","HID Input 1","01 00 00 10 00 00 00 00 00" +"0","62.557937875","HID Input 1","01 00 00 10 04 00 00 00 00" +"0","62.602940875","HID Input 1","01 00 00 04 00 00 00 00 00" +"0","62.604190750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","62.692948750","HID Input 1","01 00 00 06 00 00 00 00 00" +"0","62.737952750","HID Input 1","01 00 00 06 0B 00 00 00 00" +"0","62.782957500","HID Input 1","01 00 00 0B 00 00 00 00 00" +"0","62.872964375","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","62.874214250","HID Input 1","01 00 00 0C 00 00 00 00 00" +"0","62.962971250","HID Input 1","01 00 00 0C 11 00 00 00 00" +"0","63.007974750","HID Input 1","01 00 00 0C 11 08 00 00 00" +"0","63.052978125","HID Input 1","01 00 00 08 11 00 00 00 00" +"0","63.054228125","HID Input 1","01 00 00 08 00 00 00 00 00" +"0","63.097981750","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","63.187990000","HID Input 1","01 00 00 37 00 00 00 00 00" +"0","63.323001250","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","63.593020125","HID Input 1","01 00 00 28 00 00 00 00 00" +"0","63.683028125","HID Input 1","01 00 00 00 00 00 00 00 00" +"0","63.773035125","HID Input 1","01 00 00 28 00 00 00 00 00" +"0","63.818038625","HID Input 1","01 00 00 00 00 00 00 00 00" diff --git a/libbtbb-2015-10-R1/python/utils/encode_sw.py b/libbtbb-2015-10-R1/python/utils/encode_sw.py new file mode 100755 index 0000000..6583abf --- /dev/null +++ b/libbtbb-2015-10-R1/python/utils/encode_sw.py @@ -0,0 +1,67 @@ +#!/usr/bin/python + +# produce a sync word for a given LAP + +lap = 0xffffff + +pn = 0x83848D96BBCC54FC + +# generator matrix for (64,30) linear block code +# based on polynomial 0260534236651 +# (see gen_check_tables.py for automatic generation) +g = ( + 0x8000000000000001, + 0x40000002c2b89ed4, + 0x20000001615c4f6a, + 0x10000000b0ae27b5, + 0x080000029aef8d0e, + 0x040000014d77c687, + 0x0200000264037d97, + 0x01000003f0b9201f, + 0x008000033ae40edb, + 0x004000035fca99b9, + 0x002000036d5dd208, + 0x00100001b6aee904, + 0x00080000db577482, + 0x000400006dabba41, + 0x00020002f46d43f4, + 0x000100017a36a1fa, + 0x00008000bd1b50fd, + 0x000040029c3536aa, + 0x000020014e1a9b55, + 0x0000100265b5d37e, + 0x0000080132dae9bf, + 0x000004025bd5ea0b, + 0x00000203ef526bd1, + 0x000001033511ab3c, + 0x000000819a88d59e, + 0x00000040cd446acf, + 0x00000022a41aabb3, + 0x0000001390b5cb0d, + 0x0000000b0ae27b52, + 0x0000000585713da9) + +def encode(data): + assert data < 2**30 + codeword = 0 + for i in range(30): + if (data & (0x20000000 >> i)): + codeword ^= g[i] + return codeword + +# append barker code +if (lap & 0x800000): + data = 0x13000000 | lap +else: + data = 0x2c000000 | lap + +# scramble +data ^= (pn >> 34) + +# encode +codeword = encode(data) + +# scramble again +syncword = codeword ^ pn + +print "0x%06x 0x%016x 0x%016x" % (lap, codeword, syncword) diff --git a/libbtbb-2015-10-R1/python/utils/gen_barker_correct.py b/libbtbb-2015-10-R1/python/utils/gen_barker_correct.py new file mode 100755 index 0000000..f428def --- /dev/null +++ b/libbtbb-2015-10-R1/python/utils/gen_barker_correct.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +# Reverse the binary of thesebarker codes for the host code +barkers = (0x0d, 0x72) +distances = [] +corrections = [] + +def count_bits(x): + i = 0 + while x: + i += 1 + x &= x - 1 + return i + +for i in range(128): + diffs = [(count_bits(barkers[0] ^ i), barkers[0]), + (count_bits(barkers[1] ^ i), barkers[1])] + diffs.sort() + distances.append(diffs[0][0]) + corrections.append(diffs[0][1]) + +print "Barker distance:", distances +print "Barker correct:", ["0x%x" % c for c in corrections] diff --git a/libbtbb-2015-10-R1/python/utils/gen_check_tables.py b/libbtbb-2015-10-R1/python/utils/gen_check_tables.py new file mode 100755 index 0000000..0ae41df --- /dev/null +++ b/libbtbb-2015-10-R1/python/utils/gen_check_tables.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +# (64,30) linear block code stuff + +polynomial = 0260534236651 + +# produce generator matrix g +g = [] +for i in range(30): + g.append(polynomial << i) + for j in range(i): + if g[i] & (1 << (33 + i - j)): + g[i] ^= g[i-j-1] + +#print +#for i in range(29,-1,-1): + #print "0x%016x," % g[i] +#print + +# produce check matrix h +h = [] +for i in range(34): + h.append(0) + for j in range(30): + h[i] |= (g[29-j] >> i) & 0x1 + h[i] <<= 1 + h[i] <<= 33 + h[i] |= (0x1 << i) + +#print +#for i in range(34): + #print "0x%016x," % h[i] +#print + +# reverse the order +g = g[::-1] +h = h[::-1] + +def count_bits(n): + i = 0 + while n != 0: + n &= n - 1 + i += 1 + return i + +def gen_syndrome(c): + assert c < 2**64 + s = 0 + # look for a faster GF(2) matrix multiplication algorithm + for i in range(34): + s <<= 1 + s |= (count_bits(c & h[i]) % 2) + return s + +# optimized check table generation (sw_check_tables.h) +for shift in range(8): + for i in range(256): + print "0x%09x, " % gen_syndrome(i<<(shift*8)), + print diff --git a/libbtbb-2015-10-R1/python/utils/le_whitening.py b/libbtbb-2015-10-R1/python/utils/le_whitening.py new file mode 100755 index 0000000..6ce9a9b --- /dev/null +++ b/libbtbb-2015-10-R1/python/utils/le_whitening.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +num_channels = 40 +bits = [] +channels = {} +reg = 0x57 + +while not (len(bits) and reg==0x57): + if reg & 0x3f < num_channels and reg & 0x40: + channels[reg & 0x3f] = len(bits) + bit = (reg & 1) + bits.append(bit) + reg >>= 1 + reg |= (bit << 6) + reg ^= (bit << 2) + +print bits + +print "\nArray index:" +for k in sorted(channels.keys()): + print channels[k] diff --git a/libbtbb-2015-10-R1/tests/Makefile b/libbtbb-2015-10-R1/tests/Makefile new file mode 100644 index 0000000..b0f16ac --- /dev/null +++ b/libbtbb-2015-10-R1/tests/Makefile @@ -0,0 +1,36 @@ +# Copyright 2011 Michael Ossmann, Dominic Spill +# +# This file is part of Project Ubertooth. +# +# 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, 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +CC ?= gcc + +SOURCE_FILES = test_syndromes.c +LIBRARY_SOURCE = ../bluetooth_packet.c +BINARY_FILES = test_syndromes +HEADER_FILES = ../bluetooth_packet.h + +CFLAGS += -DHASH_FUNCTION=HASH_FNV -DHASH_EMIT_KEYS=3 + +all: test_packet + +test_packet: + $(CC) $(CFLAGS) $(CPPFLAGS) -O2 -Wall $(LIBRARY_SOURCE) $(SOURCE_FILES) -o $(BINARY_FILES) + +clean: + rm -f $(BINARY_FILES) + diff --git a/libbtbb-2015-10-R1/tests/test_fec23.c b/libbtbb-2015-10-R1/tests/test_fec23.c new file mode 100644 index 0000000..d886a44 --- /dev/null +++ b/libbtbb-2015-10-R1/tests/test_fec23.c @@ -0,0 +1,122 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2011 Dominic Spill, Michael Ossmann + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "../bluetooth_packet.h" +#include + +int test_unfec23() { + char *optr; + int i, j, ret, err; + ret = 0; + + printf("Testing unfec23\n"); + printf("---------------\n"); + + char input[20][15] = { + /* No errors */ + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1}, + /* Errors */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1} + }; + + char output[20][15] = { + /* No errors */ + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + /* Errors */ + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1} + }; + + for(i = 0; i < 20; i++) { + if (optr = unfec23(input[i], 1)) { + err = 0; + for(j = 0; j < 10; j++) { + if (optr[j] != output[i][j]) { + err = 1; + break; + } + } + if (err == 1) { + printf("E"); + ret++; + } + else + printf("."); + } else { + printf("F"); + ret++; + } + } + + if (ret > 0) + printf("%d errors\n", ret); + printf("\n--------------------\n"); + printf("Done testing unfec23\n"); + return ret; +} + +int main(int argc, char** argv) { + int ret = 0; + + ret += test_unfec23(); + + exit(ret); +} diff --git a/libbtbb-2015-10-R1/tests/test_header.c b/libbtbb-2015-10-R1/tests/test_header.c new file mode 100644 index 0000000..4988103 --- /dev/null +++ b/libbtbb-2015-10-R1/tests/test_header.c @@ -0,0 +1,118 @@ +/* -*- c -*- */ +/* + * Copyright 2012 Dominic Spill + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +/* +UAP Data HEC Header (octal) +---------------------------------- +00 123 e1 770007 007070 000777 +47 123 06 770007 007007 700000 +00 124 32 007007 007007 007700 +47 124 d5 007007 007070 707077 +00 125 5a 707007 007007 077070 +47 125 bd 707007 007070 777707 +00 126 e2 077007 007007 000777 +47 126 05 077007 007070 700000 +00 127 8a 777007 007007 070007 +47 127 6d 777007 007070 770770 +00 11b 9e 770770 007007 777007 +47 11b 79 770770 007070 077770 +00 11c 4d 007770 007070 770070 +47 11c aa 007770 007007 070707 +00 11d 25 707770 007070 700700 +47 11d c2 707770 007007 000077 +00 11e 9d 077770 007070 777007 +47 11e 7a 077770 007007 077770 +00 11f f5 777770 007070 707777 +47 11f 12 777770 007007 007000 +*/ + +#include "../bluetooth_packet_tx.h" +#include + +int test_gen_packet_header() { + char *optr; + int i, j, ret, err; + ret = 0; + + printf("Testing header\n"); + printf("---------------\n"); + + /* lt_addr, type, flow, arqn, seqn, UAP, HEC */ + uint8_t data[20][7] = { + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {} + UAP Data HE + ----------- + 00 123 e1 + 47 123 06 + 00 124 32 + 47 124 d5 + 00 125 5a + 47 125 bd + 00 126 e2 + 47 126 05 + 00 127 8a + 47 127 6d + 00 11b 9e + 47 11b 79 + 00 11c 4d + 47 11c aa + 00 11d 25 + 47 11d c2 + 00 11e 9d + 47 11e 7a + 00 11f f5 + 47 11f 12 + + }; + + for(i = 0; i < 20; i++) { + gen_packet_header(uint8_t lt_addr, uint8_t type, uint8_t flow, uint8_t arqn, uint8_t seqn) + if (uap == 1) { + printf("E"); + ret++; + } + else + printf("."); + } + + if (ret > 0) + printf("%d errors\n", ret); + printf("\n--------------------\n"); + printf("Done testing unfec23\n"); + return ret; +} + +int main(int argc, char** argv) { + int ret = 0; + + ret += test_unfec23(); + + exit(ret); +} diff --git a/libbtbb-2015-10-R1/tests/test_syndromes.c b/libbtbb-2015-10-R1/tests/test_syndromes.c new file mode 100644 index 0000000..300a328 --- /dev/null +++ b/libbtbb-2015-10-R1/tests/test_syndromes.c @@ -0,0 +1,100 @@ +/* -*- c -*- */ +/* + * Copyright 2007 - 2011 Dominic Spill, Michael Ossmann + * + * This file is part of libbtbb + * + * 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, 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 libbtbb; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "../bluetooth_packet.h" +#include + +int test_syndromes() { + int ret, i; + uint64_t syndrome, syncword; + ret = 0; + + printf("Testing syndromes\n"); + printf("-----------------\n"); + + uint64_t syndrome_input[2] = { + /* No errors */ + 0xcc7b7268ff614e1b, + /* Errors */ + 0xcc7d7268ff614e1b + }; + + uint64_t syndrome_output[2] = { + /* No errors */ + 0, + /* Errors */ + 0x0000000299c6f9b5 + }; + + for(i = 0; i < 2; i++) { + syndrome = gen_syndrome(syndrome_input[i]); + if (syndrome == syndrome_output[i]) { + printf("."); + } else { + printf("F"); + ret++; + } + } + + uint64_t syncword_input[2] = { + /* No errors */ + 0xcc7b7268ff614e1b, + /* Errors */ + 0xcc7b7268ff514e1b + }; + + uint64_t syncword_output[2] = { + /* No errors */ + 0x4ffffffe44ad1ae7, + /* Errors */ + 0x4ffffffe44ad1ae7 + }; + + gen_syndrome_map(); + for(i = 0; i < 2; i++) { + syncword = decode_syncword(syncword_input[i] ^ pn); + if (syncword == syncword_output[i]) { + printf("."); + } else { + printf("F"); + ret++; + } + } + + if (ret > 0) + printf("%d errors\n", ret); + printf("\n-----------------\n"); + printf("Done testing syndrome generation\n"); + return ret; +} + +int main(int argc, char** argv) { + int ret = 0; + + ret += test_syndromes(); + + exit(ret); +} diff --git a/libbtbb-2015-10-R1/web/index.html b/libbtbb-2015-10-R1/web/index.html new file mode 100644 index 0000000..37e8af6 --- /dev/null +++ b/libbtbb-2015-10-R1/web/index.html @@ -0,0 +1,40 @@ + + + + +Libbtbb - Bluetooth baseband library + + +

Libbtbb - Bluetooth baseband library

+

Libbtbb is the Bluetooth baseband library used by the Ubertooth and +gr-bluetooth projects. It is freely available under the +GPL v2 license.

+ +

Getting libbtbb

+

Libbtbb is built from source using either a released archive or the latest +code from our git repository. +To get started, do either of the following:

+
    +
  • +Download the latest release
  • +
  • or clone the git repository using the following command: +
    git clone https://github.com/greatscottgadgets/libbtbb.git
  • +
  • If you prefer to use ssh and have a GitHub +account, you can use this command: +
    git clone git@github.com:greatscottgadgets/libbtbb.git
  • +
+ +

Support

+

Support for libbtbb is provided by +project Ubertooth, either using +the +mailing list or via IRC in #ubertooth on +chat.freenode.net

+

Bugs may be reported and tracked in the +ticketing system. +Although it often helps to mention the bug report on the + +Ubertooth mailing list to be sure that it has been seen.

+ + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/AUTHORS b/libbtbb-2015-10-R1/wireshark/plugins/btatt/AUTHORS new file mode 100644 index 0000000..b0e215f --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/AUTHORS @@ -0,0 +1,5 @@ +Authors: +Allan M. Madsen + +Converted to plugin by: +Mike Ryan diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/CMakeLists.txt b/libbtbb-2015-10-R1/wireshark/plugins/btatt/CMakeLists.txt new file mode 100644 index 0000000..078c838 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/CMakeLists.txt @@ -0,0 +1,88 @@ +# CMakeLists.txt +# +# $Id: CMakeLists.txt 31995 2010-02-24 22:32:10Z jmayer $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +project(btatt-wireshark-plugin C) + +cmake_minimum_required(VERSION 2.6) +set(CMAKE_BACKWARDS_COMPATIBILITY 2.6) +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +IF ( NOT CMAKE_INSTALL_LIBDIR ) + set(CMAKE_INSTALL_LIBDIR ~/.wireshark/plugins) +ENDIF ( NOT CMAKE_INSTALL_LIBDIR ) +MESSAGE (STATUS "Plugin will be installed in: ${CMAKE_INSTALL_LIBDIR}") + +INCLUDE(UseMakeDissectorReg) + +set(GLIB2_MIN_VERSION 2.4.0) + +find_package(GLIB2) +include_directories (${GLIB2_INCLUDE_DIRS}) + +find_package(Wireshark) +include_directories (${WIRESHARK_INCLUDE_DIRS}) + +set(LINK_MODE_LIB SHARED) +set(LINK_MODE_MODULE MODULE) + + +set(DISSECTOR_SRC + packet-btatt.c +) + +set(PLUGIN_FILES + plugin.c + ${DISSECTOR_SRC} +) + +set(CLEAN_FILES + ${PLUGIN_FILES} +) + +if (WERROR) + set_source_files_properties( + ${CLEAN_FILES} + PROPERTIES + COMPILE_FLAGS -Werror + ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +register_dissector_files(plugin.c + plugin + ${DISSECTOR_SRC} +) + +add_library(btatt ${LINK_MODE_MODULE} + ${PLUGIN_FILES} +) +set_target_properties(btatt PROPERTIES PREFIX "") +set_target_properties(btatt PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + +target_link_libraries(btatt wireshark) + +install(TARGETS btatt + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ NAMELINK_SKIP +) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btatt/COPYING new file mode 100644 index 0000000..aa0aea5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.am b/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.am new file mode 100644 index 0000000..d379428 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.am @@ -0,0 +1,125 @@ +# Makefile.am +# Automake file for AgentX plugin +# +# $Id: Makefile.am 24488 2008-02-27 16:18:30Z stig $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +INCLUDES = -I$(top_srcdir) -I$(includedir) + +include Makefile.common + +#if HAVE_WARNINGS_AS_ERRORS +#AM_CFLAGS = -Werror +#endif + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = btatt.la +btatt_la_SOURCES = \ + plugin.c \ + moduleinfo.h \ + $(DISSECTOR_SRC) \ + $(DISSECTOR_SUPPORT_SRC) \ + $(DISSECTOR_INCLUDES) +btatt_la_LDFLAGS = -module -avoid-version +btatt_la_LIBADD = @PLUGIN_LIBS@ + +# Libs must be cleared, or else libtool won't create a shared module. +# If your module needs to be linked against any particular libraries, +# add them here. +LIBS = + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \ + $(top_srcdir)/tools/make-dissector-reg.py + @if test -n "$(PYTHON)"; then \ + echo Making plugin.c with python ; \ + $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + plugin $(DISSECTOR_SRC) ; \ + else \ + echo Making plugin.c with shell script ; \ + $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + $(plugin_src) plugin $(DISSECTOR_SRC) ; \ + fi + +# +# Currently plugin.c can be included in the distribution because +# we always build all protocol dissectors. We used to have to check +# whether or not to build the snmp dissector. If we again need to +# variably build something, making plugin.c non-portable, uncomment +# the dist-hook line below. +# +# Oh, yuk. We don't want to include "plugin.c" in the distribution, as +# its contents depend on the configuration, and therefore we want it +# to be built when the first "make" is done; however, Automake insists +# on putting *all* source into the distribution. +# +# We work around this by having a "dist-hook" rule that deletes +# "plugin.c", so that "dist" won't pick it up. +# +#dist-hook: +# @rm -f $(distdir)/plugin.c + +CLEANFILES = \ + btatt \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in \ + plugin.c + +EXTRA_DIST = \ + Makefile.common \ + Makefile.nmake \ + moduleinfo.nmake \ + plugin.rc.in diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.common b/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.common new file mode 100644 index 0000000..5dbd7c1 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.common @@ -0,0 +1,39 @@ +# Makefile.common for AgentX plugin +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id: Makefile.common 23848 2007-12-12 22:10:50Z jake $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. + +# the name of the plugin +PLUGIN_NAME = btatt + +# the dissector sources (without any helpers) +DISSECTOR_SRC = \ + packet-btatt.c + +# corresponding headers +DISSECTOR_INCLUDES = + +# Dissector helpers. They're included in the source files in this +# directory, but they're not dissectors themselves, i.e. they're not +# used to generate "plugin.c". +DISSECTOR_SUPPORT_SRC = diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.nmake b/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.nmake new file mode 100644 index 0000000..857e435 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/Makefile.nmake @@ -0,0 +1,100 @@ +# Makefile.nmake +# nmake file for Wireshark plugin +# +# $Id: Makefile.nmake 24520 2008-03-01 12:31:01Z jake $ +# + +include ..\..\config.nmake +include moduleinfo.nmake + +include Makefile.common + +CFLAGS=/WX /DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \ + /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS) + +.c.obj:: + $(CC) $(CFLAGS) -Fd.\ -c $< + +LDFLAGS = $(PLUGIN_LDFLAGS) + +!IFDEF ENABLE_LIBWIRESHARK +LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib +CFLAGS=/DHAVE_WIN32_LIBWIRESHARK_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS) + +DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj) + +DISSECTOR_SUPPORT_OBJECTS = $(DISSECTOR_SUPPORT_SRC:.c=.obj) + +OBJECTS = $(DISSECTOR_OBJECTS) $(DISSECTOR_SUPPORT_OBJECTS) plugin.obj + +RESOURCE=$(PLUGIN_NAME).res + +all: $(PLUGIN_NAME).dll + +$(PLUGIN_NAME).rc : moduleinfo.nmake + sed -e s/@PLUGIN_NAME@/$(PLUGIN_NAME)/ \ + -e s/@RC_MODULE_VERSION@/$(RC_MODULE_VERSION)/ \ + -e s/@RC_VERSION@/$(RC_VERSION)/ \ + -e s/@MODULE_VERSION@/$(MODULE_VERSION)/ \ + -e s/@PACKAGE@/$(PACKAGE)/ \ + -e s/@VERSION@/$(VERSION)/ \ + -e s/@MSVC_VARIANT@/$(MSVC_VARIANT)/ \ + < plugin.rc.in > $@ + +$(PLUGIN_NAME).dll $(PLUGIN_NAME).exp $(PLUGIN_NAME).lib : $(OBJECTS) $(LINK_PLUGIN_WITH) $(RESOURCE) + link -dll /out:$(PLUGIN_NAME).dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ + $(GLIB_LIBS) $(RESOURCE) + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +!IFDEF PYTHON +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg.py + @echo Making plugin.c (using python) + @$(PYTHON) "../../tools/make-dissector-reg.py" . plugin $(DISSECTOR_SRC) +!ELSE +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg + @echo Making plugin.c (using sh) + @$(SH) ../../tools/make-dissector-reg . plugin $(DISSECTOR_SRC) +!ENDIF + +!ENDIF + +clean: + rm -f $(OBJECTS) $(RESOURCE) plugin.c *.pdb \ + $(PLUGIN_NAME).dll $(PLUGIN_NAME).dll.manifest $(PLUGIN_NAME).lib \ + $(PLUGIN_NAME).exp $(PLUGIN_NAME).rc + +distclean: clean + +maintainer-clean: distclean diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/README b/libbtbb-2015-10-R1/wireshark/plugins/btatt/README new file mode 100644 index 0000000..97538d5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/README @@ -0,0 +1,11 @@ +Bluetooth ATT Protocol Dissector +================================ + +This is a plugin-ized version of the Bluetooth ATT protocol dissector +from the Wireshark trunk. I made the very minimal changes necessary to +get it to build as a plugin: defining a couple constants and changing an +include path. + +This plugin is unneccessary if you are using Wireshark trunk. Only use +it if you are using a distro packaged Wireshark that does not have btatt +protocol support. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/COPYING new file mode 100644 index 0000000..53b6b71 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/COPYING @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/COPYING-CMAKE-SCRIPTS b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..280ed6c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,27 @@ +Copyright notice for the files copied from +http://www.opensync.org/browser/branches/3rd-party-cmake-modules/modules + +$Id: COPYING-CMAKE-SCRIPTS 34248 2010-09-25 15:38:12Z jmayer $ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/FindGLIB2.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/FindGLIB2.cmake new file mode 100644 index 0000000..ae7badd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/FindGLIB2.cmake @@ -0,0 +1,238 @@ +# +# $Id: FindGLIB2.cmake 34248 2010-09-25 15:38:12Z jmayer $ +# +# - Try to find GLib2 +# Once done this will define +# +# GLIB2_FOUND - system has GLib2 +# GLIB2_INCLUDE_DIRS - the GLib2 include directory +# GLIB2_LIBRARIES - Link these to use GLib2 +# +# HAVE_GLIB_GREGEX_H glib has gregex.h header and +# supports g_regex_match_simple +# +# Copyright (c) 2006 Andreas Schneider +# Copyright (c) 2006 Philippe Bernery +# Copyright (c) 2007 Daniel Gollub +# Copyright (c) 2007 Alban Browaeys +# Copyright (c) 2008 Michael Bell +# Copyright (c) 2008-2009 Bjoern Ricks +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +IF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + # in cache already + SET(GLIB2_FOUND TRUE) +ELSE (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + + INCLUDE(FindPkgConfig) + + ## Glib + IF ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "REQUIRED" ) + ELSE ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "" ) + ENDIF ( GLIB2_FIND_REQUIRED ) + + IF ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0>=${GLIB2_MIN_VERSION} ) + ELSE ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0 ) + ENDIF ( GLIB2_MIN_VERSION ) + IF ( PKG_CONFIG_FOUND ) + IF ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( GLIB2_FOUND ) + ENDIF ( PKG_CONFIG_FOUND ) + + # Look for glib2 include dir and libraries w/o pkgconfig + IF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + FIND_PATH( + _glibconfig_include_DIR + NAMES + glibconfig.h + PATHS + /opt/gnome/lib64 + /opt/gnome/lib + /opt/lib/ + /opt/local/lib + /sw/lib/ + /usr/lib64 + /usr/lib + /usr/local/include + ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES + glib-2.0/include + ) + + FIND_PATH( + _glib2_include_DIR + NAMES + glib.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + PATH_SUFFIXES + glib-2.0 + ) + + #MESSAGE(STATUS "Glib headers: ${_glib2_include_DIR}") + + FIND_LIBRARY( + _glib2_link_DIR + NAMES + glib-2.0 + glib + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + IF ( _glib2_include_DIR AND _glib2_link_DIR ) + SET ( _glib2_FOUND TRUE ) + ENDIF ( _glib2_include_DIR AND _glib2_link_DIR ) + + + IF ( _glib2_FOUND ) + SET ( GLIB2_INCLUDE_DIRS ${_glib2_include_DIR} ${_glibconfig_include_DIR} ) + SET ( GLIB2_LIBRARIES ${_glib2_link_DIR} ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( _glib2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( _glib2_FOUND ) + + # Handle dependencies + # libintl + IF ( NOT LIBINTL_FOUND ) + FIND_PATH(LIBINTL_INCLUDE_DIR + NAMES + libintl.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + ) + + FIND_LIBRARY(LIBINTL_LIBRARY + NAMES + intl + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/local/lib + /usr/lib + ) + + IF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + SET (LIBINTL_FOUND TRUE) + ENDIF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + ENDIF ( NOT LIBINTL_FOUND ) + + # libiconv + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR + NAMES + iconv.h + PATHS + /opt/gnome/include + /opt/local/include + /opt/local/include + /sw/include + /sw/include + /usr/local/include + /usr/include + PATH_SUFFIXES + glib-2.0 + ) + + FIND_LIBRARY(LIBICONV_LIBRARY + NAMES + iconv + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + + IF (LIBINTL_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBINTL_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBINTL_INCLUDE_DIR}) + ENDIF (LIBINTL_FOUND) + + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) + + ENDIF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + ## + + IF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + SET (GLIB2_FOUND TRUE) + ENDIF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + + IF (GLIB2_FOUND) + IF (NOT GLIB2_FIND_QUIETLY) + MESSAGE (STATUS "Found GLib2: ${GLIB2_LIBRARIES} ${GLIB2_INCLUDE_DIRS}") + ENDIF (NOT GLIB2_FIND_QUIETLY) + ELSE (GLIB2_FOUND) + IF (GLIB2_FIND_REQUIRED) + MESSAGE (SEND_ERROR "Could not find GLib2") + ENDIF (GLIB2_FIND_REQUIRED) + ENDIF (GLIB2_FOUND) + + # show the GLIB2_INCLUDE_DIRS and GLIB2_LIBRARIES variables only in the advanced view + MARK_AS_ADVANCED(GLIB2_INCLUDE_DIRS GLIB2_LIBRARIES) + MARK_AS_ADVANCED(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARY) + MARK_AS_ADVANCED(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY) + +ENDIF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS) + +IF ( WIN32 ) + # include libiconv for win32 + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR iconv.h PATH_SUFFIXES glib-2.0) + + FIND_LIBRARY(LIBICONV_LIBRARY NAMES iconv) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) +ENDIF ( WIN32 ) + +IF ( GLIB2_FOUND ) + # Check if system has a newer version of glib + # which supports g_regex_match_simple + INCLUDE( CheckIncludeFiles ) + SET( CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS} ) + CHECK_INCLUDE_FILES ( glib/gregex.h HAVE_GLIB_GREGEX_H ) + CHECK_INCLUDE_FILES ( glib/gchecksum.h HAVE_GLIB_GCHECKSUM_H ) + # Reset CMAKE_REQUIRED_INCLUDES + SET( CMAKE_REQUIRED_INCLUDES "" ) +ENDIF( GLIB2_FOUND ) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/FindWireshark.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/FindWireshark.cmake new file mode 100644 index 0000000..16fabed --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/FindWireshark.cmake @@ -0,0 +1,28 @@ +# +# Try to find the wireshark library and its includes +# +# This snippet sets the following variables: +# WIRESHARK_FOUND True if wireshark library got found +# WIRESHARK_INCLUDE_DIRS Location of the wireshark headers +# WIRESHARK_LIBRARIES List of libraries to use wireshark +# +# Copyright (c) 2011 Reinhold Kainhofer +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + +# wireshark does not install its library with pkg-config information, +# so we need to manually find the libraries and headers + +FIND_PATH( WIRESHARK_INCLUDE_DIRS epan/packet.h PATH_SUFFIXES wireshark ) +FIND_LIBRARY( WIRESHARK_LIBRARIES wireshark ) + +# Report results +IF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + SET( WIRESHARK_FOUND 1 ) +ELSE ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + MESSAGE( SEND_ERROR "Could NOT find the wireshark library and headers" ) +ENDIF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/UseMakeDissectorReg.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/UseMakeDissectorReg.cmake new file mode 100644 index 0000000..e7e1a73 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/cmake/UseMakeDissectorReg.cmake @@ -0,0 +1,33 @@ +# +# $Id: UseMakeDissectorReg.cmake 33616 2010-07-22 12:18:36Z stig $ +# +MACRO(REGISTER_DISSECTOR_FILES _outputfile _registertype ) + # FIXME: Only the Python stuff has been implemented + # Make this into a MACRO, to avoid duplication with plugins/.../ + #register.c: $(plugin_src) $(ALL_DISSECTORS_SRC) $(top_srcdir)/tools/make-dissector-reg \ + # $(top_srcdir)/tools/make-dissector-reg.py + # @if test -n "$(PYTHON)"; then \ + # echo Making register.c with python ; \ + # $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + # dissectors $(ALL_DISSECTORS_SRC) ; \ + # else \ + # echo Making register.c with shell script ; \ + # $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + # dissectors $(plugin_src) $(ALL_DISSECTORS_SRC) ; \ + # fi + set( _sources ${ARGN} ) + ADD_CUSTOM_COMMAND( + OUTPUT + ${_outputfile} + COMMAND ${PYTHON_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ${CMAKE_CURRENT_SOURCE_DIR} + ${_registertype} + ${_sources} + DEPENDS + ${_sources} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ) +ENDMACRO(REGISTER_DISSECTOR_FILES) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/moduleinfo.h b/libbtbb-2015-10-R1/wireshark/plugins/btatt/moduleinfo.h new file mode 100644 index 0000000..7dfa9cd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/moduleinfo.h @@ -0,0 +1,17 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "btle" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/moduleinfo.nmake b/libbtbb-2015-10-R1/wireshark/plugins/btatt/moduleinfo.nmake new file mode 100644 index 0000000..d67b402 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/moduleinfo.nmake @@ -0,0 +1,28 @@ +# +# $Id: moduleinfo.nmake 20155 2006-12-19 22:22:34Z jake $ +# + +# The name +PACKAGE=btle + +# The version +MODULE_VERSION_MAJOR=0 +MODULE_VERSION_MINOR=0 +MODULE_VERSION_MICRO=0 +MODULE_VERSION_EXTRA=1 + +# +# The RC_VERSION should be comma-separated, not dot-separated, +# as per Graham Bloice's message in +# +# http://www.ethereal.com/lists/ethereal-dev/200303/msg00283.html +# +# "The RC_VERSION variable in config.nmake should be comma separated. +# This allows the resources to be built correctly and the version +# number to be correctly displayed in the explorer properties dialog +# for the executables, and XP's tooltip, rather than 0.0.0.0." +# + +MODULE_VERSION=$(MODULE_VERSION_MAJOR).$(MODULE_VERSION_MINOR).$(MODULE_VERSION_MICRO).$(MODULE_VERSION_EXTRA) +RC_MODULE_VERSION=$(MODULE_VERSION_MAJOR),$(MODULE_VERSION_MINOR),$(MODULE_VERSION_MICRO),$(MODULE_VERSION_EXTRA) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/packet-btatt.c b/libbtbb-2015-10-R1/wireshark/plugins/btatt/packet-btatt.c new file mode 100644 index 0000000..c913be1 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/packet-btatt.c @@ -0,0 +1,698 @@ +/* packet-btatt.c + * Routines for Bluetooth Attribute Protocol dissection + * + * Copyright 2012, Allan M. Madsen + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#define BTL2CAP_PSM_ATT 0x001f +#define BTL2CAP_FIXED_CID_ATT 0x0004 + +/* Initialize the protocol and registered fields */ +static int proto_btatt = -1; + +static int hf_btatt_opcode = -1; +static int hf_btatt_handle = -1; +static int hf_btatt_starting_handle = -1; +static int hf_btatt_ending_handle = -1; +static int hf_btatt_group_end_handle = -1; +static int hf_btatt_value = -1; +static int hf_btatt_req_opcode_in_error = -1; +static int hf_btatt_handle_in_error = -1; +static int hf_btatt_error_code = -1; +static int hf_btatt_uuid16 = -1; +static int hf_btatt_uuid128 = -1; +static int hf_btatt_client_rx_mtu = -1; +static int hf_btatt_server_rx_mtu = -1; +static int hf_btatt_uuid_format = -1; +static int hf_btatt_length = -1; +static int hf_btatt_offset = -1; +static int hf_btatt_flags = -1; +static int hf_btatt_sign_counter = -1; +static int hf_btatt_signature = -1; + +/* Initialize the subtree pointers */ +static gint ett_btatt = -1; +static gint ett_btatt_list = -1; + +/* Opcodes */ +static const value_string opcode_vals[] = { + {0x01, "Error Response"}, + {0x02, "Exchange MTU Request"}, + {0x03, "Exchange MTU Response"}, + {0x04, "Find Information Request"}, + {0x05, "Find Information Response"}, + {0x06, "Find By Type Value Request"}, + {0x07, "Find By Type Value Response"}, + {0x08, "Read By Type Request"}, + {0x09, "Read By Type Response"}, + {0x0a, "Read Request"}, + {0x0b, "Read Response"}, + {0x0c, "Read Blob Request"}, + {0x0d, "Read Blob Response"}, + {0x0e, "Read Multiple Request"}, + {0x0f, "Read Multiple Response"}, + {0x10, "Read By Group Type Request"}, + {0x11, "Read By Group Type Response"}, + {0x12, "Write Request"}, + {0x13, "Write Response"}, + {0x16, "Prepare Write Request"}, + {0x17, "Prepare Write Response"}, + {0x18, "Execute Write Request"}, + {0x19, "Execute Write Response"}, + {0x1B, "Handle Value Notification"}, + {0x1D, "Handle Value Indication"}, + {0x1E, "Handle Value Confirmation"}, + {0x52, "Write Command"}, + {0xD2, "Signed Write Command"}, + {0x0, NULL} +}; + +/* Error codes */ +static const value_string error_vals[] = { + {0x01, "Invalid Handle"}, + {0x02, "Read Not Permitted"}, + {0x03, "Write Not Permitted"}, + {0x04, "Invalid PDU"}, + {0x05, "Insufficient Authentication"}, + {0x06, "Request Not Supported"}, + {0x07, "Invalid Offset"}, + {0x08, "Insufficient Authorization"}, + {0x09, "Prepare Queue Full"}, + {0x0a, "Attribute Not Found"}, + {0x0b, "Attribute Not Long"}, + {0x0c, "Insufficient Encryption Key Size"}, + {0x0d, "Invalid Attribute Value Length"}, + {0x0e, "Unlikely Error"}, + {0x0f, "Insufficient Encryption"}, + {0x10, "Unsupported Group Type"}, + {0x11, "Insufficient Resources"}, + {0x80, "Application Error"}, + {0xfd, "Improper Client Characteristic Configuration Descriptor"}, + {0xfe, "Procedure Already In Progress"}, + {0xff, "Out of Range"}, + {0x0, NULL} +}; + +static const value_string uuid_vals[] = { + /* Services - http://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx */ + {0x1800, "Generic Access"}, + {0x1801, "Generic Attribute"}, + {0x1802, "Immediate Alert"}, + {0x1803, "Link Loss"}, + {0x1804, "Tx Power"}, + {0x1805, "Current Time Service"}, + {0x1806, "Reference Time Update Service"}, + {0x1807, "Next DST Change Service"}, + {0x1808, "Glucose"}, + {0x1809, "Health Thermometer"}, + {0x180a, "Device Information"}, + {0x180d, "Heart Rate"}, + {0x180e, "Phone Alert Status Service"}, + {0x180f, "Battery Service"}, + {0x1810, "Blood Pressure"}, + {0x1811, "Alert Notification Service"}, + {0x1812, "Human Interface Device"}, + {0x1813, "Scan Parameters"}, + {0x1814, "Running Speed and Cadence"}, + {0x1816, "Cycling Speed and Cadence"}, + /* Declarations - http://developer.bluetooth.org/gatt/declarations/Pages/DeclarationsHome.aspx */ + {0x2800, "GATT Primary Service Declaration"}, + {0x2801, "GATT Secondary Service Declaration"}, + {0x2802, "GATT Include Declaration"}, + {0x2803, "GATT Characteristic Declaration"}, + /* Descriptors - http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorsHomePage.aspx */ + {0x2900, "Characteristic Extended Properties"}, + {0x2901, "Characteristic User Description"}, + {0x2902, "Client Characteristic Configuration"}, + {0x2903, "Server Characteristic Configuration"}, + {0x2904, "Characteristic Presentation Format"}, + {0x2905, "Characteristic Aggregate Format"}, + {0x2906, "Valid Range"}, + {0x2907, "External Report Reference"}, + {0x2908, "Report Reference"}, + /* Characteristics - http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicsHome.aspx */ + {0x2a00, "Device Name"}, + {0x2a01, "Appearance"}, + {0x2a02, "Peripheral Privacy Flag"}, + {0x2a03, "Reconnection Address"}, + {0x2a04, "Peripheral Preferred Connection Parameters"}, + {0x2a05, "Service Changed"}, + {0x2a06, "Alert Level"}, + {0x2a07, "Tx Power Level"}, + {0x2a08, "Date Time"}, + {0x2a09, "Day of Week"}, + {0x2a0a, "Day Date Time"}, + {0x2a0c, "Exact Time 256"}, + {0x2a0d, "DST Offset"}, + {0x2a0e, "Time Zone"}, + {0x2a0f, "Local Time Information"}, + {0x2a11, "Time with DST"}, + {0x2a12, "Time Accuracy"}, + {0x2a13, "Time Source"}, + {0x2a14, "Reference Time Information"}, + {0x2a16, "Time Update Control Point"}, + {0x2a17, "Time Update State"}, + {0x2a18, "Glucose Measurement"}, + {0x2a19, "Battery Level"}, + {0x2a1c, "Temperature Measurement"}, + {0x2a1d, "Temperature Type"}, + {0x2a1e, "Intermediate Temperature"}, + {0x2a21, "Measurement Interval"}, + {0x2a22, "Boot Keyboard Input Report"}, + {0x2a23, "System ID"}, + {0x2a24, "Model Number String"}, + {0x2a25, "Serial Number String"}, + {0x2a26, "Firmware Revision String"}, + {0x2a27, "Hardware Revision String"}, + {0x2a28, "Software Revision String"}, + {0x2a29, "Manufacturer Name String"}, + {0x2a2a, "IEEE 11073-20601 Reg. Cert. Data List"}, + {0x2a2b, "Current Time"}, + {0x2a31, "Scan Refresh"}, + {0x2a32, "Boot Keyboard Output Report"}, + {0x2a33, "Boot Mouse Input Report"}, + {0x2a34, "Glucose Measurement Context"}, + {0x2a35, "Blood Pressure Measurement"}, + {0x2a36, "Intermediate Cuff Pressure"}, + {0x2a37, "Heart Rate Measurement"}, + {0x2a38, "Body Sensor Location"}, + {0x2a39, "Heart Rate Control Point"}, + {0x2a3f, "Alert Status"}, + {0x2a40, "Ringer Control Point"}, + {0x2a41, "Ringer Setting"}, + {0x2a42, "Alert Category ID Bit Mask"}, + {0x2a43, "Alert Category ID"}, + {0x2a44, "Alert Notification Control Point"}, + {0x2a45, "Unread Alert Status"}, + {0x2a46, "New Alert"}, + {0x2a47, "Supported New Alert Category"}, + {0x2a48, "Supported Unread Alert Category"}, + {0x2a49, "Blood Pressure Feature"}, + {0x2a4a, "HID Information"}, + {0x2a4b, "Report Map"}, + {0x2a4c, "HID Control Point"}, + {0x2a4d, "Report"}, + {0x2a4e, "Protocol Mode"}, + {0x2a4f, "Scan Interval Window"}, + {0x2a50, "PnP ID"}, + {0x2a51, "Glucose Feature"}, + {0x2a52, "Record Access Control Point"}, + {0x2a53, "RSC Measurement"}, + {0x2a54, "RSC Feature"}, + {0x2a55, "SC Control Point"}, + {0x2a5b, "CSC Measurement"}, + {0x2a5c, "CSC Feature"}, + {0x2a5d, "Sensor Location"}, + {0x0, NULL} +}; +static value_string_ext uuid_vals_ext = VALUE_STRING_EXT_INIT(uuid_vals); + +static const value_string uuid_format_vals[] = { + {0x01, "16-bit UUIDs"}, + {0x02, "128-bit UUIDs"}, + {0x0, NULL} +}; + +static const value_string flags_vals[] = { + {0x00, "Cancel All"}, + {0x01, "Immediately Write All"}, + {0x0, NULL} +}; + +static void +dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + int offset = 0; + proto_item *ti, *item; + proto_tree *st, *ltree; + guint8 opcode; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATT"); + + switch (pinfo->p2p_dir) { + + case P2P_DIR_SENT: + col_add_str(pinfo->cinfo, COL_INFO, "Sent "); + break; + + case P2P_DIR_RECV: + col_add_str(pinfo->cinfo, COL_INFO, "Rcvd "); + break; + + case P2P_DIR_UNKNOWN: + break; + + default: + col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ", + pinfo->p2p_dir); + break; + } + + if (tvb_length_remaining(tvb, 0) < 1) + return; + + ti = proto_tree_add_item(tree, proto_btatt, tvb, 0, -1, ENC_NA); + st = proto_item_add_subtree(ti, ett_btatt); + + item = proto_tree_add_item(st, hf_btatt_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN); + opcode = tvb_get_guint8(tvb, 0); + offset++; + + col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(opcode, opcode_vals, "")); + + switch (opcode) { + case 0x01: /* Error Response */ + proto_tree_add_item(st, hf_btatt_req_opcode_in_error, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + proto_tree_add_item(st, hf_btatt_handle_in_error, tvb, offset, 2, ENC_LITTLE_ENDIAN); + col_append_fstr(pinfo->cinfo, COL_INFO, " - %s, Handle: 0x%04x", + val_to_str(tvb_get_guint8(tvb, offset+2), error_vals, ""), + tvb_get_letohs(tvb, offset)); + offset += 2; + proto_tree_add_item(st, hf_btatt_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0x02: /* Exchange MTU Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Client Rx MTU: %u", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_client_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x03: /* Exchange MTU Response */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Server Rx MTU: %u", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_server_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x04: /* Find Information Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handles: 0x%04x..0x%04x", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x05: /* Find Information Response */ + { + guint8 format = tvb_get_guint8(tvb, offset); + + item = proto_tree_add_item(st, hf_btatt_uuid_format, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + if( format == 1 ) { + while( tvb_length_remaining(tvb, offset) > 0) { + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } + } + else if( format == 2 ) { + while( tvb_length_remaining(tvb, offset) > 0) { + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA); + offset += 16; + } + } + else { + expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Unknown format"); + } + } + break; + + case 0x06: /* Find By Type Value Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x", + val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, ""), + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + if( tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x07: /* Find By Type Value Response */ + while( tvb_length_remaining(tvb, offset) > 0 ) { + item = proto_tree_add_text(st, tvb, offset, 4, + "Handles Info, Handle: 0x%04x, Group End Handle: 0x%04x", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + ltree = proto_item_add_subtree(item, ett_btatt_list); + + proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } + break; + + case 0x08: /* Read By Type Request */ + case 0x10: /* Read By Group Type Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x", + val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, ""), + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + if (tvb_length_remaining(tvb, offset) == 2) { + proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } + else if (tvb_length_remaining(tvb, offset) == 16) { + item = proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA); + proto_item_append_text(item, " (%s)", val_to_str_ext_const(tvb_get_letohs(tvb, offset), + &uuid_vals_ext, "")); + offset += 16; + } + break; + + case 0x09: /* Read By Type Response */ + { + guint8 length = tvb_get_guint8(tvb, offset); + + proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + if(length > 0) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u", + tvb_length_remaining(tvb, offset)/length); + + while (tvb_length_remaining(tvb, offset) >= length) + { + item = proto_tree_add_text(st, tvb, offset, length, "Attribute Data, Handle: 0x%04x", + tvb_get_letohs(tvb, offset)); + + ltree = proto_item_add_subtree(item, ett_btatt_list); + + proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length-2, ENC_LITTLE_ENDIAN); + offset += (length-2); + } + } + } + break; + + case 0x0a: /* Read Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x0b: /* Read Response */ + case 0x0d: /* Read Blob Response */ + case 0x0f: /* Multiple Read Response */ + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x0c: /* Read Blob Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + break; + + case 0x0e: /* Multiple Read Request */ + if(tvb_length_remaining(tvb, offset) < 4) { + expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, + "Too few handles, should be 2 or more"); + break; + } + + col_append_str(pinfo->cinfo, COL_INFO, ", Handles: "); + while (tvb_length_remaining(tvb, offset) >= 2) { + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + col_append_fstr(pinfo->cinfo, COL_INFO, "0x%04x ", tvb_get_letohs(tvb, offset)); + offset += 2; + } + break; + + case 0x11: /* Read By Group Type Response */ + { + guint8 length = tvb_get_guint8(tvb, offset); + + proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + + if(length > 0) { + col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u", tvb_length_remaining(tvb, offset)/length); + + while (tvb_length_remaining(tvb, offset) >= length) { + item = proto_tree_add_text(st, tvb, offset, length, + "Attribute Data, Handle: 0x%04x, Group End Handle: 0x%04x", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + + ltree = proto_item_add_subtree(item, ett_btatt_list); + + proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length-4, ENC_LITTLE_ENDIAN); + offset += (length-4); + } + } + } + break; + + case 0x12: /* Write Request */ + case 0x52: /* Write Command */ + case 0x1b: /* Handle Value Notification */ + case 0x1d: /* Handle Value Indication */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x16: /* Prepare Write Request */ + case 0x17: /* Prepare Write Response */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u", + tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA); + break; + + case 0x18: /* Execute Write Request */ + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", + val_to_str(tvb_get_guint8(tvb, offset), flags_vals, "")); + proto_tree_add_item(st, hf_btatt_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset++; + break; + + case 0xd2: /* Signed Write Command */ + { + guint8 length; + + col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset)); + proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + length = tvb_length_remaining(tvb, offset); + if (length > 12) { + proto_tree_add_item(st, hf_btatt_value, tvb, offset, length-12, ENC_NA); + offset+=length-12; + } + + proto_tree_add_item(st, hf_btatt_sign_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + proto_tree_add_item(st, hf_btatt_signature, tvb, offset, 8, ENC_NA); + offset+=8; + break; + } + default: + break; + } +} + +void +proto_register_btatt(void) +{ + module_t *module; + + static hf_register_info hf[] = { + {&hf_btatt_opcode, + {"Opcode", "btatt.opcode", + FT_UINT8, BASE_HEX, VALS(opcode_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_handle, + {"Handle", "btatt.handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_starting_handle, + {"Starting Handle", "btatt.starting_handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_ending_handle, + {"Ending Handle", "btatt.ending_handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_group_end_handle, + {"Group End Handle", "btatt.group_end_handle", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_value, + {"Value", "btatt.value", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_req_opcode_in_error, + {"Request Opcode in Error", "btatt.req_opcode_in_error", + FT_UINT8, BASE_HEX, VALS(opcode_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_handle_in_error, + {"Handle in Error", "btatt.handle_in_error", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_error_code, + {"Error Code", "btatt.error_code", + FT_UINT8, BASE_HEX, VALS(error_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_uuid16, + {"UUID", "btatt.uuid16", + FT_UINT16, BASE_HEX |BASE_EXT_STRING, &uuid_vals_ext, 0x0, + NULL, HFILL} + }, + {&hf_btatt_uuid128, + {"UUID", "btatt.uuid128", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_client_rx_mtu, + {"Client Rx MTU", "btatt.client_rx_mtu", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_server_rx_mtu, + {"Server Rx MTU", "btatt.server_rx_mtu", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_uuid_format, + {"UUID Format", "btatt.uuid_format", + FT_UINT8, BASE_HEX, VALS(uuid_format_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_length, + {"Length", "btatt.length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Length of Handle/Value Pair", HFILL} + }, + {&hf_btatt_offset, + {"Offset", "btatt.offset", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_flags, + {"Flags", "btatt.flags", + FT_UINT8, BASE_HEX, VALS(flags_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_sign_counter, + {"Sign Counter", "btatt.sign_counter", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_signature, + {"Signature", "btatt.signature", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_btatt, + &ett_btatt_list + }; + + /* Register the protocol name and description */ + proto_btatt = proto_register_protocol("Bluetooth Attribute Protocol", "ATT", "btatt"); + + register_dissector("btatt", dissect_btatt, proto_btatt); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_btatt, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + module = prefs_register_protocol(proto_btatt, NULL); + prefs_register_static_text_preference(module, "att.version", + "Bluetooth Protocol ATT version from Core 4.0", + "Version of protocol supported by this dissector."); +} + +void +proto_reg_handoff_btatt(void) +{ + dissector_handle_t btatt_handle; + + btatt_handle = find_dissector("btatt"); + dissector_add_uint("btl2cap.psm", BTL2CAP_PSM_ATT, btatt_handle); + dissector_add_uint("btl2cap.cid", BTL2CAP_FIXED_CID_ATT, btatt_handle); +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/plugin.rc.in b/libbtbb-2015-10-R1/wireshark/plugins/btatt/plugin.rc.in new file mode 100644 index 0000000..568dc07 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/plugin.rc.in @@ -0,0 +1,34 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @RC_MODULE_VERSION@ + PRODUCTVERSION @RC_VERSION@ + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0" + VALUE "FileDescription", "@PACKAGE@ dissector\0" + VALUE "FileVersion", "@MODULE_VERSION@\0" + VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0" + VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs , Gilbert Ramirez and others\0" + VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0" + VALUE "ProductName", "Wireshark\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "Comments", "Build with @MSVC_VARIANT@\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/tools/make-dissector-reg b/libbtbb-2015-10-R1/wireshark/plugins/btatt/tools/make-dissector-reg new file mode 100755 index 0000000..d2efa7c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/tools/make-dissector-reg @@ -0,0 +1,186 @@ +#! /bin/sh + +# +# $Id: make-dissector-reg 21716 2007-05-07 17:55:42Z gal $ +# + +# +# The first argument is the directory in which the source files live. +# +srcdir="$1" +shift + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype="$1" +shift +if [ "$registertype" = plugin ] +then + outfile="plugin.c" +elif [ "$registertype" = dissectors ] +then + outfile="register.c" +else + echo "Unknown output type '$registertype'" 1>&2 + exit 1 +fi + +# +# All subsequent arguments are the files to scan. +# +rm -f ${outfile}-tmp +echo '/* Do not modify this file. */' >${outfile}-tmp +echo '/* It is created automatically by the Makefile. */'>>${outfile}-tmp +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp + +fi +echo '}' >>${outfile}-tmp + + +# +# Build code to call all the protocol handoff registration routines. +# +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +fi +echo '}' >>${outfile}-tmp +if [ "$registertype" = plugin ] +then + echo '#endif' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +gulong register_count(void) +{ +EOF + proto_regs=`grep RA_REGISTER ${outfile}-tmp | wc -l` + handoff_regs=`grep RA_HANDOFF ${outfile}-tmp | wc -l` + echo " return $proto_regs + $handoff_regs;" >>${outfile}-tmp + echo '}' >>${outfile}-tmp +fi +mv ${outfile}-tmp ${outfile} diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btatt/tools/make-dissector-reg.py b/libbtbb-2015-10-R1/wireshark/plugins/btatt/tools/make-dissector-reg.py new file mode 100755 index 0000000..060460c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btatt/tools/make-dissector-reg.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# +# Looks for registration routines in the protocol dissectors, +# and assembles C code to call all the routines. +# +# This is a Python version of the make-reg-dotc shell script. +# Running the shell script on Win32 is very very slow because of +# all the process-launching that goes on --- multiple greps and +# seds for each input file. I wrote this python version so that +# less processes would have to be started. +# +# $Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $ + +import os +import sys +import re +import pickle +from stat import * + +VERSION_KEY = '_VERSION' +CUR_VERSION = '$Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $' + +# +# The first argument is the directory in which the source files live. +# +srcdir = sys.argv[1] + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype = sys.argv[2] +if registertype == "plugin" or registertype == "plugin_wtap": + tmp_filename = "plugin.c-tmp" + final_filename = "plugin.c" + cache_filename = None + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by Makefile or Makefile.nmake. + */ +""" +elif registertype == "dissectors": + tmp_filename = "register.c-tmp" + final_filename = "register.c" + cache_filename = "register-cache.pkl" + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by the "register.c" target in + * epan/dissectors/Makefile or Makefile.nmake using information in + * epan/dissectors/register-cache.pkl. + * + * You can force this file to be regenerated completely by deleting + * it along with epan/dissectors/register-cache.pkl. + */ +""" +else: + print(("Unknown output type '%s'" % registertype)) + sys.exit(1) + + +# +# All subsequent arguments are the files to scan. +# +files = sys.argv[3:] + +# Create the proper list of filenames +filenames = [] +for file in files: + if os.path.isfile(file): + filenames.append(file) + else: + filenames.append(os.path.join(srcdir, file)) + +if len(filenames) < 1: + print("No files found") + sys.exit(1) + + +# Look through all files, applying the regex to each line. +# If the pattern matches, save the "symbol" section to the +# appropriate array. +regs = { + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } + +# For those that don't know Python, r"" indicates a raw string, +# devoid of Python escapes. +proto_regex0 = r"^(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" +proto_regex1 = r"void\s+(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +handoff_regex0 = r"^(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" +handoff_regex1 = r"void\s+(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" + +wtap_reg_regex0 = r"^(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" +wtap_reg_regex1 = r"void\s+(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +# This table drives the pattern-matching and symbol-harvesting +patterns = [ + ( 'proto_reg', re.compile(proto_regex0) ), + ( 'proto_reg', re.compile(proto_regex1) ), + ( 'handoff_reg', re.compile(handoff_regex0) ), + ( 'handoff_reg', re.compile(handoff_regex1) ), + ( 'wtap_register', re.compile(wtap_reg_regex0) ), + ( 'wtap_register', re.compile(wtap_reg_regex1) ), + ] + +# Open our registration symbol cache +cache = None +if cache_filename: + try: + cache_file = open(cache_filename, 'rb') + cache = pickle.load(cache_file) + cache_file.close() + if VERSION_KEY not in cache or cache[VERSION_KEY] != CUR_VERSION: + cache = {VERSION_KEY: CUR_VERSION} + except: + cache = {VERSION_KEY: CUR_VERSION} + + print(("Registering %d files, %d cached" % (len(filenames), len(list(cache.keys()))-1))) + +# Grep +cache_hits = 0 +cache_misses = 0 +for filename in filenames: + file = open(filename) + cur_mtime = os.fstat(file.fileno())[ST_MTIME] + if cache and filename in cache: + cdict = cache[filename] + if cur_mtime == cdict['mtime']: + cache_hits += 1 +# print "Pulling %s from cache" % (filename) + regs['proto_reg'].extend(cdict['proto_reg']) + regs['handoff_reg'].extend(cdict['handoff_reg']) + regs['wtap_register'].extend(cdict['wtap_register']) + file.close() + continue + # We don't have a cache entry + if cache is not None: + cache_misses += 1 + cache[filename] = { + 'mtime': cur_mtime, + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } +# print "Searching %s" % (filename) + for line in file.readlines(): + for action in patterns: + regex = action[1] + match = regex.search(line) + if match: + symbol = match.group("symbol") + sym_type = action[0] + regs[sym_type].append(symbol) + if cache is not None: +# print "Caching %s for %s: %s" % (sym_type, filename, symbol) + cache[filename][sym_type].append(symbol) + file.close() + + +if cache is not None and cache_filename is not None: + cache_file = open(cache_filename, 'wb') + pickle.dump(cache, cache_file) + cache_file.close() + print(("Cache hits: %d, misses: %d" % (cache_hits, cache_misses))) + +# Make sure we actually processed something +if len(regs['proto_reg']) < 1: + print("No protocol registrations found") + sys.exit(1) + +# Sort the lists to make them pretty +regs['proto_reg'].sort() +regs['handoff_reg'].sort() +regs['wtap_register'].sort() + +reg_code = open(tmp_filename, "w") + +reg_code.write(preamble) + +# Make the routine to register all protocols +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +"""); +else: + reg_code.write(""" +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['proto_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + + +# Make the routine to register all protocol handoffs +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +"""); +else: + reg_code.write(""" +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['handoff_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + +if registertype == "plugin": + reg_code.write("#endif\n"); +elif registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +register_wtap_module(void) +{ +"""); + + for symbol in regs['wtap_register']: + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + reg_code.write(line) + + reg_code.write("}\n"); + reg_code.write("#endif\n"); +else: + reg_code.write(""" +static gulong proto_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['proto_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +static gulong handoff_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['handoff_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +gulong register_count(void) +{ +"""); + + line = " return proto_reg_count() + handoff_reg_count();" + reg_code.write(line) + + reg_code.write(""" +}\n +"""); + + +# Close the file +reg_code.close() + +# Remove the old final_file if it exists. +try: + os.stat(final_filename) + os.remove(final_filename) +except OSError: + pass + +# Move from tmp file to final file +os.rename(tmp_filename, final_filename) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/AUTHORS b/libbtbb-2015-10-R1/wireshark/plugins/btbb/AUTHORS new file mode 100644 index 0000000..71a4f07 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/AUTHORS @@ -0,0 +1,2 @@ +Authors: +Michael Ossmann diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/CMakeLists.txt b/libbtbb-2015-10-R1/wireshark/plugins/btbb/CMakeLists.txt new file mode 100644 index 0000000..4c29915 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/CMakeLists.txt @@ -0,0 +1,89 @@ +# CMakeLists.txt +# +# $Id: CMakeLists.txt 31995 2010-02-24 22:32:10Z jmayer $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +project(btbb-wireshark-plugin C) + +cmake_minimum_required(VERSION 2.6) +set(CMAKE_BACKWARDS_COMPATIBILITY 2.6) +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +IF ( NOT CMAKE_INSTALL_LIBDIR ) + set(CMAKE_INSTALL_LIBDIR ~/.wireshark/plugins) +ENDIF ( NOT CMAKE_INSTALL_LIBDIR ) +MESSAGE (STATUS "Plugin will be installed in: ${CMAKE_INSTALL_LIBDIR}") + +INCLUDE(UseMakeDissectorReg) + +set(GLIB2_MIN_VERSION 2.4.0) + +find_package(GLIB2) +include_directories (${GLIB2_INCLUDE_DIRS}) + +find_package(Wireshark) +include_directories (${WIRESHARK_INCLUDE_DIRS}) + +set(LINK_MODE_LIB SHARED) +set(LINK_MODE_MODULE MODULE) + + +set(DISSECTOR_SRC + packet-btbb.c + packet-btbrlmp.c +) + +set(PLUGIN_FILES + plugin.c + ${DISSECTOR_SRC} +) + +set(CLEAN_FILES + ${PLUGIN_FILES} +) + +if (WERROR) + set_source_files_properties( + ${CLEAN_FILES} + PROPERTIES + COMPILE_FLAGS -Werror + ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +register_dissector_files(plugin.c + plugin + ${DISSECTOR_SRC} +) + +add_library(btbb ${LINK_MODE_MODULE} + ${PLUGIN_FILES} +) +set_target_properties(btbb PROPERTIES PREFIX "") +set_target_properties(btbb PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + +target_link_libraries(btbb wireshark) + +install(TARGETS btbb + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ NAMELINK_SKIP +) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btbb/COPYING new file mode 100644 index 0000000..aa0aea5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/README b/libbtbb-2015-10-R1/wireshark/plugins/btbb/README new file mode 100644 index 0000000..3ce11c6 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/README @@ -0,0 +1,17 @@ +BTBB Wireshark plugin + +This is the Bluetooth baseband plugin for Wireshark, it also includes an LMP +level dissector. + +To build this on Debian/Ubuntu/BackTrack linux distributions: + sudo apt-get install wireshark-dev wireshark + cd libbtbb/wireshark/plugins/btbb/ + mkdir build + cd build + cmake .. + make + make install + +This will install to the .wireshark/ in your home directory. To override this +set the DESTDIR environment variable when running cmake. + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/btbb-sample-mouse.pcap b/libbtbb-2015-10-R1/wireshark/plugins/btbb/btbb-sample-mouse.pcap new file mode 100644 index 0000000..092c9ce Binary files /dev/null and b/libbtbb-2015-10-R1/wireshark/plugins/btbb/btbb-sample-mouse.pcap differ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/COPYING new file mode 100644 index 0000000..53b6b71 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/COPYING @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/COPYING-CMAKE-SCRIPTS b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..280ed6c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,27 @@ +Copyright notice for the files copied from +http://www.opensync.org/browser/branches/3rd-party-cmake-modules/modules + +$Id: COPYING-CMAKE-SCRIPTS 34248 2010-09-25 15:38:12Z jmayer $ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/FindGLIB2.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/FindGLIB2.cmake new file mode 100644 index 0000000..ae7badd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/FindGLIB2.cmake @@ -0,0 +1,238 @@ +# +# $Id: FindGLIB2.cmake 34248 2010-09-25 15:38:12Z jmayer $ +# +# - Try to find GLib2 +# Once done this will define +# +# GLIB2_FOUND - system has GLib2 +# GLIB2_INCLUDE_DIRS - the GLib2 include directory +# GLIB2_LIBRARIES - Link these to use GLib2 +# +# HAVE_GLIB_GREGEX_H glib has gregex.h header and +# supports g_regex_match_simple +# +# Copyright (c) 2006 Andreas Schneider +# Copyright (c) 2006 Philippe Bernery +# Copyright (c) 2007 Daniel Gollub +# Copyright (c) 2007 Alban Browaeys +# Copyright (c) 2008 Michael Bell +# Copyright (c) 2008-2009 Bjoern Ricks +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +IF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + # in cache already + SET(GLIB2_FOUND TRUE) +ELSE (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + + INCLUDE(FindPkgConfig) + + ## Glib + IF ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "REQUIRED" ) + ELSE ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "" ) + ENDIF ( GLIB2_FIND_REQUIRED ) + + IF ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0>=${GLIB2_MIN_VERSION} ) + ELSE ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0 ) + ENDIF ( GLIB2_MIN_VERSION ) + IF ( PKG_CONFIG_FOUND ) + IF ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( GLIB2_FOUND ) + ENDIF ( PKG_CONFIG_FOUND ) + + # Look for glib2 include dir and libraries w/o pkgconfig + IF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + FIND_PATH( + _glibconfig_include_DIR + NAMES + glibconfig.h + PATHS + /opt/gnome/lib64 + /opt/gnome/lib + /opt/lib/ + /opt/local/lib + /sw/lib/ + /usr/lib64 + /usr/lib + /usr/local/include + ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES + glib-2.0/include + ) + + FIND_PATH( + _glib2_include_DIR + NAMES + glib.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + PATH_SUFFIXES + glib-2.0 + ) + + #MESSAGE(STATUS "Glib headers: ${_glib2_include_DIR}") + + FIND_LIBRARY( + _glib2_link_DIR + NAMES + glib-2.0 + glib + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + IF ( _glib2_include_DIR AND _glib2_link_DIR ) + SET ( _glib2_FOUND TRUE ) + ENDIF ( _glib2_include_DIR AND _glib2_link_DIR ) + + + IF ( _glib2_FOUND ) + SET ( GLIB2_INCLUDE_DIRS ${_glib2_include_DIR} ${_glibconfig_include_DIR} ) + SET ( GLIB2_LIBRARIES ${_glib2_link_DIR} ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( _glib2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( _glib2_FOUND ) + + # Handle dependencies + # libintl + IF ( NOT LIBINTL_FOUND ) + FIND_PATH(LIBINTL_INCLUDE_DIR + NAMES + libintl.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + ) + + FIND_LIBRARY(LIBINTL_LIBRARY + NAMES + intl + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/local/lib + /usr/lib + ) + + IF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + SET (LIBINTL_FOUND TRUE) + ENDIF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + ENDIF ( NOT LIBINTL_FOUND ) + + # libiconv + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR + NAMES + iconv.h + PATHS + /opt/gnome/include + /opt/local/include + /opt/local/include + /sw/include + /sw/include + /usr/local/include + /usr/include + PATH_SUFFIXES + glib-2.0 + ) + + FIND_LIBRARY(LIBICONV_LIBRARY + NAMES + iconv + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + + IF (LIBINTL_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBINTL_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBINTL_INCLUDE_DIR}) + ENDIF (LIBINTL_FOUND) + + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) + + ENDIF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + ## + + IF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + SET (GLIB2_FOUND TRUE) + ENDIF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + + IF (GLIB2_FOUND) + IF (NOT GLIB2_FIND_QUIETLY) + MESSAGE (STATUS "Found GLib2: ${GLIB2_LIBRARIES} ${GLIB2_INCLUDE_DIRS}") + ENDIF (NOT GLIB2_FIND_QUIETLY) + ELSE (GLIB2_FOUND) + IF (GLIB2_FIND_REQUIRED) + MESSAGE (SEND_ERROR "Could not find GLib2") + ENDIF (GLIB2_FIND_REQUIRED) + ENDIF (GLIB2_FOUND) + + # show the GLIB2_INCLUDE_DIRS and GLIB2_LIBRARIES variables only in the advanced view + MARK_AS_ADVANCED(GLIB2_INCLUDE_DIRS GLIB2_LIBRARIES) + MARK_AS_ADVANCED(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARY) + MARK_AS_ADVANCED(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY) + +ENDIF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS) + +IF ( WIN32 ) + # include libiconv for win32 + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR iconv.h PATH_SUFFIXES glib-2.0) + + FIND_LIBRARY(LIBICONV_LIBRARY NAMES iconv) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) +ENDIF ( WIN32 ) + +IF ( GLIB2_FOUND ) + # Check if system has a newer version of glib + # which supports g_regex_match_simple + INCLUDE( CheckIncludeFiles ) + SET( CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS} ) + CHECK_INCLUDE_FILES ( glib/gregex.h HAVE_GLIB_GREGEX_H ) + CHECK_INCLUDE_FILES ( glib/gchecksum.h HAVE_GLIB_GCHECKSUM_H ) + # Reset CMAKE_REQUIRED_INCLUDES + SET( CMAKE_REQUIRED_INCLUDES "" ) +ENDIF( GLIB2_FOUND ) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/FindWireshark.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/FindWireshark.cmake new file mode 100644 index 0000000..16fabed --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/FindWireshark.cmake @@ -0,0 +1,28 @@ +# +# Try to find the wireshark library and its includes +# +# This snippet sets the following variables: +# WIRESHARK_FOUND True if wireshark library got found +# WIRESHARK_INCLUDE_DIRS Location of the wireshark headers +# WIRESHARK_LIBRARIES List of libraries to use wireshark +# +# Copyright (c) 2011 Reinhold Kainhofer +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + +# wireshark does not install its library with pkg-config information, +# so we need to manually find the libraries and headers + +FIND_PATH( WIRESHARK_INCLUDE_DIRS epan/packet.h PATH_SUFFIXES wireshark ) +FIND_LIBRARY( WIRESHARK_LIBRARIES wireshark ) + +# Report results +IF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + SET( WIRESHARK_FOUND 1 ) +ELSE ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + MESSAGE( SEND_ERROR "Could NOT find the wireshark library and headers" ) +ENDIF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/UseMakeDissectorReg.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/UseMakeDissectorReg.cmake new file mode 100644 index 0000000..e7e1a73 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/cmake/UseMakeDissectorReg.cmake @@ -0,0 +1,33 @@ +# +# $Id: UseMakeDissectorReg.cmake 33616 2010-07-22 12:18:36Z stig $ +# +MACRO(REGISTER_DISSECTOR_FILES _outputfile _registertype ) + # FIXME: Only the Python stuff has been implemented + # Make this into a MACRO, to avoid duplication with plugins/.../ + #register.c: $(plugin_src) $(ALL_DISSECTORS_SRC) $(top_srcdir)/tools/make-dissector-reg \ + # $(top_srcdir)/tools/make-dissector-reg.py + # @if test -n "$(PYTHON)"; then \ + # echo Making register.c with python ; \ + # $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + # dissectors $(ALL_DISSECTORS_SRC) ; \ + # else \ + # echo Making register.c with shell script ; \ + # $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + # dissectors $(plugin_src) $(ALL_DISSECTORS_SRC) ; \ + # fi + set( _sources ${ARGN} ) + ADD_CUSTOM_COMMAND( + OUTPUT + ${_outputfile} + COMMAND ${PYTHON_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ${CMAKE_CURRENT_SOURCE_DIR} + ${_registertype} + ${_sources} + DEPENDS + ${_sources} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ) +ENDMACRO(REGISTER_DISSECTOR_FILES) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/moduleinfo.h b/libbtbb-2015-10-R1/wireshark/plugins/btbb/moduleinfo.h new file mode 100644 index 0000000..9a9a9c0 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/moduleinfo.h @@ -0,0 +1,17 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "btbb" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/packet-btbb.c b/libbtbb-2015-10-R1/wireshark/plugins/btbb/packet-btbb.c new file mode 100644 index 0000000..a7d6b5c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/packet-btbb.c @@ -0,0 +1,593 @@ +/* packet-btbb.c + * Routines for Bluetooth baseband dissection + * Copyright 2009, Michael Ossmann + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#include +#endif + +#include +#include + +/* function prototypes */ +void proto_reg_handoff_btbb(void); + +/* initialize the protocol and registered fields */ +static int proto_btbb = -1; +static int hf_btbb_meta = -1; +static int hf_btbb_dir = -1; +static int hf_btbb_clk = -1; +static int hf_btbb_channel = -1; +static int hf_btbb_addrbits = -1; +static int hf_btbb_clkbits = -1; +static int hf_btbb_pkthdr = -1; +static int hf_btbb_ltaddr = -1; +static int hf_btbb_type = -1; +static int hf_btbb_flags = -1; +static int hf_btbb_flow = -1; +static int hf_btbb_arqn = -1; +static int hf_btbb_seqn = -1; +static int hf_btbb_hec = -1; +static int hf_btbb_payload = -1; +static int hf_btbb_pldhdr = -1; +static int hf_btbb_llid = -1; +static int hf_btbb_pldflow = -1; +static int hf_btbb_length = -1; +static int hf_btbb_pldbody = -1; +static int hf_btbb_crc = -1; +static int hf_btbb_fhs_parity = -1; +static int hf_btbb_fhs_lap = -1; +static int hf_btbb_fhs_eir = -1; +static int hf_btbb_fhs_sr = -1; +static int hf_btbb_fhs_uap = -1; +static int hf_btbb_fhs_nap = -1; +static int hf_btbb_fhs_class = -1; +static int hf_btbb_fhs_ltaddr = -1; +static int hf_btbb_fhs_clk = -1; +static int hf_btbb_fhs_psmode = -1; + +/* field values */ +static const true_false_string direction = { + "Slave to Master", + "Master to Slave" +}; + +static const true_false_string clock_bits = { + "27", + "6" +}; + +static const true_false_string address_bits = { + "48 (NAP known)", + "32 (NAP unknown)" +}; + +static const value_string packet_types[] = { + /* generic names for unknown logical transport */ + { 0x0, "NULL" }, + { 0x1, "POLL" }, + { 0x2, "FHS" }, + { 0x3, "DM1" }, + { 0x4, "DH1/2-DH1" }, + { 0x5, "HV1" }, + { 0x6, "HV2/2-EV3" }, + { 0x7, "HV3/EV3/3-EV3" }, + { 0x8, "DV/3-DH1" }, + { 0x9, "AUX1" }, + { 0xa, "DM3/2-DH3" }, + { 0xb, "DH3/3-DH3" }, + { 0xc, "EV4/2-EV5" }, + { 0xd, "EV5/3-EV5" }, + { 0xe, "DM5/2-DH5" }, + { 0xf, "DH5/3-DH5" }, + { 0, NULL } +}; + +static const value_string sr_modes[] = { + { 0x0, "R0" }, + { 0x1, "R1" }, + { 0x2, "R2" }, + { 0x3, "Reserved" }, + { 0, NULL } +}; + +static const range_string ps_modes[] = { + { 0x0, 0x0, "Mandatory scan mode" }, + { 0x1, 0x7, "Reserved" }, + { 0, 0, NULL } +}; + +static const value_string llid_codes[] = { + { 0x0, "undefined" }, + { 0x1, "Continuation fragment of an L2CAP message (ACL-U)" }, + { 0x2, "Start of an L2CAP message or no fragmentation (ACL-U)" }, + { 0x3, "LMP message (ACL-C)" }, + { 0, NULL } +}; + +/* initialize the subtree pointers */ +static gint ett_btbb = -1; +static gint ett_btbb_meta = -1; +static gint ett_btbb_pkthdr = -1; +static gint ett_btbb_flags = -1; +static gint ett_btbb_payload = -1; +static gint ett_btbb_pldhdr = -1; + +/* subdissectors */ +static dissector_handle_t btbrlmp_handle = NULL; +static dissector_handle_t btl2cap_handle = NULL; + +/* packet header flags */ +static const int *flag_fields[] = { + &hf_btbb_flow, + &hf_btbb_arqn, + &hf_btbb_seqn, + NULL +}; + +/* one byte payload header */ +int +dissect_payload_header1(proto_tree *tree, tvbuff_t *tvb, int offset) +{ + proto_item *hdr_item; + proto_tree *hdr_tree; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + hdr_item = proto_tree_add_item(tree, hf_btbb_pldhdr, tvb, offset, 1, ENC_NA); + hdr_tree = proto_item_add_subtree(hdr_item, ett_btbb_pldhdr); + + proto_tree_add_item(hdr_tree, hf_btbb_llid, tvb, offset, 1, ENC_NA); + proto_tree_add_item(hdr_tree, hf_btbb_pldflow, tvb, offset, 1, ENC_NA); + proto_tree_add_item(hdr_tree, hf_btbb_length, tvb, offset, 1, ENC_NA); + + /* payload length */ + return tvb_get_guint8(tvb, offset) >> 3; +} + +void +dissect_fhs(proto_tree *tree, tvbuff_t *tvb, int offset) +{ + proto_item *fhs_item, *psmode_item; + proto_tree *fhs_tree; + const gchar *description; + guint8 psmode; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) == 20); + + fhs_item = proto_tree_add_item(tree, hf_btbb_payload, tvb, offset, -1, ENC_NA); + fhs_tree = proto_item_add_subtree(fhs_item, ett_btbb_payload); + + /* Use proto_tree_add_bits_item() to get around 32bit limit on bitmasks */ + proto_tree_add_bits_item(fhs_tree, hf_btbb_fhs_parity, tvb, offset*8, 34, ENC_LITTLE_ENDIAN); + /* proto_tree_add_item(fhs_tree, hf_btbb_fhs_parity, tvb, offset, 5, ENC_LITTLE_ENDIAN); */ + offset += 4; + + proto_tree_add_item(fhs_tree, hf_btbb_fhs_lap, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 3; + + proto_tree_add_item(fhs_tree, hf_btbb_fhs_eir, tvb, offset, 1, ENC_NA); + /* skipping 1 undefined bit */ + proto_tree_add_item(fhs_tree, hf_btbb_fhs_sr, tvb, offset, 1, ENC_NA); + /* skipping 2 reserved bits */ + offset += 1; + + proto_tree_add_item(fhs_tree, hf_btbb_fhs_uap, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(fhs_tree, hf_btbb_fhs_nap, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fhs_tree, hf_btbb_fhs_class, tvb, offset, 3, ENC_LITTLE_ENDIAN); + offset += 3; + + proto_tree_add_item(fhs_tree, hf_btbb_fhs_ltaddr, tvb, offset, 1, ENC_NA); + proto_tree_add_item(fhs_tree, hf_btbb_fhs_clk, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 3; + + psmode = tvb_get_guint8(tvb, offset); + description = try_rval_to_str(psmode, ps_modes); + psmode_item = proto_tree_add_item(fhs_tree, hf_btbb_fhs_psmode, tvb, offset, 1, ENC_NA); + if (description) + proto_item_append_text(psmode_item, " (%s)", description); + offset += 1; + + proto_tree_add_item(fhs_tree, hf_btbb_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; +} + +void +dissect_dm1(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset) +{ + int len; /* payload length indicated by payload header */ + int llid; /* logical link id */ + int l2len; /* length indicated by l2cap header */ + proto_item *dm1_item; + proto_tree *dm1_tree; + tvbuff_t *pld_tvb; + + /* + * FIXME + * I'm probably doing a terrible, terrible thing here, but it gets my + * initial test cases working. + */ + guint16 fake_acl_data; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + dm1_item = proto_tree_add_item(tree, hf_btbb_payload, tvb, offset, -1, ENC_NA); + dm1_tree = proto_item_add_subtree(dm1_item, ett_btbb_payload); + + len = dissect_payload_header1(dm1_tree, tvb, offset); + llid = tvb_get_guint8(tvb, offset) & 0x3; + offset += 1; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) == len + 2); + + if (llid == 3 && btbrlmp_handle) { + /* LMP */ + pld_tvb = tvb_new_subset(tvb, offset, len, len); + call_dissector(btbrlmp_handle, pld_tvb, pinfo, dm1_tree); + } else if (llid == 2 && btl2cap_handle) { + /* unfragmented L2CAP or start of fragment */ + l2len = tvb_get_letohs(tvb, offset); + if (l2len + 4 == len) { + /* unfragmented */ + pinfo->private_data = &fake_acl_data; + pld_tvb = tvb_new_subset(tvb, offset, len, len); + call_dissector(btl2cap_handle, pld_tvb, pinfo, dm1_tree); + } else { + /* start of fragment */ + proto_tree_add_item(dm1_tree, hf_btbb_pldbody, tvb, offset, len, ENC_NA); + } + } else { + proto_tree_add_item(dm1_tree, hf_btbb_pldbody, tvb, offset, len, ENC_NA); + } + offset += len; + + proto_tree_add_item(dm1_tree, hf_btbb_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; +} + +/* dissect a packet */ +static int +dissect_btbb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + proto_item *btbb_item, *meta_item, *pkthdr_item; + proto_tree *btbb_tree, *meta_tree, *pkthdr_tree; + int offset; + /* Avoid error: 'type' may be used uninitialized in this function */ + guint8 type = 0xff; + const gchar *info; + + /* sanity check: length */ + if (tvb_length(tvb) > 0 && tvb_length(tvb) < 9) + /* bad length: look for a different dissector */ + return 0; + + /* maybe should verify HEC */ + + /* make entries in protocol column and info column on summary display */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Bluetooth"); + + if (tvb_length(tvb) == 0) { + info = "ID"; + } else { + type = (tvb_get_guint8(tvb, 6) >> 3) & 0x0f; + info = val_to_str(type, packet_types, "Unknown type: 0x%x"); + } + + col_clear(pinfo->cinfo, COL_INFO); + col_add_str(pinfo->cinfo, COL_INFO, info); + + /* see if we are being asked for details */ + if (tree) { + + /* create display subtree for the protocol */ + offset = 0; + btbb_item = proto_tree_add_item(tree, proto_btbb, tvb, offset, -1, ENC_NA); + btbb_tree = proto_item_add_subtree(btbb_item, ett_btbb); + + /* ID packets have no header, no payload */ + if (tvb_length(tvb) == 0) + return 1; + + /* meta data */ + meta_item = proto_tree_add_item(btbb_tree, hf_btbb_meta, tvb, offset, 3, ENC_NA); + meta_tree = proto_item_add_subtree(meta_item, ett_btbb_meta); + + proto_tree_add_item(meta_tree, hf_btbb_dir, tvb, offset, 1, ENC_NA); + proto_tree_add_item(meta_tree, hf_btbb_clk, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 4; + + proto_tree_add_item(meta_tree, hf_btbb_channel, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(meta_tree, hf_btbb_clkbits, tvb, offset, 1, ENC_NA); + proto_tree_add_item(meta_tree, hf_btbb_addrbits, tvb, offset, 1, ENC_NA); + offset += 1; + + /* packet header */ + pkthdr_item = proto_tree_add_item(btbb_tree, hf_btbb_pkthdr, tvb, offset, 3, ENC_NA); + pkthdr_tree = proto_item_add_subtree(pkthdr_item, ett_btbb_pkthdr); + + proto_tree_add_item(pkthdr_tree, hf_btbb_ltaddr, tvb, offset, 1, ENC_NA); + proto_tree_add_item(pkthdr_tree, hf_btbb_type, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_bitmask(pkthdr_tree, tvb, offset, hf_btbb_flags, + ett_btbb_flags, flag_fields, ENC_NA); + offset += 1; + proto_tree_add_item(pkthdr_tree, hf_btbb_hec, tvb, offset, 1, ENC_NA); + offset += 1; + + /* payload */ + switch (type) { + case 0x0: /* NULL */ + case 0x1: /* POLL */ + break; + case 0x2: /* FHS */ + dissect_fhs(btbb_tree, tvb, offset); + break; + case 0x3: /* DM1 */ + dissect_dm1(btbb_tree, tvb, pinfo, offset); + break; + case 0x4: /* DH1/2-DH1 */ + dissect_dm1(btbb_tree, tvb, pinfo, offset); + break; + case 0x5: /* HV1 */ + case 0x6: /* HV2/2-EV3 */ + case 0x7: /* HV3/EV3/3-EV3 */ + case 0x8: /* DV/3-DH1 */ + case 0x9: /* AUX1 */ + case 0xa: /* DM3/2-DH3 */ + case 0xb: /* DH3/3-DH3 */ + case 0xc: /* EV4/2-EV5 */ + case 0xd: /* EV5/3-EV5 */ + case 0xe: /* DM5/2-DH5 */ + case 0xf: /* DH5/3-DH5 */ + proto_tree_add_item(btbb_tree, hf_btbb_payload, tvb, offset, -1, ENC_NA); + break; + default: + break; + } + } + + /* Return the amount of data this dissector was able to dissect */ + return tvb_length(tvb); +} + +/* register the protocol with Wireshark */ +void +proto_register_btbb(void) +{ + /* list of fields */ + static hf_register_info hf[] = { + { &hf_btbb_meta, + { "Meta Data", "btbb.meta", + FT_NONE, BASE_NONE, NULL, 0x0, + "Meta Data About the Packet", HFILL } + }, + { &hf_btbb_dir, + { "Direction", "btbb.dir", + FT_BOOLEAN, 8, TFS(&direction), 0x01, + "Direction of Transmission", HFILL } + }, + { &hf_btbb_clk, + { "CLK", "btbb.clk", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Clock bits 1 through 27", HFILL } + }, + { &hf_btbb_channel, + { "Channel", "btbb.channel", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Channel (0-78)", HFILL } + }, + { &hf_btbb_clkbits, + { "Known Clock Bits", "btbb.clkbits", + FT_BOOLEAN, 8, TFS(&clock_bits), 0x01, + "Number of Known Master CLK Bits (6 or 27)", HFILL } + }, + { &hf_btbb_addrbits, + { "Known Address Bits", "btbb.addrbits", + FT_BOOLEAN, 8, TFS(&address_bits), 0x02, + "Number of Known Bits of BD_ADDR (32 or 48)", HFILL } + }, + { &hf_btbb_pkthdr, + { "Packet Header", "btbb.pkthdr", + FT_NONE, BASE_NONE, NULL, 0x0, + "Bluetooth Baseband Packet Header", HFILL } + }, + { &hf_btbb_ltaddr, + { "LT_ADDR", "btbb.lt_addr", + FT_UINT8, BASE_HEX, NULL, 0x07, + "Logical Transport Address", HFILL } + }, + { &hf_btbb_type, + { "TYPE", "btbb.type", + FT_UINT8, BASE_HEX, VALS(packet_types), 0x78, + "Packet Type", HFILL } + }, + { &hf_btbb_flags, + { "Flags", "btbb.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Packet Header Flags", HFILL } + }, + { &hf_btbb_flow, + { "FLOW", "btbb.flow", + FT_BOOLEAN, 8, NULL, 0x01, + "Flow control indication", HFILL } + }, + { &hf_btbb_arqn, + { "ARQN", "btbb.arqn", + FT_BOOLEAN, 8, NULL, 0x02, + "Acknowledgment indication", HFILL } + }, + { &hf_btbb_seqn, + { "SEQN", "btbb.seqn", + FT_BOOLEAN, 8, NULL, 0x04, + "Sequence number", HFILL } + }, + { &hf_btbb_hec, + { "HEC", "btbb.lt_addr", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Header Error Check", HFILL } + }, + { &hf_btbb_payload, + { "Payload", "btbb.payload", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbb_llid, + { "LLID", "btbb.llid", + FT_UINT8, BASE_HEX, VALS(llid_codes), 0x03, + "Logical Link ID", HFILL } + }, + { &hf_btbb_pldflow, + { "Flow", "btbb.flow", + FT_BOOLEAN, 8, NULL, 0x04, + "Payload Flow indication", HFILL } + }, + { &hf_btbb_length, + { "Length", "btbb.length", + FT_UINT8, BASE_DEC, NULL, 0xf8, + "Payload Length", HFILL } + }, + { &hf_btbb_pldhdr, + { "Payload Header", "btbb.pldhdr", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbb_pldbody, + { "Payload Body", "btbb.pldbody", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbb_crc, + { "CRC", "btbb.crc", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Payload CRC", HFILL } + }, + { &hf_btbb_fhs_parity, + { "Parity", "btbb.parity", + /* FIXME this doesn't work because bitmasks can only be 32 bits */ + FT_UINT64, BASE_HEX, NULL, /*0x00000003ffffffffULL,*/ 0x0, + "LAP parity", HFILL } + }, + { &hf_btbb_fhs_lap, + { "LAP", "btbb.lap", + FT_UINT24, BASE_HEX, NULL, 0x03fffffc, + "Lower Address Part", HFILL } + }, + { &hf_btbb_fhs_eir, + { "EIR", "btbb.eir", + FT_BOOLEAN, 8, NULL, 0x04, + "Extended Inquiry Response packet may follow", HFILL } + }, + { &hf_btbb_fhs_sr, + { "SR", "btbb.sr", + FT_UINT8, BASE_HEX, VALS(sr_modes), 0x30, + "Scan Repetition", HFILL } + }, + { &hf_btbb_fhs_uap, + { "UAP", "btbb.uap", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Upper Address Part", HFILL } + }, + { &hf_btbb_fhs_nap, + { "NAP", "btbb.nap", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Non-Significant Address Part", HFILL } + }, + { &hf_btbb_fhs_class, /* FIXME break out further */ + { "Class of Device", "btbb.class", + FT_UINT24, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbb_fhs_ltaddr, + { "LT_ADDR", "btbb.lt_addr", + FT_UINT8, BASE_HEX, NULL, 0x07, + "Logical Transport Address", HFILL } + }, + { &hf_btbb_fhs_clk, + { "CLK", "btbb.clk", + FT_UINT32, BASE_HEX, NULL, 0x1ffffff8, + "Clock bits 2 through 27", HFILL } + }, + { &hf_btbb_fhs_psmode, + { "Page Scan Mode", "btbb.psmode", + FT_UINT8, BASE_HEX, NULL, 0xe0, + NULL, HFILL } + }, + }; + + /* protocol subtree arrays */ + static gint *ett[] = { + &ett_btbb, + &ett_btbb_meta, + &ett_btbb_pkthdr, + &ett_btbb_flags, + &ett_btbb_payload, + &ett_btbb_pldhdr, + }; + + /* register the protocol name and description */ + proto_btbb = proto_register_protocol( + "Bluetooth Baseband", /* full name */ + "BT Baseband", /* short name */ + "btbb" /* abbreviation (e.g. for filters) */ + ); + + /* register the header fields and subtrees used */ + proto_register_field_array(proto_btbb, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_btbb(void) +{ + dissector_handle_t btbb_handle; + + btbb_handle = new_create_dissector_handle(dissect_btbb, proto_btbb); + /* hijacking this ethertype */ + dissector_add_uint("ethertype", 0xFFF0, btbb_handle); + /* dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_BASEBAND, btbb_handle); */ + + btbrlmp_handle = find_dissector("btbrlmp"); + btl2cap_handle = find_dissector("btl2cap"); +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/packet-btbrlmp.c b/libbtbb-2015-10-R1/wireshark/plugins/btbb/packet-btbrlmp.c new file mode 100644 index 0000000..aba1bfe --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/packet-btbrlmp.c @@ -0,0 +1,2887 @@ +/* packet-btbrlmp.c + * Routines for Bluetooth LMP dissection + * Copyright 2009, Michael Ossmann + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#include +#endif + +#include /* needed for epan/gcc-4.x */ +#include +#include + +/* LMP opcodes */ +#define LMP_NAME_REQ 1 +#define LMP_NAME_RES 2 +#define LMP_ACCEPTED 3 +#define LMP_NOT_ACCEPTED 4 +#define LMP_CLKOFFSET_REQ 5 +#define LMP_CLKOFFSET_RES 6 +#define LMP_DETACH 7 +#define LMP_IN_RAND 8 +#define LMP_COMB_KEY 9 +#define LMP_UNIT_KEY 10 +#define LMP_AU_RAND 11 +#define LMP_SRES 12 +#define LMP_TEMP_RAND 13 +#define LMP_TEMP_KEY 14 +#define LMP_ENCRYPTION_MODE_REQ 15 +#define LMP_ENCRYPTION_KEY_SIZE_REQ 16 +#define LMP_START_ENCRYPTION_REQ 17 +#define LMP_STOP_ENCRYPTION_REQ 18 +#define LMP_SWITCH_REQ 19 +#define LMP_HOLD 20 +#define LMP_HOLD_REQ 21 +#define LMP_SNIFF_REQ 23 +#define LMP_UNSNIFF_REQ 24 +#define LMP_PARK_REQ 25 +#define LMP_SET_BROADCAST_SCAN_WINDOW 27 +#define LMP_MODIFY_BEACON 28 +#define LMP_UNPARK_BD_ADDR_REQ 29 +#define LMP_UNPARK_PM_ADDR_REQ 30 +#define LMP_INCR_POWER_REQ 31 +#define LMP_DECR_POWER_REQ 32 +#define LMP_MAX_POWER 33 +#define LMP_MIN_POWER 34 +#define LMP_AUTO_RATE 35 +#define LMP_PREFERRED_RATE 36 +#define LMP_VERSION_REQ 37 +#define LMP_VERSION_RES 38 +#define LMP_FEATURES_REQ 39 +#define LMP_FEATURES_RES 40 +#define LMP_QUALITY_OF_SERVICE 41 +#define LMP_QUALITY_OF_SERVICE_REQ 42 +#define LMP_SCO_LINK_REQ 43 +#define LMP_REMOVE_SCO_LINK_REQ 44 +#define LMP_MAX_SLOT 45 +#define LMP_MAX_SLOT_REQ 46 +#define LMP_TIMING_ACCURACY_REQ 47 +#define LMP_TIMING_ACCURACY_RES 48 +#define LMP_SETUP_COMPLETE 49 +#define LMP_USE_SEMI_PERMANENT_KEY 50 +#define LMP_HOST_CONNECTION_REQ 51 +#define LMP_SLOT_OFFSET 52 +#define LMP_PAGE_MODE_REQ 53 +#define LMP_PAGE_SCAN_MODE_REQ 54 +#define LMP_SUPERVISION_TIMEOUT 55 +#define LMP_TEST_ACTIVATE 56 +#define LMP_TEST_CONTROL 57 +#define LMP_ENCRYPTION_KEY_SIZE_MASK_REQ 58 +#define LMP_ENCRYPTION_KEY_SIZE_MASK_RES 59 +#define LMP_SET_AFH 60 +#define LMP_ENCAPSULATED_HEADER 61 +#define LMP_ENCAPSULATED_PAYLOAD 62 +#define LMP_SIMPLE_PAIRING_CONFIRM 63 +#define LMP_SIMPLE_PAIRING_NUMBER 64 +#define LMP_DHKEY_CHECK 65 +#define LMP_ESCAPE_1 124 +#define LMP_ESCAPE_2 125 +#define LMP_ESCAPE_3 126 +#define LMP_ESCAPE_4 127 + +/* LMP extended opcodes */ +#define LMP_ACCEPTED_EXT 1 +#define LMP_NOT_ACCEPTED_EXT 2 +#define LMP_FEATURES_REQ_EXT 3 +#define LMP_FEATURES_RES_EXT 4 +#define LMP_PACKET_TYPE_TABLE_REQ 11 +#define LMP_ESCO_LINK_REQ 12 +#define LMP_REMOVE_ESCO_LINK_REQ 13 +#define LMP_CHANNEL_CLASSIFICATION_REQ 16 +#define LMP_CHANNEL_CLASSIFICATION 17 +#define LMP_SNIFF_SUBRATING_REQ 21 +#define LMP_SNIFF_SUBRATING_RES 22 +#define LMP_PAUSE_ENCRYPTION_REQ 23 +#define LMP_RESUME_ENCRYPTION_REQ 24 +#define LMP_IO_CAPABILITY_REQ 25 +#define LMP_IO_CAPABILITY_RES 26 +#define LMP_NUMERIC_COMPARISON_FAILED 27 +#define LMP_PASSKEY_FAILED 28 +#define LMP_OOB_FAILED 29 +#define LMP_KEYPRESS_NOTIFICATION 30 +#define LMP_POWER_CONTROL_REQ 31 +#define LMP_POWER_CONTROL_RES 32 + +/* initialize the protocol and registered fields */ +static int proto_btbrlmp = -1; +static int hf_lmp_accscheme = -1; +static int hf_lmp_afhchmap = -1; +static int hf_lmp_afhclass = -1; +static int hf_lmp_afhinst = -1; +static int hf_lmp_afhmaxintvl = -1; +static int hf_lmp_afhminintvl = -1; +static int hf_lmp_afhmode = -1; +static int hf_lmp_afhrptmode = -1; +static int hf_lmp_airmode = -1; +static int hf_lmp_araddr = -1; +static int hf_lmp_authreqs = -1; +static int hf_lmp_authres = -1; +static int hf_lmp_bdaddr = -1; +static int hf_lmp_bdaddr1 = -1; +static int hf_lmp_bdaddr2 = -1; +static int hf_lmp_bsw = -1; +static int hf_lmp_clkoffset = -1; +static int hf_lmp_commit = -1; +static int hf_lmp_confirm = -1; +static int hf_lmp_compid = -1; +static int hf_lmp_cryptmode = -1; +static int hf_lmp_daccess = -1; +static int hf_lmp_db = -1; +static int hf_lmp_dbsleep = -1; +static int hf_lmp_deltab = -1; +static int hf_lmp_desco = -1; +static int hf_lmp_drift = -1; +static int hf_lmp_dsco = -1; +static int hf_lmp_dsniff = -1; +static int hf_lmp_encdata = -1; +static int hf_lmp_enclen = -1; +static int hf_lmp_encmaj = -1; +static int hf_lmp_encmin = -1; +static int hf_lmp_eop = -1; +static int hf_lmp_eopinre = -1; +static int hf_lmp_escolenms = -1; +static int hf_lmp_escolensm = -1; +static int hf_lmp_escotypems = -1; +static int hf_lmp_escotypesm = -1; +static int hf_lmp_err = -1; +static int hf_lmp_escohdl = -1; +static int hf_lmp_escoltaddr = -1; +static int hf_lmp_features = -1; +static int hf_lmp_fpage = -1; +static int hf_lmp_htime = -1; +static int hf_lmp_hinst = -1; +static int hf_lmp_hopmode = -1; +static int hf_lmp_iocaps = -1; +static int hf_lmp_jitter = -1; +static int hf_lmp_key = -1; +static int hf_lmp_keysz = -1; +static int hf_lmp_ksmask = -1; +static int hf_lmp_ltaddr1 = -1; +static int hf_lmp_ltaddr2 = -1; +static int hf_lmp_ltaddr3 = -1; +static int hf_lmp_ltaddr4 = -1; +static int hf_lmp_ltaddr5 = -1; +static int hf_lmp_ltaddr6 = -1; +static int hf_lmp_ltaddr7 = -1; +static int hf_lmp_maccess = -1; +static int hf_lmp_maxslots = -1; +static int hf_lmp_maxsp = -1; +static int hf_lmp_maxss = -1; +static int hf_lmp_minsmt = -1; +static int hf_lmp_naccslots = -1; +static int hf_lmp_namefrag = -1; +static int hf_lmp_namelen = -1; +static int hf_lmp_nameoffset = -1; +static int hf_lmp_nb = -1; +static int hf_lmp_nbc = -1; +static int hf_lmp_nbsleep = -1; +static int hf_lmp_negstate = -1; +static int hf_lmp_nonce = -1; +static int hf_lmp_nottype = -1; +static int hf_lmp_npoll = -1; +static int hf_lmp_oobauthdata = -1; +static int hf_lmp_op = -1; +static int hf_lmp_opinre = -1; +static int hf_lmp_pagesch = -1; +static int hf_lmp_pcmode = -1; +static int hf_lmp_pkttype = -1; +static int hf_lmp_pkttypetbl = -1; +static int hf_lmp_pmaddr = -1; +static int hf_lmp_pmaddr1 = -1; +static int hf_lmp_pmaddr2 = -1; +static int hf_lmp_pmaddr3 = -1; +static int hf_lmp_pmaddr4 = -1; +static int hf_lmp_pmaddr5 = -1; +static int hf_lmp_pmaddr6 = -1; +static int hf_lmp_pmaddr7 = -1; +static int hf_lmp_pollintvl = -1; +static int hf_lmp_pollper = -1; +static int hf_lmp_pssettings = -1; +static int hf_lmp_pwradjreq = -1; +static int hf_lmp_pwradjres = -1; +static int hf_lmp_pwradj_8dpsk = -1; +static int hf_lmp_pwradj_dqpsk = -1; +static int hf_lmp_pwradj_gfsk = -1; +static int hf_lmp_rand = -1; +static int hf_lmp_rate = -1; +static int hf_lmp_rate_fec = -1; +static int hf_lmp_rate_size = -1; +static int hf_lmp_rate_type = -1; +static int hf_lmp_rate_edrsize = -1; +static int hf_lmp_rxfreq = -1; +static int hf_lmp_scohdl = -1; +static int hf_lmp_scopkt = -1; +static int hf_lmp_slotoffset = -1; +static int hf_lmp_sniffatt = -1; +static int hf_lmp_sniffsi = -1; +static int hf_lmp_sniffto = -1; +static int hf_lmp_subversnr = -1; +static int hf_lmp_suptimeout = -1; +static int hf_lmp_swinst = -1; +static int hf_lmp_taccess = -1; +static int hf_lmp_tb = -1; +static int hf_lmp_tesco = -1; +static int hf_lmp_testlen = -1; +static int hf_lmp_testscen = -1; +static int hf_lmp_tid = -1; +static int hf_lmp_timectrl = -1; +static int hf_lmp_time_change = -1; +static int hf_lmp_time_init = -1; +static int hf_lmp_time_accwin = -1; +static int hf_lmp_tsco = -1; +static int hf_lmp_tsniff = -1; +static int hf_lmp_txfreq = -1; +static int hf_lmp_versnr = -1; +static int hf_lmp_wesco = -1; + +/* timing control flags */ +static const int *timectrl_fields[] = { + &hf_lmp_time_change, + &hf_lmp_time_init, + &hf_lmp_time_accwin, + /* bits 3-7 reserved */ + NULL +}; + +static const true_false_string time_change = { + "timing change", + "no timing change" +}; + +static const true_false_string time_init = { + "use initialization 2", + "use initialization 1" +}; + +static const true_false_string time_accwin = { + "no access window", + "access window" +}; + +static const true_false_string fec = { + "do not use FEC", + "use FEC" +}; + +static const true_false_string tid = { + "transaction initiated by slave", + "transaction initiated by master" +}; + +/* short LMP opcodes */ +static const value_string opcode[] = { + { LMP_NAME_REQ, "LMP_name_req" }, + { LMP_NAME_RES, "LMP_name_res" }, + { LMP_ACCEPTED, "LMP_accepted" }, + { LMP_NOT_ACCEPTED, "LMP_not_accepted" }, + { LMP_CLKOFFSET_REQ, "LMP_clkoffset_req" }, + { LMP_CLKOFFSET_RES, "LMP_clkoffset_res" }, + { LMP_DETACH, "LMP_detach" }, + { LMP_IN_RAND, "LMP_in_rand" }, + { LMP_COMB_KEY, "LMP_comb_key" }, + { LMP_UNIT_KEY, "LMP_unit_key" }, + { LMP_AU_RAND, "LMP_au_rand" }, + { LMP_SRES, "LMP_sres" }, + { LMP_TEMP_RAND, "LMP_temp_rand" }, + { LMP_TEMP_KEY, "LMP_temp_key" }, + { LMP_ENCRYPTION_MODE_REQ, "LMP_encryption_mode_req" }, + { LMP_ENCRYPTION_KEY_SIZE_REQ, "LMP_encryption_key_size_req" }, + { LMP_START_ENCRYPTION_REQ, "LMP_start_encryption_req" }, + { LMP_STOP_ENCRYPTION_REQ, "LMP_stop_encryption_req" }, + { LMP_SWITCH_REQ, "LMP_switch_req" }, + { LMP_HOLD, "LMP_hold" }, + { LMP_HOLD_REQ, "LMP_hold_req" }, + { LMP_SNIFF_REQ, "LMP_sniff_req" }, + { LMP_UNSNIFF_REQ, "LMP_unsniff_req" }, + { LMP_PARK_REQ, "LMP_park_req" }, + { LMP_SET_BROADCAST_SCAN_WINDOW, "LMP_set_broadcast_scan_window" }, + { LMP_MODIFY_BEACON, "LMP_modify_beacon" }, + { LMP_UNPARK_BD_ADDR_REQ, "LMP_unpark_BD_ADDR_req" }, + { LMP_UNPARK_PM_ADDR_REQ, "LMP_unpark_PM_ADDR_req" }, + { LMP_INCR_POWER_REQ, "LMP_incr_power_req" }, + { LMP_DECR_POWER_REQ, "LMP_decr_power_req" }, + { LMP_MAX_POWER, "LMP_max_power" }, + { LMP_MIN_POWER, "LMP_min_power" }, + { LMP_AUTO_RATE, "LMP_auto_rate" }, + { LMP_PREFERRED_RATE, "LMP_preferred_rate" }, + { LMP_VERSION_REQ, "LMP_version_req" }, + { LMP_VERSION_RES, "LMP_version_res" }, + { LMP_FEATURES_REQ, "LMP_features_req" }, + { LMP_FEATURES_RES, "LMP_features_res" }, + { LMP_QUALITY_OF_SERVICE, "LMP_quality_of_service" }, + { LMP_QUALITY_OF_SERVICE_REQ, "LMP_quality_of_service_req" }, + { LMP_SCO_LINK_REQ, "LMP_SCO_link_req" }, + { LMP_REMOVE_SCO_LINK_REQ, "LMP_remove_SCO_link_req" }, + { LMP_MAX_SLOT, "LMP_max_slot" }, + { LMP_MAX_SLOT_REQ, "LMP_max_slot_req" }, + { LMP_TIMING_ACCURACY_REQ, "LMP_timing_accuracy_req" }, + { LMP_TIMING_ACCURACY_RES, "LMP_timing_accuracy_res" }, + { LMP_SETUP_COMPLETE, "LMP_setup_complete" }, + { LMP_USE_SEMI_PERMANENT_KEY, "LMP_use_semi_permanent_key" }, + { LMP_HOST_CONNECTION_REQ, "LMP_host_connection_req" }, + { LMP_SLOT_OFFSET, "LMP_slot_offset" }, + { LMP_PAGE_MODE_REQ, "LMP_page_mode_req" }, + { LMP_PAGE_SCAN_MODE_REQ, "LMP_page_scan_mode_req" }, + { LMP_SUPERVISION_TIMEOUT, "LMP_supervision_timeout" }, + { LMP_TEST_ACTIVATE, "LMP_test_activate" }, + { LMP_TEST_CONTROL, "LMP_test_control" }, + { LMP_ENCRYPTION_KEY_SIZE_MASK_REQ, "LMP_encryption_key_size_mask_req" }, + { LMP_ENCRYPTION_KEY_SIZE_MASK_RES, "LMP_encryption_key_size_mask_res" }, + { LMP_SET_AFH, "LMP_set_AFH" }, + { LMP_ENCAPSULATED_HEADER, "LMP_encapsulated_header" }, + { LMP_ENCAPSULATED_PAYLOAD, "LMP_encapsulated_payload" }, + { LMP_SIMPLE_PAIRING_CONFIRM, "LMP_Simple_Pairing_Confirm" }, + { LMP_SIMPLE_PAIRING_NUMBER, "LMP_Simple_Pairing_Number" }, + { LMP_DHKEY_CHECK, "LMP_DHkey_Check" }, + { LMP_ESCAPE_1, "Escape 1" }, + { LMP_ESCAPE_2, "Escape 2" }, + { LMP_ESCAPE_3, "Escape 3" }, + { LMP_ESCAPE_4, "Escape 4" }, + { 0, NULL } +}; + +/* extended LMP opcodes */ +static const value_string ext_opcode[] = { + { LMP_ACCEPTED_EXT, "LMP_accepted_ext" }, + { LMP_NOT_ACCEPTED_EXT, "LMP_not_accepted_ext" }, + { LMP_FEATURES_REQ_EXT, "LMP_features_req_ext" }, + { LMP_FEATURES_RES_EXT, "LMP_features_res_ext" }, + { LMP_PACKET_TYPE_TABLE_REQ, "LMP_packet_type_table_req" }, + { LMP_ESCO_LINK_REQ, "LMP_eSCO_link_req" }, + { LMP_REMOVE_ESCO_LINK_REQ, "LMP_remove_eSCO_link_req" }, + { LMP_CHANNEL_CLASSIFICATION_REQ, "LMP_channel_classification_req" }, + { LMP_CHANNEL_CLASSIFICATION, "LMP_channel_classification" }, + { LMP_SNIFF_SUBRATING_REQ, "LMP_sniff_subrating_req" }, + { LMP_SNIFF_SUBRATING_RES, "LMP_sniff_subrating_res" }, + { LMP_PAUSE_ENCRYPTION_REQ, "LMP_pause_encryption_req" }, + { LMP_RESUME_ENCRYPTION_REQ, "LMP_resume_encryption_req" }, + { LMP_IO_CAPABILITY_REQ, "LMP_IO_Capability_req" }, + { LMP_IO_CAPABILITY_RES, "LMP_IO_Capability_res" }, + { LMP_NUMERIC_COMPARISON_FAILED, "LMP_numeric_comparison_failed" }, + { LMP_PASSKEY_FAILED, "LMP_passkey_failed" }, + { LMP_OOB_FAILED, "LMP_oob_failed" }, + { LMP_KEYPRESS_NOTIFICATION, "LMP_keypress_notification" }, + { LMP_POWER_CONTROL_REQ, "LMP_power_control_req" }, + { LMP_POWER_CONTROL_RES, "LMP_power_control_res" }, + { 0, NULL } +}; + +/* LMP error codes */ +static const value_string error_code[] = { + { 0x00, "Success" }, + { 0x01, "Unknown HCI Command" }, + { 0x02, "Unknown Connection Identifier" }, + { 0x03, "Hardware Failure" }, + { 0x04, "Page Timeout" }, + { 0x05, "Authentication Failure" }, + { 0x06, "PIN or Key Missing" }, + { 0x07, "Memory Capacity Exceeded" }, + { 0x08, "Connection Timeout" }, + { 0x09, "Connection Limit Exceeded" }, + { 0x0A, "Synchronous Connection Limit To A Device Exceeded" }, + { 0x0B, "ACL Connection Already Exists" }, + { 0x0C, "Command Disallowed" }, + { 0x0D, "Connection Rejected due to Limited Resources" }, + { 0x0E, "Connection Rejected Due To Security Reasons" }, + { 0x0F, "Connection Rejected due to Unacceptable BD_ADDR" }, + { 0x10, "Connection Accept Timeout Exceeded" }, + { 0x11, "Unsupported Feature or Parameter Value" }, + { 0x12, "Invalid HCI Command Parameters" }, + { 0x13, "Remote User Terminated Connection" }, + { 0x14, "Remote Device Terminated Connection due to Low Resources" }, + { 0x15, "Remote Device Terminated Connection due to Power Off" }, + { 0x16, "Connection Terminated By Local Host" }, + { 0x17, "Repeated Attempts" }, + { 0x18, "Pairing Not Allowed" }, + { 0x19, "Unknown LMP PDU" }, + { 0x1A, "Unsupported Remote Feature / Unsupported LMP Feature" }, + { 0x1B, "SCO Offset Rejected" }, + { 0x1C, "SCO Interval Rejected" }, + { 0x1D, "SCO Air Mode Rejected" }, + { 0x1E, "Invalid LMP Parameters" }, + { 0x1F, "Unspecified Error" }, + { 0x20, "Unsupported LMP Parameter Value" }, + { 0x21, "Role Change Not Allowed" }, + { 0x22, "LMP Response Timeout" }, + { 0x23, "LMP Error Transaction Collision" }, + { 0x24, "LMP PDU Not Allowed" }, + { 0x25, "Encryption Mode Not Acceptable" }, + { 0x26, "Link Key Can Not be Changed" }, + { 0x27, "Requested QoS Not Supported" }, + { 0x28, "Instant Passed" }, + { 0x29, "Pairing With Unit Key Not Supported" }, + { 0x2A, "Different Transaction Collision" }, + { 0x2B, "Reserved" }, + { 0x2C, "QoS Unacceptable Parameter" }, + { 0x2D, "QoS Rejected" }, + { 0x2E, "Channel Classification Not Supported" }, + { 0x2F, "Insufficient Security" }, + { 0x30, "Parameter Out Of Mandatory Range" }, + { 0x31, "Reserved" }, + { 0x32, "Role Switch Pending" }, + { 0x33, "Reserved" }, + { 0x34, "Reserved Slot Violation" }, + { 0x35, "Role Switch Failed" }, + { 0x36, "Extended Inquiry Response Too Large" }, + { 0x37, "Secure Simple Pairing Not Supported By Host." }, + { 0x38, "Host Busy - Pairing" }, + { 0x39, "Connection Rejected due to No Suitable Channel Found" }, + { 0, NULL } +}; + +static const value_string encryption_mode[] = { + { 0, "no encryption" }, + { 1, "encryption" }, + { 2, "encryption" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string access_scheme[] = { + { 0, "polling technique" }, + /* 1 - 15 reserved */ + { 0, NULL } +}; + +static const value_string packet_size[] = { + { 0, "no packet-size preference available" }, + { 1, "use 1-slot packets" }, + { 2, "use 3-slot packets" }, + { 3, "use 5-slot packets" }, + { 0, NULL } +}; + +static const value_string edr_type[] = { + { 0, "use DM1 packets" }, + { 1, "use 2 Mbps packets" }, + { 2, "use 3 Mbps packets" }, + /* 3 reserved */ + { 0, NULL } +}; + +static const value_string versnr[] = { + { 0, "Bluetooth Core Specification 1.0b" }, + { 1, "Bluetooth Core Specification 1.1" }, + { 2, "Bluetooth Core Specification 1.2" }, + { 3, "Bluetooth Core Specification 2.0 + EDR" }, + { 4, "Bluetooth Core Specification 2.1 + EDR" }, + { 5, "Bluetooth Core Specification 3.0 + HS" }, + /* 6 - 255 reserved */ + { 0, NULL } +}; + +static const value_string compid[] = { + { 0, "Ericsson Technology Licensing" }, + { 1, "Nokia Mobile Phones" }, + { 2, "Intel Corp." }, + { 3, "IBM Corp." }, + { 4, "Toshiba Corp." }, + { 5, "3Com" }, + { 6, "Microsoft" }, + { 7, "Lucent" }, + { 8, "Motorola" }, + { 9, "Infineon Technologies AG" }, + { 10, "Cambridge Silicon Radio" }, + { 11, "Silicon Wave" }, + { 12, "Digianswer A/S" }, + { 13, "Texas Instruments Inc." }, + { 14, "Parthus Technologies Inc." }, + { 15, "Broadcom Corporation" }, + { 16, "Mitel Semiconductor" }, + { 17, "Widcomm, Inc." }, + { 18, "Zeevo, Inc." }, + { 19, "Atmel Corporation" }, + { 20, "Mitsubishi Electric Corporation" }, + { 21, "RTX Telecom A/S" }, + { 22, "KC Technology Inc." }, + { 23, "Newlogic" }, + { 24, "Transilica, Inc." }, + { 25, "Rohde & Schwarz GmbH & Co. KG" }, + { 26, "TTPCom Limited" }, + { 27, "Signia Technologies, Inc." }, + { 28, "Conexant Systems Inc." }, + { 29, "Qualcomm" }, + { 30, "Inventel" }, + { 31, "AVM Berlin" }, + { 32, "BandSpeed, Inc." }, + { 33, "Mansella Ltd" }, + { 34, "NEC Corporation" }, + { 35, "WavePlus Technology Co., Ltd." }, + { 36, "Alcatel" }, + { 37, "Philips Semiconductors" }, + { 38, "C Technologies" }, + { 39, "Open Interface" }, + { 40, "R F Micro Devices" }, + { 41, "Hitachi Ltd" }, + { 42, "Symbol Technologies, Inc." }, + { 43, "Tenovis" }, + { 44, "Macronix International Co. Ltd." }, + { 45, "GCT Semiconductor" }, + { 46, "Norwood Systems" }, + { 47, "MewTel Technology Inc." }, + { 48, "ST Microelectronics" }, + { 49, "Synopsys" }, + { 50, "Red-M (Communications) Ltd" }, + { 51, "Commil Ltd" }, + { 52, "Computer Access Technology Corporation (CATC)" }, + { 53, "Eclipse (HQ Espana) S.L." }, + { 54, "Renesas Technology Corp." }, + { 55, "Mobilian Corporation" }, + { 56, "Terax" }, + { 57, "Integrated System Solution Corp." }, + { 58, "Matsushita Electric Industrial Co., Ltd." }, + { 59, "Gennum Corporation" }, + { 60, "Research In Motion" }, + { 61, "IPextreme, Inc." }, + { 62, "Systems and Chips, Inc" }, + { 63, "Bluetooth SIG, Inc" }, + { 64, "Seiko Epson Corporation" }, + { 65, "Integrated Silicon Solution Taiwan, Inc." }, + { 66, "CONWISE Technology Corporation Ltd" }, + { 67, "PARROT SA" }, + { 68, "Socket Mobile" }, + { 69, "Atheros Communications, Inc." }, + { 70, "MediaTek, Inc." }, + { 71, "Bluegiga (tentative)" }, + { 72, "Marvell Technology Group Ltd." }, + { 73, "3DSP Corporation" }, + { 74, "Accel Semiconductor Ltd." }, + { 75, "Continental Automotive Systems" }, + { 76, "Apple, Inc." }, + { 77, "Staccato Communications, Inc." }, + { 78, "Avago Technologies" }, + { 79, "APT Ltd." }, + { 80, "SiRF Technology, Inc." }, + { 81, "Tzero Technologies, Inc." }, + { 82, "J&M Corporation" }, + { 83, "Free2move AB" }, + /* 84 - 65534 reserved */ + { 65535, "test" }, + { 0, NULL } +}; + +static const value_string sco_packet[] = { + { 0, "HV1" }, + { 1, "HV2" }, + { 2, "HV3" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string air_mode[] = { + { 0, "mu-law log" }, + { 1, "A-law log" }, + { 2, "CVSD" }, + { 3, "transparent data" }, + /* 4 - 255 reserved */ + { 0, NULL } +}; + +static const value_string paging_scheme[] = { + { 0, "mandatory scheme" }, + /* 1 - 255 reserved */ + { 0, NULL } +}; + +static const value_string paging_scheme_settings[] = { + /* for mandatory scheme: */ + { 0, "R0" }, + { 1, "R1" }, + { 2, "R2" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string afh_mode[] = { + { 0, "AFH disabled" }, + { 1, "AFH enabled" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string features_page[] = { + { 0, "standard features" }, + /* 1 - 255 other feature pages */ + { 0, NULL } +}; + +static const value_string packet_type_table[] = { + { 0, "1 Mbps only" }, + { 1, "2/3 Mbps" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string negotiation_state[] = { + { 0, "Initiate negotiation" }, + { 1, "The latest received set of negotiable parameters were possible but these parameters are preferred." }, + { 2, "The latest received set of negotiable parameters would cause a reserved slot violation." }, + { 3, "The latest received set of negotiable parameters would cause a latency violation." }, + { 4, "The latest received set of negotiable parameters are not supported." }, + /* 5 - 255 reserved */ + { 0, NULL } +}; + +static const value_string afh_reporting_mode[] = { + { 0, "AFH reporting disabled" }, + { 1, "AFH reporting enabled" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string io_capabilities[] = { + { 0, "Display Only" }, + { 1, "Display Yes/No" }, + { 2, "Keyboard Only" }, + { 3, "No Input/No Output" }, + /* 4 - 255 reserved */ + { 0, NULL } +}; + +static const value_string oob_auth_data[] = { + { 0, "No OOB Authentication Data received" }, + { 1, "OOB Authentication Data received" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string auth_requirements[] = { + { 0x00, "MITM Protection Not Required - No Bonding" }, + { 0x01, "MITM Protection Required - No Bonding" }, + { 0x02, "MITM Protection Not Required - Dedicated Bonding" }, + { 0x03, "MITM Protection Required - Dedicated Bonding" }, + { 0x04, "MITM Protection Not Required - General Bonding" }, + { 0x05, "MITM Protection Required - General Bonding" }, + /* 0x06 - 0xff reserved */ + { 0, NULL } +}; + +static const value_string power_adjust_req[] = { + { 0, "decrement power one step" }, + { 1, "increment power one step" }, + { 2, "increase to maximum power" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string power_adjust_res[] = { + { 0, "not supported" }, + { 1, "changed one step (not min or max)" }, + { 2, "max power" }, + { 3, "min power" }, + /* 4 - 255 reserved */ + { 0, NULL } +}; + +static const value_string test_scenario[] = { + { 0, "Pause Test Mode" }, + { 1, "Transmitter test - 0 pattern" }, + { 2, "Transmitter test - 1 pattern" }, + { 3, "Transmitter test - 1010 pattern" }, + { 4, "Pseudorandom bit sequence" }, + { 5, "Closed Loop Back - ACL packets" }, + { 6, "Closed Loop Back - Synchronous packets" }, + { 7, "ACL Packets without whitening" }, + { 8, "Synchronous Packets without whitening" }, + { 9, "Transmitter test - 1111 0000 pattern" }, + /* 10 - 254 reserved */ + { 255, "Exit Test Mode" }, + { 0, NULL } +}; + +static const value_string hopping_mode[] = { + { 0, "RX/TX on single frequency" }, + { 1, "Normal hopping" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string power_control_mode[] = { + { 0, "fixed TX output power" }, + { 1, "adaptive power control" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string esco_packet_type[] = { + { 0x00, "NULL/POLL" }, + { 0x07, "EV3" }, + { 0x0C, "EV4" }, + { 0x0D, "EV5" }, + { 0x26, "2-EV3" }, + { 0x2C, "2-EV5" }, + { 0x37, "3-EV3" }, + { 0x3D, "3-EV5" }, + /* other values reserved */ + { 0, NULL } +}; + +static const value_string notification_value[] = { + { 0, "passkey entry started" }, + { 1, "passkey digit entered" }, + { 2, "passkey digit erased" }, + { 3, "passkey cleared" }, + { 4, "passkey entry completed" }, + /* 5 - 255 reserved */ + { 0, NULL } +}; + +/* initialize the subtree pointers */ +static gint ett_lmp = -1; +static gint ett_lmp_pwradjres = -1; +static gint ett_lmp_rate = -1; +static gint ett_lmp_timectrl = -1; + +/* LMP PDUs with short opcodes */ + +void +dissect_name_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_nameoffset, tvb, offset, 1, ENC_NA); +} + +void +dissect_name_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_nameoffset, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_namelen, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_namefrag, tvb, offset, 14, ENC_ASCII|ENC_NA); +} + +void +dissect_accepted(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_NA); +} + +void +dissect_not_accepted(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_clkoffset_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_clkoffset_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_clkoffset, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_detach(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_in_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_comb_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_unit_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_key, tvb, offset, 16, ENC_NA); +} + +void +dissect_au_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_sres(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4); + + proto_tree_add_item(tree, hf_lmp_authres, tvb, offset, 4, ENC_NA); +} + +void +dissect_temp_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_temp_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_key, tvb, offset, 16, ENC_NA); +} + +void +dissect_encryption_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_cryptmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_encryption_key_size_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_keysz, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_start_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_stop_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_switch_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4); + + proto_tree_add_item(tree, hf_lmp_swinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); +} + +void +dissect_hold(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6); + + proto_tree_add_item(tree, hf_lmp_htime, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_hinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); +} + +void +dissect_hold_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6); + + proto_tree_add_item(tree, hf_lmp_htime, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_hinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); +} + +void +dissect_sniff_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 10); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_dsniff, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_tsniff, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffatt, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffto, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_unsniff_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_park_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_tb, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nb, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_deltab, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_araddr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_nbsleep, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_dbsleep, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_daccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_taccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_naccslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_npoll, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_accscheme, tvb, offset, 1, ENC_NA); +} + +void +dissect_set_broadcast_scan_window(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 6); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + } + + proto_tree_add_item(tree, hf_lmp_bsw, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_modify_beacon(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 13); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 11); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 11); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9); + } + + proto_tree_add_item(tree, hf_lmp_tb, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nb, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_deltab, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_daccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_taccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_naccslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_npoll, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_accscheme, tvb, offset, 1, ENC_NA); +} + +void +dissect_unpark_bd_addr_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + proto_item *item; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 15); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 15); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 13); + } + + proto_tree_add_item(tree, hf_lmp_ltaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_bdaddr1, tvb, offset, 6, ENC_LITTLE_ENDIAN); + offset += 6; + + proto_tree_add_item(tree, hf_lmp_bdaddr2, tvb, offset, 6, ENC_LITTLE_ENDIAN); + offset += 6; +} + +void +dissect_unpark_pm_addr_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 15); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 13); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 13); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 11); + } + + proto_tree_add_item(tree, hf_lmp_ltaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_ltaddr3, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr4, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr3, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr4, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_ltaddr5, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr6, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr5, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr6, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_ltaddr7, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr7, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_incr_power_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + + /* skipping one byte "for future use" */ +} + +void +dissect_decr_power_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + + /* skipping one byte "for future use" */ +} + +void +dissect_max_power(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_min_power(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_auto_rate(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_preferred_rate(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + proto_item *rate_item; + proto_tree *rate_tree; + + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + rate_item = proto_tree_add_item(tree, hf_lmp_rate, tvb, offset, 1, ENC_LITTLE_ENDIAN); + rate_tree = proto_item_add_subtree(rate_item, ett_lmp_rate); + + proto_tree_add_item(rate_tree, hf_lmp_rate_fec, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(rate_tree, hf_lmp_rate_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(rate_tree, hf_lmp_rate_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(rate_tree, hf_lmp_rate_edrsize, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_version_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 6); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5); + + proto_tree_add_item(tree, hf_lmp_versnr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_compid, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_subversnr, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_version_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 6); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5); + + proto_tree_add_item(tree, hf_lmp_versnr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_compid, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_subversnr, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_features_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8); + + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_features_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8); + + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_quality_of_service(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_pollintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nbc, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_quality_of_service_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_pollintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nbc, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_sco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6); + + proto_tree_add_item(tree, hf_lmp_scohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_dsco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_tsco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_scopkt, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_airmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_remove_sco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_scohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_max_slot(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_maxslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_max_slot_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_maxslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_timing_accuracy_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_timing_accuracy_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_drift, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_jitter, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_setup_complete(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_use_semi_permanent_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_host_connection_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_slot_offset(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8); + + proto_tree_add_item(tree, hf_lmp_slotoffset, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_bdaddr, tvb, offset, 6, ENC_LITTLE_ENDIAN); +} + +void +dissect_page_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_pagesch, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pssettings, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_page_scan_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_pagesch, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pssettings, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_supervision_timeout(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_suptimeout, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_test_activate(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_test_control(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 10); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9); + + /* FIXME these fields should all be XORed with 0x55. . . */ + + proto_tree_add_item(tree, hf_lmp_testscen, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_hopmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_txfreq, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_rxfreq, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pcmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pollper, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pkttype, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_testlen, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_encryption_key_size_mask_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_encryption_key_size_mask_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_ksmask, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_set_afh(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 16); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 15); + + proto_tree_add_item(tree, hf_lmp_afhinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 4; + + proto_tree_add_item(tree, hf_lmp_afhmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_afhchmap, tvb, offset, 10, ENC_NA); +} + +void +dissect_encapsulated_header(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_encmaj, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_encmin, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_enclen, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_encapsulated_payload(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_encdata, tvb, offset, 16, ENC_NA); +} + +void +dissect_simple_pairing_confirm(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_commit, tvb, offset, 16, ENC_NA); +} + +void +dissect_simple_pairing_number(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_nonce, tvb, offset, 16, ENC_NA); +} + +void +dissect_dhkey_check(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_confirm, tvb, offset, 16, ENC_NA); +} + +/* LMP PDUs with extended opcodes */ + +void +dissect_accepted_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_eopinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_not_accepted_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_eopinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_features_req_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 12); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10); + + proto_tree_add_item(tree, hf_lmp_fpage, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maxsp, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + /* + * extended features might need to be different from hf_lmp_features + * if hf_lmp_features is broken out + */ + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_features_res_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 12); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10); + + proto_tree_add_item(tree, hf_lmp_fpage, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maxsp, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + /* + * extended features might need to be different from hf_lmp_features + * if hf_lmp_features is broken out + */ + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_packet_type_table_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_pkttypetbl, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_esco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 16); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 14); + + proto_tree_add_item(tree, hf_lmp_escohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escoltaddr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_desco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_tesco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_wesco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escotypems, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escotypesm, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escolenms, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_escolensm, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_airmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_negstate, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_remove_esco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_escohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_channel_classification_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5); + + proto_tree_add_item(tree, hf_lmp_afhrptmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_afhminintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_afhmaxintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_channel_classification(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 12); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10); + + proto_tree_add_item(tree, hf_lmp_afhclass, tvb, offset, 10, ENC_NA); +} + +void +dissect_sniff_subrating_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 7); + + proto_tree_add_item(tree, hf_lmp_maxss, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_minsmt, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffsi, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_sniff_subrating_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 7); + + proto_tree_add_item(tree, hf_lmp_maxss, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_minsmt, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffsi, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_pause_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_resume_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_io_capability_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_iocaps, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_oobauthdata, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_authreqs, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_io_capability_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_iocaps, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_oobauthdata, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_authreqs, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_numeric_comparison_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_passkey_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_oob_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_keypress_notification(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_nottype, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_power_control_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_pwradjreq, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_power_control_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + proto_item *pa_item; + proto_tree *pa_tree; + + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + pa_item = proto_tree_add_item(tree, hf_lmp_pwradjres, tvb, offset, 1, ENC_LITTLE_ENDIAN); + pa_tree = proto_item_add_subtree(pa_item, ett_lmp_pwradjres); + + proto_tree_add_item(pa_tree, hf_lmp_pwradj_gfsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(pa_tree, hf_lmp_pwradj_dqpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(pa_tree, hf_lmp_pwradj_8dpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +/* Link Manager Protocol */ +static void +dissect_btbrlmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *lmp_item; + proto_tree *lmp_tree; + int offset; + int len; + int op; /* opcode */ + int eop; /* extended opcode */ + + offset = 0; + len = tvb_length(tvb); + + DISSECTOR_ASSERT(len >= 1); + + /* make entries in protocol column and info column on summary display */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "LMP"); + + /* clear the info column first just in case of type fetching failure. */ + col_clear(pinfo->cinfo, COL_INFO); + + op = tvb_get_guint8(tvb, offset) >> 1; + + if (op == LMP_ESCAPE_4) { + DISSECTOR_ASSERT(len >= 2); + + eop = tvb_get_guint8(tvb, offset + 1); + + col_add_str(pinfo->cinfo, COL_INFO, val_to_str(eop, + opcode, "Unknown Extended Opcode (%d)")); + } else { + col_add_str(pinfo->cinfo, COL_INFO, val_to_str(op, + opcode, "Unknown Opcode (%d)")); + } + + /* see if we are being asked for details */ + if (!tree) + return; + + lmp_item = proto_tree_add_item(tree, proto_btbrlmp, tvb, offset, -1, ENC_NA); + lmp_tree = proto_item_add_subtree(lmp_item, ett_lmp); + + proto_tree_add_item(lmp_tree, hf_lmp_tid, tvb, offset, 1, ENC_LITTLE_ENDIAN); + + proto_tree_add_item(lmp_tree, hf_lmp_op, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + switch (op) { + case LMP_NAME_REQ: + dissect_name_req(lmp_tree, tvb, offset, len); + break; + case LMP_NAME_RES: + dissect_name_res(lmp_tree, tvb, offset, len); + break; + case LMP_ACCEPTED: + dissect_accepted(lmp_tree, tvb, offset, len); + break; + case LMP_NOT_ACCEPTED: + dissect_not_accepted(lmp_tree, tvb, offset, len); + break; + case LMP_CLKOFFSET_REQ: + dissect_clkoffset_req(lmp_tree, tvb, offset, len); + break; + case LMP_CLKOFFSET_RES: + dissect_clkoffset_res(lmp_tree, tvb, offset, len); + break; + case LMP_DETACH: + dissect_detach(lmp_tree, tvb, offset, len); + break; + case LMP_IN_RAND: + dissect_in_rand(lmp_tree, tvb, offset, len); + break; + case LMP_COMB_KEY: + dissect_comb_key(lmp_tree, tvb, offset, len); + break; + case LMP_UNIT_KEY: + dissect_unit_key(lmp_tree, tvb, offset, len); + break; + case LMP_AU_RAND: + dissect_au_rand(lmp_tree, tvb, offset, len); + break; + case LMP_SRES: + dissect_sres(lmp_tree, tvb, offset, len); + break; + case LMP_TEMP_RAND: + dissect_temp_rand(lmp_tree, tvb, offset, len); + break; + case LMP_TEMP_KEY: + dissect_temp_key(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_MODE_REQ: + dissect_encryption_mode_req(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_KEY_SIZE_REQ: + dissect_encryption_key_size_req(lmp_tree, tvb, offset, len); + break; + case LMP_START_ENCRYPTION_REQ: + dissect_start_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_STOP_ENCRYPTION_REQ: + dissect_stop_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_SWITCH_REQ: + dissect_switch_req(lmp_tree, tvb, offset, len); + break; + case LMP_HOLD: + dissect_hold(lmp_tree, tvb, offset, len); + break; + case LMP_HOLD_REQ: + dissect_hold_req(lmp_tree, tvb, offset, len); + break; + case LMP_SNIFF_REQ: + dissect_sniff_req(lmp_tree, tvb, offset, len); + break; + case LMP_UNSNIFF_REQ: + dissect_unsniff_req(lmp_tree, tvb, offset, len); + break; + case LMP_PARK_REQ: + dissect_park_req(lmp_tree, tvb, offset, len); + break; + case LMP_SET_BROADCAST_SCAN_WINDOW: + dissect_set_broadcast_scan_window(lmp_tree, tvb, offset, len); + break; + case LMP_MODIFY_BEACON: + dissect_modify_beacon(lmp_tree, tvb, offset, len); + break; + case LMP_UNPARK_BD_ADDR_REQ: + dissect_unpark_bd_addr_req(lmp_tree, tvb, offset, len); + break; + case LMP_UNPARK_PM_ADDR_REQ: + dissect_unpark_pm_addr_req(lmp_tree, tvb, offset, len); + break; + case LMP_INCR_POWER_REQ: + dissect_incr_power_req(lmp_tree, tvb, offset, len); + break; + case LMP_DECR_POWER_REQ: + dissect_decr_power_req(lmp_tree, tvb, offset, len); + break; + case LMP_MAX_POWER: + dissect_max_power(lmp_tree, tvb, offset, len); + break; + case LMP_MIN_POWER: + dissect_min_power(lmp_tree, tvb, offset, len); + break; + case LMP_AUTO_RATE: + dissect_auto_rate(lmp_tree, tvb, offset, len); + break; + case LMP_PREFERRED_RATE: + dissect_preferred_rate(lmp_tree, tvb, offset, len); + break; + case LMP_VERSION_REQ: + dissect_version_req(lmp_tree, tvb, offset, len); + break; + case LMP_VERSION_RES: + dissect_version_res(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_REQ: + dissect_features_req(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_RES: + dissect_features_res(lmp_tree, tvb, offset, len); + break; + case LMP_QUALITY_OF_SERVICE: + dissect_quality_of_service(lmp_tree, tvb, offset, len); + break; + case LMP_QUALITY_OF_SERVICE_REQ: + dissect_quality_of_service_req(lmp_tree, tvb, offset, len); + break; + case LMP_SCO_LINK_REQ: + dissect_sco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_REMOVE_SCO_LINK_REQ: + dissect_remove_sco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_MAX_SLOT: + dissect_max_slot(lmp_tree, tvb, offset, len); + break; + case LMP_MAX_SLOT_REQ: + dissect_max_slot_req(lmp_tree, tvb, offset, len); + break; + case LMP_TIMING_ACCURACY_REQ: + dissect_timing_accuracy_req(lmp_tree, tvb, offset, len); + break; + case LMP_TIMING_ACCURACY_RES: + dissect_timing_accuracy_res(lmp_tree, tvb, offset, len); + break; + case LMP_SETUP_COMPLETE: + dissect_setup_complete(lmp_tree, tvb, offset, len); + break; + case LMP_USE_SEMI_PERMANENT_KEY: + dissect_use_semi_permanent_key(lmp_tree, tvb, offset, len); + break; + case LMP_HOST_CONNECTION_REQ: + dissect_host_connection_req(lmp_tree, tvb, offset, len); + break; + case LMP_SLOT_OFFSET: + dissect_slot_offset(lmp_tree, tvb, offset, len); + break; + case LMP_PAGE_MODE_REQ: + dissect_page_mode_req(lmp_tree, tvb, offset, len); + break; + case LMP_PAGE_SCAN_MODE_REQ: + dissect_page_scan_mode_req(lmp_tree, tvb, offset, len); + break; + case LMP_SUPERVISION_TIMEOUT: + dissect_supervision_timeout(lmp_tree, tvb, offset, len); + break; + case LMP_TEST_ACTIVATE: + dissect_test_activate(lmp_tree, tvb, offset, len); + break; + case LMP_TEST_CONTROL: + dissect_test_control(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_KEY_SIZE_MASK_REQ: + dissect_encryption_key_size_mask_req(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_KEY_SIZE_MASK_RES: + dissect_encryption_key_size_mask_res(lmp_tree, tvb, offset, len); + break; + case LMP_SET_AFH: + dissect_set_afh(lmp_tree, tvb, offset, len); + break; + case LMP_ENCAPSULATED_HEADER: + dissect_encapsulated_header(lmp_tree, tvb, offset, len); + break; + case LMP_ENCAPSULATED_PAYLOAD: + dissect_encapsulated_payload(lmp_tree, tvb, offset, len); + break; + case LMP_SIMPLE_PAIRING_CONFIRM: + dissect_simple_pairing_confirm(lmp_tree, tvb, offset, len); + break; + case LMP_SIMPLE_PAIRING_NUMBER: + dissect_simple_pairing_number(lmp_tree, tvb, offset, len); + break; + case LMP_DHKEY_CHECK: + dissect_dhkey_check(lmp_tree, tvb, offset, len); + break; + case LMP_ESCAPE_1: + break; + case LMP_ESCAPE_2: + break; + case LMP_ESCAPE_3: + break; + case LMP_ESCAPE_4: + /* extended opcode */ + DISSECTOR_ASSERT(len >= 2); + proto_tree_add_item(lmp_tree, hf_lmp_eop, tvb, offset, 1, ENC_NA); + offset += 1; + + switch (eop) { + case LMP_ACCEPTED_EXT: + dissect_accepted_ext(lmp_tree, tvb, offset, len); + break; + case LMP_NOT_ACCEPTED_EXT: + dissect_not_accepted_ext(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_REQ_EXT: + dissect_features_req_ext(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_RES_EXT: + dissect_features_res_ext(lmp_tree, tvb, offset, len); + break; + case LMP_PACKET_TYPE_TABLE_REQ: + dissect_packet_type_table_req(lmp_tree, tvb, offset, len); + break; + case LMP_ESCO_LINK_REQ: + dissect_esco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_REMOVE_ESCO_LINK_REQ: + dissect_remove_esco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_CHANNEL_CLASSIFICATION_REQ: + dissect_channel_classification_req(lmp_tree, tvb, offset, len); + break; + case LMP_CHANNEL_CLASSIFICATION: + dissect_channel_classification(lmp_tree, tvb, offset, len); + break; + case LMP_SNIFF_SUBRATING_REQ: + dissect_sniff_subrating_req(lmp_tree, tvb, offset, len); + break; + case LMP_SNIFF_SUBRATING_RES: + dissect_sniff_subrating_res(lmp_tree, tvb, offset, len); + break; + case LMP_PAUSE_ENCRYPTION_REQ: + dissect_pause_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_RESUME_ENCRYPTION_REQ: + dissect_resume_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_IO_CAPABILITY_REQ: + dissect_io_capability_req(lmp_tree, tvb, offset, len); + break; + case LMP_IO_CAPABILITY_RES: + dissect_io_capability_res(lmp_tree, tvb, offset, len); + break; + case LMP_NUMERIC_COMPARISON_FAILED: + dissect_numeric_comparison_failed(lmp_tree, tvb, offset, len); + break; + case LMP_PASSKEY_FAILED: + dissect_passkey_failed(lmp_tree, tvb, offset, len); + break; + case LMP_OOB_FAILED: + dissect_oob_failed(lmp_tree, tvb, offset, len); + break; + case LMP_KEYPRESS_NOTIFICATION: + dissect_keypress_notification(lmp_tree, tvb, offset, len); + break; + case LMP_POWER_CONTROL_REQ: + dissect_power_control_req(lmp_tree, tvb, offset, len); + break; + case LMP_POWER_CONTROL_RES: + dissect_power_control_res(lmp_tree, tvb, offset, len); + break; + default: + break; + } + default: + break; + } +}; + +/* register the protocol with Wireshark */ +void +proto_register_btbrlmp(void) +{ + + /* list of fields */ + static hf_register_info hf[] = { + { &hf_lmp_accscheme, + { "Access Scheme", "btbrlmp.accscheme", + FT_UINT8, BASE_DEC, VALS(access_scheme), 0xf0, + NULL, HFILL } + }, + { &hf_lmp_afhchmap, + { "AFH Channel Map", "btbrlmp.afhchmap", + /* could break out individual channels but long */ + FT_BYTES, BASE_NONE, NULL, 0x0, + "Adaptive Frequency Hopping Channel Map", HFILL } + }, + { &hf_lmp_afhclass, + { "AFH Channel Classification", "btbrlmp.afhclass", + /* could break out individual channels but long */ + FT_BYTES, BASE_NONE, NULL, 0x0, + "Adaptive Frequency Hopping Channel Classification", HFILL } + }, + { &hf_lmp_afhinst, + { "AFH Instant", "btbrlmp.afhinst", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Adaptive Frequency Hopping Instant (slot)", HFILL } + }, + { &hf_lmp_afhmaxintvl, + { "AFH Max Interval", "btbrlmp.maxintvl", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Adaptive Maximum Interval in slots", HFILL } + }, + { &hf_lmp_afhminintvl, + { "AFH Min Interval", "btbrlmp.minintvl", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Adaptive Minimum Interval in slots", HFILL } + }, + { &hf_lmp_afhmode, + { "AFH Mode", "btbrlmp.afhmode", + FT_UINT8, BASE_DEC, VALS(afh_mode), 0x0, + "Adaptive Frequency Hopping Mode", HFILL } + }, + { &hf_lmp_afhrptmode, + { "AFH Reporting Mode", "btbrlmp.afhrptmode", + FT_UINT8, BASE_DEC, VALS(afh_reporting_mode), 0x0, + "Adaptive Frequency Hopping Reporting Mode", HFILL } + }, + { &hf_lmp_airmode, + { "Air Mode", "btbrlmp.airmode", + FT_UINT8, BASE_HEX, VALS(air_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_araddr, + { "AR_ADDR", "btbrlmp.araddr", + FT_UINT8, BASE_HEX, NULL, 0xfe, + NULL, HFILL } + }, + { &hf_lmp_authreqs, + { "Authentication Requirements", "btbrlmp.authreqs", + FT_UINT8, BASE_HEX, VALS(auth_requirements), 0xf0, + NULL, HFILL } + }, + { &hf_lmp_authres, + { "Authentication Response", "btbrlmp.authres", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_bdaddr, + { "BD_ADDR", "btbrlmp.bdaddr", + FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff, + NULL, HFILL } + }, + { &hf_lmp_bdaddr1, + { "BD_ADDR 1", "btbrlmp.bdaddr", + FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff, + NULL, HFILL } + }, + { &hf_lmp_bdaddr2, + { "BD_ADDR2", "btbrlmp.bdaddr", + FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff, + "BD_ADDR 2", HFILL } + }, + { &hf_lmp_bsw, + { "Broadcast Scan Window", "btbrlmp.bsw", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Broadcast Scan Window in slots", HFILL } + }, + { &hf_lmp_clkoffset, + { "Clock Offset", "btbrlmp.clkoffset", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Clock Offset in units of 1.25 ms", HFILL } + }, + { &hf_lmp_commit, + { "Commitment Value", "btbrlmp.commit", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_confirm, + { "Confirmation Value", "btbrlmp.confirm", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_compid, + { "Company ID", "btbrlmp.compid", + FT_UINT16, BASE_DEC, VALS(compid), 0x0, + NULL, HFILL } + }, + { &hf_lmp_cryptmode, + { "Encryption Mode", "btbrlmp.cryptmode", + FT_UINT8, BASE_DEC, VALS(encryption_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_daccess, + { "Daccess", "btbrlmp.daccess", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Daccess in slots", HFILL } + }, + { &hf_lmp_db, + { "Db", "btbrlmp.db", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Db in slots", HFILL } + }, + { &hf_lmp_dbsleep, + { "Dbsleep", "btbrlmp.dbsleep", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_deltab, + { "Deltab", "btbrlmp.deltab", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Deltab in slots", HFILL } + }, + { &hf_lmp_desco, + { "Desco", "btbrlmp.desco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Desco in slots", HFILL } + }, + { &hf_lmp_drift, + { "Drift", "btbrlmp.drift", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Drift in ppm", HFILL } + }, + { &hf_lmp_dsco, + { "Dsco", "btbrlmp.dsco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Dsco in slots", HFILL } + }, + { &hf_lmp_dsniff, + { "Dsniff", "btbrlmp.dsniff", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Dsniff in slots", HFILL } + }, + { &hf_lmp_encdata, + { "Encapsulated Data", "btbrlmp.encdata", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_enclen, + { "Encapsulated Length", "btbrlmp.enclen", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_encmaj, + { "Encapsulated Major Type", "btbrlmp.encmaj", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_encmin, + { "Encapsulated Minor Type", "btbrlmp.encmin", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_eop, + { "Extended Opcode", "btbrlmp.eop", + FT_UINT8, BASE_DEC, VALS(ext_opcode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_eopinre, + { "In Response To", "btbrlmp.eopinre", + FT_UINT8, BASE_DEC, VALS(ext_opcode), 0x0, + "Extended Opcode this is in response to", HFILL } + }, + { &hf_lmp_escolenms, + { "Packet Length M -> S", "btbrlmp.escolenms", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Packet Length in bytes Master to Slave", HFILL } + }, + { &hf_lmp_escolensm, + { "Packet Length S -> M", "btbrlmp.escolensm", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Packet Length in bytes Slave to Master", HFILL } + }, + { &hf_lmp_escotypems, + { "eSCO Packet Type M -> S", "btbrlmp.escotypems", + FT_UINT8, BASE_HEX, VALS(esco_packet_type), 0x0, + "eSCO Packet Type Master to Slave", HFILL } + }, + { &hf_lmp_escotypesm, + { "eSCO Packet Type S -> M", "btbrlmp.escotypesm", + FT_UINT8, BASE_HEX, VALS(esco_packet_type), 0x0, + "eSCO Packet Type Slave to Master", HFILL } + }, + { &hf_lmp_err, + { "Error Code", "btbrlmp.err", + FT_UINT8, BASE_HEX, VALS(error_code), 0x0, + NULL, HFILL } + }, + { &hf_lmp_escohdl, + { "eSCO Handle", "btbrlmp.escohdl", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_escoltaddr, + { "eSCO LT_ADDR", "btbrlmp.escoltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0, + "eSCO Logical Transport Address", HFILL } + }, + { &hf_lmp_features, + { "Features", "btbrlmp.features", + /* could break out individual features but long */ + FT_BYTES, BASE_NONE, NULL, 0x0, + "Feature Mask", HFILL } + }, + { &hf_lmp_fpage, + { "Features Page", "btbrlmp.fpage", + FT_UINT8, BASE_DEC, VALS(features_page), 0x0, + NULL, HFILL } + }, + { &hf_lmp_htime, + { "Hold Time", "btbrlmp.htime", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Hold Time in slots", HFILL } + }, + { &hf_lmp_hinst, + { "Hold Instant", "btbrlmp.hinst", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Hold Instant (slot)", HFILL } + }, + { &hf_lmp_hopmode, + { "Hopping Mode", "btbrlmp.hopmode", + FT_UINT8, BASE_DEC, VALS(hopping_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_iocaps, + { "IO Capabilities", "btbrlmp.iocaps", + FT_UINT8, BASE_DEC, VALS(io_capabilities), 0x0, + "Input/Output Capabilities", HFILL } + }, + { &hf_lmp_jitter, + { "Jitter", "btbrlmp.jitter", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Jitter in microseconds", HFILL } + }, + { &hf_lmp_key, + { "Key", "btbrlmp.key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_keysz, + { "Key Size", "btbrlmp.keysz", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Key Size in bytes", HFILL } + }, + { &hf_lmp_ksmask, + { "Key Size Mask", "btbrlmp.ksmask", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_ltaddr1, + { "LT_ADDR 1", "btbrlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 1", HFILL } + }, + { &hf_lmp_ltaddr2, + { "LT_ADDR 2", "btbrlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0xf0, + "Logical Transport Address 2", HFILL } + }, + { &hf_lmp_ltaddr3, + { "LT_ADDR 3", "btbrlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 3", HFILL } + }, + { &hf_lmp_ltaddr4, + { "LT_ADDR 4", "btbrlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0xf0, + "Logical Transport Address 4", HFILL } + }, + { &hf_lmp_ltaddr5, + { "LT_ADDR 5", "btbrlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 5", HFILL } + }, + { &hf_lmp_ltaddr6, + { "LT_ADDR 6", "btbrlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0xf0, + "Logical Transport Address 6", HFILL } + }, + { &hf_lmp_ltaddr7, + { "LT_ADDR 7", "btbrlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 7", HFILL } + }, + { &hf_lmp_maccess, + { "Maccess", "btbrlmp.maccess", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Number of access windows", HFILL } + }, + { &hf_lmp_maxslots, + { "Max Slots", "btbrlmp.maxslots", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_maxsp, + { "Max Supported Page", "btbrlmp.maxsp", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Highest extended features page with non-zero bit", HFILL } + }, + { &hf_lmp_maxss, + { "Max Sniff Subrate", "btbrlmp.maxss", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_minsmt, + { "Min Sniff Mode Timeout", "btbrlmp.minsmt", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Min Sniff Mode Timeout in slots", HFILL } + }, + { &hf_lmp_naccslots, + { "Nacc-slots", "btbrlmp.naccslots", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_namefrag, + { "Name Fragment", "btbrlmp.namefrag", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_namelen, + { "Name Length", "btbrlmp.namelen", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Name Length in bytes", HFILL } + }, + { &hf_lmp_nameoffset, + { "Name Offset", "btbrlmp.nameoffset", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Name Offset in bytes", HFILL } + }, + { &hf_lmp_nb, + { "Nb", "btbrlmp.nb", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_nbc, + { "Nbc", "btbrlmp.nbc", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_nbsleep, + { "Nbsleep", "btbrlmp.nbsleep", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_negstate, + { "Negotiation State", "btbrlmp.negstate", + FT_UINT8, BASE_DEC, VALS(negotiation_state), 0x0, + NULL, HFILL } + }, + { &hf_lmp_nonce, + { "Nonce Value", "btbrlmp.nonce", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_nottype, + { "Notification Type", "btbrlmp.nottype", + FT_UINT8, BASE_DEC, VALS(notification_value), 0x0, + NULL, HFILL } + }, + { &hf_lmp_npoll, + { "Npoll", "btbrlmp.npoll", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_oobauthdata, + { "OOB Authentication Data", "btbrlmp.oobauthdata", + FT_UINT8, BASE_DEC, VALS(oob_auth_data), 0xfe, + NULL, HFILL } + }, + { &hf_lmp_op, + { "Opcode", "btbrlmp.op", + FT_UINT8, BASE_DEC, VALS(opcode), 0xfe, + NULL, HFILL } + }, + { &hf_lmp_opinre, + { "In Response To", "btbrlmp.opinre", + FT_UINT8, BASE_DEC, VALS(opcode), 0x7f, + "Opcode this is in response to", HFILL } + }, + { &hf_lmp_pagesch, + { "Paging Scheme", "btbrlmp.pagesch", + FT_UINT8, BASE_DEC, VALS(paging_scheme), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pcmode, + { "Power Control Mode", "btbrlmp.pcmode", + FT_UINT8, BASE_DEC, VALS(power_control_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pkttype, + { "Packet Type", "btbrlmp.pkttype", + /* FIXME break out further */ + FT_UINT8, BASE_HEX, NULL, 0x0, + "Packet Type", HFILL } + }, + { &hf_lmp_pkttypetbl, + { "Packet Type Table", "btbrlmp.pkttypetbl", + FT_UINT8, BASE_DEC, VALS(packet_type_table), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr, + { "PM_ADDR", "btbrlmp.pmaddr", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr1, + { "PM_ADDR 1", "btbrlmp.pmaddr1", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr2, + { "PM_ADDR 2", "btbrlmp.pmaddr2", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr3, + { "PM_ADDR 3", "btbrlmp.pmaddr3", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr4, + { "PM_ADDR 4", "btbrlmp.pmaddr4", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr5, + { "PM_ADDR 5", "btbrlmp.pmaddr5", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr6, + { "PM_ADDR 6", "btbrlmp.pmaddr6", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr7, + { "PM_ADDR 7", "btbrlmp.pmaddr7", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pollintvl, + { "Poll Interval", "btbrlmp.pollintvl", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Poll Interval in slots", HFILL } + }, + { &hf_lmp_pollper, + { "Poll Period", "btbrlmp.pollper", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Poll Period in units of 1.25 ms", HFILL } + }, + { &hf_lmp_pssettings, + { "Paging Scheme Settings", "btbrlmp.pssettings", + FT_UINT8, BASE_DEC, VALS(paging_scheme_settings), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pwradjreq, + { "Power Adjustment Request", "btbrlmp.pwradjreq", + FT_UINT8, BASE_DEC, VALS(power_adjust_req), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pwradjres, + { "Power Adjustment Response", "btbrlmp.pwradjres", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pwradj_8dpsk, + { "8DPSK", "btbrlmp.pwradj_8dpsk", + FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x30, + "8DPSK Power Adjustment Response", HFILL } + }, + { &hf_lmp_pwradj_dqpsk, + { "DQPSK", "btbrlmp.pwradj_dqpsk", + FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x0C, + "DQPSK Power Adjustment Response", HFILL } + }, + { &hf_lmp_pwradj_gfsk, + { "GFSK", "btbrlmp.pwradj_gfsk", + FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x03, + "GFSK Power Adjustment Response", HFILL } + }, + { &hf_lmp_rand, + { "Random Number", "btbrlmp.rand", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_rate, + { "Data Rate", "btbrlmp.rate", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_rate_fec, + { "FEC", "btbrlmp.rate.fec", + FT_BOOLEAN, BASE_DEC, TFS(&fec), 0x01, + "Forward Error Correction", HFILL } + }, + { &hf_lmp_rate_size, + { "Packet Size", "btbrlmp.rate.size", + FT_UINT8, BASE_HEX, VALS(packet_size), 0x06, + "Basic Rate Packet Size", HFILL } + }, + { &hf_lmp_rate_type, + { "EDR Type", "btbrlmp.rate.type", + FT_UINT8, BASE_HEX, VALS(edr_type), 0x18, + "Enhanced Data Rate type", HFILL } + }, + { &hf_lmp_rate_edrsize, + { "EDR Size", "btbrlmp.rate.edrsize", + FT_UINT8, BASE_HEX, VALS(packet_size), 0x60, + "Enhanced Data Rate packet size", HFILL } + }, + { &hf_lmp_rxfreq, + { "RX Frequency", "btbrlmp.rxfreq", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Receive Frequency in MHz above 2402", HFILL } + }, + { &hf_lmp_scohdl, + { "SCO Handle", "btbrlmp.scohdl", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_scopkt, + { "SCO Packet", "btbrlmp.scopkt", + FT_UINT8, BASE_DEC, VALS(sco_packet), 0x0, + NULL, HFILL } + }, + { &hf_lmp_slotoffset, + { "Slot Offset", "btbrlmp.slotoffset", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Slot Offset in microseconds", HFILL } + }, + { &hf_lmp_sniffatt, + { "Sniff Attempt", "btbrlmp.sniffatt", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Number of receive slots", HFILL } + }, + { &hf_lmp_sniffsi, + { "Sniff Subrating Instant", "btbrlmp.sniffsi", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Sniff Subrating Instant (slot)", HFILL } + }, + { &hf_lmp_sniffto, + { "Sniff Timeout", "btbrlmp.sniffto", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Number of receive slots", HFILL } + }, + { &hf_lmp_subversnr, + { "SubVersNr", "btbrlmp.subversnr", + FT_UINT16, BASE_DEC, NULL, 0x0, + "SubVersion", HFILL } + }, + { &hf_lmp_suptimeout, + { "Supervision Timeout", "btbrlmp.suptimeout", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Supervision Timeout in slots", HFILL } + }, + { &hf_lmp_swinst, + { "Switch Instant", "btbrlmp.swinst", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Switch Instant (slot)", HFILL } + }, + { &hf_lmp_taccess, + { "Taccess", "btbrlmp.taccess", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Taccess in slots", HFILL } + }, + { &hf_lmp_tb, + { "Tb", "btbrlmp.tb", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Tb in slots", HFILL } + }, + { &hf_lmp_tesco, + { "Tesco", "btbrlmp.tesco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Tesco in slots", HFILL } + }, + { &hf_lmp_testlen, + { "Test Length", "btbrlmp.testlen", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Length of test sequence in bytes", HFILL } + }, + { &hf_lmp_testscen, + { "Test Scenario", "btbrlmp.testscen", + FT_UINT8, BASE_DEC, VALS(test_scenario), 0x0, + NULL, HFILL } + }, + { &hf_lmp_tid, + { "TID", "btbrlmp.tid", + FT_BOOLEAN, BASE_DEC, TFS(&tid), 0x01, + "Transaction ID", HFILL } + }, + { &hf_lmp_timectrl, + { "Timing Control Flags", "btbrlmp.timectrl", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_time_change, + { "Timing Change", "btbrlmp.time.change", + FT_BOOLEAN, 8, TFS(&time_change), 0x01, + NULL, HFILL } + }, + { &hf_lmp_time_init, + { "Initialization", "btbrlmp.time.init", + FT_BOOLEAN, 8, TFS(&time_init), 0x02, + NULL, HFILL } + }, + { &hf_lmp_time_accwin, + { "Access Window", "btbrlmp.time.accwin", + FT_BOOLEAN, 8, TFS(&time_accwin), 0x04, + NULL, HFILL } + }, + { &hf_lmp_tsco, + { "Tsco", "btbrlmp.tsco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Tsco in slots", HFILL } + }, + { &hf_lmp_tsniff, + { "Tsniff", "btbrlmp.tsniff", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Tsniff in slots", HFILL } + }, + { &hf_lmp_txfreq, + { "TX Frequency", "btbrlmp.txfreq", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Transmit Frequency in MHz above 2402", HFILL } + }, + { &hf_lmp_versnr, + { "VersNr", "btbrlmp.versnr", + FT_UINT8, BASE_DEC, VALS(versnr), 0x0, + "Version", HFILL } + }, + { &hf_lmp_wesco, + { "Wesco", "btbrlmp.wesco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Number of slots in retransmission window", HFILL } + }, + }; + + /* protocol subtree arrays */ + static gint *ett[] = { + &ett_lmp, + &ett_lmp_pwradjres, + &ett_lmp_rate, + &ett_lmp_timectrl, + }; + + /* register the protocol name and description */ + proto_btbrlmp = proto_register_protocol( + "Bluetooth BR Link Manager Protocol", /* full name */ + "btbrlmp", /* short name */ + "btbrlmp" /* abbreviation (e.g. for filters) */ + ); + + register_dissector("btbrlmp", dissect_btbrlmp, proto_btbrlmp); + + /* register the header fields and subtrees used */ + proto_register_field_array(proto_btbrlmp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_btbrlmp(void) +{ +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/plugin.rc.in b/libbtbb-2015-10-R1/wireshark/plugins/btbb/plugin.rc.in new file mode 100644 index 0000000..568dc07 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/plugin.rc.in @@ -0,0 +1,34 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @RC_MODULE_VERSION@ + PRODUCTVERSION @RC_VERSION@ + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0" + VALUE "FileDescription", "@PACKAGE@ dissector\0" + VALUE "FileVersion", "@MODULE_VERSION@\0" + VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0" + VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs , Gilbert Ramirez and others\0" + VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0" + VALUE "ProductName", "Wireshark\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "Comments", "Build with @MSVC_VARIANT@\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/tools/make-dissector-reg b/libbtbb-2015-10-R1/wireshark/plugins/btbb/tools/make-dissector-reg new file mode 100755 index 0000000..d2efa7c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/tools/make-dissector-reg @@ -0,0 +1,186 @@ +#! /bin/sh + +# +# $Id: make-dissector-reg 21716 2007-05-07 17:55:42Z gal $ +# + +# +# The first argument is the directory in which the source files live. +# +srcdir="$1" +shift + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype="$1" +shift +if [ "$registertype" = plugin ] +then + outfile="plugin.c" +elif [ "$registertype" = dissectors ] +then + outfile="register.c" +else + echo "Unknown output type '$registertype'" 1>&2 + exit 1 +fi + +# +# All subsequent arguments are the files to scan. +# +rm -f ${outfile}-tmp +echo '/* Do not modify this file. */' >${outfile}-tmp +echo '/* It is created automatically by the Makefile. */'>>${outfile}-tmp +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp + +fi +echo '}' >>${outfile}-tmp + + +# +# Build code to call all the protocol handoff registration routines. +# +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +fi +echo '}' >>${outfile}-tmp +if [ "$registertype" = plugin ] +then + echo '#endif' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +gulong register_count(void) +{ +EOF + proto_regs=`grep RA_REGISTER ${outfile}-tmp | wc -l` + handoff_regs=`grep RA_HANDOFF ${outfile}-tmp | wc -l` + echo " return $proto_regs + $handoff_regs;" >>${outfile}-tmp + echo '}' >>${outfile}-tmp +fi +mv ${outfile}-tmp ${outfile} diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbb/tools/make-dissector-reg.py b/libbtbb-2015-10-R1/wireshark/plugins/btbb/tools/make-dissector-reg.py new file mode 100755 index 0000000..060460c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbb/tools/make-dissector-reg.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# +# Looks for registration routines in the protocol dissectors, +# and assembles C code to call all the routines. +# +# This is a Python version of the make-reg-dotc shell script. +# Running the shell script on Win32 is very very slow because of +# all the process-launching that goes on --- multiple greps and +# seds for each input file. I wrote this python version so that +# less processes would have to be started. +# +# $Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $ + +import os +import sys +import re +import pickle +from stat import * + +VERSION_KEY = '_VERSION' +CUR_VERSION = '$Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $' + +# +# The first argument is the directory in which the source files live. +# +srcdir = sys.argv[1] + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype = sys.argv[2] +if registertype == "plugin" or registertype == "plugin_wtap": + tmp_filename = "plugin.c-tmp" + final_filename = "plugin.c" + cache_filename = None + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by Makefile or Makefile.nmake. + */ +""" +elif registertype == "dissectors": + tmp_filename = "register.c-tmp" + final_filename = "register.c" + cache_filename = "register-cache.pkl" + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by the "register.c" target in + * epan/dissectors/Makefile or Makefile.nmake using information in + * epan/dissectors/register-cache.pkl. + * + * You can force this file to be regenerated completely by deleting + * it along with epan/dissectors/register-cache.pkl. + */ +""" +else: + print(("Unknown output type '%s'" % registertype)) + sys.exit(1) + + +# +# All subsequent arguments are the files to scan. +# +files = sys.argv[3:] + +# Create the proper list of filenames +filenames = [] +for file in files: + if os.path.isfile(file): + filenames.append(file) + else: + filenames.append(os.path.join(srcdir, file)) + +if len(filenames) < 1: + print("No files found") + sys.exit(1) + + +# Look through all files, applying the regex to each line. +# If the pattern matches, save the "symbol" section to the +# appropriate array. +regs = { + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } + +# For those that don't know Python, r"" indicates a raw string, +# devoid of Python escapes. +proto_regex0 = r"^(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" +proto_regex1 = r"void\s+(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +handoff_regex0 = r"^(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" +handoff_regex1 = r"void\s+(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" + +wtap_reg_regex0 = r"^(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" +wtap_reg_regex1 = r"void\s+(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +# This table drives the pattern-matching and symbol-harvesting +patterns = [ + ( 'proto_reg', re.compile(proto_regex0) ), + ( 'proto_reg', re.compile(proto_regex1) ), + ( 'handoff_reg', re.compile(handoff_regex0) ), + ( 'handoff_reg', re.compile(handoff_regex1) ), + ( 'wtap_register', re.compile(wtap_reg_regex0) ), + ( 'wtap_register', re.compile(wtap_reg_regex1) ), + ] + +# Open our registration symbol cache +cache = None +if cache_filename: + try: + cache_file = open(cache_filename, 'rb') + cache = pickle.load(cache_file) + cache_file.close() + if VERSION_KEY not in cache or cache[VERSION_KEY] != CUR_VERSION: + cache = {VERSION_KEY: CUR_VERSION} + except: + cache = {VERSION_KEY: CUR_VERSION} + + print(("Registering %d files, %d cached" % (len(filenames), len(list(cache.keys()))-1))) + +# Grep +cache_hits = 0 +cache_misses = 0 +for filename in filenames: + file = open(filename) + cur_mtime = os.fstat(file.fileno())[ST_MTIME] + if cache and filename in cache: + cdict = cache[filename] + if cur_mtime == cdict['mtime']: + cache_hits += 1 +# print "Pulling %s from cache" % (filename) + regs['proto_reg'].extend(cdict['proto_reg']) + regs['handoff_reg'].extend(cdict['handoff_reg']) + regs['wtap_register'].extend(cdict['wtap_register']) + file.close() + continue + # We don't have a cache entry + if cache is not None: + cache_misses += 1 + cache[filename] = { + 'mtime': cur_mtime, + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } +# print "Searching %s" % (filename) + for line in file.readlines(): + for action in patterns: + regex = action[1] + match = regex.search(line) + if match: + symbol = match.group("symbol") + sym_type = action[0] + regs[sym_type].append(symbol) + if cache is not None: +# print "Caching %s for %s: %s" % (sym_type, filename, symbol) + cache[filename][sym_type].append(symbol) + file.close() + + +if cache is not None and cache_filename is not None: + cache_file = open(cache_filename, 'wb') + pickle.dump(cache, cache_file) + cache_file.close() + print(("Cache hits: %d, misses: %d" % (cache_hits, cache_misses))) + +# Make sure we actually processed something +if len(regs['proto_reg']) < 1: + print("No protocol registrations found") + sys.exit(1) + +# Sort the lists to make them pretty +regs['proto_reg'].sort() +regs['handoff_reg'].sort() +regs['wtap_register'].sort() + +reg_code = open(tmp_filename, "w") + +reg_code.write(preamble) + +# Make the routine to register all protocols +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +"""); +else: + reg_code.write(""" +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['proto_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + + +# Make the routine to register all protocol handoffs +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +"""); +else: + reg_code.write(""" +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['handoff_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + +if registertype == "plugin": + reg_code.write("#endif\n"); +elif registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +register_wtap_module(void) +{ +"""); + + for symbol in regs['wtap_register']: + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + reg_code.write(line) + + reg_code.write("}\n"); + reg_code.write("#endif\n"); +else: + reg_code.write(""" +static gulong proto_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['proto_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +static gulong handoff_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['handoff_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +gulong register_count(void) +{ +"""); + + line = " return proto_reg_count() + handoff_reg_count();" + reg_code.write(line) + + reg_code.write(""" +}\n +"""); + + +# Close the file +reg_code.close() + +# Remove the old final_file if it exists. +try: + os.stat(final_filename) + os.remove(final_filename) +except OSError: + pass + +# Move from tmp file to final file +os.rename(tmp_filename, final_filename) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/AUTHORS b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/AUTHORS new file mode 100644 index 0000000..b127790 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/AUTHORS @@ -0,0 +1,3 @@ +Authors: +Michael Ossmann +Dominic Spill diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/CMakeLists.txt b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/CMakeLists.txt new file mode 100644 index 0000000..2bc4948 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/CMakeLists.txt @@ -0,0 +1,86 @@ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +project(btbredr-wireshark-plugin C) + +cmake_minimum_required(VERSION 2.6) +set(CMAKE_BACKWARDS_COMPATIBILITY 2.6) +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +IF ( NOT CMAKE_INSTALL_LIBDIR ) + set(CMAKE_INSTALL_LIBDIR ~/.wireshark/plugins) +ENDIF ( NOT CMAKE_INSTALL_LIBDIR ) +MESSAGE (STATUS "Plugin will be installed in: ${CMAKE_INSTALL_LIBDIR}") + +INCLUDE(UseMakeDissectorReg) + +set(GLIB2_MIN_VERSION 2.4.0) + +find_package(GLIB2) +include_directories (${GLIB2_INCLUDE_DIRS}) + +find_package(Wireshark) +include_directories (${WIRESHARK_INCLUDE_DIRS}) + +set(LINK_MODE_LIB SHARED) +set(LINK_MODE_MODULE MODULE) + + +set(DISSECTOR_SRC + packet-btbredr.c + packet-btlmp.c +) + +set(PLUGIN_FILES + plugin.c + ${DISSECTOR_SRC} +) + +set(CLEAN_FILES + ${PLUGIN_FILES} +) + +if (WERROR) + set_source_files_properties( + ${CLEAN_FILES} + PROPERTIES + COMPILE_FLAGS -Werror + ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +register_dissector_files(plugin.c + plugin + ${DISSECTOR_SRC} +) + +add_library(btbredr ${LINK_MODE_MODULE} + ${PLUGIN_FILES} +) +set_target_properties(btbredr PROPERTIES PREFIX "") +set_target_properties(btbredr PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + +target_link_libraries(btbredr wireshark) + +install(TARGETS btbredr + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ NAMELINK_SKIP +) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/COPYING new file mode 100644 index 0000000..aa0aea5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/README b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/README new file mode 100644 index 0000000..d08629c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/README @@ -0,0 +1,16 @@ +BTBB Basic and Enhanced Data Rate Wireshark plugin + +This is the Bluetooth baseband plugin for Wireshark, it also includes an LMP +level dissector. + +To build this on Debian/Ubuntu/BackTrack linux distributions: + sudo apt-get install wireshark-dev wireshark + cd libbtbb/wireshark/plugins/btbredr/ + mkdir build + cd build + cmake .. + make + make install + +This will install to the .wireshark/ in your home directory. To override this +set the DESTDIR environment variable when running cmake. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/btbredr_test.pcap b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/btbredr_test.pcap new file mode 100644 index 0000000..bb5cd8e Binary files /dev/null and b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/btbredr_test.pcap differ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/COPYING new file mode 100644 index 0000000..53b6b71 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/COPYING @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/COPYING-CMAKE-SCRIPTS b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..280ed6c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,27 @@ +Copyright notice for the files copied from +http://www.opensync.org/browser/branches/3rd-party-cmake-modules/modules + +$Id: COPYING-CMAKE-SCRIPTS 34248 2010-09-25 15:38:12Z jmayer $ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/FindGLIB2.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/FindGLIB2.cmake new file mode 100644 index 0000000..ae7badd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/FindGLIB2.cmake @@ -0,0 +1,238 @@ +# +# $Id: FindGLIB2.cmake 34248 2010-09-25 15:38:12Z jmayer $ +# +# - Try to find GLib2 +# Once done this will define +# +# GLIB2_FOUND - system has GLib2 +# GLIB2_INCLUDE_DIRS - the GLib2 include directory +# GLIB2_LIBRARIES - Link these to use GLib2 +# +# HAVE_GLIB_GREGEX_H glib has gregex.h header and +# supports g_regex_match_simple +# +# Copyright (c) 2006 Andreas Schneider +# Copyright (c) 2006 Philippe Bernery +# Copyright (c) 2007 Daniel Gollub +# Copyright (c) 2007 Alban Browaeys +# Copyright (c) 2008 Michael Bell +# Copyright (c) 2008-2009 Bjoern Ricks +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +IF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + # in cache already + SET(GLIB2_FOUND TRUE) +ELSE (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + + INCLUDE(FindPkgConfig) + + ## Glib + IF ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "REQUIRED" ) + ELSE ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "" ) + ENDIF ( GLIB2_FIND_REQUIRED ) + + IF ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0>=${GLIB2_MIN_VERSION} ) + ELSE ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0 ) + ENDIF ( GLIB2_MIN_VERSION ) + IF ( PKG_CONFIG_FOUND ) + IF ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( GLIB2_FOUND ) + ENDIF ( PKG_CONFIG_FOUND ) + + # Look for glib2 include dir and libraries w/o pkgconfig + IF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + FIND_PATH( + _glibconfig_include_DIR + NAMES + glibconfig.h + PATHS + /opt/gnome/lib64 + /opt/gnome/lib + /opt/lib/ + /opt/local/lib + /sw/lib/ + /usr/lib64 + /usr/lib + /usr/local/include + ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES + glib-2.0/include + ) + + FIND_PATH( + _glib2_include_DIR + NAMES + glib.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + PATH_SUFFIXES + glib-2.0 + ) + + #MESSAGE(STATUS "Glib headers: ${_glib2_include_DIR}") + + FIND_LIBRARY( + _glib2_link_DIR + NAMES + glib-2.0 + glib + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + IF ( _glib2_include_DIR AND _glib2_link_DIR ) + SET ( _glib2_FOUND TRUE ) + ENDIF ( _glib2_include_DIR AND _glib2_link_DIR ) + + + IF ( _glib2_FOUND ) + SET ( GLIB2_INCLUDE_DIRS ${_glib2_include_DIR} ${_glibconfig_include_DIR} ) + SET ( GLIB2_LIBRARIES ${_glib2_link_DIR} ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( _glib2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( _glib2_FOUND ) + + # Handle dependencies + # libintl + IF ( NOT LIBINTL_FOUND ) + FIND_PATH(LIBINTL_INCLUDE_DIR + NAMES + libintl.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + ) + + FIND_LIBRARY(LIBINTL_LIBRARY + NAMES + intl + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/local/lib + /usr/lib + ) + + IF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + SET (LIBINTL_FOUND TRUE) + ENDIF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + ENDIF ( NOT LIBINTL_FOUND ) + + # libiconv + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR + NAMES + iconv.h + PATHS + /opt/gnome/include + /opt/local/include + /opt/local/include + /sw/include + /sw/include + /usr/local/include + /usr/include + PATH_SUFFIXES + glib-2.0 + ) + + FIND_LIBRARY(LIBICONV_LIBRARY + NAMES + iconv + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + + IF (LIBINTL_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBINTL_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBINTL_INCLUDE_DIR}) + ENDIF (LIBINTL_FOUND) + + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) + + ENDIF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + ## + + IF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + SET (GLIB2_FOUND TRUE) + ENDIF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + + IF (GLIB2_FOUND) + IF (NOT GLIB2_FIND_QUIETLY) + MESSAGE (STATUS "Found GLib2: ${GLIB2_LIBRARIES} ${GLIB2_INCLUDE_DIRS}") + ENDIF (NOT GLIB2_FIND_QUIETLY) + ELSE (GLIB2_FOUND) + IF (GLIB2_FIND_REQUIRED) + MESSAGE (SEND_ERROR "Could not find GLib2") + ENDIF (GLIB2_FIND_REQUIRED) + ENDIF (GLIB2_FOUND) + + # show the GLIB2_INCLUDE_DIRS and GLIB2_LIBRARIES variables only in the advanced view + MARK_AS_ADVANCED(GLIB2_INCLUDE_DIRS GLIB2_LIBRARIES) + MARK_AS_ADVANCED(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARY) + MARK_AS_ADVANCED(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY) + +ENDIF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS) + +IF ( WIN32 ) + # include libiconv for win32 + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR iconv.h PATH_SUFFIXES glib-2.0) + + FIND_LIBRARY(LIBICONV_LIBRARY NAMES iconv) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) +ENDIF ( WIN32 ) + +IF ( GLIB2_FOUND ) + # Check if system has a newer version of glib + # which supports g_regex_match_simple + INCLUDE( CheckIncludeFiles ) + SET( CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS} ) + CHECK_INCLUDE_FILES ( glib/gregex.h HAVE_GLIB_GREGEX_H ) + CHECK_INCLUDE_FILES ( glib/gchecksum.h HAVE_GLIB_GCHECKSUM_H ) + # Reset CMAKE_REQUIRED_INCLUDES + SET( CMAKE_REQUIRED_INCLUDES "" ) +ENDIF( GLIB2_FOUND ) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/FindWireshark.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/FindWireshark.cmake new file mode 100644 index 0000000..16fabed --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/FindWireshark.cmake @@ -0,0 +1,28 @@ +# +# Try to find the wireshark library and its includes +# +# This snippet sets the following variables: +# WIRESHARK_FOUND True if wireshark library got found +# WIRESHARK_INCLUDE_DIRS Location of the wireshark headers +# WIRESHARK_LIBRARIES List of libraries to use wireshark +# +# Copyright (c) 2011 Reinhold Kainhofer +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + +# wireshark does not install its library with pkg-config information, +# so we need to manually find the libraries and headers + +FIND_PATH( WIRESHARK_INCLUDE_DIRS epan/packet.h PATH_SUFFIXES wireshark ) +FIND_LIBRARY( WIRESHARK_LIBRARIES wireshark ) + +# Report results +IF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + SET( WIRESHARK_FOUND 1 ) +ELSE ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + MESSAGE( SEND_ERROR "Could NOT find the wireshark library and headers" ) +ENDIF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/UseMakeDissectorReg.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/UseMakeDissectorReg.cmake new file mode 100644 index 0000000..e7e1a73 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/cmake/UseMakeDissectorReg.cmake @@ -0,0 +1,33 @@ +# +# $Id: UseMakeDissectorReg.cmake 33616 2010-07-22 12:18:36Z stig $ +# +MACRO(REGISTER_DISSECTOR_FILES _outputfile _registertype ) + # FIXME: Only the Python stuff has been implemented + # Make this into a MACRO, to avoid duplication with plugins/.../ + #register.c: $(plugin_src) $(ALL_DISSECTORS_SRC) $(top_srcdir)/tools/make-dissector-reg \ + # $(top_srcdir)/tools/make-dissector-reg.py + # @if test -n "$(PYTHON)"; then \ + # echo Making register.c with python ; \ + # $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + # dissectors $(ALL_DISSECTORS_SRC) ; \ + # else \ + # echo Making register.c with shell script ; \ + # $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + # dissectors $(plugin_src) $(ALL_DISSECTORS_SRC) ; \ + # fi + set( _sources ${ARGN} ) + ADD_CUSTOM_COMMAND( + OUTPUT + ${_outputfile} + COMMAND ${PYTHON_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ${CMAKE_CURRENT_SOURCE_DIR} + ${_registertype} + ${_sources} + DEPENDS + ${_sources} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ) +ENDMACRO(REGISTER_DISSECTOR_FILES) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/moduleinfo.h b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/moduleinfo.h new file mode 100644 index 0000000..fcf5c22 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/moduleinfo.h @@ -0,0 +1,17 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "btbredr" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/packet-btbredr.c b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/packet-btbredr.c new file mode 100644 index 0000000..2954ccd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/packet-btbredr.c @@ -0,0 +1,673 @@ +/* packet-btbredr.c + * Routines for Bluetooth baseband dissection + * Copyright 2014, Dominic Spill + * Copyright 2009, Michael Ossmann + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#include +#endif + +#include +#include + +#include + +/* function prototypes */ +void proto_reg_handoff_btbredr(void); + +/* initialize the protocol and registered fields */ +static int proto_btbredr = -1; +static int hf_btbredr_meta = -1; +static int hf_btbredr_channel = -1; +static int hf_btbredr_signal = -1; +static int hf_btbredr_noise = -1; +static int hf_btbredr_ac_offenses = -1; +static int hf_btbredr_mod = -1; +static int hf_btbredr_transport = -1; +static int hf_btbredr_corrected_header = -1; +static int hf_btbredr_corrected_payload = -1; +static int hf_btbredr_lap = -1; +static int hf_btbredr_ref_lap = -1; +static int hf_btbredr_ref_uap = -1; +static int hf_btbredr_pkthdr = -1; +static int hf_btbredr_ltaddr = -1; +static int hf_btbredr_type = -1; +static int hf_btbredr_flags = -1; +static int hf_btbredr_flow = -1; +static int hf_btbredr_arqn = -1; +static int hf_btbredr_seqn = -1; +static int hf_btbredr_hec = -1; +static int hf_btbredr_payload = -1; +static int hf_btbredr_pldhdr = -1; +static int hf_btbredr_llid = -1; +static int hf_btbredr_pldflow = -1; +static int hf_btbredr_length = -1; +static int hf_btbredr_pldbody = -1; +static int hf_btbredr_crc = -1; +static int hf_btbredr_fhs_parity = -1; +static int hf_btbredr_fhs_lap = -1; +static int hf_btbredr_fhs_eir = -1; +static int hf_btbredr_fhs_sr = -1; +static int hf_btbredr_fhs_uap = -1; +static int hf_btbredr_fhs_nap = -1; +static int hf_btbredr_fhs_class = -1; +static int hf_btbredr_fhs_ltaddr = -1; +static int hf_btbredr_fhs_clk = -1; +static int hf_btbredr_fhs_psmode = -1; + +/* field values */ +static const true_false_string direction = { + "Slave to Master", + "Master to Slave" +}; + +static const true_false_string clock_bits = { + "27", + "6" +}; + +static const true_false_string valid_flags = { + "Invalid", + "Valid" +}; + +static const value_string modulation[] = { + { 0x0, "Basic Rate (GFSK)" }, + { 0x1, "Enhanced Data Rate (PI/2-DQPSK)" }, + { 0x2, "Enhanced Data Rate (8DPSK)" } +}; + +static const value_string transports[] = { + { 0x0, "unknown" }, + { 0x1, "SCO" }, + { 0x2, "eSCO" }, + { 0x3, "ACL" }, + { 0x4, "CSB" } +}; + +static const value_string packet_types[] = { + /* generic names for unknown logical transport */ + { 0x0, "NULL" }, + { 0x1, "POLL" }, + { 0x2, "FHS" }, + { 0x3, "DM1" }, + { 0x4, "DH1/2-DH1" }, + { 0x5, "HV1" }, + { 0x6, "HV2/2-EV3" }, + { 0x7, "HV3/EV3/3-EV3" }, + { 0x8, "DV/3-DH1" }, + { 0x9, "AUX1" }, + { 0xa, "DM3/2-DH3" }, + { 0xb, "DH3/3-DH3" }, + { 0xc, "EV4/2-EV5" }, + { 0xd, "EV5/3-EV5" }, + { 0xe, "DM5/2-DH5" }, + { 0xf, "DH5/3-DH5" }, + { 0, NULL } +}; + +static const value_string sr_modes[] = { + { 0x0, "R0" }, + { 0x1, "R1" }, + { 0x2, "R2" }, + { 0x3, "Reserved" }, + { 0, NULL } +}; + +static const range_string ps_modes[] = { + { 0x0, 0x0, "Mandatory scan mode" }, + { 0x1, 0x7, "Reserved" }, + { 0, 0, NULL } +}; + +static const value_string llid_codes[] = { + { 0x0, "undefined" }, + { 0x1, "Continuation fragment of an L2CAP message (ACL-U)" }, + { 0x2, "Start of an L2CAP message or no fragmentation (ACL-U)" }, + { 0x3, "LMP message (ACL-C)" }, + { 0, NULL } +}; + +/* initialize the subtree pointers */ +static gint ett_btbredr = -1; +static gint ett_btbredr_meta = -1; +static gint ett_btbredr_pkthdr = -1; +static gint ett_btbredr_flags = -1; +static gint ett_btbredr_payload = -1; +static gint ett_btbredr_pldhdr = -1; + +/* subdissectors */ +static dissector_handle_t btlmp_handle = NULL; +static dissector_handle_t btl2cap_handle = NULL; + +/* packet header flags */ +static const int *flag_fields[] = { + &hf_btbredr_flow, + &hf_btbredr_arqn, + &hf_btbredr_seqn, + NULL +}; + +/* one byte payload header */ +int +dissect_payload_header1(proto_tree *tree, tvbuff_t *tvb, int offset) +{ + proto_item *hdr_item; + proto_tree *hdr_tree; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + hdr_item = proto_tree_add_item(tree, hf_btbredr_pldhdr, tvb, offset, 1, ENC_NA); + hdr_tree = proto_item_add_subtree(hdr_item, ett_btbredr_pldhdr); + + proto_tree_add_item(hdr_tree, hf_btbredr_llid, tvb, offset, 1, ENC_NA); + proto_tree_add_item(hdr_tree, hf_btbredr_pldflow, tvb, offset, 1, ENC_NA); + proto_tree_add_item(hdr_tree, hf_btbredr_length, tvb, offset, 1, ENC_NA); + + /* payload length */ + return tvb_get_guint8(tvb, offset) >> 3; +} + +void +dissect_fhs(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset) +{ + proto_item *fhs_item, *psmode_item; + proto_tree *fhs_tree; + const gchar *description; + guint8 psmode; + + if(tvb_length_remaining(tvb, offset) != 20) { + col_add_str(pinfo->cinfo, COL_INFO, "Encrypted or malformed payload data"); + return; + } + + fhs_item = proto_tree_add_item(tree, hf_btbredr_payload, tvb, offset, -1, ENC_NA); + fhs_tree = proto_item_add_subtree(fhs_item, ett_btbredr_payload); + + /* Use proto_tree_add_bits_item() to get around 32bit limit on bitmasks */ + proto_tree_add_bits_item(fhs_tree, hf_btbredr_fhs_parity, tvb, offset*8, 34, ENC_LITTLE_ENDIAN); + /* proto_tree_add_item(fhs_tree, hf_btbredr_fhs_parity, tvb, offset, 5, ENC_LITTLE_ENDIAN); */ + offset += 4; + + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_lap, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 3; + + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_eir, tvb, offset, 1, ENC_NA); + /* skipping 1 undefined bit */ + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_sr, tvb, offset, 1, ENC_NA); + /* skipping 2 reserved bits */ + offset += 1; + + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_uap, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_nap, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_class, tvb, offset, 3, ENC_LITTLE_ENDIAN); + offset += 3; + + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_ltaddr, tvb, offset, 1, ENC_NA); + proto_tree_add_item(fhs_tree, hf_btbredr_fhs_clk, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 3; + + psmode = tvb_get_guint8(tvb, offset); + description = try_rval_to_str(psmode, ps_modes); + psmode_item = proto_tree_add_item(fhs_tree, hf_btbredr_fhs_psmode, tvb, offset, 1, ENC_NA); + if (description) + proto_item_append_text(psmode_item, " (%s)", description); + offset += 1; + + proto_tree_add_item(fhs_tree, hf_btbredr_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; +} + +void +dissect_dm1(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset) +{ + int len; /* payload length indicated by payload header */ + int llid; /* logical link id */ + int l2len; /* length indicated by l2cap header */ + proto_item *dm1_item; + proto_tree *dm1_tree; + tvbuff_t *pld_tvb; + + /* + * FIXME + * I'm probably doing a terrible, terrible thing here, but it gets my + * initial test cases working. + */ + guint16 fake_acl_data; + + if(tvb_length_remaining(tvb, offset) < 3) { + col_add_str(pinfo->cinfo, COL_INFO, "Encrypted or malformed payload data"); + return; + } + + dm1_item = proto_tree_add_item(tree, hf_btbredr_payload, tvb, offset, -1, ENC_NA); + dm1_tree = proto_item_add_subtree(dm1_item, ett_btbredr_payload); + + len = dissect_payload_header1(dm1_tree, tvb, offset); + llid = tvb_get_guint8(tvb, offset) & 0x3; + offset += 1; + + if(tvb_length_remaining(tvb, offset) < len + 2) { + col_add_str(pinfo->cinfo, COL_INFO, "Encrypted or malformed payload data"); + return; + } + + if (llid == 3 && btlmp_handle) { + /* LMP */ + pld_tvb = tvb_new_subset(tvb, offset, len, len); + call_dissector(btlmp_handle, pld_tvb, pinfo, dm1_tree); + } else if (llid == 2 && btl2cap_handle) { + /* unfragmented L2CAP or start of fragment */ + l2len = tvb_get_letohs(tvb, offset); + if (l2len + 4 == len) { + /* unfragmented */ + pinfo->private_data = &fake_acl_data; + pld_tvb = tvb_new_subset(tvb, offset, len, len); + call_dissector(btl2cap_handle, pld_tvb, pinfo, dm1_tree); + } else { + /* start of fragment */ + proto_tree_add_item(dm1_tree, hf_btbredr_pldbody, tvb, offset, len, ENC_NA); + } + } else { + proto_tree_add_item(dm1_tree, hf_btbredr_pldbody, tvb, offset, len, ENC_NA); + } + offset += len; + + proto_tree_add_item(dm1_tree, hf_btbredr_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; +} + +/* dissect a packet */ +static int +dissect_btbredr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + proto_item *btbredr_item, *meta_item, *pkthdr_item; + proto_tree *btbredr_tree, *meta_tree, *pkthdr_tree; + int offset; + /* Avoid error: 'type' may be used uninitialized in this function */ + guint8 type = 0xff; + const gchar *info; + + /* sanity check: length */ + if (tvb_length(tvb) > 0 && tvb_length(tvb) < 9) + /* bad length: look for a different dissector */ + return 0; + + /* maybe should verify HEC */ + + /* make entries in protocol column and info column on summary display */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Bluetooth"); + + if (tvb_length(tvb) == 0) { + info = "ID"; + } else { + type = (tvb_get_guint8(tvb, 16) >> 3) & 0x0f; + info = val_to_str(type, packet_types, "Unknown type: 0x%x"); + } + + col_clear(pinfo->cinfo, COL_INFO); + col_add_str(pinfo->cinfo, COL_INFO, info); + + /* see if we are being asked for details */ + if (tree) { + + /* create display subtree for the protocol */ + offset = 0; + btbredr_item = proto_tree_add_item(tree, proto_btbredr, tvb, offset, -1, ENC_NA); + btbredr_tree = proto_item_add_subtree(btbredr_item, ett_btbredr); + + /* ID packets have no header, no payload */ + if (tvb_length(tvb) == 0) + return 1; + + /* meta data */ + meta_item = proto_tree_add_item(btbredr_tree, hf_btbredr_meta, tvb, offset, 3, ENC_NA); + meta_tree = proto_item_add_subtree(meta_item, ett_btbredr_meta); + + proto_tree_add_item(meta_tree, hf_btbredr_channel, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(meta_tree, hf_btbredr_signal, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(meta_tree, hf_btbredr_noise, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(meta_tree, hf_btbredr_ac_offenses, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(meta_tree, hf_btbredr_mod, tvb, offset, 1, ENC_NA); + proto_tree_add_item(meta_tree, hf_btbredr_transport, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(meta_tree, hf_btbredr_corrected_header, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(meta_tree, hf_btbredr_corrected_payload, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(meta_tree, hf_btbredr_lap, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 4; + proto_tree_add_item(meta_tree, hf_btbredr_ref_lap, tvb, offset, 3, ENC_LITTLE_ENDIAN); + offset += 3; + proto_tree_add_item(meta_tree, hf_btbredr_ref_uap, tvb, offset, 1, ENC_NA); + offset += 1; + + + /* packet header */ + pkthdr_item = proto_tree_add_item(btbredr_tree, hf_btbredr_pkthdr, tvb, offset, 3, ENC_NA); + pkthdr_tree = proto_item_add_subtree(pkthdr_item, ett_btbredr_pkthdr); + + proto_tree_add_item(pkthdr_tree, hf_btbredr_ltaddr, tvb, offset, 1, ENC_NA); + proto_tree_add_item(pkthdr_tree, hf_btbredr_type, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_bitmask(pkthdr_tree, tvb, offset, hf_btbredr_flags, + ett_btbredr_flags, flag_fields, ENC_NA); + offset += 1; + proto_tree_add_item(pkthdr_tree, hf_btbredr_hec, tvb, offset, 1, ENC_NA); + offset += 2; + + /* payload */ + switch (type) { + case 0x0: /* NULL */ + case 0x1: /* POLL */ + break; + case 0x2: /* FHS */ + dissect_fhs(btbredr_tree, tvb, pinfo, offset); + break; + case 0x3: /* DM1 */ + dissect_dm1(btbredr_tree, tvb, pinfo, offset); + break; + case 0x4: /* DH1/2-DH1 */ + dissect_dm1(btbredr_tree, tvb, pinfo, offset); + break; + case 0x5: /* HV1 */ + case 0x6: /* HV2/2-EV3 */ + case 0x7: /* HV3/EV3/3-EV3 */ + case 0x8: /* DV/3-DH1 */ + case 0x9: /* AUX1 */ + case 0xa: /* DM3/2-DH3 */ + case 0xb: /* DH3/3-DH3 */ + case 0xc: /* EV4/2-EV5 */ + case 0xd: /* EV5/3-EV5 */ + case 0xe: /* DM5/2-DH5 */ + case 0xf: /* DH5/3-DH5 */ + proto_tree_add_item(btbredr_tree, hf_btbredr_payload, tvb, offset, -1, ENC_NA); + break; + default: + break; + } + } + + /* Return the amount of data this dissector was able to dissect */ + return tvb_length(tvb); +} + +/* register the protocol with Wireshark */ +void +proto_register_btbredr(void) +{ + /* list of fields */ + static hf_register_info hf[] = { + { &hf_btbredr_meta, + { "Meta Data", "btbredr.meta", + FT_NONE, BASE_NONE, NULL, 0x0, + "Meta Data About the Packet", HFILL } + }, + { &hf_btbredr_channel, + { "Channel", "btbredr.channel", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Channel (0-78)", HFILL } + }, + { &hf_btbredr_signal, + { "Signal", "btbredr.signal", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Signal Power", HFILL } + }, + { &hf_btbredr_noise, + { "Noise", "btbredr.noise", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Noise Power", HFILL } + }, + { &hf_btbredr_ac_offenses, + { "AC Offenses", "btbredr.ac_offenses", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Access Code Offenses", HFILL } + }, + { &hf_btbredr_mod, + { "Transport Rate", "btbredr.mod", + FT_UINT8, BASE_HEX, VALS(&modulation), 0x02, + "Transport Data Rate", HFILL } + }, + { &hf_btbredr_transport, + { "Transport", "btbredr.transport", + FT_UINT8, BASE_HEX, VALS(&transports), 0x70, + "Logical Transport", HFILL } + }, + { &hf_btbredr_corrected_header, + { "Corrected Header", "btbredr.corrected_header", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Corrected Header Bits", HFILL } + }, + { &hf_btbredr_corrected_payload, + { "Corrected Payload", "btbredr.corrected_payload", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Corrected Payload Bits", HFILL } + }, + { &hf_btbredr_lap, + { "LAP", "btbredr.lap", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Lower Address Part", HFILL } + }, + { &hf_btbredr_ref_lap, + { "Ref. LAP", "btbredr.ref_lap", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Reference LAP", HFILL } + }, + { &hf_btbredr_ref_uap, + { "Ref. UAP", "btbredr.ref_uap", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Reference UAP", HFILL } + }, + { &hf_btbredr_pkthdr, + { "Packet Header", "btbredr.pkthdr", + FT_NONE, BASE_NONE, NULL, 0x0, + "Bluetooth Baseband Packet Header", HFILL } + }, + { &hf_btbredr_ltaddr, + { "LT_ADDR", "btbredr.lt_addr", + FT_UINT8, BASE_HEX, NULL, 0x07, + "Logical Transport Address", HFILL } + }, + { &hf_btbredr_type, + { "TYPE", "btbredr.type", + FT_UINT8, BASE_HEX, VALS(packet_types), 0x78, + "Packet Type", HFILL } + }, + { &hf_btbredr_flags, + { "Flags", "btbredr.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Packet Header Flags", HFILL } + }, + { &hf_btbredr_flow, + { "FLOW", "btbredr.flow", + FT_BOOLEAN, 8, NULL, 0x01, + "Flow control indication", HFILL } + }, + { &hf_btbredr_arqn, + { "ARQN", "btbredr.arqn", + FT_BOOLEAN, 8, NULL, 0x02, + "Acknowledgment indication", HFILL } + }, + { &hf_btbredr_seqn, + { "SEQN", "btbredr.seqn", + FT_BOOLEAN, 8, NULL, 0x04, + "Sequence number", HFILL } + }, + { &hf_btbredr_hec, + { "HEC", "btbredr.lt_addr", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Header Error Check", HFILL } + }, + { &hf_btbredr_payload, + { "Payload", "btbredr.payload", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbredr_llid, + { "LLID", "btbredr.llid", + FT_UINT8, BASE_HEX, VALS(llid_codes), 0x03, + "Logical Link ID", HFILL } + }, + { &hf_btbredr_pldflow, + { "Flow", "btbredr.flow", + FT_BOOLEAN, 8, NULL, 0x04, + "Payload Flow indication", HFILL } + }, + { &hf_btbredr_length, + { "Length", "btbredr.length", + FT_UINT8, BASE_DEC, NULL, 0xf8, + "Payload Length", HFILL } + }, + { &hf_btbredr_pldhdr, + { "Payload Header", "btbredr.pldhdr", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbredr_pldbody, + { "Payload Body", "btbredr.pldbody", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbredr_crc, + { "CRC", "btbredr.crc", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Payload CRC", HFILL } + }, + { &hf_btbredr_fhs_parity, + { "Parity", "btbredr.parity", + /* FIXME this doesn't work because bitmasks can only be 32 bits */ + FT_UINT64, BASE_HEX, NULL, /*0x00000003ffffffffULL,*/ 0x0, + "LAP parity", HFILL } + }, + { &hf_btbredr_fhs_lap, + { "LAP", "btbredr.lap", + FT_UINT24, BASE_HEX, NULL, 0x03fffffc, + "Lower Address Part", HFILL } + }, + { &hf_btbredr_fhs_eir, + { "EIR", "btbredr.eir", + FT_BOOLEAN, 8, NULL, 0x04, + "Extended Inquiry Response packet may follow", HFILL } + }, + { &hf_btbredr_fhs_sr, + { "SR", "btbredr.sr", + FT_UINT8, BASE_HEX, VALS(sr_modes), 0x30, + "Scan Repetition", HFILL } + }, + { &hf_btbredr_fhs_uap, + { "UAP", "btbredr.uap", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Upper Address Part", HFILL } + }, + { &hf_btbredr_fhs_nap, + { "NAP", "btbredr.nap", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Non-Significant Address Part", HFILL } + }, + { &hf_btbredr_fhs_class, /* FIXME break out further */ + { "Class of Device", "btbredr.class", + FT_UINT24, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btbredr_fhs_ltaddr, + { "LT_ADDR", "btbredr.lt_addr", + FT_UINT8, BASE_HEX, NULL, 0x07, + "Logical Transport Address", HFILL } + }, + { &hf_btbredr_fhs_clk, + { "CLK", "btbredr.clk", + FT_UINT32, BASE_HEX, NULL, 0x1ffffff8, + "Clock bits 2 through 27", HFILL } + }, + { &hf_btbredr_fhs_psmode, + { "Page Scan Mode", "btbredr.psmode", + FT_UINT8, BASE_HEX, NULL, 0xe0, + NULL, HFILL } + }, + }; + + /* protocol subtree arrays */ + static gint *ett[] = { + &ett_btbredr, + &ett_btbredr_meta, + &ett_btbredr_pkthdr, + &ett_btbredr_flags, + &ett_btbredr_payload, + &ett_btbredr_pldhdr, + }; + + /* register the protocol name and description */ + proto_btbredr = proto_register_protocol( + "Bluetooth BR/EDR Baseband", /* full name */ + "BT BR/EDR Baseband", /* short name */ + "btbredr" /* abbreviation (e.g. for filters) */ + ); + + /* register the header fields and subtrees used */ + proto_register_field_array(proto_btbredr, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +/* Remove this once recent Wireshark/TCPdump releases are more common */ +#ifndef WTAP_ENCAP_BLUETOOTH_BREDR_BB +#define WTAP_ENCAP_BLUETOOTH_BREDR_BB 161 +#endif + +void +proto_reg_handoff_btbredr(void) +{ + dissector_handle_t btbredr_handle; + btbredr_handle = new_create_dissector_handle(dissect_btbredr, + proto_btbredr); + dissector_add_uint("wtap_encap", + WTAP_ENCAP_BLUETOOTH_BREDR_BB, + btbredr_handle); + + btlmp_handle = find_dissector("btlmp"); + btl2cap_handle = find_dissector("btl2cap"); +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/packet-btlmp.c b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/packet-btlmp.c new file mode 100644 index 0000000..1a67a2c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/packet-btlmp.c @@ -0,0 +1,2887 @@ +/* packet-btlmp.c + * Routines for Bluetooth LMP dissection + * Copyright 2009, Michael Ossmann + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#include +#endif + +#include /* needed for epan/gcc-4.x */ +#include +#include + +/* LMP opcodes */ +#define LMP_NAME_REQ 1 +#define LMP_NAME_RES 2 +#define LMP_ACCEPTED 3 +#define LMP_NOT_ACCEPTED 4 +#define LMP_CLKOFFSET_REQ 5 +#define LMP_CLKOFFSET_RES 6 +#define LMP_DETACH 7 +#define LMP_IN_RAND 8 +#define LMP_COMB_KEY 9 +#define LMP_UNIT_KEY 10 +#define LMP_AU_RAND 11 +#define LMP_SRES 12 +#define LMP_TEMP_RAND 13 +#define LMP_TEMP_KEY 14 +#define LMP_ENCRYPTION_MODE_REQ 15 +#define LMP_ENCRYPTION_KEY_SIZE_REQ 16 +#define LMP_START_ENCRYPTION_REQ 17 +#define LMP_STOP_ENCRYPTION_REQ 18 +#define LMP_SWITCH_REQ 19 +#define LMP_HOLD 20 +#define LMP_HOLD_REQ 21 +#define LMP_SNIFF_REQ 23 +#define LMP_UNSNIFF_REQ 24 +#define LMP_PARK_REQ 25 +#define LMP_SET_BROADCAST_SCAN_WINDOW 27 +#define LMP_MODIFY_BEACON 28 +#define LMP_UNPARK_BD_ADDR_REQ 29 +#define LMP_UNPARK_PM_ADDR_REQ 30 +#define LMP_INCR_POWER_REQ 31 +#define LMP_DECR_POWER_REQ 32 +#define LMP_MAX_POWER 33 +#define LMP_MIN_POWER 34 +#define LMP_AUTO_RATE 35 +#define LMP_PREFERRED_RATE 36 +#define LMP_VERSION_REQ 37 +#define LMP_VERSION_RES 38 +#define LMP_FEATURES_REQ 39 +#define LMP_FEATURES_RES 40 +#define LMP_QUALITY_OF_SERVICE 41 +#define LMP_QUALITY_OF_SERVICE_REQ 42 +#define LMP_SCO_LINK_REQ 43 +#define LMP_REMOVE_SCO_LINK_REQ 44 +#define LMP_MAX_SLOT 45 +#define LMP_MAX_SLOT_REQ 46 +#define LMP_TIMING_ACCURACY_REQ 47 +#define LMP_TIMING_ACCURACY_RES 48 +#define LMP_SETUP_COMPLETE 49 +#define LMP_USE_SEMI_PERMANENT_KEY 50 +#define LMP_HOST_CONNECTION_REQ 51 +#define LMP_SLOT_OFFSET 52 +#define LMP_PAGE_MODE_REQ 53 +#define LMP_PAGE_SCAN_MODE_REQ 54 +#define LMP_SUPERVISION_TIMEOUT 55 +#define LMP_TEST_ACTIVATE 56 +#define LMP_TEST_CONTROL 57 +#define LMP_ENCRYPTION_KEY_SIZE_MASK_REQ 58 +#define LMP_ENCRYPTION_KEY_SIZE_MASK_RES 59 +#define LMP_SET_AFH 60 +#define LMP_ENCAPSULATED_HEADER 61 +#define LMP_ENCAPSULATED_PAYLOAD 62 +#define LMP_SIMPLE_PAIRING_CONFIRM 63 +#define LMP_SIMPLE_PAIRING_NUMBER 64 +#define LMP_DHKEY_CHECK 65 +#define LMP_ESCAPE_1 124 +#define LMP_ESCAPE_2 125 +#define LMP_ESCAPE_3 126 +#define LMP_ESCAPE_4 127 + +/* LMP extended opcodes */ +#define LMP_ACCEPTED_EXT 1 +#define LMP_NOT_ACCEPTED_EXT 2 +#define LMP_FEATURES_REQ_EXT 3 +#define LMP_FEATURES_RES_EXT 4 +#define LMP_PACKET_TYPE_TABLE_REQ 11 +#define LMP_ESCO_LINK_REQ 12 +#define LMP_REMOVE_ESCO_LINK_REQ 13 +#define LMP_CHANNEL_CLASSIFICATION_REQ 16 +#define LMP_CHANNEL_CLASSIFICATION 17 +#define LMP_SNIFF_SUBRATING_REQ 21 +#define LMP_SNIFF_SUBRATING_RES 22 +#define LMP_PAUSE_ENCRYPTION_REQ 23 +#define LMP_RESUME_ENCRYPTION_REQ 24 +#define LMP_IO_CAPABILITY_REQ 25 +#define LMP_IO_CAPABILITY_RES 26 +#define LMP_NUMERIC_COMPARISON_FAILED 27 +#define LMP_PASSKEY_FAILED 28 +#define LMP_OOB_FAILED 29 +#define LMP_KEYPRESS_NOTIFICATION 30 +#define LMP_POWER_CONTROL_REQ 31 +#define LMP_POWER_CONTROL_RES 32 + +/* initialize the protocol and registered fields */ +static int proto_btlmp = -1; +static int hf_lmp_accscheme = -1; +static int hf_lmp_afhchmap = -1; +static int hf_lmp_afhclass = -1; +static int hf_lmp_afhinst = -1; +static int hf_lmp_afhmaxintvl = -1; +static int hf_lmp_afhminintvl = -1; +static int hf_lmp_afhmode = -1; +static int hf_lmp_afhrptmode = -1; +static int hf_lmp_airmode = -1; +static int hf_lmp_araddr = -1; +static int hf_lmp_authreqs = -1; +static int hf_lmp_authres = -1; +static int hf_lmp_bdaddr = -1; +static int hf_lmp_bdaddr1 = -1; +static int hf_lmp_bdaddr2 = -1; +static int hf_lmp_bsw = -1; +static int hf_lmp_clkoffset = -1; +static int hf_lmp_commit = -1; +static int hf_lmp_confirm = -1; +static int hf_lmp_compid = -1; +static int hf_lmp_cryptmode = -1; +static int hf_lmp_daccess = -1; +static int hf_lmp_db = -1; +static int hf_lmp_dbsleep = -1; +static int hf_lmp_deltab = -1; +static int hf_lmp_desco = -1; +static int hf_lmp_drift = -1; +static int hf_lmp_dsco = -1; +static int hf_lmp_dsniff = -1; +static int hf_lmp_encdata = -1; +static int hf_lmp_enclen = -1; +static int hf_lmp_encmaj = -1; +static int hf_lmp_encmin = -1; +static int hf_lmp_eop = -1; +static int hf_lmp_eopinre = -1; +static int hf_lmp_escolenms = -1; +static int hf_lmp_escolensm = -1; +static int hf_lmp_escotypems = -1; +static int hf_lmp_escotypesm = -1; +static int hf_lmp_err = -1; +static int hf_lmp_escohdl = -1; +static int hf_lmp_escoltaddr = -1; +static int hf_lmp_features = -1; +static int hf_lmp_fpage = -1; +static int hf_lmp_htime = -1; +static int hf_lmp_hinst = -1; +static int hf_lmp_hopmode = -1; +static int hf_lmp_iocaps = -1; +static int hf_lmp_jitter = -1; +static int hf_lmp_key = -1; +static int hf_lmp_keysz = -1; +static int hf_lmp_ksmask = -1; +static int hf_lmp_ltaddr1 = -1; +static int hf_lmp_ltaddr2 = -1; +static int hf_lmp_ltaddr3 = -1; +static int hf_lmp_ltaddr4 = -1; +static int hf_lmp_ltaddr5 = -1; +static int hf_lmp_ltaddr6 = -1; +static int hf_lmp_ltaddr7 = -1; +static int hf_lmp_maccess = -1; +static int hf_lmp_maxslots = -1; +static int hf_lmp_maxsp = -1; +static int hf_lmp_maxss = -1; +static int hf_lmp_minsmt = -1; +static int hf_lmp_naccslots = -1; +static int hf_lmp_namefrag = -1; +static int hf_lmp_namelen = -1; +static int hf_lmp_nameoffset = -1; +static int hf_lmp_nb = -1; +static int hf_lmp_nbc = -1; +static int hf_lmp_nbsleep = -1; +static int hf_lmp_negstate = -1; +static int hf_lmp_nonce = -1; +static int hf_lmp_nottype = -1; +static int hf_lmp_npoll = -1; +static int hf_lmp_oobauthdata = -1; +static int hf_lmp_op = -1; +static int hf_lmp_opinre = -1; +static int hf_lmp_pagesch = -1; +static int hf_lmp_pcmode = -1; +static int hf_lmp_pkttype = -1; +static int hf_lmp_pkttypetbl = -1; +static int hf_lmp_pmaddr = -1; +static int hf_lmp_pmaddr1 = -1; +static int hf_lmp_pmaddr2 = -1; +static int hf_lmp_pmaddr3 = -1; +static int hf_lmp_pmaddr4 = -1; +static int hf_lmp_pmaddr5 = -1; +static int hf_lmp_pmaddr6 = -1; +static int hf_lmp_pmaddr7 = -1; +static int hf_lmp_pollintvl = -1; +static int hf_lmp_pollper = -1; +static int hf_lmp_pssettings = -1; +static int hf_lmp_pwradjreq = -1; +static int hf_lmp_pwradjres = -1; +static int hf_lmp_pwradj_8dpsk = -1; +static int hf_lmp_pwradj_dqpsk = -1; +static int hf_lmp_pwradj_gfsk = -1; +static int hf_lmp_rand = -1; +static int hf_lmp_rate = -1; +static int hf_lmp_rate_fec = -1; +static int hf_lmp_rate_size = -1; +static int hf_lmp_rate_type = -1; +static int hf_lmp_rate_edrsize = -1; +static int hf_lmp_rxfreq = -1; +static int hf_lmp_scohdl = -1; +static int hf_lmp_scopkt = -1; +static int hf_lmp_slotoffset = -1; +static int hf_lmp_sniffatt = -1; +static int hf_lmp_sniffsi = -1; +static int hf_lmp_sniffto = -1; +static int hf_lmp_subversnr = -1; +static int hf_lmp_suptimeout = -1; +static int hf_lmp_swinst = -1; +static int hf_lmp_taccess = -1; +static int hf_lmp_tb = -1; +static int hf_lmp_tesco = -1; +static int hf_lmp_testlen = -1; +static int hf_lmp_testscen = -1; +static int hf_lmp_tid = -1; +static int hf_lmp_timectrl = -1; +static int hf_lmp_time_change = -1; +static int hf_lmp_time_init = -1; +static int hf_lmp_time_accwin = -1; +static int hf_lmp_tsco = -1; +static int hf_lmp_tsniff = -1; +static int hf_lmp_txfreq = -1; +static int hf_lmp_versnr = -1; +static int hf_lmp_wesco = -1; + +/* timing control flags */ +static const int *timectrl_fields[] = { + &hf_lmp_time_change, + &hf_lmp_time_init, + &hf_lmp_time_accwin, + /* bits 3-7 reserved */ + NULL +}; + +static const true_false_string time_change = { + "timing change", + "no timing change" +}; + +static const true_false_string time_init = { + "use initialization 2", + "use initialization 1" +}; + +static const true_false_string time_accwin = { + "no access window", + "access window" +}; + +static const true_false_string fec = { + "do not use FEC", + "use FEC" +}; + +static const true_false_string tid = { + "transaction initiated by slave", + "transaction initiated by master" +}; + +/* short LMP opcodes */ +static const value_string opcode[] = { + { LMP_NAME_REQ, "LMP_name_req" }, + { LMP_NAME_RES, "LMP_name_res" }, + { LMP_ACCEPTED, "LMP_accepted" }, + { LMP_NOT_ACCEPTED, "LMP_not_accepted" }, + { LMP_CLKOFFSET_REQ, "LMP_clkoffset_req" }, + { LMP_CLKOFFSET_RES, "LMP_clkoffset_res" }, + { LMP_DETACH, "LMP_detach" }, + { LMP_IN_RAND, "LMP_in_rand" }, + { LMP_COMB_KEY, "LMP_comb_key" }, + { LMP_UNIT_KEY, "LMP_unit_key" }, + { LMP_AU_RAND, "LMP_au_rand" }, + { LMP_SRES, "LMP_sres" }, + { LMP_TEMP_RAND, "LMP_temp_rand" }, + { LMP_TEMP_KEY, "LMP_temp_key" }, + { LMP_ENCRYPTION_MODE_REQ, "LMP_encryption_mode_req" }, + { LMP_ENCRYPTION_KEY_SIZE_REQ, "LMP_encryption_key_size_req" }, + { LMP_START_ENCRYPTION_REQ, "LMP_start_encryption_req" }, + { LMP_STOP_ENCRYPTION_REQ, "LMP_stop_encryption_req" }, + { LMP_SWITCH_REQ, "LMP_switch_req" }, + { LMP_HOLD, "LMP_hold" }, + { LMP_HOLD_REQ, "LMP_hold_req" }, + { LMP_SNIFF_REQ, "LMP_sniff_req" }, + { LMP_UNSNIFF_REQ, "LMP_unsniff_req" }, + { LMP_PARK_REQ, "LMP_park_req" }, + { LMP_SET_BROADCAST_SCAN_WINDOW, "LMP_set_broadcast_scan_window" }, + { LMP_MODIFY_BEACON, "LMP_modify_beacon" }, + { LMP_UNPARK_BD_ADDR_REQ, "LMP_unpark_BD_ADDR_req" }, + { LMP_UNPARK_PM_ADDR_REQ, "LMP_unpark_PM_ADDR_req" }, + { LMP_INCR_POWER_REQ, "LMP_incr_power_req" }, + { LMP_DECR_POWER_REQ, "LMP_decr_power_req" }, + { LMP_MAX_POWER, "LMP_max_power" }, + { LMP_MIN_POWER, "LMP_min_power" }, + { LMP_AUTO_RATE, "LMP_auto_rate" }, + { LMP_PREFERRED_RATE, "LMP_preferred_rate" }, + { LMP_VERSION_REQ, "LMP_version_req" }, + { LMP_VERSION_RES, "LMP_version_res" }, + { LMP_FEATURES_REQ, "LMP_features_req" }, + { LMP_FEATURES_RES, "LMP_features_res" }, + { LMP_QUALITY_OF_SERVICE, "LMP_quality_of_service" }, + { LMP_QUALITY_OF_SERVICE_REQ, "LMP_quality_of_service_req" }, + { LMP_SCO_LINK_REQ, "LMP_SCO_link_req" }, + { LMP_REMOVE_SCO_LINK_REQ, "LMP_remove_SCO_link_req" }, + { LMP_MAX_SLOT, "LMP_max_slot" }, + { LMP_MAX_SLOT_REQ, "LMP_max_slot_req" }, + { LMP_TIMING_ACCURACY_REQ, "LMP_timing_accuracy_req" }, + { LMP_TIMING_ACCURACY_RES, "LMP_timing_accuracy_res" }, + { LMP_SETUP_COMPLETE, "LMP_setup_complete" }, + { LMP_USE_SEMI_PERMANENT_KEY, "LMP_use_semi_permanent_key" }, + { LMP_HOST_CONNECTION_REQ, "LMP_host_connection_req" }, + { LMP_SLOT_OFFSET, "LMP_slot_offset" }, + { LMP_PAGE_MODE_REQ, "LMP_page_mode_req" }, + { LMP_PAGE_SCAN_MODE_REQ, "LMP_page_scan_mode_req" }, + { LMP_SUPERVISION_TIMEOUT, "LMP_supervision_timeout" }, + { LMP_TEST_ACTIVATE, "LMP_test_activate" }, + { LMP_TEST_CONTROL, "LMP_test_control" }, + { LMP_ENCRYPTION_KEY_SIZE_MASK_REQ, "LMP_encryption_key_size_mask_req" }, + { LMP_ENCRYPTION_KEY_SIZE_MASK_RES, "LMP_encryption_key_size_mask_res" }, + { LMP_SET_AFH, "LMP_set_AFH" }, + { LMP_ENCAPSULATED_HEADER, "LMP_encapsulated_header" }, + { LMP_ENCAPSULATED_PAYLOAD, "LMP_encapsulated_payload" }, + { LMP_SIMPLE_PAIRING_CONFIRM, "LMP_Simple_Pairing_Confirm" }, + { LMP_SIMPLE_PAIRING_NUMBER, "LMP_Simple_Pairing_Number" }, + { LMP_DHKEY_CHECK, "LMP_DHkey_Check" }, + { LMP_ESCAPE_1, "Escape 1" }, + { LMP_ESCAPE_2, "Escape 2" }, + { LMP_ESCAPE_3, "Escape 3" }, + { LMP_ESCAPE_4, "Escape 4" }, + { 0, NULL } +}; + +/* extended LMP opcodes */ +static const value_string ext_opcode[] = { + { LMP_ACCEPTED_EXT, "LMP_accepted_ext" }, + { LMP_NOT_ACCEPTED_EXT, "LMP_not_accepted_ext" }, + { LMP_FEATURES_REQ_EXT, "LMP_features_req_ext" }, + { LMP_FEATURES_RES_EXT, "LMP_features_res_ext" }, + { LMP_PACKET_TYPE_TABLE_REQ, "LMP_packet_type_table_req" }, + { LMP_ESCO_LINK_REQ, "LMP_eSCO_link_req" }, + { LMP_REMOVE_ESCO_LINK_REQ, "LMP_remove_eSCO_link_req" }, + { LMP_CHANNEL_CLASSIFICATION_REQ, "LMP_channel_classification_req" }, + { LMP_CHANNEL_CLASSIFICATION, "LMP_channel_classification" }, + { LMP_SNIFF_SUBRATING_REQ, "LMP_sniff_subrating_req" }, + { LMP_SNIFF_SUBRATING_RES, "LMP_sniff_subrating_res" }, + { LMP_PAUSE_ENCRYPTION_REQ, "LMP_pause_encryption_req" }, + { LMP_RESUME_ENCRYPTION_REQ, "LMP_resume_encryption_req" }, + { LMP_IO_CAPABILITY_REQ, "LMP_IO_Capability_req" }, + { LMP_IO_CAPABILITY_RES, "LMP_IO_Capability_res" }, + { LMP_NUMERIC_COMPARISON_FAILED, "LMP_numeric_comparison_failed" }, + { LMP_PASSKEY_FAILED, "LMP_passkey_failed" }, + { LMP_OOB_FAILED, "LMP_oob_failed" }, + { LMP_KEYPRESS_NOTIFICATION, "LMP_keypress_notification" }, + { LMP_POWER_CONTROL_REQ, "LMP_power_control_req" }, + { LMP_POWER_CONTROL_RES, "LMP_power_control_res" }, + { 0, NULL } +}; + +/* LMP error codes */ +static const value_string error_code[] = { + { 0x00, "Success" }, + { 0x01, "Unknown HCI Command" }, + { 0x02, "Unknown Connection Identifier" }, + { 0x03, "Hardware Failure" }, + { 0x04, "Page Timeout" }, + { 0x05, "Authentication Failure" }, + { 0x06, "PIN or Key Missing" }, + { 0x07, "Memory Capacity Exceeded" }, + { 0x08, "Connection Timeout" }, + { 0x09, "Connection Limit Exceeded" }, + { 0x0A, "Synchronous Connection Limit To A Device Exceeded" }, + { 0x0B, "ACL Connection Already Exists" }, + { 0x0C, "Command Disallowed" }, + { 0x0D, "Connection Rejected due to Limited Resources" }, + { 0x0E, "Connection Rejected Due To Security Reasons" }, + { 0x0F, "Connection Rejected due to Unacceptable BD_ADDR" }, + { 0x10, "Connection Accept Timeout Exceeded" }, + { 0x11, "Unsupported Feature or Parameter Value" }, + { 0x12, "Invalid HCI Command Parameters" }, + { 0x13, "Remote User Terminated Connection" }, + { 0x14, "Remote Device Terminated Connection due to Low Resources" }, + { 0x15, "Remote Device Terminated Connection due to Power Off" }, + { 0x16, "Connection Terminated By Local Host" }, + { 0x17, "Repeated Attempts" }, + { 0x18, "Pairing Not Allowed" }, + { 0x19, "Unknown LMP PDU" }, + { 0x1A, "Unsupported Remote Feature / Unsupported LMP Feature" }, + { 0x1B, "SCO Offset Rejected" }, + { 0x1C, "SCO Interval Rejected" }, + { 0x1D, "SCO Air Mode Rejected" }, + { 0x1E, "Invalid LMP Parameters" }, + { 0x1F, "Unspecified Error" }, + { 0x20, "Unsupported LMP Parameter Value" }, + { 0x21, "Role Change Not Allowed" }, + { 0x22, "LMP Response Timeout" }, + { 0x23, "LMP Error Transaction Collision" }, + { 0x24, "LMP PDU Not Allowed" }, + { 0x25, "Encryption Mode Not Acceptable" }, + { 0x26, "Link Key Can Not be Changed" }, + { 0x27, "Requested QoS Not Supported" }, + { 0x28, "Instant Passed" }, + { 0x29, "Pairing With Unit Key Not Supported" }, + { 0x2A, "Different Transaction Collision" }, + { 0x2B, "Reserved" }, + { 0x2C, "QoS Unacceptable Parameter" }, + { 0x2D, "QoS Rejected" }, + { 0x2E, "Channel Classification Not Supported" }, + { 0x2F, "Insufficient Security" }, + { 0x30, "Parameter Out Of Mandatory Range" }, + { 0x31, "Reserved" }, + { 0x32, "Role Switch Pending" }, + { 0x33, "Reserved" }, + { 0x34, "Reserved Slot Violation" }, + { 0x35, "Role Switch Failed" }, + { 0x36, "Extended Inquiry Response Too Large" }, + { 0x37, "Secure Simple Pairing Not Supported By Host." }, + { 0x38, "Host Busy - Pairing" }, + { 0x39, "Connection Rejected due to No Suitable Channel Found" }, + { 0, NULL } +}; + +static const value_string encryption_mode[] = { + { 0, "no encryption" }, + { 1, "encryption" }, + { 2, "encryption" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string access_scheme[] = { + { 0, "polling technique" }, + /* 1 - 15 reserved */ + { 0, NULL } +}; + +static const value_string packet_size[] = { + { 0, "no packet-size preference available" }, + { 1, "use 1-slot packets" }, + { 2, "use 3-slot packets" }, + { 3, "use 5-slot packets" }, + { 0, NULL } +}; + +static const value_string edr_type[] = { + { 0, "use DM1 packets" }, + { 1, "use 2 Mbps packets" }, + { 2, "use 3 Mbps packets" }, + /* 3 reserved */ + { 0, NULL } +}; + +static const value_string versnr[] = { + { 0, "Bluetooth Core Specification 1.0b" }, + { 1, "Bluetooth Core Specification 1.1" }, + { 2, "Bluetooth Core Specification 1.2" }, + { 3, "Bluetooth Core Specification 2.0 + EDR" }, + { 4, "Bluetooth Core Specification 2.1 + EDR" }, + { 5, "Bluetooth Core Specification 3.0 + HS" }, + /* 6 - 255 reserved */ + { 0, NULL } +}; + +static const value_string compid[] = { + { 0, "Ericsson Technology Licensing" }, + { 1, "Nokia Mobile Phones" }, + { 2, "Intel Corp." }, + { 3, "IBM Corp." }, + { 4, "Toshiba Corp." }, + { 5, "3Com" }, + { 6, "Microsoft" }, + { 7, "Lucent" }, + { 8, "Motorola" }, + { 9, "Infineon Technologies AG" }, + { 10, "Cambridge Silicon Radio" }, + { 11, "Silicon Wave" }, + { 12, "Digianswer A/S" }, + { 13, "Texas Instruments Inc." }, + { 14, "Parthus Technologies Inc." }, + { 15, "Broadcom Corporation" }, + { 16, "Mitel Semiconductor" }, + { 17, "Widcomm, Inc." }, + { 18, "Zeevo, Inc." }, + { 19, "Atmel Corporation" }, + { 20, "Mitsubishi Electric Corporation" }, + { 21, "RTX Telecom A/S" }, + { 22, "KC Technology Inc." }, + { 23, "Newlogic" }, + { 24, "Transilica, Inc." }, + { 25, "Rohde & Schwarz GmbH & Co. KG" }, + { 26, "TTPCom Limited" }, + { 27, "Signia Technologies, Inc." }, + { 28, "Conexant Systems Inc." }, + { 29, "Qualcomm" }, + { 30, "Inventel" }, + { 31, "AVM Berlin" }, + { 32, "BandSpeed, Inc." }, + { 33, "Mansella Ltd" }, + { 34, "NEC Corporation" }, + { 35, "WavePlus Technology Co., Ltd." }, + { 36, "Alcatel" }, + { 37, "Philips Semiconductors" }, + { 38, "C Technologies" }, + { 39, "Open Interface" }, + { 40, "R F Micro Devices" }, + { 41, "Hitachi Ltd" }, + { 42, "Symbol Technologies, Inc." }, + { 43, "Tenovis" }, + { 44, "Macronix International Co. Ltd." }, + { 45, "GCT Semiconductor" }, + { 46, "Norwood Systems" }, + { 47, "MewTel Technology Inc." }, + { 48, "ST Microelectronics" }, + { 49, "Synopsys" }, + { 50, "Red-M (Communications) Ltd" }, + { 51, "Commil Ltd" }, + { 52, "Computer Access Technology Corporation (CATC)" }, + { 53, "Eclipse (HQ Espana) S.L." }, + { 54, "Renesas Technology Corp." }, + { 55, "Mobilian Corporation" }, + { 56, "Terax" }, + { 57, "Integrated System Solution Corp." }, + { 58, "Matsushita Electric Industrial Co., Ltd." }, + { 59, "Gennum Corporation" }, + { 60, "Research In Motion" }, + { 61, "IPextreme, Inc." }, + { 62, "Systems and Chips, Inc" }, + { 63, "Bluetooth SIG, Inc" }, + { 64, "Seiko Epson Corporation" }, + { 65, "Integrated Silicon Solution Taiwan, Inc." }, + { 66, "CONWISE Technology Corporation Ltd" }, + { 67, "PARROT SA" }, + { 68, "Socket Mobile" }, + { 69, "Atheros Communications, Inc." }, + { 70, "MediaTek, Inc." }, + { 71, "Bluegiga (tentative)" }, + { 72, "Marvell Technology Group Ltd." }, + { 73, "3DSP Corporation" }, + { 74, "Accel Semiconductor Ltd." }, + { 75, "Continental Automotive Systems" }, + { 76, "Apple, Inc." }, + { 77, "Staccato Communications, Inc." }, + { 78, "Avago Technologies" }, + { 79, "APT Ltd." }, + { 80, "SiRF Technology, Inc." }, + { 81, "Tzero Technologies, Inc." }, + { 82, "J&M Corporation" }, + { 83, "Free2move AB" }, + /* 84 - 65534 reserved */ + { 65535, "test" }, + { 0, NULL } +}; + +static const value_string sco_packet[] = { + { 0, "HV1" }, + { 1, "HV2" }, + { 2, "HV3" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string air_mode[] = { + { 0, "mu-law log" }, + { 1, "A-law log" }, + { 2, "CVSD" }, + { 3, "transparent data" }, + /* 4 - 255 reserved */ + { 0, NULL } +}; + +static const value_string paging_scheme[] = { + { 0, "mandatory scheme" }, + /* 1 - 255 reserved */ + { 0, NULL } +}; + +static const value_string paging_scheme_settings[] = { + /* for mandatory scheme: */ + { 0, "R0" }, + { 1, "R1" }, + { 2, "R2" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string afh_mode[] = { + { 0, "AFH disabled" }, + { 1, "AFH enabled" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string features_page[] = { + { 0, "standard features" }, + /* 1 - 255 other feature pages */ + { 0, NULL } +}; + +static const value_string packet_type_table[] = { + { 0, "1 Mbps only" }, + { 1, "2/3 Mbps" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string negotiation_state[] = { + { 0, "Initiate negotiation" }, + { 1, "The latest received set of negotiable parameters were possible but these parameters are preferred." }, + { 2, "The latest received set of negotiable parameters would cause a reserved slot violation." }, + { 3, "The latest received set of negotiable parameters would cause a latency violation." }, + { 4, "The latest received set of negotiable parameters are not supported." }, + /* 5 - 255 reserved */ + { 0, NULL } +}; + +static const value_string afh_reporting_mode[] = { + { 0, "AFH reporting disabled" }, + { 1, "AFH reporting enabled" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string io_capabilities[] = { + { 0, "Display Only" }, + { 1, "Display Yes/No" }, + { 2, "Keyboard Only" }, + { 3, "No Input/No Output" }, + /* 4 - 255 reserved */ + { 0, NULL } +}; + +static const value_string oob_auth_data[] = { + { 0, "No OOB Authentication Data received" }, + { 1, "OOB Authentication Data received" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string auth_requirements[] = { + { 0x00, "MITM Protection Not Required - No Bonding" }, + { 0x01, "MITM Protection Required - No Bonding" }, + { 0x02, "MITM Protection Not Required - Dedicated Bonding" }, + { 0x03, "MITM Protection Required - Dedicated Bonding" }, + { 0x04, "MITM Protection Not Required - General Bonding" }, + { 0x05, "MITM Protection Required - General Bonding" }, + /* 0x06 - 0xff reserved */ + { 0, NULL } +}; + +static const value_string power_adjust_req[] = { + { 0, "decrement power one step" }, + { 1, "increment power one step" }, + { 2, "increase to maximum power" }, + /* 3 - 255 reserved */ + { 0, NULL } +}; + +static const value_string power_adjust_res[] = { + { 0, "not supported" }, + { 1, "changed one step (not min or max)" }, + { 2, "max power" }, + { 3, "min power" }, + /* 4 - 255 reserved */ + { 0, NULL } +}; + +static const value_string test_scenario[] = { + { 0, "Pause Test Mode" }, + { 1, "Transmitter test - 0 pattern" }, + { 2, "Transmitter test - 1 pattern" }, + { 3, "Transmitter test - 1010 pattern" }, + { 4, "Pseudorandom bit sequence" }, + { 5, "Closed Loop Back - ACL packets" }, + { 6, "Closed Loop Back - Synchronous packets" }, + { 7, "ACL Packets without whitening" }, + { 8, "Synchronous Packets without whitening" }, + { 9, "Transmitter test - 1111 0000 pattern" }, + /* 10 - 254 reserved */ + { 255, "Exit Test Mode" }, + { 0, NULL } +}; + +static const value_string hopping_mode[] = { + { 0, "RX/TX on single frequency" }, + { 1, "Normal hopping" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string power_control_mode[] = { + { 0, "fixed TX output power" }, + { 1, "adaptive power control" }, + /* 2 - 255 reserved */ + { 0, NULL } +}; + +static const value_string esco_packet_type[] = { + { 0x00, "NULL/POLL" }, + { 0x07, "EV3" }, + { 0x0C, "EV4" }, + { 0x0D, "EV5" }, + { 0x26, "2-EV3" }, + { 0x2C, "2-EV5" }, + { 0x37, "3-EV3" }, + { 0x3D, "3-EV5" }, + /* other values reserved */ + { 0, NULL } +}; + +static const value_string notification_value[] = { + { 0, "passkey entry started" }, + { 1, "passkey digit entered" }, + { 2, "passkey digit erased" }, + { 3, "passkey cleared" }, + { 4, "passkey entry completed" }, + /* 5 - 255 reserved */ + { 0, NULL } +}; + +/* initialize the subtree pointers */ +static gint ett_lmp = -1; +static gint ett_lmp_pwradjres = -1; +static gint ett_lmp_rate = -1; +static gint ett_lmp_timectrl = -1; + +/* LMP PDUs with short opcodes */ + +void +dissect_name_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_nameoffset, tvb, offset, 1, ENC_NA); +} + +void +dissect_name_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_nameoffset, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_namelen, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_namefrag, tvb, offset, 14, ENC_ASCII|ENC_NA); +} + +void +dissect_accepted(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_NA); +} + +void +dissect_not_accepted(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_clkoffset_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_clkoffset_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_clkoffset, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_detach(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_in_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_comb_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_unit_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_key, tvb, offset, 16, ENC_NA); +} + +void +dissect_au_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_sres(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4); + + proto_tree_add_item(tree, hf_lmp_authres, tvb, offset, 4, ENC_NA); +} + +void +dissect_temp_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_temp_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_key, tvb, offset, 16, ENC_NA); +} + +void +dissect_encryption_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_cryptmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_encryption_key_size_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_keysz, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_start_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA); +} + +void +dissect_stop_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_switch_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4); + + proto_tree_add_item(tree, hf_lmp_swinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); +} + +void +dissect_hold(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6); + + proto_tree_add_item(tree, hf_lmp_htime, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_hinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); +} + +void +dissect_hold_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6); + + proto_tree_add_item(tree, hf_lmp_htime, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_hinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); +} + +void +dissect_sniff_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 10); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_dsniff, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_tsniff, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffatt, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffto, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_unsniff_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_park_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_tb, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nb, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_deltab, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_araddr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_nbsleep, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_dbsleep, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_daccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_taccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_naccslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_npoll, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_accscheme, tvb, offset, 1, ENC_NA); +} + +void +dissect_set_broadcast_scan_window(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 6); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + } + + proto_tree_add_item(tree, hf_lmp_bsw, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_modify_beacon(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 13); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 11); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 11); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9); + } + + proto_tree_add_item(tree, hf_lmp_tb, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nb, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_deltab, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_daccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_taccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_naccslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_npoll, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maccess, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_accscheme, tvb, offset, 1, ENC_NA); +} + +void +dissect_unpark_bd_addr_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + proto_item *item; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 15); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 15); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 13); + } + + proto_tree_add_item(tree, hf_lmp_ltaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_bdaddr1, tvb, offset, 6, ENC_LITTLE_ENDIAN); + offset += 6; + + proto_tree_add_item(tree, hf_lmp_bdaddr2, tvb, offset, 6, ENC_LITTLE_ENDIAN); + offset += 6; +} + +void +dissect_unpark_pm_addr_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + int db_present; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + + /* bit0 of timing control flags indicates presence of db */ + db_present = tvb_get_guint8(tvb, offset) & 0x01; + offset += 1; + + if (db_present) { + DISSECTOR_ASSERT(len == 15); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 13); + + proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + } else { + DISSECTOR_ASSERT(len == 13); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 11); + } + + proto_tree_add_item(tree, hf_lmp_ltaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_ltaddr3, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr4, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr3, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr4, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_ltaddr5, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_lmp_ltaddr6, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr5, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr6, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_ltaddr7, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pmaddr7, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_incr_power_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + + /* skipping one byte "for future use" */ +} + +void +dissect_decr_power_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + + /* skipping one byte "for future use" */ +} + +void +dissect_max_power(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_min_power(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_auto_rate(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_preferred_rate(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + proto_item *rate_item; + proto_tree *rate_tree; + + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + rate_item = proto_tree_add_item(tree, hf_lmp_rate, tvb, offset, 1, ENC_LITTLE_ENDIAN); + rate_tree = proto_item_add_subtree(rate_item, ett_lmp_rate); + + proto_tree_add_item(rate_tree, hf_lmp_rate_fec, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(rate_tree, hf_lmp_rate_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(rate_tree, hf_lmp_rate_type, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(rate_tree, hf_lmp_rate_edrsize, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_version_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 6); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5); + + proto_tree_add_item(tree, hf_lmp_versnr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_compid, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_subversnr, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_version_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 6); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5); + + proto_tree_add_item(tree, hf_lmp_versnr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_compid, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_subversnr, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_features_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8); + + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_features_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8); + + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_quality_of_service(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_pollintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nbc, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_quality_of_service_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_pollintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_nbc, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_sco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6); + + proto_tree_add_item(tree, hf_lmp_scohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_dsco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_tsco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_scopkt, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_airmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_remove_sco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_scohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_max_slot(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_maxslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_max_slot_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_maxslots, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_timing_accuracy_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_timing_accuracy_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_drift, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_jitter, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_setup_complete(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_use_semi_permanent_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_host_connection_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_slot_offset(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8); + + proto_tree_add_item(tree, hf_lmp_slotoffset, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_bdaddr, tvb, offset, 6, ENC_LITTLE_ENDIAN); +} + +void +dissect_page_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_pagesch, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pssettings, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_page_scan_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_pagesch, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pssettings, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_supervision_timeout(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_suptimeout, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_test_activate(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_test_control(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 10); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9); + + /* FIXME these fields should all be XORed with 0x55. . . */ + + proto_tree_add_item(tree, hf_lmp_testscen, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_hopmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_txfreq, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_rxfreq, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pcmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pollper, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_pkttype, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_testlen, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_encryption_key_size_mask_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 1); +} + +void +dissect_encryption_key_size_mask_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_ksmask, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_set_afh(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 16); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 15); + + proto_tree_add_item(tree, hf_lmp_afhinst, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 4; + + proto_tree_add_item(tree, hf_lmp_afhmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_afhchmap, tvb, offset, 10, ENC_NA); +} + +void +dissect_encapsulated_header(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_encmaj, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_encmin, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_enclen, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_encapsulated_payload(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_encdata, tvb, offset, 16, ENC_NA); +} + +void +dissect_simple_pairing_confirm(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_commit, tvb, offset, 16, ENC_NA); +} + +void +dissect_simple_pairing_number(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_nonce, tvb, offset, 16, ENC_NA); +} + +void +dissect_dhkey_check(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 17); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16); + + proto_tree_add_item(tree, hf_lmp_confirm, tvb, offset, 16, ENC_NA); +} + +/* LMP PDUs with extended opcodes */ + +void +dissect_accepted_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_eopinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_not_accepted_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_eopinre, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_features_req_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 12); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10); + + proto_tree_add_item(tree, hf_lmp_fpage, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maxsp, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + /* + * extended features might need to be different from hf_lmp_features + * if hf_lmp_features is broken out + */ + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_features_res_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 12); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10); + + proto_tree_add_item(tree, hf_lmp_fpage, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_maxsp, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + /* + * extended features might need to be different from hf_lmp_features + * if hf_lmp_features is broken out + */ + proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA); +} + +void +dissect_packet_type_table_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_pkttypetbl, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_esco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 16); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 14); + + proto_tree_add_item(tree, hf_lmp_escohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escoltaddr, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl, + ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_desco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_tesco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_wesco, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escotypems, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escotypesm, tvb, offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_escolenms, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_escolensm, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_airmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_negstate, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_remove_esco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 4); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2); + + proto_tree_add_item(tree, hf_lmp_escohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA); +} + +void +dissect_channel_classification_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 7); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5); + + proto_tree_add_item(tree, hf_lmp_afhrptmode, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_afhminintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_afhmaxintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_channel_classification(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 12); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10); + + proto_tree_add_item(tree, hf_lmp_afhclass, tvb, offset, 10, ENC_NA); +} + +void +dissect_sniff_subrating_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 7); + + proto_tree_add_item(tree, hf_lmp_maxss, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_minsmt, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffsi, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_sniff_subrating_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 9); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 7); + + proto_tree_add_item(tree, hf_lmp_maxss, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_minsmt, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_lmp_sniffsi, tvb, offset, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_pause_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_resume_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_io_capability_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_iocaps, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_oobauthdata, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_authreqs, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_io_capability_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 5); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3); + + proto_tree_add_item(tree, hf_lmp_iocaps, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_oobauthdata, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_lmp_authreqs, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_numeric_comparison_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_passkey_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_oob_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 2); +} + +void +dissect_keypress_notification(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_nottype, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_power_control_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + proto_tree_add_item(tree, hf_lmp_pwradjreq, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +void +dissect_power_control_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len) +{ + proto_item *pa_item; + proto_tree *pa_tree; + + DISSECTOR_ASSERT(len == 3); + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + pa_item = proto_tree_add_item(tree, hf_lmp_pwradjres, tvb, offset, 1, ENC_LITTLE_ENDIAN); + pa_tree = proto_item_add_subtree(pa_item, ett_lmp_pwradjres); + + proto_tree_add_item(pa_tree, hf_lmp_pwradj_gfsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(pa_tree, hf_lmp_pwradj_dqpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(pa_tree, hf_lmp_pwradj_8dpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN); +} + +/* Link Manager Protocol */ +static void +dissect_btlmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *lmp_item; + proto_tree *lmp_tree; + int offset; + int len; + int op; /* opcode */ + int eop; /* extended opcode */ + + offset = 0; + len = tvb_length(tvb); + + DISSECTOR_ASSERT(len >= 1); + + /* make entries in protocol column and info column on summary display */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "LMP"); + + /* clear the info column first just in case of type fetching failure. */ + col_clear(pinfo->cinfo, COL_INFO); + + op = tvb_get_guint8(tvb, offset) >> 1; + + if (op == LMP_ESCAPE_4) { + DISSECTOR_ASSERT(len >= 2); + + eop = tvb_get_guint8(tvb, offset + 1); + + col_add_str(pinfo->cinfo, COL_INFO, val_to_str(eop, + opcode, "Unknown Extended Opcode (%d)")); + } else { + col_add_str(pinfo->cinfo, COL_INFO, val_to_str(op, + opcode, "Unknown Opcode (%d)")); + } + + /* see if we are being asked for details */ + if (!tree) + return; + + lmp_item = proto_tree_add_item(tree, proto_btlmp, tvb, offset, -1, ENC_NA); + lmp_tree = proto_item_add_subtree(lmp_item, ett_lmp); + + proto_tree_add_item(lmp_tree, hf_lmp_tid, tvb, offset, 1, ENC_LITTLE_ENDIAN); + + proto_tree_add_item(lmp_tree, hf_lmp_op, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + + switch (op) { + case LMP_NAME_REQ: + dissect_name_req(lmp_tree, tvb, offset, len); + break; + case LMP_NAME_RES: + dissect_name_res(lmp_tree, tvb, offset, len); + break; + case LMP_ACCEPTED: + dissect_accepted(lmp_tree, tvb, offset, len); + break; + case LMP_NOT_ACCEPTED: + dissect_not_accepted(lmp_tree, tvb, offset, len); + break; + case LMP_CLKOFFSET_REQ: + dissect_clkoffset_req(lmp_tree, tvb, offset, len); + break; + case LMP_CLKOFFSET_RES: + dissect_clkoffset_res(lmp_tree, tvb, offset, len); + break; + case LMP_DETACH: + dissect_detach(lmp_tree, tvb, offset, len); + break; + case LMP_IN_RAND: + dissect_in_rand(lmp_tree, tvb, offset, len); + break; + case LMP_COMB_KEY: + dissect_comb_key(lmp_tree, tvb, offset, len); + break; + case LMP_UNIT_KEY: + dissect_unit_key(lmp_tree, tvb, offset, len); + break; + case LMP_AU_RAND: + dissect_au_rand(lmp_tree, tvb, offset, len); + break; + case LMP_SRES: + dissect_sres(lmp_tree, tvb, offset, len); + break; + case LMP_TEMP_RAND: + dissect_temp_rand(lmp_tree, tvb, offset, len); + break; + case LMP_TEMP_KEY: + dissect_temp_key(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_MODE_REQ: + dissect_encryption_mode_req(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_KEY_SIZE_REQ: + dissect_encryption_key_size_req(lmp_tree, tvb, offset, len); + break; + case LMP_START_ENCRYPTION_REQ: + dissect_start_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_STOP_ENCRYPTION_REQ: + dissect_stop_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_SWITCH_REQ: + dissect_switch_req(lmp_tree, tvb, offset, len); + break; + case LMP_HOLD: + dissect_hold(lmp_tree, tvb, offset, len); + break; + case LMP_HOLD_REQ: + dissect_hold_req(lmp_tree, tvb, offset, len); + break; + case LMP_SNIFF_REQ: + dissect_sniff_req(lmp_tree, tvb, offset, len); + break; + case LMP_UNSNIFF_REQ: + dissect_unsniff_req(lmp_tree, tvb, offset, len); + break; + case LMP_PARK_REQ: + dissect_park_req(lmp_tree, tvb, offset, len); + break; + case LMP_SET_BROADCAST_SCAN_WINDOW: + dissect_set_broadcast_scan_window(lmp_tree, tvb, offset, len); + break; + case LMP_MODIFY_BEACON: + dissect_modify_beacon(lmp_tree, tvb, offset, len); + break; + case LMP_UNPARK_BD_ADDR_REQ: + dissect_unpark_bd_addr_req(lmp_tree, tvb, offset, len); + break; + case LMP_UNPARK_PM_ADDR_REQ: + dissect_unpark_pm_addr_req(lmp_tree, tvb, offset, len); + break; + case LMP_INCR_POWER_REQ: + dissect_incr_power_req(lmp_tree, tvb, offset, len); + break; + case LMP_DECR_POWER_REQ: + dissect_decr_power_req(lmp_tree, tvb, offset, len); + break; + case LMP_MAX_POWER: + dissect_max_power(lmp_tree, tvb, offset, len); + break; + case LMP_MIN_POWER: + dissect_min_power(lmp_tree, tvb, offset, len); + break; + case LMP_AUTO_RATE: + dissect_auto_rate(lmp_tree, tvb, offset, len); + break; + case LMP_PREFERRED_RATE: + dissect_preferred_rate(lmp_tree, tvb, offset, len); + break; + case LMP_VERSION_REQ: + dissect_version_req(lmp_tree, tvb, offset, len); + break; + case LMP_VERSION_RES: + dissect_version_res(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_REQ: + dissect_features_req(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_RES: + dissect_features_res(lmp_tree, tvb, offset, len); + break; + case LMP_QUALITY_OF_SERVICE: + dissect_quality_of_service(lmp_tree, tvb, offset, len); + break; + case LMP_QUALITY_OF_SERVICE_REQ: + dissect_quality_of_service_req(lmp_tree, tvb, offset, len); + break; + case LMP_SCO_LINK_REQ: + dissect_sco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_REMOVE_SCO_LINK_REQ: + dissect_remove_sco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_MAX_SLOT: + dissect_max_slot(lmp_tree, tvb, offset, len); + break; + case LMP_MAX_SLOT_REQ: + dissect_max_slot_req(lmp_tree, tvb, offset, len); + break; + case LMP_TIMING_ACCURACY_REQ: + dissect_timing_accuracy_req(lmp_tree, tvb, offset, len); + break; + case LMP_TIMING_ACCURACY_RES: + dissect_timing_accuracy_res(lmp_tree, tvb, offset, len); + break; + case LMP_SETUP_COMPLETE: + dissect_setup_complete(lmp_tree, tvb, offset, len); + break; + case LMP_USE_SEMI_PERMANENT_KEY: + dissect_use_semi_permanent_key(lmp_tree, tvb, offset, len); + break; + case LMP_HOST_CONNECTION_REQ: + dissect_host_connection_req(lmp_tree, tvb, offset, len); + break; + case LMP_SLOT_OFFSET: + dissect_slot_offset(lmp_tree, tvb, offset, len); + break; + case LMP_PAGE_MODE_REQ: + dissect_page_mode_req(lmp_tree, tvb, offset, len); + break; + case LMP_PAGE_SCAN_MODE_REQ: + dissect_page_scan_mode_req(lmp_tree, tvb, offset, len); + break; + case LMP_SUPERVISION_TIMEOUT: + dissect_supervision_timeout(lmp_tree, tvb, offset, len); + break; + case LMP_TEST_ACTIVATE: + dissect_test_activate(lmp_tree, tvb, offset, len); + break; + case LMP_TEST_CONTROL: + dissect_test_control(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_KEY_SIZE_MASK_REQ: + dissect_encryption_key_size_mask_req(lmp_tree, tvb, offset, len); + break; + case LMP_ENCRYPTION_KEY_SIZE_MASK_RES: + dissect_encryption_key_size_mask_res(lmp_tree, tvb, offset, len); + break; + case LMP_SET_AFH: + dissect_set_afh(lmp_tree, tvb, offset, len); + break; + case LMP_ENCAPSULATED_HEADER: + dissect_encapsulated_header(lmp_tree, tvb, offset, len); + break; + case LMP_ENCAPSULATED_PAYLOAD: + dissect_encapsulated_payload(lmp_tree, tvb, offset, len); + break; + case LMP_SIMPLE_PAIRING_CONFIRM: + dissect_simple_pairing_confirm(lmp_tree, tvb, offset, len); + break; + case LMP_SIMPLE_PAIRING_NUMBER: + dissect_simple_pairing_number(lmp_tree, tvb, offset, len); + break; + case LMP_DHKEY_CHECK: + dissect_dhkey_check(lmp_tree, tvb, offset, len); + break; + case LMP_ESCAPE_1: + break; + case LMP_ESCAPE_2: + break; + case LMP_ESCAPE_3: + break; + case LMP_ESCAPE_4: + /* extended opcode */ + DISSECTOR_ASSERT(len >= 2); + proto_tree_add_item(lmp_tree, hf_lmp_eop, tvb, offset, 1, ENC_NA); + offset += 1; + + switch (eop) { + case LMP_ACCEPTED_EXT: + dissect_accepted_ext(lmp_tree, tvb, offset, len); + break; + case LMP_NOT_ACCEPTED_EXT: + dissect_not_accepted_ext(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_REQ_EXT: + dissect_features_req_ext(lmp_tree, tvb, offset, len); + break; + case LMP_FEATURES_RES_EXT: + dissect_features_res_ext(lmp_tree, tvb, offset, len); + break; + case LMP_PACKET_TYPE_TABLE_REQ: + dissect_packet_type_table_req(lmp_tree, tvb, offset, len); + break; + case LMP_ESCO_LINK_REQ: + dissect_esco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_REMOVE_ESCO_LINK_REQ: + dissect_remove_esco_link_req(lmp_tree, tvb, offset, len); + break; + case LMP_CHANNEL_CLASSIFICATION_REQ: + dissect_channel_classification_req(lmp_tree, tvb, offset, len); + break; + case LMP_CHANNEL_CLASSIFICATION: + dissect_channel_classification(lmp_tree, tvb, offset, len); + break; + case LMP_SNIFF_SUBRATING_REQ: + dissect_sniff_subrating_req(lmp_tree, tvb, offset, len); + break; + case LMP_SNIFF_SUBRATING_RES: + dissect_sniff_subrating_res(lmp_tree, tvb, offset, len); + break; + case LMP_PAUSE_ENCRYPTION_REQ: + dissect_pause_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_RESUME_ENCRYPTION_REQ: + dissect_resume_encryption_req(lmp_tree, tvb, offset, len); + break; + case LMP_IO_CAPABILITY_REQ: + dissect_io_capability_req(lmp_tree, tvb, offset, len); + break; + case LMP_IO_CAPABILITY_RES: + dissect_io_capability_res(lmp_tree, tvb, offset, len); + break; + case LMP_NUMERIC_COMPARISON_FAILED: + dissect_numeric_comparison_failed(lmp_tree, tvb, offset, len); + break; + case LMP_PASSKEY_FAILED: + dissect_passkey_failed(lmp_tree, tvb, offset, len); + break; + case LMP_OOB_FAILED: + dissect_oob_failed(lmp_tree, tvb, offset, len); + break; + case LMP_KEYPRESS_NOTIFICATION: + dissect_keypress_notification(lmp_tree, tvb, offset, len); + break; + case LMP_POWER_CONTROL_REQ: + dissect_power_control_req(lmp_tree, tvb, offset, len); + break; + case LMP_POWER_CONTROL_RES: + dissect_power_control_res(lmp_tree, tvb, offset, len); + break; + default: + break; + } + default: + break; + } +}; + +/* register the protocol with Wireshark */ +void +proto_register_btlmp(void) +{ + + /* list of fields */ + static hf_register_info hf[] = { + { &hf_lmp_accscheme, + { "Access Scheme", "btlmp.accscheme", + FT_UINT8, BASE_DEC, VALS(access_scheme), 0xf0, + NULL, HFILL } + }, + { &hf_lmp_afhchmap, + { "AFH Channel Map", "btlmp.afhchmap", + /* could break out individual channels but long */ + FT_BYTES, BASE_NONE, NULL, 0x0, + "Adaptive Frequency Hopping Channel Map", HFILL } + }, + { &hf_lmp_afhclass, + { "AFH Channel Classification", "btlmp.afhclass", + /* could break out individual channels but long */ + FT_BYTES, BASE_NONE, NULL, 0x0, + "Adaptive Frequency Hopping Channel Classification", HFILL } + }, + { &hf_lmp_afhinst, + { "AFH Instant", "btlmp.afhinst", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Adaptive Frequency Hopping Instant (slot)", HFILL } + }, + { &hf_lmp_afhmaxintvl, + { "AFH Max Interval", "btlmp.maxintvl", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Adaptive Maximum Interval in slots", HFILL } + }, + { &hf_lmp_afhminintvl, + { "AFH Min Interval", "btlmp.minintvl", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Adaptive Minimum Interval in slots", HFILL } + }, + { &hf_lmp_afhmode, + { "AFH Mode", "btlmp.afhmode", + FT_UINT8, BASE_DEC, VALS(afh_mode), 0x0, + "Adaptive Frequency Hopping Mode", HFILL } + }, + { &hf_lmp_afhrptmode, + { "AFH Reporting Mode", "btlmp.afhrptmode", + FT_UINT8, BASE_DEC, VALS(afh_reporting_mode), 0x0, + "Adaptive Frequency Hopping Reporting Mode", HFILL } + }, + { &hf_lmp_airmode, + { "Air Mode", "btlmp.airmode", + FT_UINT8, BASE_HEX, VALS(air_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_araddr, + { "AR_ADDR", "btlmp.araddr", + FT_UINT8, BASE_HEX, NULL, 0xfe, + NULL, HFILL } + }, + { &hf_lmp_authreqs, + { "Authentication Requirements", "btlmp.authreqs", + FT_UINT8, BASE_HEX, VALS(auth_requirements), 0xf0, + NULL, HFILL } + }, + { &hf_lmp_authres, + { "Authentication Response", "btlmp.authres", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_bdaddr, + { "BD_ADDR", "btlmp.bdaddr", + FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff, + NULL, HFILL } + }, + { &hf_lmp_bdaddr1, + { "BD_ADDR 1", "btlmp.bdaddr", + FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff, + NULL, HFILL } + }, + { &hf_lmp_bdaddr2, + { "BD_ADDR2", "btlmp.bdaddr", + FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff, + "BD_ADDR 2", HFILL } + }, + { &hf_lmp_bsw, + { "Broadcast Scan Window", "btlmp.bsw", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Broadcast Scan Window in slots", HFILL } + }, + { &hf_lmp_clkoffset, + { "Clock Offset", "btlmp.clkoffset", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Clock Offset in units of 1.25 ms", HFILL } + }, + { &hf_lmp_commit, + { "Commitment Value", "btlmp.commit", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_confirm, + { "Confirmation Value", "btlmp.confirm", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_compid, + { "Company ID", "btlmp.compid", + FT_UINT16, BASE_DEC, VALS(compid), 0x0, + NULL, HFILL } + }, + { &hf_lmp_cryptmode, + { "Encryption Mode", "btlmp.cryptmode", + FT_UINT8, BASE_DEC, VALS(encryption_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_daccess, + { "Daccess", "btlmp.daccess", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Daccess in slots", HFILL } + }, + { &hf_lmp_db, + { "Db", "btlmp.db", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Db in slots", HFILL } + }, + { &hf_lmp_dbsleep, + { "Dbsleep", "btlmp.dbsleep", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_deltab, + { "Deltab", "btlmp.deltab", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Deltab in slots", HFILL } + }, + { &hf_lmp_desco, + { "Desco", "btlmp.desco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Desco in slots", HFILL } + }, + { &hf_lmp_drift, + { "Drift", "btlmp.drift", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Drift in ppm", HFILL } + }, + { &hf_lmp_dsco, + { "Dsco", "btlmp.dsco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Dsco in slots", HFILL } + }, + { &hf_lmp_dsniff, + { "Dsniff", "btlmp.dsniff", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Dsniff in slots", HFILL } + }, + { &hf_lmp_encdata, + { "Encapsulated Data", "btlmp.encdata", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_enclen, + { "Encapsulated Length", "btlmp.enclen", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_encmaj, + { "Encapsulated Major Type", "btlmp.encmaj", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_encmin, + { "Encapsulated Minor Type", "btlmp.encmin", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_eop, + { "Extended Opcode", "btlmp.eop", + FT_UINT8, BASE_DEC, VALS(ext_opcode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_eopinre, + { "In Response To", "btlmp.eopinre", + FT_UINT8, BASE_DEC, VALS(ext_opcode), 0x0, + "Extended Opcode this is in response to", HFILL } + }, + { &hf_lmp_escolenms, + { "Packet Length M -> S", "btlmp.escolenms", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Packet Length in bytes Master to Slave", HFILL } + }, + { &hf_lmp_escolensm, + { "Packet Length S -> M", "btlmp.escolensm", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Packet Length in bytes Slave to Master", HFILL } + }, + { &hf_lmp_escotypems, + { "eSCO Packet Type M -> S", "btlmp.escotypems", + FT_UINT8, BASE_HEX, VALS(esco_packet_type), 0x0, + "eSCO Packet Type Master to Slave", HFILL } + }, + { &hf_lmp_escotypesm, + { "eSCO Packet Type S -> M", "btlmp.escotypesm", + FT_UINT8, BASE_HEX, VALS(esco_packet_type), 0x0, + "eSCO Packet Type Slave to Master", HFILL } + }, + { &hf_lmp_err, + { "Error Code", "btlmp.err", + FT_UINT8, BASE_HEX, VALS(error_code), 0x0, + NULL, HFILL } + }, + { &hf_lmp_escohdl, + { "eSCO Handle", "btlmp.escohdl", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_escoltaddr, + { "eSCO LT_ADDR", "btlmp.escoltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0, + "eSCO Logical Transport Address", HFILL } + }, + { &hf_lmp_features, + { "Features", "btlmp.features", + /* could break out individual features but long */ + FT_BYTES, BASE_NONE, NULL, 0x0, + "Feature Mask", HFILL } + }, + { &hf_lmp_fpage, + { "Features Page", "btlmp.fpage", + FT_UINT8, BASE_DEC, VALS(features_page), 0x0, + NULL, HFILL } + }, + { &hf_lmp_htime, + { "Hold Time", "btlmp.htime", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Hold Time in slots", HFILL } + }, + { &hf_lmp_hinst, + { "Hold Instant", "btlmp.hinst", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Hold Instant (slot)", HFILL } + }, + { &hf_lmp_hopmode, + { "Hopping Mode", "btlmp.hopmode", + FT_UINT8, BASE_DEC, VALS(hopping_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_iocaps, + { "IO Capabilities", "btlmp.iocaps", + FT_UINT8, BASE_DEC, VALS(io_capabilities), 0x0, + "Input/Output Capabilities", HFILL } + }, + { &hf_lmp_jitter, + { "Jitter", "btlmp.jitter", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Jitter in microseconds", HFILL } + }, + { &hf_lmp_key, + { "Key", "btlmp.key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_keysz, + { "Key Size", "btlmp.keysz", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Key Size in bytes", HFILL } + }, + { &hf_lmp_ksmask, + { "Key Size Mask", "btlmp.ksmask", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_ltaddr1, + { "LT_ADDR 1", "btlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 1", HFILL } + }, + { &hf_lmp_ltaddr2, + { "LT_ADDR 2", "btlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0xf0, + "Logical Transport Address 2", HFILL } + }, + { &hf_lmp_ltaddr3, + { "LT_ADDR 3", "btlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 3", HFILL } + }, + { &hf_lmp_ltaddr4, + { "LT_ADDR 4", "btlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0xf0, + "Logical Transport Address 4", HFILL } + }, + { &hf_lmp_ltaddr5, + { "LT_ADDR 5", "btlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 5", HFILL } + }, + { &hf_lmp_ltaddr6, + { "LT_ADDR 6", "btlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0xf0, + "Logical Transport Address 6", HFILL } + }, + { &hf_lmp_ltaddr7, + { "LT_ADDR 7", "btlmp.ltaddr", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Logical Transport Address 7", HFILL } + }, + { &hf_lmp_maccess, + { "Maccess", "btlmp.maccess", + FT_UINT8, BASE_HEX, NULL, 0x0f, + "Number of access windows", HFILL } + }, + { &hf_lmp_maxslots, + { "Max Slots", "btlmp.maxslots", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_maxsp, + { "Max Supported Page", "btlmp.maxsp", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Highest extended features page with non-zero bit", HFILL } + }, + { &hf_lmp_maxss, + { "Max Sniff Subrate", "btlmp.maxss", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_minsmt, + { "Min Sniff Mode Timeout", "btlmp.minsmt", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Min Sniff Mode Timeout in slots", HFILL } + }, + { &hf_lmp_naccslots, + { "Nacc-slots", "btlmp.naccslots", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_namefrag, + { "Name Fragment", "btlmp.namefrag", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_namelen, + { "Name Length", "btlmp.namelen", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Name Length in bytes", HFILL } + }, + { &hf_lmp_nameoffset, + { "Name Offset", "btlmp.nameoffset", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Name Offset in bytes", HFILL } + }, + { &hf_lmp_nb, + { "Nb", "btlmp.nb", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_nbc, + { "Nbc", "btlmp.nbc", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_nbsleep, + { "Nbsleep", "btlmp.nbsleep", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_negstate, + { "Negotiation State", "btlmp.negstate", + FT_UINT8, BASE_DEC, VALS(negotiation_state), 0x0, + NULL, HFILL } + }, + { &hf_lmp_nonce, + { "Nonce Value", "btlmp.nonce", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_nottype, + { "Notification Type", "btlmp.nottype", + FT_UINT8, BASE_DEC, VALS(notification_value), 0x0, + NULL, HFILL } + }, + { &hf_lmp_npoll, + { "Npoll", "btlmp.npoll", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_oobauthdata, + { "OOB Authentication Data", "btlmp.oobauthdata", + FT_UINT8, BASE_DEC, VALS(oob_auth_data), 0xfe, + NULL, HFILL } + }, + { &hf_lmp_op, + { "Opcode", "btlmp.op", + FT_UINT8, BASE_DEC, VALS(opcode), 0xfe, + NULL, HFILL } + }, + { &hf_lmp_opinre, + { "In Response To", "btlmp.opinre", + FT_UINT8, BASE_DEC, VALS(opcode), 0x7f, + "Opcode this is in response to", HFILL } + }, + { &hf_lmp_pagesch, + { "Paging Scheme", "btlmp.pagesch", + FT_UINT8, BASE_DEC, VALS(paging_scheme), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pcmode, + { "Power Control Mode", "btlmp.pcmode", + FT_UINT8, BASE_DEC, VALS(power_control_mode), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pkttype, + { "Packet Type", "btlmp.pkttype", + /* FIXME break out further */ + FT_UINT8, BASE_HEX, NULL, 0x0, + "Packet Type", HFILL } + }, + { &hf_lmp_pkttypetbl, + { "Packet Type Table", "btlmp.pkttypetbl", + FT_UINT8, BASE_DEC, VALS(packet_type_table), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr, + { "PM_ADDR", "btlmp.pmaddr", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr1, + { "PM_ADDR 1", "btlmp.pmaddr1", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr2, + { "PM_ADDR 2", "btlmp.pmaddr2", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr3, + { "PM_ADDR 3", "btlmp.pmaddr3", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr4, + { "PM_ADDR 4", "btlmp.pmaddr4", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr5, + { "PM_ADDR 5", "btlmp.pmaddr5", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr6, + { "PM_ADDR 6", "btlmp.pmaddr6", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pmaddr7, + { "PM_ADDR 7", "btlmp.pmaddr7", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pollintvl, + { "Poll Interval", "btlmp.pollintvl", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Poll Interval in slots", HFILL } + }, + { &hf_lmp_pollper, + { "Poll Period", "btlmp.pollper", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Poll Period in units of 1.25 ms", HFILL } + }, + { &hf_lmp_pssettings, + { "Paging Scheme Settings", "btlmp.pssettings", + FT_UINT8, BASE_DEC, VALS(paging_scheme_settings), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pwradjreq, + { "Power Adjustment Request", "btlmp.pwradjreq", + FT_UINT8, BASE_DEC, VALS(power_adjust_req), 0x0, + NULL, HFILL } + }, + { &hf_lmp_pwradjres, + { "Power Adjustment Response", "btlmp.pwradjres", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_pwradj_8dpsk, + { "8DPSK", "btlmp.pwradj_8dpsk", + FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x30, + "8DPSK Power Adjustment Response", HFILL } + }, + { &hf_lmp_pwradj_dqpsk, + { "DQPSK", "btlmp.pwradj_dqpsk", + FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x0C, + "DQPSK Power Adjustment Response", HFILL } + }, + { &hf_lmp_pwradj_gfsk, + { "GFSK", "btlmp.pwradj_gfsk", + FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x03, + "GFSK Power Adjustment Response", HFILL } + }, + { &hf_lmp_rand, + { "Random Number", "btlmp.rand", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_rate, + { "Data Rate", "btlmp.rate", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_rate_fec, + { "FEC", "btlmp.rate.fec", + FT_BOOLEAN, BASE_DEC, TFS(&fec), 0x01, + "Forward Error Correction", HFILL } + }, + { &hf_lmp_rate_size, + { "Packet Size", "btlmp.rate.size", + FT_UINT8, BASE_HEX, VALS(packet_size), 0x06, + "Basic Rate Packet Size", HFILL } + }, + { &hf_lmp_rate_type, + { "EDR Type", "btlmp.rate.type", + FT_UINT8, BASE_HEX, VALS(edr_type), 0x18, + "Enhanced Data Rate type", HFILL } + }, + { &hf_lmp_rate_edrsize, + { "EDR Size", "btlmp.rate.edrsize", + FT_UINT8, BASE_HEX, VALS(packet_size), 0x60, + "Enhanced Data Rate packet size", HFILL } + }, + { &hf_lmp_rxfreq, + { "RX Frequency", "btlmp.rxfreq", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Receive Frequency in MHz above 2402", HFILL } + }, + { &hf_lmp_scohdl, + { "SCO Handle", "btlmp.scohdl", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_scopkt, + { "SCO Packet", "btlmp.scopkt", + FT_UINT8, BASE_DEC, VALS(sco_packet), 0x0, + NULL, HFILL } + }, + { &hf_lmp_slotoffset, + { "Slot Offset", "btlmp.slotoffset", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Slot Offset in microseconds", HFILL } + }, + { &hf_lmp_sniffatt, + { "Sniff Attempt", "btlmp.sniffatt", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Number of receive slots", HFILL } + }, + { &hf_lmp_sniffsi, + { "Sniff Subrating Instant", "btlmp.sniffsi", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Sniff Subrating Instant (slot)", HFILL } + }, + { &hf_lmp_sniffto, + { "Sniff Timeout", "btlmp.sniffto", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Number of receive slots", HFILL } + }, + { &hf_lmp_subversnr, + { "SubVersNr", "btlmp.subversnr", + FT_UINT16, BASE_DEC, NULL, 0x0, + "SubVersion", HFILL } + }, + { &hf_lmp_suptimeout, + { "Supervision Timeout", "btlmp.suptimeout", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Supervision Timeout in slots", HFILL } + }, + { &hf_lmp_swinst, + { "Switch Instant", "btlmp.swinst", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Switch Instant (slot)", HFILL } + }, + { &hf_lmp_taccess, + { "Taccess", "btlmp.taccess", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Taccess in slots", HFILL } + }, + { &hf_lmp_tb, + { "Tb", "btlmp.tb", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Tb in slots", HFILL } + }, + { &hf_lmp_tesco, + { "Tesco", "btlmp.tesco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Tesco in slots", HFILL } + }, + { &hf_lmp_testlen, + { "Test Length", "btlmp.testlen", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Length of test sequence in bytes", HFILL } + }, + { &hf_lmp_testscen, + { "Test Scenario", "btlmp.testscen", + FT_UINT8, BASE_DEC, VALS(test_scenario), 0x0, + NULL, HFILL } + }, + { &hf_lmp_tid, + { "TID", "btlmp.tid", + FT_BOOLEAN, BASE_DEC, TFS(&tid), 0x01, + "Transaction ID", HFILL } + }, + { &hf_lmp_timectrl, + { "Timing Control Flags", "btlmp.timectrl", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_lmp_time_change, + { "Timing Change", "btlmp.time.change", + FT_BOOLEAN, 8, TFS(&time_change), 0x01, + NULL, HFILL } + }, + { &hf_lmp_time_init, + { "Initialization", "btlmp.time.init", + FT_BOOLEAN, 8, TFS(&time_init), 0x02, + NULL, HFILL } + }, + { &hf_lmp_time_accwin, + { "Access Window", "btlmp.time.accwin", + FT_BOOLEAN, 8, TFS(&time_accwin), 0x04, + NULL, HFILL } + }, + { &hf_lmp_tsco, + { "Tsco", "btlmp.tsco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Tsco in slots", HFILL } + }, + { &hf_lmp_tsniff, + { "Tsniff", "btlmp.tsniff", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Tsniff in slots", HFILL } + }, + { &hf_lmp_txfreq, + { "TX Frequency", "btlmp.txfreq", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Transmit Frequency in MHz above 2402", HFILL } + }, + { &hf_lmp_versnr, + { "VersNr", "btlmp.versnr", + FT_UINT8, BASE_DEC, VALS(versnr), 0x0, + "Version", HFILL } + }, + { &hf_lmp_wesco, + { "Wesco", "btlmp.wesco", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Number of slots in retransmission window", HFILL } + }, + }; + + /* protocol subtree arrays */ + static gint *ett[] = { + &ett_lmp, + &ett_lmp_pwradjres, + &ett_lmp_rate, + &ett_lmp_timectrl, + }; + + /* register the protocol name and description */ + proto_btlmp = proto_register_protocol( + "Bluetooth Link Manager Protocol", /* full name */ + "btlmp", /* short name */ + "btlmp" /* abbreviation (e.g. for filters) */ + ); + + register_dissector("btlmp", dissect_btlmp, proto_btlmp); + + /* register the header fields and subtrees used */ + proto_register_field_array(proto_btlmp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_btlmp(void) +{ +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/plugin.rc.in b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/plugin.rc.in new file mode 100644 index 0000000..568dc07 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/plugin.rc.in @@ -0,0 +1,34 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @RC_MODULE_VERSION@ + PRODUCTVERSION @RC_VERSION@ + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0" + VALUE "FileDescription", "@PACKAGE@ dissector\0" + VALUE "FileVersion", "@MODULE_VERSION@\0" + VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0" + VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs , Gilbert Ramirez and others\0" + VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0" + VALUE "ProductName", "Wireshark\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "Comments", "Build with @MSVC_VARIANT@\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/tools/make-dissector-reg b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/tools/make-dissector-reg new file mode 100755 index 0000000..d2efa7c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/tools/make-dissector-reg @@ -0,0 +1,186 @@ +#! /bin/sh + +# +# $Id: make-dissector-reg 21716 2007-05-07 17:55:42Z gal $ +# + +# +# The first argument is the directory in which the source files live. +# +srcdir="$1" +shift + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype="$1" +shift +if [ "$registertype" = plugin ] +then + outfile="plugin.c" +elif [ "$registertype" = dissectors ] +then + outfile="register.c" +else + echo "Unknown output type '$registertype'" 1>&2 + exit 1 +fi + +# +# All subsequent arguments are the files to scan. +# +rm -f ${outfile}-tmp +echo '/* Do not modify this file. */' >${outfile}-tmp +echo '/* It is created automatically by the Makefile. */'>>${outfile}-tmp +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp + +fi +echo '}' >>${outfile}-tmp + + +# +# Build code to call all the protocol handoff registration routines. +# +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +fi +echo '}' >>${outfile}-tmp +if [ "$registertype" = plugin ] +then + echo '#endif' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +gulong register_count(void) +{ +EOF + proto_regs=`grep RA_REGISTER ${outfile}-tmp | wc -l` + handoff_regs=`grep RA_HANDOFF ${outfile}-tmp | wc -l` + echo " return $proto_regs + $handoff_regs;" >>${outfile}-tmp + echo '}' >>${outfile}-tmp +fi +mv ${outfile}-tmp ${outfile} diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btbredr/tools/make-dissector-reg.py b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/tools/make-dissector-reg.py new file mode 100755 index 0000000..060460c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btbredr/tools/make-dissector-reg.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# +# Looks for registration routines in the protocol dissectors, +# and assembles C code to call all the routines. +# +# This is a Python version of the make-reg-dotc shell script. +# Running the shell script on Win32 is very very slow because of +# all the process-launching that goes on --- multiple greps and +# seds for each input file. I wrote this python version so that +# less processes would have to be started. +# +# $Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $ + +import os +import sys +import re +import pickle +from stat import * + +VERSION_KEY = '_VERSION' +CUR_VERSION = '$Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $' + +# +# The first argument is the directory in which the source files live. +# +srcdir = sys.argv[1] + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype = sys.argv[2] +if registertype == "plugin" or registertype == "plugin_wtap": + tmp_filename = "plugin.c-tmp" + final_filename = "plugin.c" + cache_filename = None + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by Makefile or Makefile.nmake. + */ +""" +elif registertype == "dissectors": + tmp_filename = "register.c-tmp" + final_filename = "register.c" + cache_filename = "register-cache.pkl" + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by the "register.c" target in + * epan/dissectors/Makefile or Makefile.nmake using information in + * epan/dissectors/register-cache.pkl. + * + * You can force this file to be regenerated completely by deleting + * it along with epan/dissectors/register-cache.pkl. + */ +""" +else: + print(("Unknown output type '%s'" % registertype)) + sys.exit(1) + + +# +# All subsequent arguments are the files to scan. +# +files = sys.argv[3:] + +# Create the proper list of filenames +filenames = [] +for file in files: + if os.path.isfile(file): + filenames.append(file) + else: + filenames.append(os.path.join(srcdir, file)) + +if len(filenames) < 1: + print("No files found") + sys.exit(1) + + +# Look through all files, applying the regex to each line. +# If the pattern matches, save the "symbol" section to the +# appropriate array. +regs = { + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } + +# For those that don't know Python, r"" indicates a raw string, +# devoid of Python escapes. +proto_regex0 = r"^(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" +proto_regex1 = r"void\s+(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +handoff_regex0 = r"^(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" +handoff_regex1 = r"void\s+(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" + +wtap_reg_regex0 = r"^(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" +wtap_reg_regex1 = r"void\s+(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +# This table drives the pattern-matching and symbol-harvesting +patterns = [ + ( 'proto_reg', re.compile(proto_regex0) ), + ( 'proto_reg', re.compile(proto_regex1) ), + ( 'handoff_reg', re.compile(handoff_regex0) ), + ( 'handoff_reg', re.compile(handoff_regex1) ), + ( 'wtap_register', re.compile(wtap_reg_regex0) ), + ( 'wtap_register', re.compile(wtap_reg_regex1) ), + ] + +# Open our registration symbol cache +cache = None +if cache_filename: + try: + cache_file = open(cache_filename, 'rb') + cache = pickle.load(cache_file) + cache_file.close() + if VERSION_KEY not in cache or cache[VERSION_KEY] != CUR_VERSION: + cache = {VERSION_KEY: CUR_VERSION} + except: + cache = {VERSION_KEY: CUR_VERSION} + + print(("Registering %d files, %d cached" % (len(filenames), len(list(cache.keys()))-1))) + +# Grep +cache_hits = 0 +cache_misses = 0 +for filename in filenames: + file = open(filename) + cur_mtime = os.fstat(file.fileno())[ST_MTIME] + if cache and filename in cache: + cdict = cache[filename] + if cur_mtime == cdict['mtime']: + cache_hits += 1 +# print "Pulling %s from cache" % (filename) + regs['proto_reg'].extend(cdict['proto_reg']) + regs['handoff_reg'].extend(cdict['handoff_reg']) + regs['wtap_register'].extend(cdict['wtap_register']) + file.close() + continue + # We don't have a cache entry + if cache is not None: + cache_misses += 1 + cache[filename] = { + 'mtime': cur_mtime, + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } +# print "Searching %s" % (filename) + for line in file.readlines(): + for action in patterns: + regex = action[1] + match = regex.search(line) + if match: + symbol = match.group("symbol") + sym_type = action[0] + regs[sym_type].append(symbol) + if cache is not None: +# print "Caching %s for %s: %s" % (sym_type, filename, symbol) + cache[filename][sym_type].append(symbol) + file.close() + + +if cache is not None and cache_filename is not None: + cache_file = open(cache_filename, 'wb') + pickle.dump(cache, cache_file) + cache_file.close() + print(("Cache hits: %d, misses: %d" % (cache_hits, cache_misses))) + +# Make sure we actually processed something +if len(regs['proto_reg']) < 1: + print("No protocol registrations found") + sys.exit(1) + +# Sort the lists to make them pretty +regs['proto_reg'].sort() +regs['handoff_reg'].sort() +regs['wtap_register'].sort() + +reg_code = open(tmp_filename, "w") + +reg_code.write(preamble) + +# Make the routine to register all protocols +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +"""); +else: + reg_code.write(""" +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['proto_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + + +# Make the routine to register all protocol handoffs +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +"""); +else: + reg_code.write(""" +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['handoff_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + +if registertype == "plugin": + reg_code.write("#endif\n"); +elif registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +register_wtap_module(void) +{ +"""); + + for symbol in regs['wtap_register']: + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + reg_code.write(line) + + reg_code.write("}\n"); + reg_code.write("#endif\n"); +else: + reg_code.write(""" +static gulong proto_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['proto_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +static gulong handoff_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['handoff_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +gulong register_count(void) +{ +"""); + + line = " return proto_reg_count() + handoff_reg_count();" + reg_code.write(line) + + reg_code.write(""" +}\n +"""); + + +# Close the file +reg_code.close() + +# Remove the old final_file if it exists. +try: + os.stat(final_filename) + os.remove(final_filename) +except OSError: + pass + +# Move from tmp file to final file +os.rename(tmp_filename, final_filename) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/AUTHORS b/libbtbb-2015-10-R1/wireshark/plugins/btle/AUTHORS new file mode 100644 index 0000000..7658f97 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/AUTHORS @@ -0,0 +1,3 @@ +Authors: +Mike Ryan +Michael Ossmann diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/CMakeLists.txt b/libbtbb-2015-10-R1/wireshark/plugins/btle/CMakeLists.txt new file mode 100644 index 0000000..1e71b1f --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/CMakeLists.txt @@ -0,0 +1,88 @@ +# CMakeLists.txt +# +# $Id: CMakeLists.txt 31995 2010-02-24 22:32:10Z jmayer $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +project(btle-wireshark-plugin C) + +cmake_minimum_required(VERSION 2.6) +set(CMAKE_BACKWARDS_COMPATIBILITY 2.6) +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +IF ( NOT CMAKE_INSTALL_LIBDIR ) + set(CMAKE_INSTALL_LIBDIR ~/.wireshark/plugins) +ENDIF ( NOT CMAKE_INSTALL_LIBDIR ) +MESSAGE (STATUS "Plugin will be installed in: ${CMAKE_INSTALL_LIBDIR}") + +INCLUDE(UseMakeDissectorReg) + +set(GLIB2_MIN_VERSION 2.4.0) + +find_package(GLIB2) +include_directories (${GLIB2_INCLUDE_DIRS}) + +find_package(Wireshark) +include_directories (${WIRESHARK_INCLUDE_DIRS}) + +set(LINK_MODE_LIB SHARED) +set(LINK_MODE_MODULE MODULE) + + +set(DISSECTOR_SRC + packet-btle.c +) + +set(PLUGIN_FILES + plugin.c + ${DISSECTOR_SRC} +) + +set(CLEAN_FILES + ${PLUGIN_FILES} +) + +if (WERROR) + set_source_files_properties( + ${CLEAN_FILES} + PROPERTIES + COMPILE_FLAGS -Werror + ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +register_dissector_files(plugin.c + plugin + ${DISSECTOR_SRC} +) + +add_library(btle ${LINK_MODE_MODULE} + ${PLUGIN_FILES} +) +set_target_properties(btle PROPERTIES PREFIX "") +set_target_properties(btle PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + +target_link_libraries(btle wireshark) + +install(TARGETS btle + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ NAMELINK_SKIP +) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btle/COPYING new file mode 100644 index 0000000..aa0aea5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.am b/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.am new file mode 100644 index 0000000..d863ce5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.am @@ -0,0 +1,125 @@ +# Makefile.am +# Automake file for AgentX plugin +# +# $Id: Makefile.am 24488 2008-02-27 16:18:30Z stig $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +INCLUDES = -I$(top_srcdir) -I$(includedir) + +include Makefile.common + +#if HAVE_WARNINGS_AS_ERRORS +#AM_CFLAGS = -Werror +#endif + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = btle.la +btle_la_SOURCES = \ + plugin.c \ + moduleinfo.h \ + $(DISSECTOR_SRC) \ + $(DISSECTOR_SUPPORT_SRC) \ + $(DISSECTOR_INCLUDES) +btle_la_LDFLAGS = -module -avoid-version +btle_la_LIBADD = @PLUGIN_LIBS@ + +# Libs must be cleared, or else libtool won't create a shared module. +# If your module needs to be linked against any particular libraries, +# add them here. +LIBS = + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \ + $(top_srcdir)/tools/make-dissector-reg.py + @if test -n "$(PYTHON)"; then \ + echo Making plugin.c with python ; \ + $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + plugin $(DISSECTOR_SRC) ; \ + else \ + echo Making plugin.c with shell script ; \ + $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + $(plugin_src) plugin $(DISSECTOR_SRC) ; \ + fi + +# +# Currently plugin.c can be included in the distribution because +# we always build all protocol dissectors. We used to have to check +# whether or not to build the snmp dissector. If we again need to +# variably build something, making plugin.c non-portable, uncomment +# the dist-hook line below. +# +# Oh, yuk. We don't want to include "plugin.c" in the distribution, as +# its contents depend on the configuration, and therefore we want it +# to be built when the first "make" is done; however, Automake insists +# on putting *all* source into the distribution. +# +# We work around this by having a "dist-hook" rule that deletes +# "plugin.c", so that "dist" won't pick it up. +# +#dist-hook: +# @rm -f $(distdir)/plugin.c + +CLEANFILES = \ + btle \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in \ + plugin.c + +EXTRA_DIST = \ + Makefile.common \ + Makefile.nmake \ + moduleinfo.nmake \ + plugin.rc.in diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.common b/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.common new file mode 100644 index 0000000..644f6c8 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.common @@ -0,0 +1,39 @@ +# Makefile.common for AgentX plugin +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id: Makefile.common 23848 2007-12-12 22:10:50Z jake $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. + +# the name of the plugin +PLUGIN_NAME = btle + +# the dissector sources (without any helpers) +DISSECTOR_SRC = \ + packet-btle.c + +# corresponding headers +DISSECTOR_INCLUDES = + +# Dissector helpers. They're included in the source files in this +# directory, but they're not dissectors themselves, i.e. they're not +# used to generate "plugin.c". +DISSECTOR_SUPPORT_SRC = diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.nmake b/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.nmake new file mode 100644 index 0000000..857e435 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/Makefile.nmake @@ -0,0 +1,100 @@ +# Makefile.nmake +# nmake file for Wireshark plugin +# +# $Id: Makefile.nmake 24520 2008-03-01 12:31:01Z jake $ +# + +include ..\..\config.nmake +include moduleinfo.nmake + +include Makefile.common + +CFLAGS=/WX /DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \ + /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS) + +.c.obj:: + $(CC) $(CFLAGS) -Fd.\ -c $< + +LDFLAGS = $(PLUGIN_LDFLAGS) + +!IFDEF ENABLE_LIBWIRESHARK +LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib +CFLAGS=/DHAVE_WIN32_LIBWIRESHARK_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS) + +DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj) + +DISSECTOR_SUPPORT_OBJECTS = $(DISSECTOR_SUPPORT_SRC:.c=.obj) + +OBJECTS = $(DISSECTOR_OBJECTS) $(DISSECTOR_SUPPORT_OBJECTS) plugin.obj + +RESOURCE=$(PLUGIN_NAME).res + +all: $(PLUGIN_NAME).dll + +$(PLUGIN_NAME).rc : moduleinfo.nmake + sed -e s/@PLUGIN_NAME@/$(PLUGIN_NAME)/ \ + -e s/@RC_MODULE_VERSION@/$(RC_MODULE_VERSION)/ \ + -e s/@RC_VERSION@/$(RC_VERSION)/ \ + -e s/@MODULE_VERSION@/$(MODULE_VERSION)/ \ + -e s/@PACKAGE@/$(PACKAGE)/ \ + -e s/@VERSION@/$(VERSION)/ \ + -e s/@MSVC_VARIANT@/$(MSVC_VARIANT)/ \ + < plugin.rc.in > $@ + +$(PLUGIN_NAME).dll $(PLUGIN_NAME).exp $(PLUGIN_NAME).lib : $(OBJECTS) $(LINK_PLUGIN_WITH) $(RESOURCE) + link -dll /out:$(PLUGIN_NAME).dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ + $(GLIB_LIBS) $(RESOURCE) + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +!IFDEF PYTHON +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg.py + @echo Making plugin.c (using python) + @$(PYTHON) "../../tools/make-dissector-reg.py" . plugin $(DISSECTOR_SRC) +!ELSE +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg + @echo Making plugin.c (using sh) + @$(SH) ../../tools/make-dissector-reg . plugin $(DISSECTOR_SRC) +!ENDIF + +!ENDIF + +clean: + rm -f $(OBJECTS) $(RESOURCE) plugin.c *.pdb \ + $(PLUGIN_NAME).dll $(PLUGIN_NAME).dll.manifest $(PLUGIN_NAME).lib \ + $(PLUGIN_NAME).exp $(PLUGIN_NAME).rc + +distclean: clean + +maintainer-clean: distclean diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/README b/libbtbb-2015-10-R1/wireshark/plugins/btle/README new file mode 100644 index 0000000..b3674f4 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/README @@ -0,0 +1,61 @@ +BTLE Wireshark plugin +===================== + +This plugin is no longer in use, it has been merged in to the Wireshark source +tree as of release 1.12. + + +This is the Bluetooth Low Energy plugin for Wireshark. + +To build this on Debian/Ubuntu/BackTrack linux distributions: + sudo apt-get install wireshark-dev wireshark + cd libbtbb/wireshark/plugins/btle/ + cmake . + make + make install + +This will install to the .wireshark/ in your home directory. To override +this set the DESTDIR environment variable when running cmake. + +PPI Support (Patch) +------------------- + +Ubertooth records capture frequency, internal clock state, and certain +other metadata about packets in a PPI header. It is not possible to add +PPI support in an external plugin, so if you wish to access these fields +you must patch Wireshark. + +The patch wireshark-1.8-btle-ppi.patch was built against the Ubuntu +12.10 Quantal Wireshark package. It can be added to the Ubuntu package +source or applied directly to vanilla Wireshark. + +To build a .deb on Ubuntu, follow these instructions: + + mkdir wireshark && cd wireshark + apt-get source wireshark + cp wireshark-1.8-btle-ppi.patch wireshark-1.8.2/debian/patches + echo wireshark-1.8-btle-ppi.patch >> wireshark-1.8.2/debian/patches/series + cd wireshark-1.8.2 + dpkg-buildpackage -rfakeroot + +The .deb will be created in the wireshark directory, and it can be +installed with dpkg -i. + +Attribute Protocol Support +-------------------------- + +Wireshark trunk has native support for the Bluetooth Attribute protocol. +If you are using a distro package that does not support it, install the +plugin found in the btatt directory (above this directory). + +If the protocol column of non-empty data packets says L2CAP, you should +install the plugin. If it says ATT, you do not need the plugin. If it +says something else, please email me! + +Bluetooth Security Manager Protocol +----------------------------------- + +All security-related exchanges (pairing and identity resolution) take +place over the Bluetooth Security Manager (SM) protocol, which runs on +L2CAP. If you would like to dissect these packets, build and install the +plugin found in the btsm directory above this directory. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/COPYING new file mode 100644 index 0000000..53b6b71 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/COPYING @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/COPYING-CMAKE-SCRIPTS b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..280ed6c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,27 @@ +Copyright notice for the files copied from +http://www.opensync.org/browser/branches/3rd-party-cmake-modules/modules + +$Id: COPYING-CMAKE-SCRIPTS 34248 2010-09-25 15:38:12Z jmayer $ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/FindGLIB2.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/FindGLIB2.cmake new file mode 100644 index 0000000..ae7badd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/FindGLIB2.cmake @@ -0,0 +1,238 @@ +# +# $Id: FindGLIB2.cmake 34248 2010-09-25 15:38:12Z jmayer $ +# +# - Try to find GLib2 +# Once done this will define +# +# GLIB2_FOUND - system has GLib2 +# GLIB2_INCLUDE_DIRS - the GLib2 include directory +# GLIB2_LIBRARIES - Link these to use GLib2 +# +# HAVE_GLIB_GREGEX_H glib has gregex.h header and +# supports g_regex_match_simple +# +# Copyright (c) 2006 Andreas Schneider +# Copyright (c) 2006 Philippe Bernery +# Copyright (c) 2007 Daniel Gollub +# Copyright (c) 2007 Alban Browaeys +# Copyright (c) 2008 Michael Bell +# Copyright (c) 2008-2009 Bjoern Ricks +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +IF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + # in cache already + SET(GLIB2_FOUND TRUE) +ELSE (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + + INCLUDE(FindPkgConfig) + + ## Glib + IF ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "REQUIRED" ) + ELSE ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "" ) + ENDIF ( GLIB2_FIND_REQUIRED ) + + IF ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0>=${GLIB2_MIN_VERSION} ) + ELSE ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0 ) + ENDIF ( GLIB2_MIN_VERSION ) + IF ( PKG_CONFIG_FOUND ) + IF ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( GLIB2_FOUND ) + ENDIF ( PKG_CONFIG_FOUND ) + + # Look for glib2 include dir and libraries w/o pkgconfig + IF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + FIND_PATH( + _glibconfig_include_DIR + NAMES + glibconfig.h + PATHS + /opt/gnome/lib64 + /opt/gnome/lib + /opt/lib/ + /opt/local/lib + /sw/lib/ + /usr/lib64 + /usr/lib + /usr/local/include + ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES + glib-2.0/include + ) + + FIND_PATH( + _glib2_include_DIR + NAMES + glib.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + PATH_SUFFIXES + glib-2.0 + ) + + #MESSAGE(STATUS "Glib headers: ${_glib2_include_DIR}") + + FIND_LIBRARY( + _glib2_link_DIR + NAMES + glib-2.0 + glib + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + IF ( _glib2_include_DIR AND _glib2_link_DIR ) + SET ( _glib2_FOUND TRUE ) + ENDIF ( _glib2_include_DIR AND _glib2_link_DIR ) + + + IF ( _glib2_FOUND ) + SET ( GLIB2_INCLUDE_DIRS ${_glib2_include_DIR} ${_glibconfig_include_DIR} ) + SET ( GLIB2_LIBRARIES ${_glib2_link_DIR} ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( _glib2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( _glib2_FOUND ) + + # Handle dependencies + # libintl + IF ( NOT LIBINTL_FOUND ) + FIND_PATH(LIBINTL_INCLUDE_DIR + NAMES + libintl.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + ) + + FIND_LIBRARY(LIBINTL_LIBRARY + NAMES + intl + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/local/lib + /usr/lib + ) + + IF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + SET (LIBINTL_FOUND TRUE) + ENDIF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + ENDIF ( NOT LIBINTL_FOUND ) + + # libiconv + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR + NAMES + iconv.h + PATHS + /opt/gnome/include + /opt/local/include + /opt/local/include + /sw/include + /sw/include + /usr/local/include + /usr/include + PATH_SUFFIXES + glib-2.0 + ) + + FIND_LIBRARY(LIBICONV_LIBRARY + NAMES + iconv + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + + IF (LIBINTL_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBINTL_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBINTL_INCLUDE_DIR}) + ENDIF (LIBINTL_FOUND) + + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) + + ENDIF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + ## + + IF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + SET (GLIB2_FOUND TRUE) + ENDIF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + + IF (GLIB2_FOUND) + IF (NOT GLIB2_FIND_QUIETLY) + MESSAGE (STATUS "Found GLib2: ${GLIB2_LIBRARIES} ${GLIB2_INCLUDE_DIRS}") + ENDIF (NOT GLIB2_FIND_QUIETLY) + ELSE (GLIB2_FOUND) + IF (GLIB2_FIND_REQUIRED) + MESSAGE (SEND_ERROR "Could not find GLib2") + ENDIF (GLIB2_FIND_REQUIRED) + ENDIF (GLIB2_FOUND) + + # show the GLIB2_INCLUDE_DIRS and GLIB2_LIBRARIES variables only in the advanced view + MARK_AS_ADVANCED(GLIB2_INCLUDE_DIRS GLIB2_LIBRARIES) + MARK_AS_ADVANCED(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARY) + MARK_AS_ADVANCED(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY) + +ENDIF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS) + +IF ( WIN32 ) + # include libiconv for win32 + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR iconv.h PATH_SUFFIXES glib-2.0) + + FIND_LIBRARY(LIBICONV_LIBRARY NAMES iconv) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) +ENDIF ( WIN32 ) + +IF ( GLIB2_FOUND ) + # Check if system has a newer version of glib + # which supports g_regex_match_simple + INCLUDE( CheckIncludeFiles ) + SET( CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS} ) + CHECK_INCLUDE_FILES ( glib/gregex.h HAVE_GLIB_GREGEX_H ) + CHECK_INCLUDE_FILES ( glib/gchecksum.h HAVE_GLIB_GCHECKSUM_H ) + # Reset CMAKE_REQUIRED_INCLUDES + SET( CMAKE_REQUIRED_INCLUDES "" ) +ENDIF( GLIB2_FOUND ) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/FindWireshark.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/FindWireshark.cmake new file mode 100644 index 0000000..16fabed --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/FindWireshark.cmake @@ -0,0 +1,28 @@ +# +# Try to find the wireshark library and its includes +# +# This snippet sets the following variables: +# WIRESHARK_FOUND True if wireshark library got found +# WIRESHARK_INCLUDE_DIRS Location of the wireshark headers +# WIRESHARK_LIBRARIES List of libraries to use wireshark +# +# Copyright (c) 2011 Reinhold Kainhofer +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + +# wireshark does not install its library with pkg-config information, +# so we need to manually find the libraries and headers + +FIND_PATH( WIRESHARK_INCLUDE_DIRS epan/packet.h PATH_SUFFIXES wireshark ) +FIND_LIBRARY( WIRESHARK_LIBRARIES wireshark ) + +# Report results +IF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + SET( WIRESHARK_FOUND 1 ) +ELSE ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + MESSAGE( SEND_ERROR "Could NOT find the wireshark library and headers" ) +ENDIF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/UseMakeDissectorReg.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/UseMakeDissectorReg.cmake new file mode 100644 index 0000000..e7e1a73 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/cmake/UseMakeDissectorReg.cmake @@ -0,0 +1,33 @@ +# +# $Id: UseMakeDissectorReg.cmake 33616 2010-07-22 12:18:36Z stig $ +# +MACRO(REGISTER_DISSECTOR_FILES _outputfile _registertype ) + # FIXME: Only the Python stuff has been implemented + # Make this into a MACRO, to avoid duplication with plugins/.../ + #register.c: $(plugin_src) $(ALL_DISSECTORS_SRC) $(top_srcdir)/tools/make-dissector-reg \ + # $(top_srcdir)/tools/make-dissector-reg.py + # @if test -n "$(PYTHON)"; then \ + # echo Making register.c with python ; \ + # $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + # dissectors $(ALL_DISSECTORS_SRC) ; \ + # else \ + # echo Making register.c with shell script ; \ + # $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + # dissectors $(plugin_src) $(ALL_DISSECTORS_SRC) ; \ + # fi + set( _sources ${ARGN} ) + ADD_CUSTOM_COMMAND( + OUTPUT + ${_outputfile} + COMMAND ${PYTHON_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ${CMAKE_CURRENT_SOURCE_DIR} + ${_registertype} + ${_sources} + DEPENDS + ${_sources} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ) +ENDMACRO(REGISTER_DISSECTOR_FILES) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/moduleinfo.h b/libbtbb-2015-10-R1/wireshark/plugins/btle/moduleinfo.h new file mode 100644 index 0000000..7dfa9cd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/moduleinfo.h @@ -0,0 +1,17 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "btle" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/moduleinfo.nmake b/libbtbb-2015-10-R1/wireshark/plugins/btle/moduleinfo.nmake new file mode 100644 index 0000000..d67b402 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/moduleinfo.nmake @@ -0,0 +1,28 @@ +# +# $Id: moduleinfo.nmake 20155 2006-12-19 22:22:34Z jake $ +# + +# The name +PACKAGE=btle + +# The version +MODULE_VERSION_MAJOR=0 +MODULE_VERSION_MINOR=0 +MODULE_VERSION_MICRO=0 +MODULE_VERSION_EXTRA=1 + +# +# The RC_VERSION should be comma-separated, not dot-separated, +# as per Graham Bloice's message in +# +# http://www.ethereal.com/lists/ethereal-dev/200303/msg00283.html +# +# "The RC_VERSION variable in config.nmake should be comma separated. +# This allows the resources to be built correctly and the version +# number to be correctly displayed in the explorer properties dialog +# for the executables, and XP's tooltip, rather than 0.0.0.0." +# + +MODULE_VERSION=$(MODULE_VERSION_MAJOR).$(MODULE_VERSION_MINOR).$(MODULE_VERSION_MICRO).$(MODULE_VERSION_EXTRA) +RC_MODULE_VERSION=$(MODULE_VERSION_MAJOR),$(MODULE_VERSION_MINOR),$(MODULE_VERSION_MICRO),$(MODULE_VERSION_EXTRA) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/packet-btle.c b/libbtbb-2015-10-R1/wireshark/plugins/btle/packet-btle.c new file mode 100644 index 0000000..d215ac5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/packet-btle.c @@ -0,0 +1,665 @@ +/* packet-btle.c + * Routines for Bluetooth Low Energy dissection + * Copyright 2013, Mike Ryan, mikeryan /at/ isecpartners /dot/ com + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include /* needed for epan/gcc-4.x */ +#include +#include + +/* function prototypes */ +void proto_reg_handoff_btle(void); + +/* initialize the protocol and registered fields */ +static int proto_btle = -1; +static int hf_btle_pkthdr = -1; +static int hf_btle_aa = -1; +static int hf_btle_type = -1; +static int hf_btle_randomized_tx = -1; +static int hf_btle_randomized_rx = -1; +static int hf_btle_length = -1; +static int hf_btle_adv_addr = -1; +static int hf_btle_adv_data = -1; +static int hf_btle_init_addr = -1; +static int hf_btle_scan_addr = -1; +static int hf_btle_scan_rsp_data = -1; +static int hf_btle_connect = -1; +static int hf_btle_connect_aa = -1; +static int hf_btle_crc_init = -1; +static int hf_btle_win_size = -1; +static int hf_btle_win_offset = -1; +static int hf_btle_interval = -1; +static int hf_btle_latency = -1; +static int hf_btle_timeout = -1; +static int hf_btle_data = -1; +static int hf_btle_data_llid = -1; +static int hf_btle_data_nesn = -1; +static int hf_btle_data_sn = -1; +static int hf_btle_data_md = -1; +static int hf_btle_data_rfu = -1; +static int hf_btle_ll_control_opcode = -1; +static int hf_btle_ll_control_data = -1; +static int hf_btle_ll_control_ll_enc_req = -1; +static int hf_btle_ll_control_ll_enc_req_rand = -1; +static int hf_btle_ll_control_ll_enc_req_ediv = -1; +static int hf_btle_ll_control_ll_enc_req_skdm = -1; +static int hf_btle_ll_control_ll_enc_req_ivm = -1; +static int hf_btle_ll_control_ll_enc_rsp = -1; +static int hf_btle_ll_control_ll_enc_rsp_skds = -1; +static int hf_btle_ll_control_ll_enc_rsp_ivs = -1; +static int hf_btle_crc = -1; + +static const value_string packet_types[] = { + { 0x0, "ADV_IND" }, + { 0x1, "ADV_DIRECT_IND" }, + { 0x2, "ADV_NONCONN_IND" }, + { 0x3, "SCAN_REQ" }, + { 0x4, "SCAN_RSP" }, + { 0x5, "CONNECT_REQ" }, + { 0x6, "ADV_SCAN_IND" }, + { 0, NULL } +}; + +static const value_string llid_codes[] = { + { 0x0, "undefined" }, + { 0x1, "Continuation fragment of an L2CAP message" }, + { 0x2, "Start of an L2CAP message or no fragmentation" }, + { 0x3, "LL Control PDU" }, + { 0, NULL } +}; + +static const value_string ll_control_opcodes[] = { + { 0x00, "LL_CONNECTION_UPDATE_REQ" }, + { 0x01, "LL_CHANNEL_MAP_REQ" }, + { 0x02, "LL_TERMINATE_IND" }, + { 0x03, "LL_ENC_REQ" }, + { 0x04, "LL_ENC_RSP" }, + { 0x05, "LL_START_ENC_REQ" }, + { 0x06, "LL_START_ENC_RSP" }, + { 0x07, "LL_UNKNOWN_RSP" }, + { 0x08, "LL_FEATURE_REQ" }, + { 0x09, "LL_FEATURE_RSP" }, + { 0x0A, "LL_PAUSE_ENC_REQ" }, + { 0x0B, "LL_PAUSE_ENC_RSP" }, + { 0x0C, "LL_VERSION_IND" }, + { 0x0D, "LL_REJECT_IND" }, + { 0, NULL } +}; + +static const guint32 ADV_AA = 0x8e89bed6; + +/* initialize the subtree pointers */ +static gint ett_btle = -1; +static gint ett_btle_pkthdr = -1; +static gint ett_btle_connect = -1; +static gint ett_btle_data = -1; +static gint ett_ll_enc_req = -1; +static gint ett_ll_enc_rsp = -1; + +/* subdissectors */ +static dissector_handle_t btl2cap_handle = NULL; + +void +dissect_adv_ind_or_nonconn_or_scan(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int datalen) +{ + const guint8 *adv_addr; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + adv_addr = tvb_get_ptr(tvb, offset, 6); + SET_ADDRESS(&pinfo->src, AT_ETHER, 6, adv_addr); + + proto_tree_add_ether(tree, hf_btle_adv_addr, tvb, offset, 6, adv_addr); + proto_tree_add_item(tree, hf_btle_adv_data, tvb, offset + 6, datalen, TRUE); +} + +void +dissect_adv_direct_ind(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset) +{ + const guint8 *adv_addr, *init_addr; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + adv_addr = tvb_get_ptr(tvb, offset, 6); + SET_ADDRESS(&pinfo->src, AT_ETHER, 6, adv_addr); + init_addr = tvb_get_ptr(tvb, offset+6, 6); + SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, init_addr); + + proto_tree_add_ether(tree, hf_btle_adv_addr, tvb, offset, 6, adv_addr); + proto_tree_add_ether(tree, hf_btle_init_addr, tvb, offset + 6, 6, init_addr); +} + +void +dissect_scan_req(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset) +{ + const guint8 *scan_addr, *adv_addr; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + scan_addr = tvb_get_ptr(tvb, offset, 6); + SET_ADDRESS(&pinfo->src, AT_ETHER, 6, scan_addr); + adv_addr = tvb_get_ptr(tvb, offset+6, 6); + SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, adv_addr); + + proto_tree_add_ether(tree, hf_btle_scan_addr, tvb, offset, 6, scan_addr); + proto_tree_add_ether(tree, hf_btle_adv_addr, tvb, offset+6, 6, adv_addr); +} + +void +dissect_scan_rsp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int datalen) +{ + const guint8 *adv_addr; + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + adv_addr = tvb_get_ptr(tvb, offset, 6); + SET_ADDRESS(&pinfo->src, AT_ETHER, 6, adv_addr); + + proto_tree_add_ether(tree, hf_btle_adv_addr, tvb, offset, 6, adv_addr); + proto_tree_add_item(tree, hf_btle_scan_rsp_data, tvb, offset + 6, datalen, TRUE); +} + +void +dissect_connect_req(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset) +{ + proto_item *connect_item; + proto_tree *connect_tree; + const guint8 *adv_addr, *init_addr; + + + DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1); + + init_addr = tvb_get_ptr(tvb, offset, 6); + SET_ADDRESS(&pinfo->src, AT_ETHER, 6, init_addr); + adv_addr = tvb_get_ptr(tvb, offset+6, 6); + SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, adv_addr); + + proto_tree_add_ether(tree, hf_btle_init_addr, tvb, offset, 6, init_addr); + proto_tree_add_ether(tree, hf_btle_adv_addr, tvb, offset + 6, 6, adv_addr); + offset += 12; + + connect_item = proto_tree_add_item(tree, hf_btle_connect, tvb, offset, 22, TRUE); + connect_tree = proto_item_add_subtree(connect_item, ett_btle_connect); + + proto_tree_add_item(connect_tree, hf_btle_connect_aa, tvb, offset+ 0, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(connect_tree, hf_btle_crc_init, tvb, offset+ 4, 3, ENC_LITTLE_ENDIAN); + proto_tree_add_item(connect_tree, hf_btle_win_size, tvb, offset+ 7, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(connect_tree, hf_btle_win_offset, tvb, offset+ 8, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(connect_tree, hf_btle_interval, tvb, offset+10, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(connect_tree, hf_btle_latency, tvb, offset+12, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(connect_tree, hf_btle_timeout, tvb, offset+14, 2, ENC_LITTLE_ENDIAN); +} + +void +dissect_ll_enc_req(proto_tree *tree, tvbuff_t *tvb, int offset) +{ + proto_item *ll_enc_req_item; + proto_tree *ll_enc_req_tree; + + ll_enc_req_item = proto_tree_add_item(tree, hf_btle_ll_control_ll_enc_req, tvb, offset + 1, 22, TRUE); + ll_enc_req_tree = proto_item_add_subtree(ll_enc_req_item, ett_ll_enc_req); + + proto_tree_add_item(ll_enc_req_tree, hf_btle_ll_control_ll_enc_req_rand, tvb, offset + 1, 8, TRUE); + proto_tree_add_item(ll_enc_req_tree, hf_btle_ll_control_ll_enc_req_ediv, tvb, offset + 9, 2, TRUE); + proto_tree_add_item(ll_enc_req_tree, hf_btle_ll_control_ll_enc_req_skdm, tvb, offset + 11, 8, TRUE); + proto_tree_add_item(ll_enc_req_tree, hf_btle_ll_control_ll_enc_req_ivm, tvb, offset + 19, 4, TRUE); +} + +void +dissect_ll_enc_rsp(proto_tree *tree, tvbuff_t *tvb, int offset) +{ + proto_item *ll_enc_rsp_item; + proto_tree *ll_enc_rsp_tree; + + ll_enc_rsp_item = proto_tree_add_item(tree, hf_btle_ll_control_ll_enc_rsp, tvb, offset + 1, 12, TRUE); + ll_enc_rsp_tree = proto_item_add_subtree(ll_enc_rsp_item, ett_ll_enc_rsp); + + proto_tree_add_item(ll_enc_rsp_tree, hf_btle_ll_control_ll_enc_rsp_skds, tvb, offset + 1, 8, TRUE); + proto_tree_add_item(ll_enc_rsp_tree, hf_btle_ll_control_ll_enc_rsp_ivs, tvb, offset + 9, 4, TRUE); +} + +void +dissect_ll_control(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, guint8 length) +{ + guint8 ll_control_opcode; + + proto_tree_add_item(tree, hf_btle_ll_control_opcode, tvb, offset, 1, ENC_NA); + + ll_control_opcode = tvb_get_guint8(tvb, offset); + if (ll_control_opcode <= 0x0d) { + col_add_fstr(pinfo->cinfo, COL_INFO, "LL Control PDU: %s", + ll_control_opcodes[ll_control_opcode].strptr); + + switch (ll_control_opcode) { + case 0x03: // LL_ENC_REQ + dissect_ll_enc_req(tree, tvb, offset); + break; + case 0x04: // LL_ENC_RSP + dissect_ll_enc_rsp(tree, tvb, offset); + break; + default: + if (length > 1) + proto_tree_add_item(tree, hf_btle_ll_control_data, tvb, offset + 1, length-1, TRUE); + break; + } + } else { + col_set_str(pinfo->cinfo, COL_INFO, "LL Control PDU: unknown"); + if (length > 1) + proto_tree_add_item(tree, hf_btle_ll_control_data, tvb, offset + 1, length-1, TRUE); + } +} + +/* dissect a packet */ +static void +dissect_btle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *btle_item, *pkthdr_item, *data_item; + proto_tree *btle_tree, *pkthdr_tree, *data_tree; + int offset; + guint32 aa; + guint8 type, length; + guint8 llid; + tvbuff_t *pld_tvb; + + /* + * FIXME + * I have no idea what this does, but the L2CAP dissector segfaults + * without it. + */ + guint16 fake_acl_data; + +#if 0 + /* sanity check: length */ + if (tvb_length(tvb) > 0 && tvb_length(tvb) < 9) + /* bad length: look for a different dissector */ + return 0; +#endif + + /* make entries in protocol column and info column on summary display */ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Bluetooth LE"); + + aa = tvb_get_letohl(tvb, 0); + + // advertising packet + if (aa == ADV_AA) { + type = tvb_get_guint8(tvb, 4) & 0xf; + length = tvb_get_guint8(tvb, 5) & 0x3f; + + /* see if we are being asked for details */ + if (tree) { + + /* create display subtree for the protocol */ + offset = 0; + btle_item = proto_tree_add_item(tree, proto_btle, tvb, offset, -1, TRUE); + btle_tree = proto_item_add_subtree(btle_item, ett_btle); + + proto_tree_add_item(btle_tree, hf_btle_aa, tvb, offset, 4, TRUE); + offset += 4; + + /* packet header */ + pkthdr_item = proto_tree_add_item(btle_tree, hf_btle_pkthdr, tvb, offset, 2, ENC_LITTLE_ENDIAN); + pkthdr_tree = proto_item_add_subtree(pkthdr_item, ett_btle_pkthdr); + + proto_tree_add_bits_item(pkthdr_tree, hf_btle_randomized_rx, tvb, offset * 8, 1, TRUE); + proto_tree_add_bits_item(pkthdr_tree, hf_btle_randomized_tx, tvb, offset * 8 + 1, 1, TRUE); + proto_tree_add_bits_item(pkthdr_tree, hf_btle_type, tvb, offset * 8 + 4, 4, TRUE); + offset += 1; + + proto_tree_add_item(pkthdr_tree, hf_btle_length, tvb, offset, 1, TRUE); + offset += 1; + + if (check_col(pinfo->cinfo, COL_INFO)) { + if (type <= 0x6) { + col_set_str(pinfo->cinfo, COL_INFO, packet_types[type].strptr); + } else { + col_set_str(pinfo->cinfo, COL_INFO, "Unknown"); + } + } + + /* payload */ + switch (type) { + case 0x0: // ADV_IND + case 0x2: // ADV_NONCONN_IND + case 0x6: // ADV_SCAN_IND + dissect_adv_ind_or_nonconn_or_scan(btle_tree, tvb, pinfo, offset, length - 6); + break; + case 0x1: // ADV_DIRECT_IND + dissect_adv_direct_ind(btle_tree, tvb, pinfo, offset); + break; + case 0x3: + dissect_scan_req(btle_tree, tvb, pinfo, offset); + break; + case 0x4: // SCAN_RSP + dissect_scan_rsp(btle_tree, tvb, pinfo, offset, length - 6); + break; + case 0x5: // CONNECT_REQ + dissect_connect_req(btle_tree, tvb, pinfo, offset); + break; + default: + break; + } + + offset += length; + proto_tree_add_item(btle_tree, hf_btle_crc, tvb, offset, 3, TRUE); + } + } + + // data PDU + else { + if (tree) { + col_set_str(pinfo->cinfo, COL_INFO, "Data"); + + length = tvb_get_guint8(tvb, 5) & 0x1f; + + /* create display subtree for the protocol */ + offset = 0; + btle_item = proto_tree_add_item(tree, proto_btle, tvb, offset, -1, TRUE); + btle_tree = proto_item_add_subtree(btle_item, ett_btle); + + proto_tree_add_item(btle_tree, hf_btle_aa, tvb, offset, 4, TRUE); + offset += 4; + + // data PDU header + data_item = proto_tree_add_item(btle_tree, hf_btle_data, tvb, offset, 2, TRUE); + data_tree = proto_item_add_subtree(data_item, ett_btle_data); + + proto_tree_add_item(data_tree, hf_btle_data_rfu, tvb, offset, 1, ENC_NA); + proto_tree_add_item(data_tree, hf_btle_data_md, tvb, offset, 1, ENC_NA); + proto_tree_add_item(data_tree, hf_btle_data_sn, tvb, offset, 1, ENC_NA); + proto_tree_add_item(data_tree, hf_btle_data_nesn, tvb, offset, 1, ENC_NA); + proto_tree_add_item(data_tree, hf_btle_data_llid, tvb, offset, 1, ENC_NA); + llid = tvb_get_guint8(tvb, offset) & 0x3; + offset += 1; + + proto_tree_add_item(data_tree, hf_btle_length, tvb, offset, 1, TRUE); + offset += 1; + + // LL control PDU + if (llid == 0x3) { + dissect_ll_control(btle_tree, tvb, pinfo, offset, length); + } + + // L2CAP + else if (llid == 0x1 || llid == 0x2) { + if (length > 0 && btl2cap_handle) { + pinfo->private_data = &fake_acl_data; + pld_tvb = tvb_new_subset(tvb, offset, length, length); + call_dissector(btl2cap_handle, pld_tvb, pinfo, btle_tree); + } + else if (length == 0) { + col_set_str(pinfo->cinfo, COL_INFO, "Empty Data PDU"); + } + } + + offset += length; + + proto_tree_add_item(btle_tree, hf_btle_crc, tvb, offset, 3, TRUE); + } + } + + return; +} + +/* register the protocol with Wireshark */ +void +proto_register_btle(void) +{ + + /* list of fields */ + static hf_register_info hf[] = { + { &hf_btle_aa, + { "Access Address", "btle.aa", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + + { &hf_btle_pkthdr, + { "Packet Header", "btle.pkthdr", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + { &hf_btle_type, + { "TYPE", "btle.type", + FT_UINT8, BASE_HEX, VALS(packet_types), 0x0, + "Packet Type", HFILL } + }, + { &hf_btle_randomized_tx, + { "Randomized TX Address", "btle.randomized_tx", + FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, + NULL, HFILL } + }, + { &hf_btle_randomized_rx, + { "Randomized RX Address", "btle.randomized_rx", + FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, + NULL, HFILL } + }, + { &hf_btle_length, + { "Length", "btle.length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_adv_addr, + { "Advertising Address", "btle.adv_addr", + FT_ETHER, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_init_addr, + { "Init Address", "btle.init_addr", + FT_ETHER, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_scan_addr, + { "Scan Address", "btle.scan_addr", + FT_ETHER, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_adv_data, + { "Advertising Data", "btle.adv_data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_scan_rsp_data, + { "Scan Response Data", "btle.scan_rsp_data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + // connection packet fields + { &hf_btle_connect, + { "Connection Request", "btle.connect", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_connect_aa, + { "Connection AA", "btle.connect.aa", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_crc_init, + { "CRC Init", "btle.connect.crc_init", + FT_UINT24, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_win_size, + { "Window Size", "btle.connect.win_size", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_win_offset, + { "Window Offset", "btle.connect.win_offset", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_interval, + { "Interval", "btle.connect.interval", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_latency, + { "Latency", "btle.connect.latency", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_timeout, + { "Timeout", "btle.connect.timeout", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + + // data header + { &hf_btle_data, + { "Data PDU Header", "btle.data", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_data_llid, + { "LLID", "btle.data.llid", + FT_UINT8, BASE_DEC, VALS(llid_codes), 0x3, + NULL, HFILL } + }, + { &hf_btle_data_nesn, + { "NESN", "btle.data.nesn", + FT_UINT8, BASE_DEC, NULL, 0x4, + "Next Expected Sequence Number", HFILL } + }, + { &hf_btle_data_sn, + { "SN", "btle.data.sn", + FT_UINT8, BASE_DEC, NULL, 0x8, + "Sequence Number", HFILL } + }, + { &hf_btle_data_md, + { "MD", "btle.data.md", + FT_UINT8, BASE_DEC, NULL, 0x10, + "More Data", HFILL } + }, + { &hf_btle_data_rfu, + { "RFU", "btle.data.rfu", + FT_UINT8, BASE_DEC, NULL, 0xe0, + "Reserved for Future Use (must be zero)", HFILL } + }, + + { &hf_btle_ll_control_opcode, + { "LL Control Opcode", "btle.ll_control_opcode", + FT_UINT8, BASE_HEX, VALS(ll_control_opcodes), 0x0, + NULL, HFILL } + }, + { &hf_btle_ll_control_data, + { "LL Control Data", "btle.ll_control_data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + { &hf_btle_ll_control_ll_enc_req, + { "Encryption Request", "btle.ll_enc_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_ll_control_ll_enc_req_rand, + { "Rand", "btle.ll_enc_req.rand", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_ll_control_ll_enc_req_ediv, + { "EDIV", "btle.ll_enc_req.ediv", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Encrypted Diversifier", HFILL } + }, + { &hf_btle_ll_control_ll_enc_req_skdm, + { "SDKm", "btle.ll_enc_req.skdm", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Master's Session Key Identifier", HFILL } + }, + { &hf_btle_ll_control_ll_enc_req_ivm, + { "IVm", "btle.ll_enc_req.ivm", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Master's Initialization Vector", HFILL } + }, + + { &hf_btle_ll_control_ll_enc_rsp, + { "Encryption Response", "btle.ll_enc_rsp", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btle_ll_control_ll_enc_rsp_skds, + { "SDKs", "btle.ll_enc_rsp.skds", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Slave's Session Key Identifier", HFILL } + }, + { &hf_btle_ll_control_ll_enc_rsp_ivs, + { "IVs", "btle.ll_enc_rsp.ivs", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Slave's Initialization Vector", HFILL } + }, + + + { &hf_btle_crc, + { "CRC", "btle.crc", + FT_UINT24, BASE_HEX, NULL, 0x0, + "Ticklish Redundancy Check", HFILL } + }, + }; + + /* protocol subtree arrays */ + static gint *ett[] = { + &ett_btle, + &ett_btle_pkthdr, + &ett_btle_connect, + &ett_btle_data, + &ett_ll_enc_req, + &ett_ll_enc_rsp, + }; + + /* register the protocol name and description */ + proto_btle = proto_register_protocol( + "Bluetooth Low Energy", /* full name */ + "BTLE", /* short name */ + "btle" /* abbreviation (e.g. for filters) */ + ); + + register_dissector("btle", dissect_btle, proto_btle); + + /* register the header fields and subtrees used */ + proto_register_field_array(proto_btle, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_btle(void) +{ + static gboolean inited = FALSE; + + if (!inited) { + dissector_handle_t btle_handle; + + // btle_handle = new_create_dissector_handle(dissect_btle, proto_btle); + // dissector_add("ppi.dlt", 147, btle_handle); + + btl2cap_handle = find_dissector("btl2cap"); + + inited = TRUE; + } +} diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/plugin.rc.in b/libbtbb-2015-10-R1/wireshark/plugins/btle/plugin.rc.in new file mode 100644 index 0000000..568dc07 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/plugin.rc.in @@ -0,0 +1,34 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @RC_MODULE_VERSION@ + PRODUCTVERSION @RC_VERSION@ + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0" + VALUE "FileDescription", "@PACKAGE@ dissector\0" + VALUE "FileVersion", "@MODULE_VERSION@\0" + VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0" + VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs , Gilbert Ramirez and others\0" + VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0" + VALUE "ProductName", "Wireshark\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "Comments", "Build with @MSVC_VARIANT@\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/tools/make-dissector-reg b/libbtbb-2015-10-R1/wireshark/plugins/btle/tools/make-dissector-reg new file mode 100755 index 0000000..d2efa7c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/tools/make-dissector-reg @@ -0,0 +1,186 @@ +#! /bin/sh + +# +# $Id: make-dissector-reg 21716 2007-05-07 17:55:42Z gal $ +# + +# +# The first argument is the directory in which the source files live. +# +srcdir="$1" +shift + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype="$1" +shift +if [ "$registertype" = plugin ] +then + outfile="plugin.c" +elif [ "$registertype" = dissectors ] +then + outfile="register.c" +else + echo "Unknown output type '$registertype'" 1>&2 + exit 1 +fi + +# +# All subsequent arguments are the files to scan. +# +rm -f ${outfile}-tmp +echo '/* Do not modify this file. */' >${outfile}-tmp +echo '/* It is created automatically by the Makefile. */'>>${outfile}-tmp +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp + +fi +echo '}' >>${outfile}-tmp + + +# +# Build code to call all the protocol handoff registration routines. +# +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +fi +echo '}' >>${outfile}-tmp +if [ "$registertype" = plugin ] +then + echo '#endif' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +gulong register_count(void) +{ +EOF + proto_regs=`grep RA_REGISTER ${outfile}-tmp | wc -l` + handoff_regs=`grep RA_HANDOFF ${outfile}-tmp | wc -l` + echo " return $proto_regs + $handoff_regs;" >>${outfile}-tmp + echo '}' >>${outfile}-tmp +fi +mv ${outfile}-tmp ${outfile} diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/tools/make-dissector-reg.py b/libbtbb-2015-10-R1/wireshark/plugins/btle/tools/make-dissector-reg.py new file mode 100755 index 0000000..060460c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/tools/make-dissector-reg.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# +# Looks for registration routines in the protocol dissectors, +# and assembles C code to call all the routines. +# +# This is a Python version of the make-reg-dotc shell script. +# Running the shell script on Win32 is very very slow because of +# all the process-launching that goes on --- multiple greps and +# seds for each input file. I wrote this python version so that +# less processes would have to be started. +# +# $Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $ + +import os +import sys +import re +import pickle +from stat import * + +VERSION_KEY = '_VERSION' +CUR_VERSION = '$Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $' + +# +# The first argument is the directory in which the source files live. +# +srcdir = sys.argv[1] + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype = sys.argv[2] +if registertype == "plugin" or registertype == "plugin_wtap": + tmp_filename = "plugin.c-tmp" + final_filename = "plugin.c" + cache_filename = None + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by Makefile or Makefile.nmake. + */ +""" +elif registertype == "dissectors": + tmp_filename = "register.c-tmp" + final_filename = "register.c" + cache_filename = "register-cache.pkl" + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by the "register.c" target in + * epan/dissectors/Makefile or Makefile.nmake using information in + * epan/dissectors/register-cache.pkl. + * + * You can force this file to be regenerated completely by deleting + * it along with epan/dissectors/register-cache.pkl. + */ +""" +else: + print(("Unknown output type '%s'" % registertype)) + sys.exit(1) + + +# +# All subsequent arguments are the files to scan. +# +files = sys.argv[3:] + +# Create the proper list of filenames +filenames = [] +for file in files: + if os.path.isfile(file): + filenames.append(file) + else: + filenames.append(os.path.join(srcdir, file)) + +if len(filenames) < 1: + print("No files found") + sys.exit(1) + + +# Look through all files, applying the regex to each line. +# If the pattern matches, save the "symbol" section to the +# appropriate array. +regs = { + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } + +# For those that don't know Python, r"" indicates a raw string, +# devoid of Python escapes. +proto_regex0 = r"^(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" +proto_regex1 = r"void\s+(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +handoff_regex0 = r"^(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" +handoff_regex1 = r"void\s+(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" + +wtap_reg_regex0 = r"^(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" +wtap_reg_regex1 = r"void\s+(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +# This table drives the pattern-matching and symbol-harvesting +patterns = [ + ( 'proto_reg', re.compile(proto_regex0) ), + ( 'proto_reg', re.compile(proto_regex1) ), + ( 'handoff_reg', re.compile(handoff_regex0) ), + ( 'handoff_reg', re.compile(handoff_regex1) ), + ( 'wtap_register', re.compile(wtap_reg_regex0) ), + ( 'wtap_register', re.compile(wtap_reg_regex1) ), + ] + +# Open our registration symbol cache +cache = None +if cache_filename: + try: + cache_file = open(cache_filename, 'rb') + cache = pickle.load(cache_file) + cache_file.close() + if VERSION_KEY not in cache or cache[VERSION_KEY] != CUR_VERSION: + cache = {VERSION_KEY: CUR_VERSION} + except: + cache = {VERSION_KEY: CUR_VERSION} + + print(("Registering %d files, %d cached" % (len(filenames), len(list(cache.keys()))-1))) + +# Grep +cache_hits = 0 +cache_misses = 0 +for filename in filenames: + file = open(filename) + cur_mtime = os.fstat(file.fileno())[ST_MTIME] + if cache and filename in cache: + cdict = cache[filename] + if cur_mtime == cdict['mtime']: + cache_hits += 1 +# print "Pulling %s from cache" % (filename) + regs['proto_reg'].extend(cdict['proto_reg']) + regs['handoff_reg'].extend(cdict['handoff_reg']) + regs['wtap_register'].extend(cdict['wtap_register']) + file.close() + continue + # We don't have a cache entry + if cache is not None: + cache_misses += 1 + cache[filename] = { + 'mtime': cur_mtime, + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } +# print "Searching %s" % (filename) + for line in file.readlines(): + for action in patterns: + regex = action[1] + match = regex.search(line) + if match: + symbol = match.group("symbol") + sym_type = action[0] + regs[sym_type].append(symbol) + if cache is not None: +# print "Caching %s for %s: %s" % (sym_type, filename, symbol) + cache[filename][sym_type].append(symbol) + file.close() + + +if cache is not None and cache_filename is not None: + cache_file = open(cache_filename, 'wb') + pickle.dump(cache, cache_file) + cache_file.close() + print(("Cache hits: %d, misses: %d" % (cache_hits, cache_misses))) + +# Make sure we actually processed something +if len(regs['proto_reg']) < 1: + print("No protocol registrations found") + sys.exit(1) + +# Sort the lists to make them pretty +regs['proto_reg'].sort() +regs['handoff_reg'].sort() +regs['wtap_register'].sort() + +reg_code = open(tmp_filename, "w") + +reg_code.write(preamble) + +# Make the routine to register all protocols +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +"""); +else: + reg_code.write(""" +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['proto_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + + +# Make the routine to register all protocol handoffs +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +"""); +else: + reg_code.write(""" +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['handoff_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + +if registertype == "plugin": + reg_code.write("#endif\n"); +elif registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +register_wtap_module(void) +{ +"""); + + for symbol in regs['wtap_register']: + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + reg_code.write(line) + + reg_code.write("}\n"); + reg_code.write("#endif\n"); +else: + reg_code.write(""" +static gulong proto_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['proto_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +static gulong handoff_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['handoff_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +gulong register_count(void) +{ +"""); + + line = " return proto_reg_count() + handoff_reg_count();" + reg_code.write(line) + + reg_code.write(""" +}\n +"""); + + +# Close the file +reg_code.close() + +# Remove the old final_file if it exists. +try: + os.stat(final_filename) + os.remove(final_filename) +except OSError: + pass + +# Move from tmp file to final file +os.rename(tmp_filename, final_filename) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btle/wireshark-1.8-btle-ppi.patch b/libbtbb-2015-10-R1/wireshark/plugins/btle/wireshark-1.8-btle-ppi.patch new file mode 100644 index 0000000..9953779 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btle/wireshark-1.8-btle-ppi.patch @@ -0,0 +1,246 @@ +Index: wireshark-1.8.2/epan/dissectors/packet-ppi.c +=================================================================== +--- wireshark-1.8.2.orig/epan/dissectors/packet-ppi.c 2013-02-01 12:18:18.208820553 -0800 ++++ wireshark-1.8.2/epan/dissectors/packet-ppi.c 2013-02-01 12:18:50.000000000 -0800 +@@ -181,6 +181,7 @@ + PPI_VECTOR_INFO = 30003, /* currently available in draft from. jellch@harris.com */ + PPI_SENSOR_INFO = 30004, + PPI_ANTENNA_INFO = 30005, ++ PPI_BTLE = 30006, + CACE_PRIVATE = 0xCACE + /* All others RESERVED. Contact the WinPcap team for an assignment */ + } ppi_field_type; +@@ -319,7 +320,7 @@ + + static dissector_handle_t data_handle; + static dissector_handle_t ieee80211_ht_handle; +-static dissector_handle_t ppi_gps_handle, ppi_vector_handle, ppi_sensor_handle, ppi_antenna_handle; ++static dissector_handle_t ppi_gps_handle, ppi_vector_handle, ppi_sensor_handle, ppi_antenna_handle, ppi_btle_handle; + + + static const true_false_string tfs_ppi_head_flag_alignment = { "32-bit aligned", "Not aligned" }; +@@ -881,7 +882,19 @@ + call_dissector(ppi_antenna_handle, next_tvb, pinfo, ppi_tree); + } + break; +- ++ case PPI_BTLE: ++ if (ppi_btle_handle == NULL) ++ { ++ proto_tree_add_text(ppi_tree, tvb, offset, data_len, ++ "%s (%u bytes)", val_to_str(data_type, (value_string *)&vs_ppi_field_type, "BTLE: "), data_len); ++ } ++ else /* we found a suitable dissector */ ++ { ++ /* skip over the ppi_fieldheader, and pass it off to the dedicated BTLE dissetor */ ++ next_tvb = tvb_new_subset(tvb, offset + 4, data_len - 4 , -1); ++ call_dissector(ppi_btle_handle, next_tvb, pinfo, ppi_tree); ++ } ++ break; + default: + if (tree) + proto_tree_add_text(ppi_tree, tvb, offset, data_len, +@@ -1365,6 +1378,7 @@ + ppi_vector_handle = find_dissector("ppi_vector"); + ppi_sensor_handle = find_dissector("ppi_sensor"); + ppi_antenna_handle = find_dissector("ppi_antenna"); ++ ppi_btle_handle = find_dissector("ppi_btle"); + + dissector_add_uint("wtap_encap", WTAP_ENCAP_PPI, ppi_handle); + } +Index: wireshark-1.8.2/epan/dissectors/packet-ppi-btle.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ wireshark-1.8.2/epan/dissectors/packet-ppi-btle.c 2013-02-01 13:37:09.020642835 -0800 +@@ -0,0 +1,179 @@ ++/* packet-ppi-btle.c ++ * Routines for PPI-BTLE dissection ++ * Copyright 2013, Mike Ryan, mikeryan /at/ isecpartners /dot/ com ++ * ++ * $Id$ ++ * ++ * Wireshark - Network traffic analyzer ++ * By Gerald Combs ++ * Copyright 1998 Gerald Combs ++ * ++ * Copied from packet-ppi-gps.c ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include ++#include ++ ++#define PPI_BTLE_MINTAGLEN 12 ++#define PPI_BTLE_MAXTAGLEN 12 ++ ++/* protocol */ ++static int proto_ppi_btle = -1; ++ ++static int hf_ppi_btle_version = -1; ++static int hf_ppi_btle_channel = -1; ++static int hf_ppi_btle_clkn_high = -1; ++static int hf_ppi_btle_clk100ns = -1; ++static int hf_ppi_btle_rssi_max = -1; ++static int hf_ppi_btle_rssi_min = -1; ++static int hf_ppi_btle_rssi_avg = -1; ++static int hf_ppi_btle_rssi_count = -1; ++ ++static gint ett_ppi_btle = -1; ++ ++static void ++dissect_ppi_btle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { ++ /* These are locals used for processing the current tvb */ ++ guint length; ++ guint version; ++ guint32 channel, clkn_high, clk100ns; ++ guint8 urssi_max, urssi_min, urssi_avg; ++ gint8 rssi_max, rssi_min, rssi_avg; ++ guint rssi_count; ++ ++ proto_tree *ppi_btle_tree = NULL; ++ proto_tree *pt, *present_tree = NULL; ++ ++ proto_item *ti = NULL; ++ ++ /* Clear out stuff in the info column */ ++ col_clear(pinfo->cinfo,COL_INFO); ++ ++ /* Setup basic column info */ ++ if (check_col(pinfo->cinfo, COL_INFO)) ++ col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_BTLE Capture"); ++ ++ /* Create the basic dissection tree*/ ++ if (tree) ++ ti = proto_tree_add_protocol_format(tree, proto_ppi_btle, tvb, 0, length, "BTLE:"); ++ ++ /* Sanity check length of tag */ ++ length = tvb_length(tvb); ++ if (length < PPI_BTLE_MINTAGLEN) { ++ if (tree) ++ proto_item_append_text(ti, "Invalid PPI-BTLE length (got %d, %d min)", length, PPI_BTLE_MAXTAGLEN); ++ return; ++ } ++ ++ if (tree) { ++ channel = tvb_get_letohs(tvb, 1); ++ clkn_high = tvb_get_guint8(tvb, 3); ++ clk100ns = tvb_get_letohl(tvb, 4); ++ urssi_max = tvb_get_guint8(tvb, 8); ++ urssi_min = tvb_get_guint8(tvb, 9); ++ urssi_avg = tvb_get_guint8(tvb, 10); ++ rssi_count = tvb_get_guint8(tvb, 11); ++ ++ rssi_max = *(gint8 *)&urssi_max; ++ rssi_min = *(gint8 *)&urssi_min; ++ rssi_avg = *(gint8 *)&urssi_avg; ++ ++ ppi_btle_tree= proto_item_add_subtree(ti, ett_ppi_btle); ++ proto_tree_add_uint(ppi_btle_tree, hf_ppi_btle_version, tvb, 0, 1, version); ++ proto_tree_add_uint(ppi_btle_tree, hf_ppi_btle_channel, tvb, 1, 2, channel); ++ proto_tree_add_uint(ppi_btle_tree, hf_ppi_btle_clkn_high, tvb, 3, 1, clkn_high); ++ proto_tree_add_uint(ppi_btle_tree, hf_ppi_btle_clk100ns, tvb, 4, 4, clk100ns); ++ proto_tree_add_int(ppi_btle_tree, hf_ppi_btle_rssi_max, tvb, 8, 1, rssi_max); ++ proto_tree_add_int(ppi_btle_tree, hf_ppi_btle_rssi_min, tvb, 9, 1, rssi_min); ++ proto_tree_add_int(ppi_btle_tree, hf_ppi_btle_rssi_avg, tvb, 10, 1, rssi_avg); ++ proto_tree_add_uint(ppi_btle_tree, hf_ppi_btle_rssi_count, tvb, 11, 1, rssi_count); ++ } ++ ++ version = tvb_get_guint8(tvb, 0); ++ if (version > 0) { ++ if (tree) ++ proto_item_append_text(ti, "Warning: New version of PPI-BTLE (length %d, I can only decode first %d bytes)", length, PPI_BTLE_MAXTAGLEN); ++ } ++ ++ /* perform tag-specific max length sanity checking */ ++ else if (length > PPI_BTLE_MAXTAGLEN ) { ++ if (tree) ++ proto_item_append_text(ti, "Invalid PPI-BTLE length (got %d, %d max)", length, PPI_BTLE_MAXTAGLEN); ++ return; ++ } ++ ++ return; ++} ++ ++void ++proto_register_ppi_btle(void) { ++ /* The following array initializes those header fields declared above to the values displayed */ ++ static hf_register_info hf[] = { ++ ++ { &hf_ppi_btle_version, ++ { "Version", "ppi_btle.version", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } }, ++ ++ { &hf_ppi_btle_channel, ++ { "Channel", "ppi_btle.channel", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "MHz", HFILL } }, ++ ++ { &hf_ppi_btle_clkn_high, ++ { "clkn_high", "ppi_btle.clkn_high", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "High bits of native clock", HFILL } }, ++ ++ { &hf_ppi_btle_clk100ns, ++ { "clk100ns", "ppi_btle.clk100ns", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "100 ns clock", HFILL } }, ++ ++ // RSSI ++ { &hf_ppi_btle_rssi_max, ++ { "Max RSSI", "ppi_btle.rssi_max", ++ FT_INT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } }, ++ { &hf_ppi_btle_rssi_min, ++ { "Min RSSI", "ppi_btle.rssi_min", ++ FT_INT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } }, ++ { &hf_ppi_btle_rssi_avg, ++ { "Average RSSI", "ppi_btle.rssi_avg", ++ FT_INT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } }, ++ { &hf_ppi_btle_rssi_count, ++ { "RSSI Count", "ppi_btle.rssi_count", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } }, ++ ++ }; ++ ++ static gint *ett[] = { ++ &ett_ppi_btle, ++ }; ++ ++ proto_ppi_btle = proto_register_protocol("PPI Ubertooth BTLE tag decoder", "PPI BTLE Decoder", "ppi_btle"); ++ proto_register_field_array(proto_ppi_btle, hf, array_length(hf)); ++ proto_register_subtree_array(ett, array_length(ett)); ++ register_dissector("ppi_btle", dissect_ppi_btle, proto_ppi_btle); ++} +Index: wireshark-1.8.2/epan/dissectors/Makefile.common +=================================================================== +--- wireshark-1.8.2.orig/epan/dissectors/Makefile.common 2013-01-29 11:46:35.429559060 -0800 ++++ wireshark-1.8.2/epan/dissectors/Makefile.common 2013-01-29 11:56:46.541536579 -0800 +@@ -881,6 +881,7 @@ + packet-ppi-gps.c \ + packet-ppi-sensor.c \ + packet-ppi-vector.c \ ++ packet-ppi-btle.c \ + packet-ppp.c \ + packet-pppoe.c \ + packet-pptp.c \ diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/AUTHORS b/libbtbb-2015-10-R1/wireshark/plugins/btsm/AUTHORS new file mode 100644 index 0000000..7658f97 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/AUTHORS @@ -0,0 +1,3 @@ +Authors: +Mike Ryan +Michael Ossmann diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/CMakeLists.txt b/libbtbb-2015-10-R1/wireshark/plugins/btsm/CMakeLists.txt new file mode 100644 index 0000000..a1b1b81 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/CMakeLists.txt @@ -0,0 +1,88 @@ +# CMakeLists.txt +# +# $Id: CMakeLists.txt 31995 2010-02-24 22:32:10Z jmayer $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +project(btsm-wireshark-plugin C) + +cmake_minimum_required(VERSION 2.6) +set(CMAKE_BACKWARDS_COMPATIBILITY 2.6) +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +IF ( NOT CMAKE_INSTALL_LIBDIR ) + set(CMAKE_INSTALL_LIBDIR ~/.wireshark/plugins) +ENDIF ( NOT CMAKE_INSTALL_LIBDIR ) +MESSAGE (STATUS "Plugin will be installed in: ${CMAKE_INSTALL_LIBDIR}") + +INCLUDE(UseMakeDissectorReg) + +set(GLIB2_MIN_VERSION 2.4.0) + +find_package(GLIB2) +include_directories (${GLIB2_INCLUDE_DIRS}) + +find_package(Wireshark) +include_directories (${WIRESHARK_INCLUDE_DIRS}) + +set(LINK_MODE_LIB SHARED) +set(LINK_MODE_MODULE MODULE) + + +set(DISSECTOR_SRC + packet-btsm.c +) + +set(PLUGIN_FILES + plugin.c + ${DISSECTOR_SRC} +) + +set(CLEAN_FILES + ${PLUGIN_FILES} +) + +if (WERROR) + set_source_files_properties( + ${CLEAN_FILES} + PROPERTIES + COMPILE_FLAGS -Werror + ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +register_dissector_files(plugin.c + plugin + ${DISSECTOR_SRC} +) + +add_library(btsm ${LINK_MODE_MODULE} + ${PLUGIN_FILES} +) +set_target_properties(btsm PROPERTIES PREFIX "") +set_target_properties(btsm PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + +target_link_libraries(btsm wireshark) + +install(TARGETS btsm + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ NAMELINK_SKIP +) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btsm/COPYING new file mode 100644 index 0000000..aa0aea5 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.am b/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.am new file mode 100644 index 0000000..b998689 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.am @@ -0,0 +1,125 @@ +# Makefile.am +# Automake file for AgentX plugin +# +# $Id: Makefile.am 24488 2008-02-27 16:18:30Z stig $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. +# + +INCLUDES = -I$(top_srcdir) -I$(includedir) + +include Makefile.common + +#if HAVE_WARNINGS_AS_ERRORS +#AM_CFLAGS = -Werror +#endif + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = btsm.la +btsm_la_SOURCES = \ + plugin.c \ + moduleinfo.h \ + $(DISSECTOR_SRC) \ + $(DISSECTOR_SUPPORT_SRC) \ + $(DISSECTOR_INCLUDES) +btsm_la_LDFLAGS = -module -avoid-version +btsm_la_LIBADD = @PLUGIN_LIBS@ + +# Libs must be cleared, or else libtool won't create a shared module. +# If your module needs to be linked against any particular libraries, +# add them here. +LIBS = + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \ + $(top_srcdir)/tools/make-dissector-reg.py + @if test -n "$(PYTHON)"; then \ + echo Making plugin.c with python ; \ + $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + plugin $(DISSECTOR_SRC) ; \ + else \ + echo Making plugin.c with shell script ; \ + $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + $(plugin_src) plugin $(DISSECTOR_SRC) ; \ + fi + +# +# Currently plugin.c can be included in the distribution because +# we always build all protocol dissectors. We used to have to check +# whether or not to build the snmp dissector. If we again need to +# variably build something, making plugin.c non-portable, uncomment +# the dist-hook line below. +# +# Oh, yuk. We don't want to include "plugin.c" in the distribution, as +# its contents depend on the configuration, and therefore we want it +# to be built when the first "make" is done; however, Automake insists +# on putting *all* source into the distribution. +# +# We work around this by having a "dist-hook" rule that deletes +# "plugin.c", so that "dist" won't pick it up. +# +#dist-hook: +# @rm -f $(distdir)/plugin.c + +CLEANFILES = \ + btsm \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in \ + plugin.c + +EXTRA_DIST = \ + Makefile.common \ + Makefile.nmake \ + moduleinfo.nmake \ + plugin.rc.in diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.common b/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.common new file mode 100644 index 0000000..6489554 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.common @@ -0,0 +1,39 @@ +# Makefile.common for AgentX plugin +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id: Makefile.common 23848 2007-12-12 22:10:50Z jake $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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. + +# the name of the plugin +PLUGIN_NAME = btsm + +# the dissector sources (without any helpers) +DISSECTOR_SRC = \ + packet-btsm.c + +# corresponding headers +DISSECTOR_INCLUDES = + +# Dissector helpers. They're included in the source files in this +# directory, but they're not dissectors themselves, i.e. they're not +# used to generate "plugin.c". +DISSECTOR_SUPPORT_SRC = diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.nmake b/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.nmake new file mode 100644 index 0000000..857e435 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/Makefile.nmake @@ -0,0 +1,100 @@ +# Makefile.nmake +# nmake file for Wireshark plugin +# +# $Id: Makefile.nmake 24520 2008-03-01 12:31:01Z jake $ +# + +include ..\..\config.nmake +include moduleinfo.nmake + +include Makefile.common + +CFLAGS=/WX /DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \ + /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS) + +.c.obj:: + $(CC) $(CFLAGS) -Fd.\ -c $< + +LDFLAGS = $(PLUGIN_LDFLAGS) + +!IFDEF ENABLE_LIBWIRESHARK +LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib +CFLAGS=/DHAVE_WIN32_LIBWIRESHARK_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS) + +DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj) + +DISSECTOR_SUPPORT_OBJECTS = $(DISSECTOR_SUPPORT_SRC:.c=.obj) + +OBJECTS = $(DISSECTOR_OBJECTS) $(DISSECTOR_SUPPORT_OBJECTS) plugin.obj + +RESOURCE=$(PLUGIN_NAME).res + +all: $(PLUGIN_NAME).dll + +$(PLUGIN_NAME).rc : moduleinfo.nmake + sed -e s/@PLUGIN_NAME@/$(PLUGIN_NAME)/ \ + -e s/@RC_MODULE_VERSION@/$(RC_MODULE_VERSION)/ \ + -e s/@RC_VERSION@/$(RC_VERSION)/ \ + -e s/@MODULE_VERSION@/$(MODULE_VERSION)/ \ + -e s/@PACKAGE@/$(PACKAGE)/ \ + -e s/@VERSION@/$(VERSION)/ \ + -e s/@MSVC_VARIANT@/$(MSVC_VARIANT)/ \ + < plugin.rc.in > $@ + +$(PLUGIN_NAME).dll $(PLUGIN_NAME).exp $(PLUGIN_NAME).lib : $(OBJECTS) $(LINK_PLUGIN_WITH) $(RESOURCE) + link -dll /out:$(PLUGIN_NAME).dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ + $(GLIB_LIBS) $(RESOURCE) + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +!IFDEF PYTHON +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg.py + @echo Making plugin.c (using python) + @$(PYTHON) "../../tools/make-dissector-reg.py" . plugin $(DISSECTOR_SRC) +!ELSE +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg + @echo Making plugin.c (using sh) + @$(SH) ../../tools/make-dissector-reg . plugin $(DISSECTOR_SRC) +!ENDIF + +!ENDIF + +clean: + rm -f $(OBJECTS) $(RESOURCE) plugin.c *.pdb \ + $(PLUGIN_NAME).dll $(PLUGIN_NAME).dll.manifest $(PLUGIN_NAME).lib \ + $(PLUGIN_NAME).exp $(PLUGIN_NAME).rc + +distclean: clean + +maintainer-clean: distclean diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/README b/libbtbb-2015-10-R1/wireshark/plugins/btsm/README new file mode 100644 index 0000000..7013cce --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/README @@ -0,0 +1,14 @@ +BTSM Wireshark plugin +===================== + +This is the Bluetooth Low Energy Security Manager plugin for Wireshark. + +To build this on Debian/Ubuntu/BackTrack linux distributions: + sudo apt-get install wireshark-dev wireshark + cd libbtbb/wireshark/plugins/btsm/ + cmake . + make + make install + +This will install to the .wireshark/ in your home directory. To override +this set the DESTDIR environment variable when running cmake. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/COPYING b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/COPYING new file mode 100644 index 0000000..53b6b71 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/COPYING @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/COPYING-CMAKE-SCRIPTS b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..280ed6c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,27 @@ +Copyright notice for the files copied from +http://www.opensync.org/browser/branches/3rd-party-cmake-modules/modules + +$Id: COPYING-CMAKE-SCRIPTS 34248 2010-09-25 15:38:12Z jmayer $ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/FindGLIB2.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/FindGLIB2.cmake new file mode 100644 index 0000000..ae7badd --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/FindGLIB2.cmake @@ -0,0 +1,238 @@ +# +# $Id: FindGLIB2.cmake 34248 2010-09-25 15:38:12Z jmayer $ +# +# - Try to find GLib2 +# Once done this will define +# +# GLIB2_FOUND - system has GLib2 +# GLIB2_INCLUDE_DIRS - the GLib2 include directory +# GLIB2_LIBRARIES - Link these to use GLib2 +# +# HAVE_GLIB_GREGEX_H glib has gregex.h header and +# supports g_regex_match_simple +# +# Copyright (c) 2006 Andreas Schneider +# Copyright (c) 2006 Philippe Bernery +# Copyright (c) 2007 Daniel Gollub +# Copyright (c) 2007 Alban Browaeys +# Copyright (c) 2008 Michael Bell +# Copyright (c) 2008-2009 Bjoern Ricks +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +IF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + # in cache already + SET(GLIB2_FOUND TRUE) +ELSE (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) + + INCLUDE(FindPkgConfig) + + ## Glib + IF ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "REQUIRED" ) + ELSE ( GLIB2_FIND_REQUIRED ) + SET( _pkgconfig_REQUIRED "" ) + ENDIF ( GLIB2_FIND_REQUIRED ) + + IF ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0>=${GLIB2_MIN_VERSION} ) + ELSE ( GLIB2_MIN_VERSION ) + PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0 ) + ENDIF ( GLIB2_MIN_VERSION ) + IF ( PKG_CONFIG_FOUND ) + IF ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( GLIB2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( GLIB2_FOUND ) + ENDIF ( PKG_CONFIG_FOUND ) + + # Look for glib2 include dir and libraries w/o pkgconfig + IF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + FIND_PATH( + _glibconfig_include_DIR + NAMES + glibconfig.h + PATHS + /opt/gnome/lib64 + /opt/gnome/lib + /opt/lib/ + /opt/local/lib + /sw/lib/ + /usr/lib64 + /usr/lib + /usr/local/include + ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES + glib-2.0/include + ) + + FIND_PATH( + _glib2_include_DIR + NAMES + glib.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + PATH_SUFFIXES + glib-2.0 + ) + + #MESSAGE(STATUS "Glib headers: ${_glib2_include_DIR}") + + FIND_LIBRARY( + _glib2_link_DIR + NAMES + glib-2.0 + glib + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + IF ( _glib2_include_DIR AND _glib2_link_DIR ) + SET ( _glib2_FOUND TRUE ) + ENDIF ( _glib2_include_DIR AND _glib2_link_DIR ) + + + IF ( _glib2_FOUND ) + SET ( GLIB2_INCLUDE_DIRS ${_glib2_include_DIR} ${_glibconfig_include_DIR} ) + SET ( GLIB2_LIBRARIES ${_glib2_link_DIR} ) + SET ( GLIB2_CORE_FOUND TRUE ) + ELSE ( _glib2_FOUND ) + SET ( GLIB2_CORE_FOUND FALSE ) + ENDIF ( _glib2_FOUND ) + + # Handle dependencies + # libintl + IF ( NOT LIBINTL_FOUND ) + FIND_PATH(LIBINTL_INCLUDE_DIR + NAMES + libintl.h + PATHS + /opt/gnome/include + /opt/local/include + /sw/include + /usr/include + /usr/local/include + ) + + FIND_LIBRARY(LIBINTL_LIBRARY + NAMES + intl + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/local/lib + /usr/lib + ) + + IF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + SET (LIBINTL_FOUND TRUE) + ENDIF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) + ENDIF ( NOT LIBINTL_FOUND ) + + # libiconv + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR + NAMES + iconv.h + PATHS + /opt/gnome/include + /opt/local/include + /opt/local/include + /sw/include + /sw/include + /usr/local/include + /usr/include + PATH_SUFFIXES + glib-2.0 + ) + + FIND_LIBRARY(LIBICONV_LIBRARY + NAMES + iconv + PATHS + /opt/gnome/lib + /opt/local/lib + /sw/lib + /usr/lib + /usr/local/lib + ) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + + IF (LIBINTL_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBINTL_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBINTL_INCLUDE_DIR}) + ENDIF (LIBINTL_FOUND) + + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) + + ENDIF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) + ## + + IF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + SET (GLIB2_FOUND TRUE) + ENDIF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) + + IF (GLIB2_FOUND) + IF (NOT GLIB2_FIND_QUIETLY) + MESSAGE (STATUS "Found GLib2: ${GLIB2_LIBRARIES} ${GLIB2_INCLUDE_DIRS}") + ENDIF (NOT GLIB2_FIND_QUIETLY) + ELSE (GLIB2_FOUND) + IF (GLIB2_FIND_REQUIRED) + MESSAGE (SEND_ERROR "Could not find GLib2") + ENDIF (GLIB2_FIND_REQUIRED) + ENDIF (GLIB2_FOUND) + + # show the GLIB2_INCLUDE_DIRS and GLIB2_LIBRARIES variables only in the advanced view + MARK_AS_ADVANCED(GLIB2_INCLUDE_DIRS GLIB2_LIBRARIES) + MARK_AS_ADVANCED(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARY) + MARK_AS_ADVANCED(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY) + +ENDIF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS) + +IF ( WIN32 ) + # include libiconv for win32 + IF ( NOT LIBICONV_FOUND ) + FIND_PATH(LIBICONV_INCLUDE_DIR iconv.h PATH_SUFFIXES glib-2.0) + + FIND_LIBRARY(LIBICONV_LIBRARY NAMES iconv) + + IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + SET (LIBICONV_FOUND TRUE) + ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) + ENDIF ( NOT LIBICONV_FOUND ) + IF (LIBICONV_FOUND) + SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) + SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) + ENDIF (LIBICONV_FOUND) +ENDIF ( WIN32 ) + +IF ( GLIB2_FOUND ) + # Check if system has a newer version of glib + # which supports g_regex_match_simple + INCLUDE( CheckIncludeFiles ) + SET( CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS} ) + CHECK_INCLUDE_FILES ( glib/gregex.h HAVE_GLIB_GREGEX_H ) + CHECK_INCLUDE_FILES ( glib/gchecksum.h HAVE_GLIB_GCHECKSUM_H ) + # Reset CMAKE_REQUIRED_INCLUDES + SET( CMAKE_REQUIRED_INCLUDES "" ) +ENDIF( GLIB2_FOUND ) diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/FindWireshark.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/FindWireshark.cmake new file mode 100644 index 0000000..16fabed --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/FindWireshark.cmake @@ -0,0 +1,28 @@ +# +# Try to find the wireshark library and its includes +# +# This snippet sets the following variables: +# WIRESHARK_FOUND True if wireshark library got found +# WIRESHARK_INCLUDE_DIRS Location of the wireshark headers +# WIRESHARK_LIBRARIES List of libraries to use wireshark +# +# Copyright (c) 2011 Reinhold Kainhofer +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + +# wireshark does not install its library with pkg-config information, +# so we need to manually find the libraries and headers + +FIND_PATH( WIRESHARK_INCLUDE_DIRS epan/packet.h PATH_SUFFIXES wireshark ) +FIND_LIBRARY( WIRESHARK_LIBRARIES wireshark ) + +# Report results +IF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + SET( WIRESHARK_FOUND 1 ) +ELSE ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + MESSAGE( SEND_ERROR "Could NOT find the wireshark library and headers" ) +ENDIF ( WIRESHARK_LIBRARIES AND WIRESHARK_INCLUDE_DIRS ) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/UseMakeDissectorReg.cmake b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/UseMakeDissectorReg.cmake new file mode 100644 index 0000000..e7e1a73 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/cmake/UseMakeDissectorReg.cmake @@ -0,0 +1,33 @@ +# +# $Id: UseMakeDissectorReg.cmake 33616 2010-07-22 12:18:36Z stig $ +# +MACRO(REGISTER_DISSECTOR_FILES _outputfile _registertype ) + # FIXME: Only the Python stuff has been implemented + # Make this into a MACRO, to avoid duplication with plugins/.../ + #register.c: $(plugin_src) $(ALL_DISSECTORS_SRC) $(top_srcdir)/tools/make-dissector-reg \ + # $(top_srcdir)/tools/make-dissector-reg.py + # @if test -n "$(PYTHON)"; then \ + # echo Making register.c with python ; \ + # $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + # dissectors $(ALL_DISSECTORS_SRC) ; \ + # else \ + # echo Making register.c with shell script ; \ + # $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + # dissectors $(plugin_src) $(ALL_DISSECTORS_SRC) ; \ + # fi + set( _sources ${ARGN} ) + ADD_CUSTOM_COMMAND( + OUTPUT + ${_outputfile} + COMMAND ${PYTHON_EXECUTABLE} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ${CMAKE_CURRENT_SOURCE_DIR} + ${_registertype} + ${_sources} + DEPENDS + ${_sources} + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg + ${CMAKE_SOURCE_DIR}/tools/make-dissector-reg.py + ) +ENDMACRO(REGISTER_DISSECTOR_FILES) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/moduleinfo.h b/libbtbb-2015-10-R1/wireshark/plugins/btsm/moduleinfo.h new file mode 100644 index 0000000..ba9ada1 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/moduleinfo.h @@ -0,0 +1,17 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "btsm" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/moduleinfo.nmake b/libbtbb-2015-10-R1/wireshark/plugins/btsm/moduleinfo.nmake new file mode 100644 index 0000000..a6d5bbc --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/moduleinfo.nmake @@ -0,0 +1,28 @@ +# +# $Id: moduleinfo.nmake 20155 2006-12-19 22:22:34Z jake $ +# + +# The name +PACKAGE=btsm + +# The version +MODULE_VERSION_MAJOR=0 +MODULE_VERSION_MINOR=0 +MODULE_VERSION_MICRO=0 +MODULE_VERSION_EXTRA=1 + +# +# The RC_VERSION should be comma-separated, not dot-separated, +# as per Graham Bloice's message in +# +# http://www.ethereal.com/lists/ethereal-dev/200303/msg00283.html +# +# "The RC_VERSION variable in config.nmake should be comma separated. +# This allows the resources to be built correctly and the version +# number to be correctly displayed in the explorer properties dialog +# for the executables, and XP's tooltip, rather than 0.0.0.0." +# + +MODULE_VERSION=$(MODULE_VERSION_MAJOR).$(MODULE_VERSION_MINOR).$(MODULE_VERSION_MICRO).$(MODULE_VERSION_EXTRA) +RC_MODULE_VERSION=$(MODULE_VERSION_MAJOR),$(MODULE_VERSION_MINOR),$(MODULE_VERSION_MICRO),$(MODULE_VERSION_EXTRA) + diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/packet-btsm.c b/libbtbb-2015-10-R1/wireshark/plugins/btsm/packet-btsm.c new file mode 100644 index 0000000..5a068c1 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/packet-btsm.c @@ -0,0 +1,381 @@ +/* packet-btsm.c + * Routines for Bluetooth Low Energy Security Manager dissection + * Copyright 2013, Mike Ryan, mikeryan /at/ isecpartners /dot/ com + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include /* needed for epan/gcc-4.x */ +#include +#include + +#define BTL2CAP_FIXED_CID_BTSM 0x0006 + +/* initialize the protocol and registered fields */ +static int proto_btsm = -1; +static int hf_btsm_command = -1; +static int hf_btsm_pairing_request_io_capability = -1; +static int hf_btsm_pairing_request_oob_data = -1; +static int hf_btsm_pairing_request_auth_req = -1; +static int hf_btsm_pairing_request_reserved = -1; +static int hf_btsm_pairing_request_mitm = -1; +static int hf_btsm_pairing_request_bonding_flags = -1; +static int hf_btsm_pairing_request_max_key_size = -1; +static int hf_btsm_pairing_request_initiator_key_distribution = -1; +static int hf_btsm_pairing_request_responder_key_distribution = -1; +static int hf_btsm_pairing_response_io_capability = -1; +static int hf_btsm_pairing_response_oob_data = -1; +static int hf_btsm_pairing_response_auth_req = -1; +static int hf_btsm_pairing_response_reserved = -1; +static int hf_btsm_pairing_response_mitm = -1; +static int hf_btsm_pairing_response_bonding_flags = -1; +static int hf_btsm_pairing_response_max_key_size = -1; +static int hf_btsm_pairing_response_initiator_key_distribution = -1; +static int hf_btsm_pairing_response_responder_key_distribution = -1; +static int hf_btsm_pairing_confirm_confirm = -1; +static int hf_btsm_pairing_random_random = -1; +static int hf_btsm_encryption_info_ltk = -1; + +static const value_string commands[] = { + { 0x00, "Reserved" }, + { 0x01, "Pairing Request" }, + { 0x02, "Pairing Response" }, + { 0x03, "Pairing Confirm" }, + { 0x04, "Pairing Random" }, + { 0x05, "Pairing Failed" }, + { 0x06, "Encryption Information" }, + { 0x07, "Master Identification" }, + { 0x08, "Identity Information" }, + { 0x09, "Identity Address Information" }, + { 0x0A, "Signing Information" }, + { 0x0B, "Security Request" }, + { 0, NULL } +}; + +static const value_string io_capability[] = { + { 0x00, "DisplayOnly" }, + { 0x01, "DisplayYesNo" }, + { 0x02, "KeyboardOnly" }, + { 0x03, "NoInputOutput" }, + { 0x04, "KeyboardDisplay" }, + { 0, NULL } +}; + +static const value_string oob_data[] = { + { 0x00, "OOB Authentication data not present" }, + { 0x01, "OOB Authentication data from remote device present" }, + { 0, NULL } +}; + +static const value_string bonding_flags[] = { + { 0x0, "No Bonding" }, + { 0x1, "Bonding" }, + { 0, NULL }, +}; + +/* initialize the subtree pointers */ +static gint ett_btsm = -1; +static gint ett_auth_req = -1; + +static void +dissect_pairing_request(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *auth_req_item; + proto_tree *auth_req_tree; + + proto_tree_add_item(tree, hf_btsm_pairing_request_io_capability, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_btsm_pairing_request_oob_data, tvb, 2, 1, TRUE); + + auth_req_item = proto_tree_add_item(tree, hf_btsm_pairing_request_auth_req, tvb, 3, 1, TRUE); + auth_req_tree = proto_item_add_subtree(auth_req_item, ett_auth_req); + proto_tree_add_item(auth_req_tree, hf_btsm_pairing_request_reserved, tvb, 3, 1, TRUE); + proto_tree_add_bits_item(auth_req_tree, hf_btsm_pairing_request_mitm, tvb, 3 * 8 + 5, 1, TRUE); + proto_tree_add_item(auth_req_tree, hf_btsm_pairing_request_bonding_flags, tvb, 3, 1, TRUE); + + // TODO: check that max key size iswithin [7,16] + proto_tree_add_item(tree, hf_btsm_pairing_request_max_key_size, tvb, 4, 1, TRUE); + proto_tree_add_item(tree, hf_btsm_pairing_request_initiator_key_distribution, tvb, 5, 1, TRUE); + proto_tree_add_item(tree, hf_btsm_pairing_request_responder_key_distribution, tvb, 6, 1, TRUE); +} + +static void +dissect_pairing_response(tvbuff_t *tvb, proto_tree *tree) +{ + proto_item *auth_req_item; + proto_tree *auth_req_tree; + + proto_tree_add_item(tree, hf_btsm_pairing_response_io_capability, tvb, 1, 1, TRUE); + proto_tree_add_item(tree, hf_btsm_pairing_response_oob_data, tvb, 2, 1, TRUE); + + auth_req_item = proto_tree_add_item(tree, hf_btsm_pairing_response_auth_req, tvb, 3, 1, TRUE); + auth_req_tree = proto_item_add_subtree(auth_req_item, ett_auth_req); + proto_tree_add_item(auth_req_tree, hf_btsm_pairing_response_reserved, tvb, 3, 1, TRUE); + proto_tree_add_bits_item(auth_req_tree, hf_btsm_pairing_response_mitm, tvb, 3 * 8 + 5, 1, TRUE); + proto_tree_add_item(auth_req_tree, hf_btsm_pairing_response_bonding_flags, tvb, 3, 1, TRUE); + + // TODO: check that max key size iswithin [7,16] + proto_tree_add_item(tree, hf_btsm_pairing_response_max_key_size, tvb, 4, 1, TRUE); + proto_tree_add_item(tree, hf_btsm_pairing_response_initiator_key_distribution, tvb, 5, 1, TRUE); + proto_tree_add_item(tree, hf_btsm_pairing_response_responder_key_distribution, tvb, 6, 1, TRUE); +} + +static void +dissect_pairing_confirm(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_btsm_pairing_confirm_confirm, tvb, 1, 16, TRUE); +} + +static void +dissect_pairing_random(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_btsm_pairing_random_random, tvb, 1, 16, TRUE); +} + +static void +dissect_encryption_info(tvbuff_t *tvb, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_btsm_encryption_info_ltk, tvb, 1, 16, TRUE); +} + +/* dissect a packet */ +static void +dissect_btsm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *btsm_item; + proto_tree *btsm_tree; + guint8 command; + +#if 0 + /* sanity check: length */ + if (tvb_length(tvb) > 0 && tvb_length(tvb) < 9) + /* bad length: look for a different dissector */ + return 0; +#endif + + /* make entries in protocol column and info column on summary display */ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "BTLE Security Manager"); + + command = tvb_get_guint8(tvb, 0); + + /* see if we are being asked for details */ + if (tree) { + + /* create display subtree for the protocol */ + btsm_item = proto_tree_add_item(tree, proto_btsm, tvb, 0, tvb_length(tvb), TRUE); + btsm_tree = proto_item_add_subtree(btsm_item, ett_btsm); + + proto_tree_add_item(btsm_tree, hf_btsm_command, tvb, 0, 1, TRUE); + + if (check_col(pinfo->cinfo, COL_INFO)) { + if (command <= 0xb) { + col_set_str(pinfo->cinfo, COL_INFO, commands[command].strptr); + } else { + col_set_str(pinfo->cinfo, COL_INFO, "Unknown"); + } + } + + switch (command) { + // pairing request + case (0x1): + dissect_pairing_request(tvb, btsm_tree); + break; + case (0x2): + dissect_pairing_response(tvb, btsm_tree); + break; + case (0x3): + dissect_pairing_confirm(tvb, btsm_tree); + break; + case (0x4): + dissect_pairing_random(tvb, btsm_tree); + break; + case (0x6): + dissect_encryption_info(tvb, btsm_tree); + break; + default: + break; + } + } + + return; +} + +void +proto_reg_handoff_btsm(void) +{ + dissector_handle_t btsm_handle; + + btsm_handle = find_dissector("btsm"); + dissector_add_uint("btl2cap.cid", BTL2CAP_FIXED_CID_BTSM, btsm_handle); +} + +/* register the protocol with Wireshark */ +void +proto_register_btsm(void) +{ + + /* list of fields */ + static hf_register_info hf[] = { + { &hf_btsm_command, + { "Command", "btsm.command", + FT_UINT8, BASE_HEX, VALS(commands), 0x0, + NULL, HFILL } + }, + + // pairing request + { &hf_btsm_pairing_request_io_capability, + { "IO Capability", "btsm.pairing_request.io_capability", + FT_UINT8, BASE_HEX, VALS(io_capability), 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_oob_data, + { "OOB Data", "btsm.pairing_request.oob_data", + FT_UINT8, BASE_HEX, VALS(oob_data), 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_auth_req, + { "AuthReq", "btsm.pairing_request.auth_req", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_reserved, + { "Reserved", "btsm.pairing_request.auth_req.reserved", + FT_UINT8, BASE_HEX, NULL, 0xf8, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_mitm, + { "MITM Protection", "btsm.pairing_request.auth_req.mitm", + FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_bonding_flags, + { "Bonding Flags", "btsm.pairing_request.auth_req.bonding_flags", + FT_UINT8, BASE_HEX, VALS(bonding_flags), 0x3, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_max_key_size, + { "Max Key Size", "btsm.pairing_request.max_key_size", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_initiator_key_distribution, + { "Initiator Key Distribution", "btsm.pairing_request.initiator_key_distribution", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_request_responder_key_distribution, + { "Responder Key Distribution", "btsm.pairing_request.responder_key_distribution", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + + // pairing response + { &hf_btsm_pairing_response_io_capability, + { "IO Capability", "btsm.pairing_response.io_capability", + FT_UINT8, BASE_HEX, VALS(io_capability), 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_oob_data, + { "OOB Data", "btsm.pairing_response.oob_data", + FT_UINT8, BASE_HEX, VALS(oob_data), 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_auth_req, + { "AuthReq", "btsm.pairing_response.auth_req", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_reserved, + { "Reserved", "btsm.pairing_response.auth_req.reserved", + FT_UINT8, BASE_HEX, NULL, 0xf8, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_mitm, + { "MITM Protection", "btsm.pairing_response.auth_req.mitm", + FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_bonding_flags, + { "Bonding Flags", "btsm.pairing_response.auth_req.bonding_flags", + FT_UINT8, BASE_HEX, VALS(bonding_flags), 0x3, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_max_key_size, + { "Max Key Size", "btsm.pairing_response.max_key_size", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_initiator_key_distribution, + { "Initiator Key Distribution", "btsm.pairing_response.initiator_key_distribution", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_btsm_pairing_response_responder_key_distribution, + { "Responder Key Distribution", "btsm.pairing_response.responder_key_distribution", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + + + // pairing confirm + { &hf_btsm_pairing_confirm_confirm, + { "Confirm", "btsm.pairing_confirm.confirm", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + // pairing random + { &hf_btsm_pairing_random_random, + { "Random", "btsm.pairing_random.random", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + // encryption info LTK + { &hf_btsm_encryption_info_ltk, + { "LTK", "btsm.encryption_info.ltk", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + + }; + + /* protocol subtree arrays */ + static gint *ett[] = { + &ett_btsm, + &ett_auth_req, + }; + + /* register the protocol name and description */ + proto_btsm = proto_register_protocol( + "Bluetooth Low Energy Security Manager", /* full name */ + "BTSM", /* short name */ + "btsm" /* abbreviation (e.g. for filters) */ + ); + + register_dissector("btsm", dissect_btsm, proto_btsm); + + /* register the header fields and subtrees used */ + proto_register_field_array(proto_btsm, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/plugin.rc.in b/libbtbb-2015-10-R1/wireshark/plugins/btsm/plugin.rc.in new file mode 100644 index 0000000..568dc07 --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/plugin.rc.in @@ -0,0 +1,34 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @RC_MODULE_VERSION@ + PRODUCTVERSION @RC_VERSION@ + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0" + VALUE "FileDescription", "@PACKAGE@ dissector\0" + VALUE "FileVersion", "@MODULE_VERSION@\0" + VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0" + VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs , Gilbert Ramirez and others\0" + VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0" + VALUE "ProductName", "Wireshark\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "Comments", "Build with @MSVC_VARIANT@\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/tools/make-dissector-reg b/libbtbb-2015-10-R1/wireshark/plugins/btsm/tools/make-dissector-reg new file mode 100755 index 0000000..d2efa7c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/tools/make-dissector-reg @@ -0,0 +1,186 @@ +#! /bin/sh + +# +# $Id: make-dissector-reg 21716 2007-05-07 17:55:42Z gal $ +# + +# +# The first argument is the directory in which the source files live. +# +srcdir="$1" +shift + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype="$1" +shift +if [ "$registertype" = plugin ] +then + outfile="plugin.c" +elif [ "$registertype" = dissectors ] +then + outfile="register.c" +else + echo "Unknown output type '$registertype'" 1>&2 + exit 1 +fi + +# +# All subsequent arguments are the files to scan. +# +rm -f ${outfile}-tmp +echo '/* Do not modify this file. */' >${outfile}-tmp +echo '/* It is created automatically by the Makefile. */'>>${outfile}-tmp +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp + +fi +echo '}' >>${outfile}-tmp + + +# +# Build code to call all the protocol handoff registration routines. +# +if [ "$registertype" = plugin ] +then + cat <<"EOF" >>${outfile}-tmp +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +fi +echo '}' >>${outfile}-tmp +if [ "$registertype" = plugin ] +then + echo '#endif' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +gulong register_count(void) +{ +EOF + proto_regs=`grep RA_REGISTER ${outfile}-tmp | wc -l` + handoff_regs=`grep RA_HANDOFF ${outfile}-tmp | wc -l` + echo " return $proto_regs + $handoff_regs;" >>${outfile}-tmp + echo '}' >>${outfile}-tmp +fi +mv ${outfile}-tmp ${outfile} diff --git a/libbtbb-2015-10-R1/wireshark/plugins/btsm/tools/make-dissector-reg.py b/libbtbb-2015-10-R1/wireshark/plugins/btsm/tools/make-dissector-reg.py new file mode 100755 index 0000000..060460c --- /dev/null +++ b/libbtbb-2015-10-R1/wireshark/plugins/btsm/tools/make-dissector-reg.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# +# Looks for registration routines in the protocol dissectors, +# and assembles C code to call all the routines. +# +# This is a Python version of the make-reg-dotc shell script. +# Running the shell script on Win32 is very very slow because of +# all the process-launching that goes on --- multiple greps and +# seds for each input file. I wrote this python version so that +# less processes would have to be started. +# +# $Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $ + +import os +import sys +import re +import pickle +from stat import * + +VERSION_KEY = '_VERSION' +CUR_VERSION = '$Id: make-dissector-reg.py 40736 2012-01-26 21:38:53Z gerald $' + +# +# The first argument is the directory in which the source files live. +# +srcdir = sys.argv[1] + +# +# The second argument is either "plugin" or "dissectors"; if it's +# "plugin", we build a plugin.c for a plugin, and if it's +# "dissectors", we build a register.c for libwireshark. +# +registertype = sys.argv[2] +if registertype == "plugin" or registertype == "plugin_wtap": + tmp_filename = "plugin.c-tmp" + final_filename = "plugin.c" + cache_filename = None + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by Makefile or Makefile.nmake. + */ +""" +elif registertype == "dissectors": + tmp_filename = "register.c-tmp" + final_filename = "register.c" + cache_filename = "register-cache.pkl" + preamble = """\ +/* + * Do not modify this file. + * + * It is created automatically by the "register.c" target in + * epan/dissectors/Makefile or Makefile.nmake using information in + * epan/dissectors/register-cache.pkl. + * + * You can force this file to be regenerated completely by deleting + * it along with epan/dissectors/register-cache.pkl. + */ +""" +else: + print(("Unknown output type '%s'" % registertype)) + sys.exit(1) + + +# +# All subsequent arguments are the files to scan. +# +files = sys.argv[3:] + +# Create the proper list of filenames +filenames = [] +for file in files: + if os.path.isfile(file): + filenames.append(file) + else: + filenames.append(os.path.join(srcdir, file)) + +if len(filenames) < 1: + print("No files found") + sys.exit(1) + + +# Look through all files, applying the regex to each line. +# If the pattern matches, save the "symbol" section to the +# appropriate array. +regs = { + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } + +# For those that don't know Python, r"" indicates a raw string, +# devoid of Python escapes. +proto_regex0 = r"^(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" +proto_regex1 = r"void\s+(?Pproto_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +handoff_regex0 = r"^(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" +handoff_regex1 = r"void\s+(?Pproto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$" + +wtap_reg_regex0 = r"^(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" +wtap_reg_regex1 = r"void\s+(?Pwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" + +# This table drives the pattern-matching and symbol-harvesting +patterns = [ + ( 'proto_reg', re.compile(proto_regex0) ), + ( 'proto_reg', re.compile(proto_regex1) ), + ( 'handoff_reg', re.compile(handoff_regex0) ), + ( 'handoff_reg', re.compile(handoff_regex1) ), + ( 'wtap_register', re.compile(wtap_reg_regex0) ), + ( 'wtap_register', re.compile(wtap_reg_regex1) ), + ] + +# Open our registration symbol cache +cache = None +if cache_filename: + try: + cache_file = open(cache_filename, 'rb') + cache = pickle.load(cache_file) + cache_file.close() + if VERSION_KEY not in cache or cache[VERSION_KEY] != CUR_VERSION: + cache = {VERSION_KEY: CUR_VERSION} + except: + cache = {VERSION_KEY: CUR_VERSION} + + print(("Registering %d files, %d cached" % (len(filenames), len(list(cache.keys()))-1))) + +# Grep +cache_hits = 0 +cache_misses = 0 +for filename in filenames: + file = open(filename) + cur_mtime = os.fstat(file.fileno())[ST_MTIME] + if cache and filename in cache: + cdict = cache[filename] + if cur_mtime == cdict['mtime']: + cache_hits += 1 +# print "Pulling %s from cache" % (filename) + regs['proto_reg'].extend(cdict['proto_reg']) + regs['handoff_reg'].extend(cdict['handoff_reg']) + regs['wtap_register'].extend(cdict['wtap_register']) + file.close() + continue + # We don't have a cache entry + if cache is not None: + cache_misses += 1 + cache[filename] = { + 'mtime': cur_mtime, + 'proto_reg': [], + 'handoff_reg': [], + 'wtap_register': [], + } +# print "Searching %s" % (filename) + for line in file.readlines(): + for action in patterns: + regex = action[1] + match = regex.search(line) + if match: + symbol = match.group("symbol") + sym_type = action[0] + regs[sym_type].append(symbol) + if cache is not None: +# print "Caching %s for %s: %s" % (sym_type, filename, symbol) + cache[filename][sym_type].append(symbol) + file.close() + + +if cache is not None and cache_filename is not None: + cache_file = open(cache_filename, 'wb') + pickle.dump(cache, cache_file) + cache_file.close() + print(("Cache hits: %d, misses: %d" % (cache_hits, cache_misses))) + +# Make sure we actually processed something +if len(regs['proto_reg']) < 1: + print("No protocol registrations found") + sys.exit(1) + +# Sort the lists to make them pretty +regs['proto_reg'].sort() +regs['handoff_reg'].sort() +regs['wtap_register'].sort() + +reg_code = open(tmp_filename, "w") + +reg_code.write(preamble) + +# Make the routine to register all protocols +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "moduleinfo.h" + +#ifndef ENABLE_STATIC +G_MODULE_EXPORT const gchar version[] = VERSION; + +/* Start the functions we need for the plugin stuff */ + +G_MODULE_EXPORT void +plugin_register (void) +{ +"""); +else: + reg_code.write(""" +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['proto_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + + +# Make the routine to register all protocol handoffs +if registertype == "plugin" or registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +plugin_reg_handoff(void) +{ +"""); +else: + reg_code.write(""" +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +"""); + +for symbol in regs['handoff_reg']: + if registertype == "plugin" or registertype == "plugin_wtap": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) + reg_code.write(line) + +reg_code.write("}\n") + +if registertype == "plugin": + reg_code.write("#endif\n"); +elif registertype == "plugin_wtap": + reg_code.write(""" +G_MODULE_EXPORT void +register_wtap_module(void) +{ +"""); + + for symbol in regs['wtap_register']: + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + reg_code.write(line) + + reg_code.write("}\n"); + reg_code.write("#endif\n"); +else: + reg_code.write(""" +static gulong proto_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['proto_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +static gulong handoff_reg_count(void) +{ +"""); + + line = " return %d;\n" % len(regs['handoff_reg']) + reg_code.write(line) + + reg_code.write(""" +} +"""); + reg_code.write(""" +gulong register_count(void) +{ +"""); + + line = " return proto_reg_count() + handoff_reg_count();" + reg_code.write(line) + + reg_code.write(""" +}\n +"""); + + +# Close the file +reg_code.close() + +# Remove the old final_file if it exists. +try: + os.stat(final_filename) + os.remove(final_filename) +except OSError: + pass + +# Move from tmp file to final file +os.rename(tmp_filename, final_filename) diff --git a/ubertooth_install.sh b/ubertooth_install.sh new file mode 100755 index 0000000..6fe3652 --- /dev/null +++ b/ubertooth_install.sh @@ -0,0 +1,124 @@ +#!/bin/bash +# Purpose: Install ubertooth and crackle libraries +# Author: Paul Walko +# Last updated on: 12/17/16 +# ------------------------------------------------ + +# Setup +echo -e 'Installs the latest stable ubertooth release and/or crackle (git) release to /opt' +echo -e 'This script was only tested in Arch Linux (12/16). Your mileage may vary' +echo -e 'This script also assumes you have sudo access, as you will be prompted for your password\n' + +INSTALL_DIR="/opt" + +# help +function help { + echo -e 'Help:\n' + echo -e '-h: This message\n' + echo -e '-I: Custom installation directory; Defaults to '/opt/'\n' + echo -e '--remove-{libbtbb, ubertooth, crackle}: Removes respective program\n\n' +} + +# Set install directory +while getopts ":h:I:" args; do + case "${args}" in + h) + help + ;; + I) + INSTALL_DIR=${OPTARG} + ;; + *) + ;; + esac +done + +# libbtbb +cd $INSTALL_DIR +if [[ $* == *--remove-libbtbb* ]]; then + # Remove libbtbb + echo -e 'WARNING: THIS WILL REMOVE ANY FILES/DIRECTORIES WITH "libbtbb" IN THEIR NAME \nContinue? (y/N)\n' + read yn + if [[ $yn == y ]]; then + suod rm *libbtbb*gz + cd *libbtbb*/build + sudo make uninstall + cd $INSTALL_DIR + sudo rm -r *libbtbb* + fi +elif ! ls | grep -q "libbtbb"; then + echo -e 'Installing libbtbb... (Ubertooth dependency)\n' + + wget https://github.com/greatscottgadgets/libbtbb/archive/2015-10-R1.tar.gz -O libbtbb-2015-10-R1.tar.gz + tar xf libbtbb-2015-10-R1.tar.gz + cd libbtbb-2015-10-R1 + mkdir build + cd build + cmake .. + make + sudo make install +else + echo -e 'libbtbb is already installed... skipping \nRun with "--remove-libbtbb" before installing new version\n' +fi + +# ubertooth +cd $INSTALL_DIR +if [[ $* == *--remove-ubertooth* ]] +then + # Remove ubertooth + echo -e 'WARNING: THIS WILL REMOVE ANY FILES/DIRECTORIES WITH "ubertooth" IN THEIR NAME \nContinue? (y/N)\n' + read yn + if [[ $yn == y ]]; then + sudo rm *ubertooth*xz + cd *ubertooth*/host/build + sudo make uninstall + cd $INSTALL_DIR + sudo rm -r *ubertooth* + fi +elif ! type "ubertooth-util" > /dev/null; then + # Install ubertooth + echo -e 'Installing ubertooth...\n\n' + + wget https://github.com/greatscottgadgets/ubertooth/releases/download/2015-10-R1/ubertooth-2015-10-R1.tar.xz -O ubertooth-2015-10-R1.tar.xz + tar xf ubertooth-2015-10-R1.tar.xz + cd ubertooth-2015-10-R1/host + mkdir build + cd build + cmake .. + make + sudo make install +else + # Already installed + echo -e 'ubertoooth is alrady installed... skipping \nRun with "--remove-ubertooth" before installing new version\n' +fi + +# crackle +cd $INSTALL_DIR +if [[ $* == *--remove-crackle* ]] +then + # Remove crackle + echo -e 'Remove crackle? (y/N)\n' + read yn + if [[ $yn == y ]]; then + cd crackle + sudo make uninstall + cd $INSTALL_DIR + sudo rm -r crackle + fi +elif ! type "crackle" > /dev/null; then + echo -e 'Installing crackle... \n\n' + + git clone https://github.com/mikeryan/crackle.git + cd crackle + make + sudo make install +else + # Already installed + echo -e 'crackle is alrady installed.. skipping \nRun with "--remove-crackle" before installing new version\n' +fi + + +echo -e 'Running ldconfig to fix some libraries... \n' +sudo ldconfig + +echo -e 'If you plan to use wireshark to capture btle, be sure to follow the directions at the bottom of the page here to enable wireshark to recongize btle packets: \nhttps://github.com/greatscottgadgets/ubertooth/wiki/Capturing-BLE-in-Wireshark' diff --git a/ubertooth_ubuntu160401.sh b/ubertooth_ubuntu160401.sh deleted file mode 100755 index 60152f6..0000000 --- a/ubertooth_ubuntu160401.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash -echo 'This script was only tested in Ubuntu 16.04.1. Your mileage may vary' -echo 'This script also assumes you have sudo access, as you will be prompted for your password' - -sudo apt-get install git cmake libusb-1.0-0-dev make gcc g++ libbluetooth-dev pkg-config libpcap-dev python-numpy python-pyside python-qt4 wireshark git - -git clone https://github.com/greatscottgadgets/libbtbb.git -cd libbtbb -mkdir build -cd build -cmake .. -make -sudo make install -sudo ldconfig -cd ../.. - -git clone https://github.com/greatscottgadgets/ubertooth.git -cd ubertooth/host -mkdir build -cd build -cmake .. -make -sudo make install -sudo ldconfig -cd ../../.. - -sudo apt-get install wireshark wireshark-dev libwireshark-dev cmake -cd libbtbb/wireshark/plugins/btbb -mkdir build -cd build -cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/x86_64-linux-gnu/wireshark/libwireshark3/plugins .. -make -sudo make install -cd ../../../../.. - -sudo apt-get install wireshark wireshark-dev libwireshark-dev cmake -cd libbtbb/wireshark/plugins/btbredr -mkdir build -cd build -cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/x86_64-linux-gnu/wireshark/libwireshark3/plugins .. -make -sudo make install -cd ../../../../.. - -echo 'Adding user to wireshark group...' -sudo dpkg-reconfigure wireshark-common -sudo gpasswd -a $USER wireshark - -echo 'If you plan to use wireshark to capture btle, be sure to follow the directions at the bottom of the page here to enable wireshark to recongize btle packets: https://github.com/greatscottgadgets/ubertooth/wiki/Capturing-BLE-in-Wireshark'