From f19cbbffcb8c20b86faa1c225aa038b1c4812756 Mon Sep 17 00:00:00 2001 From: Itay Almog Date: Mon, 21 Oct 2019 12:55:25 +0300 Subject: [PATCH] Added ability to start, stop, close and save :) Next is adding the ability to open offline captures and then it is almost complete I guess --- .gitignore | 166 +- .idea/codeStyles/Project.xml | 230 +- .idea/discord.xml | 16 +- .idea/misc.xml | 26 +- .idea/runConfigurations.xml | 22 +- LICENSE | 42 +- app/.gitignore | 2 +- app/build.gradle | 94 +- app/proguard-rules.pro | 42 +- app/src/main/AndroidManifest.xml | 56 +- app/src/main/cpp/CMakeLists.txt | 8 +- app/src/main/cpp/bufferutils/CMakeLists.txt | 14 +- app/src/main/cpp/bufferutils/bufferutils.c | 32 +- app/src/main/cpp/pcapproxy/CMakeLists.txt | 12 +- app/src/main/cpp/pcapproxy/pcap-proxy.c | 948 ++++---- .../itay/packetmanipulator/ColorEngine.java | 232 +- .../itay/packetmanipulator/ErrorActivity.java | 44 +- .../itay/packetmanipulator/MainActivity.java | 189 +- .../me/itay/packetmanipulator/OnClick.java | 14 +- .../PacketInfoBottomSheet.java | 70 +- .../RecyclerPacketsAdapter.java | 192 +- .../packetmanipulator/SnifferActivity.java | 566 +++-- .../display/PacketDissector.java | 18 +- .../display/PacketEntry.java | 38 +- .../java/me/itay/pcapproxy/DataStream.java | 368 +-- .../java/me/itay/pcapproxy/PcapProxy.java | 456 ++-- .../me/itay/pcapproxy/PcapProxyException.java | 26 +- .../me/itay/pcapproxy/structs/in6_addr.java | 14 +- .../me/itay/pcapproxy/structs/in_addr.java | 14 +- .../me/itay/pcapproxy/structs/pcap_addr.java | 38 +- .../me/itay/pcapproxy/structs/pcap_if.java | 50 +- .../itay/pcapproxy/structs/pcap_pkthdr.java | 62 +- .../me/itay/pcapproxy/structs/pcap_stat.java | 34 +- .../me/itay/pcapproxy/structs/sockaddr.java | 60 +- .../itay/pcapproxy/structs/sockaddr_in.java | 42 +- .../itay/pcapproxy/structs/sockaddr_in6.java | 46 +- .../itay/pcapproxy/structs/sockaddr_ll.java | 74 +- .../me/itay/pcapproxy/structs/timeval.java | 48 +- app/src/main/java/org/pcap4j/LICENSE | 30 +- .../org/pcap4j/core/AbstractPcapAddress.java | 322 +-- app/src/main/java/org/pcap4j/core/Inets.java | 196 +- .../org/pcap4j/core/NotOpenException.java | 54 +- .../java/org/pcap4j/core/PcapAddress.java | 56 +- .../main/java/org/pcap4j/core/PcapDumper.java | 386 +-- .../main/java/org/pcap4j/core/PcapHandle.java | 946 ++++---- .../java/org/pcap4j/core/PcapIpV4Address.java | 108 +- .../java/org/pcap4j/core/PcapIpV6Address.java | 108 +- .../org/pcap4j/core/PcapNetworkInterface.java | 642 ++--- .../main/java/org/pcap4j/core/PcapStat.java | 98 +- app/src/main/java/org/pcap4j/core/Pcaps.java | 357 +-- .../packet/factory/PacketFactories.java | 162 +- .../pcap4j/packet/factory/PacketFactory.java | 96 +- .../packet/factory/PacketFactoryBinder.java | 60 +- .../factory/PacketFactoryBinderProvider.java | 66 +- .../factory/SimplePacketFactoryBinder.java | 74 +- .../factory/StaticUnknownPacketFactory.java | 90 +- .../services/StaticPacketFactoryBinder.java | 260 +-- .../StaticPacketFactoryBinderProvider.java | 40 +- .../main/java/org/pcap4j/util/ByteArrays.java | 2062 ++++++++--------- .../org/pcap4j/util/Inet4NetworkAddress.java | 84 +- .../main/java/org/pcap4j/util/LazyValue.java | 130 +- .../org/pcap4j/util/LinkLayerAddress.java | 180 +- .../main/java/org/pcap4j/util/MacAddress.java | 188 +- .../main/java/org/pcap4j/util/Packets.java | 176 +- .../drawable-v24/ic_launcher_foreground.xml | 68 +- app/src/main/res/drawable/border.xml | 12 +- app/src/main/res/drawable/ic_close.xml | 9 + .../res/drawable/ic_launcher_background.xml | 340 +-- app/src/main/res/drawable/ic_restart.xml | 9 + app/src/main/res/drawable/ic_start.xml | 9 + app/src/main/res/layout/activity_error.xml | 38 +- app/src/main/res/layout/activity_main.xml | 60 +- .../main/res/layout/packet_table_entry.xml | 96 +- app/src/main/res/layout/sniffer_activity.xml | 133 +- .../sniffer_packet_info_bottom_sheet.xml | 26 +- app/src/main/res/menu/sniffer_options.xml | 87 +- .../res/mipmap-anydpi-v26/ic_launcher.xml | 8 +- .../mipmap-anydpi-v26/ic_launcher_round.xml | 8 +- app/src/main/res/values/colors.xml | 12 +- app/src/main/res/values/strings.xml | 34 +- app/src/main/res/values/styles.xml | 28 +- build.gradle | 54 +- gradle.properties | 40 +- gradle/wrapper/gradle-wrapper.properties | 12 +- gradlew.bat | 168 +- settings.gradle | 4 +- 86 files changed, 6419 insertions(+), 6212 deletions(-) create mode 100644 app/src/main/res/drawable/ic_close.xml create mode 100644 app/src/main/res/drawable/ic_restart.xml create mode 100644 app/src/main/res/drawable/ic_start.xml diff --git a/.gitignore b/.gitignore index a03d785..cd157ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,84 +1,84 @@ -# Built application files -*.apk -*.ap_ -*.aab - -# Files for the ART/Dalvik VM -*.dex - -# Java class files -*.class - -# Generated files -app/.cxx/ -bin/ -gen/ -out/ -# Uncomment the following line in case you need and you don't have the release build type files in your app -# release/ - -# Gradle files -.gradle/ -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log - -# Android Studio Navigation editor temp files -.navigation/ - -# Android Studio captures folder -captures/ - -# IntelliJ -*.iml -.idea/workspace.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/dictionaries -.idea/libraries -# Android Studio 3 in .gitignore file. -.idea/caches -.idea/modules.xml -# Comment next line if keeping position of elements in Navigation Editor is relevant for you -.idea/navEditor.xml - -# Keystore files -# Uncomment the following lines if you do not want to check your keystore files in. -#*.jks -#*.keystore - -# External native build folder generated in Android Studio 2.2 and later -.externalNativeBuild - -# Google Services (e.g. APIs or Firebase) -# google-services.json - -# Freeline -freeline.py -freeline/ -freeline_project_description.json - -# fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output -fastlane/readme.md - -# Version control -vcs.xml - -# lint -lint/intermediates/ -lint/generated/ -lint/outputs/ -lint/tmp/ +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +app/.cxx/ +bin/ +gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ # lint/reports/ \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 681f41a..3279b6b 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,116 +1,116 @@ - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
-
+ + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
\ No newline at end of file diff --git a/.idea/discord.xml b/.idea/discord.xml index 59b11d1..f6c427e 100644 --- a/.idea/discord.xml +++ b/.idea/discord.xml @@ -1,9 +1,9 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 3378229..c15db10 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,14 +1,14 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml index 7f68460..9b770a6 100644 --- a/.idea/runConfigurations.xml +++ b/.idea/runConfigurations.xml @@ -1,12 +1,12 @@ - - - - - + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE index 92e943f..1223cb9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2019 Itay Almog - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2019 Itay Almog + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/.gitignore b/app/.gitignore index 796b96d..3543521 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1 @@ -/build +/build diff --git a/app/build.gradle b/app/build.gradle index ccd2028..8d91ed4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,47 +1,47 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 28 - buildToolsVersion "29.0.2" - defaultConfig { - applicationId "me.itay.packetmanipulator" - minSdkVersion 21 - targetSdkVersion 28 - versionCode 1 - versionName "1.0" - externalNativeBuild { - cmake { - cppFlags "-std=c++14" - } - } - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - externalNativeBuild { - cmake { - path "src/main/cpp/CMakeLists.txt" - version "3.10.2" - } - } - compileOptions { - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.github.Stericson:RootShell:1.6' - implementation('com.github.Stericson:RootTools:5.0') { - exclude group: 'com.github.Stericson' - } - implementation 'info.androidhive:fontawesome:0.0.5' - implementation 'androidx.recyclerview:recyclerview:1.0.0' - implementation 'com.google.android.material:material:1.0.0' -} +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + buildToolsVersion "29.0.2" + defaultConfig { + applicationId "me.itay.packetmanipulator" + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + externalNativeBuild { + cmake { + cppFlags "-std=c++14" + } + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + externalNativeBuild { + cmake { + path "src/main/cpp/CMakeLists.txt" + version "3.10.2" + } + } + compileOptions { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.github.Stericson:RootShell:1.6' + implementation('com.github.Stericson:RootTools:5.0') { + exclude group: 'com.github.Stericson' + } + implementation 'info.androidhive:fontawesome:0.0.5' + implementation 'androidx.recyclerview:recyclerview:1.0.0' + implementation 'com.google.android.material:material:1.0.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f1b4245..6e7ffa9 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,21 +1,21 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 22da5aa..05f9c7a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,29 +1,29 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index 1d8f3f0..8a86fc2 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.4.1) - -add_subdirectory(pcapproxy) -add_subdirectory(bufferutils) +cmake_minimum_required(VERSION 3.4.1) + +add_subdirectory(pcapproxy) +add_subdirectory(bufferutils) diff --git a/app/src/main/cpp/bufferutils/CMakeLists.txt b/app/src/main/cpp/bufferutils/CMakeLists.txt index 7cbc655..ed24003 100644 --- a/app/src/main/cpp/bufferutils/CMakeLists.txt +++ b/app/src/main/cpp/bufferutils/CMakeLists.txt @@ -1,7 +1,7 @@ - -cmake_minimum_required(VERSION 3.4.1) - -add_library( - bufferutils - SHARED - bufferutils.c) + +cmake_minimum_required(VERSION 3.4.1) + +add_library( + bufferutils + SHARED + bufferutils.c) diff --git a/app/src/main/cpp/bufferutils/bufferutils.c b/app/src/main/cpp/bufferutils/bufferutils.c index 5662bb2..48b7ee3 100644 --- a/app/src/main/cpp/bufferutils/bufferutils.c +++ b/app/src/main/cpp/bufferutils/bufferutils.c @@ -1,17 +1,17 @@ -#include -#include - -JNIEXPORT jobject JNICALL -Java_me_itay_packetmanipulator_pcapproxy_JNI_NewDirectByteBuffer(JNIEnv *env, jclass clazz, jlong value, jlong size) { - return (*env)->NewDirectByteBuffer(env, (void*)value, size); -} - -JNIEXPORT jboolean JNICALL -Java_me_itay_packetmanipulator_pcapproxy_JNI_is64bit(JNIEnv *env, jclass clazz) { - return sizeof(void*) == 8 ? JNI_TRUE : JNI_FALSE; -} - -JNIEXPORT jstring JNICALL -Java_me_itay_packetmanipulator_pcapproxy_JNI_NewStringUTF(JNIEnv *env, jclass clazz, jlong ptr) { - return (*env)->NewStringUTF(env, (const char *) ptr); +#include +#include + +JNIEXPORT jobject JNICALL +Java_me_itay_packetmanipulator_pcapproxy_JNI_NewDirectByteBuffer(JNIEnv *env, jclass clazz, jlong value, jlong size) { + return (*env)->NewDirectByteBuffer(env, (void*)value, size); +} + +JNIEXPORT jboolean JNICALL +Java_me_itay_packetmanipulator_pcapproxy_JNI_is64bit(JNIEnv *env, jclass clazz) { + return sizeof(void*) == 8 ? JNI_TRUE : JNI_FALSE; +} + +JNIEXPORT jstring JNICALL +Java_me_itay_packetmanipulator_pcapproxy_JNI_NewStringUTF(JNIEnv *env, jclass clazz, jlong ptr) { + return (*env)->NewStringUTF(env, (const char *) ptr); } \ No newline at end of file diff --git a/app/src/main/cpp/pcapproxy/CMakeLists.txt b/app/src/main/cpp/pcapproxy/CMakeLists.txt index 635d511..5665128 100644 --- a/app/src/main/cpp/pcapproxy/CMakeLists.txt +++ b/app/src/main/cpp/pcapproxy/CMakeLists.txt @@ -1,6 +1,6 @@ - -cmake_minimum_required(VERSION 3.4.1) - -add_executable( - libpcapproxy.so - pcap-proxy.c) + +cmake_minimum_required(VERSION 3.4.1) + +add_executable( + libpcapproxy.so + pcap-proxy.c) diff --git a/app/src/main/cpp/pcapproxy/pcap-proxy.c b/app/src/main/cpp/pcapproxy/pcap-proxy.c index 82abb69..ed51898 100644 --- a/app/src/main/cpp/pcapproxy/pcap-proxy.c +++ b/app/src/main/cpp/pcapproxy/pcap-proxy.c @@ -1,474 +1,474 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/////////////////////////////////////////////// -// libpcap loaded functions -/////////////////////////////////////////////// - -typedef struct pcap_if { - struct pcap_if* next; - char* name; - char* description; - struct pcap_addr* addresses; - int32_t flags; -} pcap_if_t; - -struct pcap_addr { - struct pcap_addr* next; - struct sockaddr addr; - struct sockaddr netmask; - struct sockaddr broadaddr; - struct sockaddr dstaddr; -}; - -struct pcap_pkthdr { - struct timeval ts; - int32_t caplen; - int32_t len; -}; - -struct pcap_stat { - int32_t ps_recv; - int32_t ps_drop; - int32_t ps_ifdrop; -}; - -typedef void pcap_t; -typedef void pcap_dumper_t; - -static const char* (*pcap_lib_version)(void); -static int (*pcap_findalldevs)(pcap_if_t **alldevsp, char *errbuf); -static void (*pcap_freealldevs)(pcap_if_t *alldevsp); -static pcap_t* (*pcap_open_live)(const char* device, int snaplen, int promisc, int to_ms, char* errbuf); -void (*pcap_close)(pcap_t*p); -int (*pcap_datalink)(pcap_t *p); -char* (*pcap_next)(pcap_t *p, struct pcap_pkthdr *h); -int (*pcap_setnonblock)(pcap_t *p, int nonblock, char *errbuf); -int (*pcap_getnonblock)(pcap_t *p, char *errbuf); -char* (*pcap_lookupdev)(char *errbuf); -char* (*pcap_strerror)(int errno); -char* (*pcap_geterr)(pcap_t *p); -int (*pcap_stats)(pcap_t *p, struct pcap_stat *ps); - -pcap_dumper_t* (*pcap_dump_open)(pcap_t *p, const char *fname); -void (*pcap_dump)(pcap_dumper_t * dumper, const struct pcap_pkthdr *h, const u_char *sp); -int (*pcap_dump_flush)(pcap_dumper_t *p); -long (*pcap_dump_ftell)(pcap_dumper_t *); -void (*pcap_dump_close)(pcap_dumper_t *p); - -/////////////////////////////////////////////// -// stream handling -/////////////////////////////////////////////// - -void write_bool(bool b) { - fwrite(&b, 1, 1, stdout); - fflush(stdout); -} - -int32_t read_int() { - int32_t num = 0; - fread(&num, 4, 1, stdin); - return num; -} - -int64_t read_long() { - int64_t num = 0; - fread(&num, 8, 1, stdin); - return num; -} - -void write_int(int32_t num) { - fwrite(&num, 4, 1, stdout); - fflush(stdout); -} - -void write_long(int64_t num) { - fwrite(&num, 8, 1, stdout); - fflush(stdout); -} - -void write_string(const char* str) { - if(str == NULL) { - write_int(0); - }else { - write_int(strlen(str)); - fwrite(str, strlen(str), 1, stdout); - } - fflush(stdout); -} - -char* read_string() { - int len = read_int(); - char* buf = malloc((size_t) len + 1); - fread(buf, 1, (size_t) len, stdin); - buf[len] = 0; - return buf; -} - -/////////////////////////////////////////////// -// the handler implementations -/////////////////////////////////////////////// - -void comm_pcap_lib_version() { - write_string(pcap_lib_version()); -} - -void comm_pcap_findalldevs() { - pcap_if_t* pifs = NULL; - char buffer[256] = {0}; - - // try to find all interfaces - if(pcap_findalldevs(&pifs, buffer) != 0) { - fprintf(stderr, "errbuf -> %s\n", buffer); - fflush(stderr); - - // go an error - write_bool(false); - write_string(buffer); - - }else { - - // everything is good - write_bool(true); - - // find how many devices there are - int devs_count = 0; - if(pifs != NULL) { - pcap_if_t* cur = pifs; - do { - devs_count++; - } while((cur = cur->next) != NULL); - } - - // iterate and write out the devices - write_int(devs_count); - pcap_if_t* cur = pifs; - while(cur != NULL) { - // write the name and description - write_string(cur->name); - write_string(cur->description); - - // check how many addresses are there - int addr_count = 0; - if(cur->addresses != NULL) { - struct pcap_addr* addr = cur->addresses; - do { - addr_count++; - } while((addr = addr->next) != NULL); - } - - // write the addresses - write_int(addr_count); - struct pcap_addr* addr = cur->addresses; - while(addr != NULL) { - fwrite(addr, sizeof(struct sockaddr) * 4, 1, stdout); - fflush(stdout); - - addr = addr->next; - } - - // write the flags - write_int(cur->flags); - - cur = cur->next; - } - - } - - // free them - pcap_freealldevs(pifs); -} - -void comm_pcap_open_live() { - char buffer[256] = {0}; - - char* device = read_string(); - int spanlen = read_int(); - int promisc = read_int(); - int to_ms = read_int(); - - void* pcap = pcap_open_live(device, spanlen, promisc, to_ms, buffer); - if(pcap == NULL) { - - fprintf(stderr, "errbuf -> %s\n", buffer); - fflush(stderr); - - write_bool(false); - write_string(buffer); - - }else { - - write_bool(true); - write_long((uint64_t)pcap); - - } - - free(device); -} - -void comm_pcap_close() { - void* handle = (void*)read_long(); - pcap_close(handle); -} - -void comm_pcap_datalink() { - void* handle = (void*)read_long(); - write_int(pcap_datalink(handle)); -} - -void comm_pcap_next() { - void* handle = (void*)read_long(); - - struct pcap_pkthdr header; - void* data = pcap_next(handle, &header); - - if(data == NULL) { - write_bool(false); - }else { - write_bool(true); - - write_long(header.ts.tv_sec); - write_long(header.ts.tv_usec); - write_int(header.caplen); - write_int(header.len); - fwrite(data, 1, (size_t) header.caplen, stdout); - fflush(stdout); - } -} - -void comm_pcap_setnonblock() { - char errbuf[256] = {0}; - - void* handle = (void*)read_long(); - int nonblock = read_int(); - - if(pcap_setnonblock(handle, nonblock, errbuf) != 0) { - - write_bool(false); - write_string(errbuf); - - }else { - - write_bool(true); - - } -} - -void comm_pcap_getnonblock() { - char errbuf[256] = {0}; - - void* handle = (void*)read_long(); - int nonblock = pcap_getnonblock(handle, errbuf); - - if(nonblock < 0) { - - write_bool(false); - write_string(errbuf); - - }else { - - write_bool(true); - write_int(nonblock); - - } -} - -void comm_pcap_lookupdev() { - char errbuf[256] = {0}; - - char* device = pcap_lookupdev(errbuf); - - if(device == NULL) { - - write_bool(false); - write_string(errbuf); - - }else { - - write_bool(true); - write_string(device); - - } -} - -void comm_pcap_strerror() { - int error = read_int(); - write_string(pcap_strerror(error)); -} - -void comm_pcap_geterr() { - void* handle = (void*)read_long(); - write_string(pcap_geterr(handle)); -} - -void comm_pcap_stats() { - void* handle = (void*)read_long(); - - struct pcap_stat stats = {0}; - pcap_stats(handle, &stats); - - write_int(stats.ps_recv); - write_int(stats.ps_drop); - write_int(stats.ps_ifdrop); -} - -void comm_pcap_dump_open() { - void* handle = (void*)read_long(); - char* str = read_string(); - void* res = pcap_dump_open(handle, str); - write_long((int64_t) res); - free(str); -} - -void comm_pcap_dump() { - void* handle = (void*)read_long(); - struct pcap_pkthdr header = {0}; - header.ts.tv_sec = (__kernel_time_t) read_long(); - header.ts.tv_usec = (__kernel_time_t) read_long(); - header.caplen = read_int(); - header.len = read_int(); - char* buffer = malloc((size_t) header.len); - fread(buffer, 1, (size_t) header.len, stdin); - pcap_dump(handle, &header, (const u_char *) buffer); - free(buffer); -} - -void comm_pcap_dump_flush() { - void* handle = (void*)read_long(); - int rc = pcap_dump_flush(handle); - if(rc != 0) { - - write_bool(false); - write_string(pcap_strerror(rc)); - - }else { - - write_bool(true); - - } -} - -void comm_pcap_dump_ftell() { - void* handle = (void*)read_long(); - pcap_dump_close(handle); -} - -void comm_pcap_dump_close() { - void* handle = (void*)read_long(); - pcap_dump_close(handle); -} - -/////////////////////////////////////////////// -// Server main -/////////////////////////////////////////////// - -// function constatns -#define PCAP_LIB_VERSION 1 -#define PCAP_FINDALLDEVS 2 -#define PCAP_OPEN_LIVE 3 -#define PCAP_CLOSE 4 -#define PCAP_DATALINK 5 -#define PCAP_NEXT 6 -#define PCAP_SETNONBLOCK 7 -#define PCAP_GETNONBLOCK 8 -#define PCAP_LOOKUPDEV 9 -#define PCAP_STRERROR 10 -#define PCAP_GETERR 11 -#define PCAP_STATS 12 -#define PCAP_DUMP_OPEN 13 -#define PCAP_DUMP 14 -#define PCAP_DUMP_FLUSH 15 -#define PCAP_DUMP_FTELL 16 -#define PCAP_DUMP_CLOSE 17 - -// handlers per function -typedef void (*command_handler_t)(); -command_handler_t handlers[] = { - [PCAP_LIB_VERSION] = comm_pcap_lib_version, - [PCAP_FINDALLDEVS] = comm_pcap_findalldevs, - [PCAP_OPEN_LIVE] = comm_pcap_open_live, - [PCAP_CLOSE] = comm_pcap_close, - [PCAP_DATALINK] = comm_pcap_datalink, - [PCAP_NEXT] = comm_pcap_next, - [PCAP_SETNONBLOCK] = comm_pcap_setnonblock, - [PCAP_GETNONBLOCK] = comm_pcap_getnonblock, - [PCAP_LOOKUPDEV] = comm_pcap_lookupdev, - [PCAP_STRERROR] = comm_pcap_strerror, - [PCAP_GETERR] = comm_pcap_geterr, - [PCAP_STATS] = comm_pcap_stats, - [PCAP_DUMP_OPEN] = comm_pcap_dump_open, - [PCAP_DUMP] = comm_pcap_dump, - [PCAP_DUMP_FLUSH] = comm_pcap_dump_flush, - [PCAP_DUMP_FTELL] = comm_pcap_dump_ftell, - [PCAP_DUMP_CLOSE] = comm_pcap_dump_close, -}; - -#define LOAD_FUNC(name) \ - do { \ - name = dlsym(handle, #name); \ - if(name == NULL) { \ - fprintf(stderr, "Failed to get function %s - %s\n", #name, dlerror()); \ - return -1; \ - } \ - } while(0) - -/* - * This is called - */ -int main(int argc, char* argv[]) { - fprintf(stderr, "pcap proxy process main\n"); - - // attempt to open libpcap - void* handle = dlopen("libpcap.so", RTLD_LAZY); - if(handle == NULL) { - fprintf(stderr, "Failed to open libpcap.so - %s\n", dlerror()); - fflush(stderr); - return -1; - } - - // load all the functions - LOAD_FUNC(pcap_lib_version); - LOAD_FUNC(pcap_findalldevs); - LOAD_FUNC(pcap_freealldevs); - LOAD_FUNC(pcap_open_live); - LOAD_FUNC(pcap_close); - LOAD_FUNC(pcap_datalink); - LOAD_FUNC(pcap_next); - LOAD_FUNC(pcap_setnonblock); - LOAD_FUNC(pcap_getnonblock); - LOAD_FUNC(pcap_lookupdev); - LOAD_FUNC(pcap_strerror); - LOAD_FUNC(pcap_geterr); - LOAD_FUNC(pcap_stats); - LOAD_FUNC(pcap_dump_open); - LOAD_FUNC(pcap_dump); - LOAD_FUNC(pcap_dump_flush); - LOAD_FUNC(pcap_dump_ftell); - LOAD_FUNC(pcap_dump_close); - - // handling of commands - while(1) { - int comm = read_int(); - if(comm >= (sizeof(handlers) / sizeof(handlers[0]))) { - - // invalid command number - fprintf(stderr, "Invalid command `%d`\n", comm); - fflush(stderr); - - }else { - // run the command - handlers[comm](); - - // flush, just in case - fflush(stdout); - } - } -} +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////// +// libpcap loaded functions +/////////////////////////////////////////////// + +typedef struct pcap_if { + struct pcap_if* next; + char* name; + char* description; + struct pcap_addr* addresses; + int32_t flags; +} pcap_if_t; + +struct pcap_addr { + struct pcap_addr* next; + struct sockaddr addr; + struct sockaddr netmask; + struct sockaddr broadaddr; + struct sockaddr dstaddr; +}; + +struct pcap_pkthdr { + struct timeval ts; + int32_t caplen; + int32_t len; +}; + +struct pcap_stat { + int32_t ps_recv; + int32_t ps_drop; + int32_t ps_ifdrop; +}; + +typedef void pcap_t; +typedef void pcap_dumper_t; + +static const char* (*pcap_lib_version)(void); +static int (*pcap_findalldevs)(pcap_if_t **alldevsp, char *errbuf); +static void (*pcap_freealldevs)(pcap_if_t *alldevsp); +static pcap_t* (*pcap_open_live)(const char* device, int snaplen, int promisc, int to_ms, char* errbuf); +void (*pcap_close)(pcap_t*p); +int (*pcap_datalink)(pcap_t *p); +char* (*pcap_next)(pcap_t *p, struct pcap_pkthdr *h); +int (*pcap_setnonblock)(pcap_t *p, int nonblock, char *errbuf); +int (*pcap_getnonblock)(pcap_t *p, char *errbuf); +char* (*pcap_lookupdev)(char *errbuf); +char* (*pcap_strerror)(int errno); +char* (*pcap_geterr)(pcap_t *p); +int (*pcap_stats)(pcap_t *p, struct pcap_stat *ps); + +pcap_dumper_t* (*pcap_dump_open)(pcap_t *p, const char *fname); +void (*pcap_dump)(pcap_dumper_t * dumper, const struct pcap_pkthdr *h, const u_char *sp); +int (*pcap_dump_flush)(pcap_dumper_t *p); +long (*pcap_dump_ftell)(pcap_dumper_t *); +void (*pcap_dump_close)(pcap_dumper_t *p); + +/////////////////////////////////////////////// +// stream handling +/////////////////////////////////////////////// + +void write_bool(bool b) { + fwrite(&b, 1, 1, stdout); + fflush(stdout); +} + +int32_t read_int() { + int32_t num = 0; + fread(&num, 4, 1, stdin); + return num; +} + +int64_t read_long() { + int64_t num = 0; + fread(&num, 8, 1, stdin); + return num; +} + +void write_int(int32_t num) { + fwrite(&num, 4, 1, stdout); + fflush(stdout); +} + +void write_long(int64_t num) { + fwrite(&num, 8, 1, stdout); + fflush(stdout); +} + +void write_string(const char* str) { + if(str == NULL) { + write_int(0); + }else { + write_int(strlen(str)); + fwrite(str, strlen(str), 1, stdout); + } + fflush(stdout); +} + +char* read_string() { + int len = read_int(); + char* buf = malloc((size_t) len + 1); + fread(buf, 1, (size_t) len, stdin); + buf[len] = 0; + return buf; +} + +/////////////////////////////////////////////// +// the handler implementations +/////////////////////////////////////////////// + +void comm_pcap_lib_version() { + write_string(pcap_lib_version()); +} + +void comm_pcap_findalldevs() { + pcap_if_t* pifs = NULL; + char buffer[256] = {0}; + + // try to find all interfaces + if(pcap_findalldevs(&pifs, buffer) != 0) { + fprintf(stderr, "errbuf -> %s\n", buffer); + fflush(stderr); + + // go an error + write_bool(false); + write_string(buffer); + + }else { + + // everything is good + write_bool(true); + + // find how many devices there are + int devs_count = 0; + if(pifs != NULL) { + pcap_if_t* cur = pifs; + do { + devs_count++; + } while((cur = cur->next) != NULL); + } + + // iterate and write out the devices + write_int(devs_count); + pcap_if_t* cur = pifs; + while(cur != NULL) { + // write the name and description + write_string(cur->name); + write_string(cur->description); + + // check how many addresses are there + int addr_count = 0; + if(cur->addresses != NULL) { + struct pcap_addr* addr = cur->addresses; + do { + addr_count++; + } while((addr = addr->next) != NULL); + } + + // write the addresses + write_int(addr_count); + struct pcap_addr* addr = cur->addresses; + while(addr != NULL) { + fwrite(addr, sizeof(struct sockaddr) * 4, 1, stdout); + fflush(stdout); + + addr = addr->next; + } + + // write the flags + write_int(cur->flags); + + cur = cur->next; + } + + } + + // free them + pcap_freealldevs(pifs); +} + +void comm_pcap_open_live() { + char buffer[256] = {0}; + + char* device = read_string(); + int spanlen = read_int(); + int promisc = read_int(); + int to_ms = read_int(); + + void* pcap = pcap_open_live(device, spanlen, promisc, to_ms, buffer); + if(pcap == NULL) { + + fprintf(stderr, "errbuf -> %s\n", buffer); + fflush(stderr); + + write_bool(false); + write_string(buffer); + + }else { + + write_bool(true); + write_long((uint64_t)pcap); + + } + + free(device); +} + +void comm_pcap_close() { + void* handle = (void*)read_long(); + pcap_close(handle); +} + +void comm_pcap_datalink() { + void* handle = (void*)read_long(); + write_int(pcap_datalink(handle)); +} + +void comm_pcap_next() { + void* handle = (void*)read_long(); + + struct pcap_pkthdr header; + void* data = pcap_next(handle, &header); + + if(data == NULL) { + write_bool(false); + }else { + write_bool(true); + + write_long(header.ts.tv_sec); + write_long(header.ts.tv_usec); + write_int(header.caplen); + write_int(header.len); + fwrite(data, 1, (size_t) header.caplen, stdout); + fflush(stdout); + } +} + +void comm_pcap_setnonblock() { + char errbuf[256] = {0}; + + void* handle = (void*)read_long(); + int nonblock = read_int(); + + if(pcap_setnonblock(handle, nonblock, errbuf) != 0) { + + write_bool(false); + write_string(errbuf); + + }else { + + write_bool(true); + + } +} + +void comm_pcap_getnonblock() { + char errbuf[256] = {0}; + + void* handle = (void*)read_long(); + int nonblock = pcap_getnonblock(handle, errbuf); + + if(nonblock < 0) { + + write_bool(false); + write_string(errbuf); + + }else { + + write_bool(true); + write_int(nonblock); + + } +} + +void comm_pcap_lookupdev() { + char errbuf[256] = {0}; + + char* device = pcap_lookupdev(errbuf); + + if(device == NULL) { + + write_bool(false); + write_string(errbuf); + + }else { + + write_bool(true); + write_string(device); + + } +} + +void comm_pcap_strerror() { + int error = read_int(); + write_string(pcap_strerror(error)); +} + +void comm_pcap_geterr() { + void* handle = (void*)read_long(); + write_string(pcap_geterr(handle)); +} + +void comm_pcap_stats() { + void* handle = (void*)read_long(); + + struct pcap_stat stats = {0}; + pcap_stats(handle, &stats); + + write_int(stats.ps_recv); + write_int(stats.ps_drop); + write_int(stats.ps_ifdrop); +} + +void comm_pcap_dump_open() { + void* handle = (void*)read_long(); + char* str = read_string(); + void* res = pcap_dump_open(handle, str); + write_long((int64_t) res); + free(str); +} + +void comm_pcap_dump() { + void* handle = (void*)read_long(); + struct pcap_pkthdr header = {0}; + header.ts.tv_sec = (__kernel_time_t) read_long(); + header.ts.tv_usec = (__kernel_time_t) read_long(); + header.caplen = read_int(); + header.len = read_int(); + char* buffer = malloc((size_t) header.len); + fread(buffer, 1, (size_t) header.len, stdin); + pcap_dump(handle, &header, (const u_char *) buffer); + free(buffer); +} + +void comm_pcap_dump_flush() { + void* handle = (void*)read_long(); + int rc = pcap_dump_flush(handle); + if(rc != 0) { + + write_bool(false); + write_string(pcap_strerror(rc)); + + }else { + + write_bool(true); + + } +} + +void comm_pcap_dump_ftell() { + void* handle = (void*)read_long(); + pcap_dump_close(handle); +} + +void comm_pcap_dump_close() { + void* handle = (void*)read_long(); + pcap_dump_close(handle); +} + +/////////////////////////////////////////////// +// Server main +/////////////////////////////////////////////// + +// function constatns +#define PCAP_LIB_VERSION 1 +#define PCAP_FINDALLDEVS 2 +#define PCAP_OPEN_LIVE 3 +#define PCAP_CLOSE 4 +#define PCAP_DATALINK 5 +#define PCAP_NEXT 6 +#define PCAP_SETNONBLOCK 7 +#define PCAP_GETNONBLOCK 8 +#define PCAP_LOOKUPDEV 9 +#define PCAP_STRERROR 10 +#define PCAP_GETERR 11 +#define PCAP_STATS 12 +#define PCAP_DUMP_OPEN 13 +#define PCAP_DUMP 14 +#define PCAP_DUMP_FLUSH 15 +#define PCAP_DUMP_FTELL 16 +#define PCAP_DUMP_CLOSE 17 + +// handlers per function +typedef void (*command_handler_t)(); +command_handler_t handlers[] = { + [PCAP_LIB_VERSION] = comm_pcap_lib_version, + [PCAP_FINDALLDEVS] = comm_pcap_findalldevs, + [PCAP_OPEN_LIVE] = comm_pcap_open_live, + [PCAP_CLOSE] = comm_pcap_close, + [PCAP_DATALINK] = comm_pcap_datalink, + [PCAP_NEXT] = comm_pcap_next, + [PCAP_SETNONBLOCK] = comm_pcap_setnonblock, + [PCAP_GETNONBLOCK] = comm_pcap_getnonblock, + [PCAP_LOOKUPDEV] = comm_pcap_lookupdev, + [PCAP_STRERROR] = comm_pcap_strerror, + [PCAP_GETERR] = comm_pcap_geterr, + [PCAP_STATS] = comm_pcap_stats, + [PCAP_DUMP_OPEN] = comm_pcap_dump_open, + [PCAP_DUMP] = comm_pcap_dump, + [PCAP_DUMP_FLUSH] = comm_pcap_dump_flush, + [PCAP_DUMP_FTELL] = comm_pcap_dump_ftell, + [PCAP_DUMP_CLOSE] = comm_pcap_dump_close, +}; + +#define LOAD_FUNC(name) \ + do { \ + name = dlsym(handle, #name); \ + if(name == NULL) { \ + fprintf(stderr, "Failed to get function %s - %s\n", #name, dlerror()); \ + return -1; \ + } \ + } while(0) + +/* + * This is called + */ +int main(int argc, char* argv[]) { + fprintf(stderr, "pcap proxy process main\n"); + + // attempt to open libpcap + void* handle = dlopen("libpcap.so", RTLD_LAZY); + if(handle == NULL) { + fprintf(stderr, "Failed to open libpcap.so - %s\n", dlerror()); + fflush(stderr); + return -1; + } + + // load all the functions + LOAD_FUNC(pcap_lib_version); + LOAD_FUNC(pcap_findalldevs); + LOAD_FUNC(pcap_freealldevs); + LOAD_FUNC(pcap_open_live); + LOAD_FUNC(pcap_close); + LOAD_FUNC(pcap_datalink); + LOAD_FUNC(pcap_next); + LOAD_FUNC(pcap_setnonblock); + LOAD_FUNC(pcap_getnonblock); + LOAD_FUNC(pcap_lookupdev); + LOAD_FUNC(pcap_strerror); + LOAD_FUNC(pcap_geterr); + LOAD_FUNC(pcap_stats); + LOAD_FUNC(pcap_dump_open); + LOAD_FUNC(pcap_dump); + LOAD_FUNC(pcap_dump_flush); + LOAD_FUNC(pcap_dump_ftell); + LOAD_FUNC(pcap_dump_close); + + // handling of commands + while(1) { + int comm = read_int(); + if(comm >= (sizeof(handlers) / sizeof(handlers[0]))) { + + // invalid command number + fprintf(stderr, "Invalid command `%d`\n", comm); + fflush(stderr); + + }else { + // run the command + handlers[comm](); + + // flush, just in case + fflush(stdout); + } + } +} diff --git a/app/src/main/java/me/itay/packetmanipulator/ColorEngine.java b/app/src/main/java/me/itay/packetmanipulator/ColorEngine.java index df84b36..093e059 100644 --- a/app/src/main/java/me/itay/packetmanipulator/ColorEngine.java +++ b/app/src/main/java/me/itay/packetmanipulator/ColorEngine.java @@ -1,116 +1,116 @@ -package me.itay.packetmanipulator; - -import android.graphics.Color; - -import org.pcap4j.packet.ArpPacket; -import org.pcap4j.packet.EthernetPacket; -import org.pcap4j.packet.IcmpV4CommonPacket; -import org.pcap4j.packet.IcmpV6CommonPacket; -import org.pcap4j.packet.Packet; -import org.pcap4j.packet.TcpPacket; -import org.pcap4j.packet.UdpPacket; -import org.pcap4j.packet.namednumber.IcmpV4Type; -import org.pcap4j.packet.namednumber.IcmpV6Type; -import org.pcap4j.util.MacAddress; - -import me.itay.packetmanipulator.display.PacketEntry; - -public class ColorEngine { - - // TODO: in the future adding a wireshark expression - // parser and executer will go a long way, since - // it will allow us to take the same rules wireshark - // has. in the meanwhile it is pretty much hard coded - - public static void color(PacketEntry entry) { - Packet packet = entry.original; - - ////////////////// - // Broadcast - ////////////////// - if(packet.contains(EthernetPacket.class)) { - EthernetPacket.EthernetHeader header = packet.get(EthernetPacket.class).getHeader(); - if((header.getDstAddr().getAddress()[0] & 1) != 0 || - (header.getSrcAddr().getAddress()[0] & 1) != 0) { - entry.textColor = Color.parseColor("#babdb6"); - } - } - - ////////////////// - // UDP - ////////////////// - if(packet.contains(UdpPacket.class)) { - entry.backgroundColor = Color.parseColor("#daeeff"); - entry.textColor = Color.parseColor("#12272e"); - } - - if(packet.contains(TcpPacket.class)) { - TcpPacket.TcpHeader header = packet.get(TcpPacket.class).getHeader(); - - ////////////////// - // TCP RST - ////////////////// - if(header.getRst()) { - entry.backgroundColor = Color.parseColor("#a40000"); - entry.textColor = Color.parseColor("#fffc9c"); - - ////////////////// - // TCP SYN/FIN - ////////////////// - } else if(header.getSyn() || header.getFin()) { - entry.backgroundColor = Color.parseColor("#a0a0a0"); - entry.textColor = Color.parseColor("#12272e"); - - ////////////////// - // TCP - ////////////////// - }else { - entry.backgroundColor = Color.parseColor("#e7e6ff"); - entry.textColor = Color.parseColor("#12272e"); - } - } - - ////////////////// - // ARP - ////////////////// - if(packet.contains(ArpPacket.class)) { - entry.backgroundColor = Color.parseColor("#faf0d7"); - entry.textColor = Color.parseColor("#12272e"); - } - - ////////////////// - // ICMP errors - ////////////////// - - if(packet.contains(IcmpV4CommonPacket.class)) { - IcmpV4CommonPacket.IcmpV4CommonHeader header = packet.get(IcmpV4CommonPacket.class).getHeader(); - - if(header.getType() == IcmpV4Type.DESTINATION_UNREACHABLE || - header.getType() == IcmpV4Type.SOURCE_QUENCH || - header.getType() == IcmpV4Type.REDIRECT || - header.getType() == IcmpV4Type.TIME_EXCEEDED) { - entry.backgroundColor = Color.parseColor("#fce0ff"); - entry.textColor = Color.parseColor("#b7f774"); - }else { - entry.backgroundColor = Color.parseColor("#fce0ff"); - entry.textColor = Color.parseColor("#12272e"); - } - } - - if(packet.contains(IcmpV6CommonPacket.class)) { - IcmpV6CommonPacket.IcmpV6CommonHeader header = packet.get(IcmpV6CommonPacket.class).getHeader(); - - if(header.getType() == IcmpV6Type.DESTINATION_UNREACHABLE || - header.getType() == IcmpV6Type.PACKET_TOO_BIG || - header.getType() == IcmpV6Type.TIME_EXCEEDED || - header.getType() == IcmpV6Type.PARAMETER_PROBLEM) { - entry.backgroundColor = Color.parseColor("#fce0ff"); - entry.textColor = Color.parseColor("#b7f774"); - }else { - entry.backgroundColor = Color.parseColor("#fce0ff"); - entry.textColor = Color.parseColor("#12272e"); - } - } - } - -} +package me.itay.packetmanipulator; + +import android.graphics.Color; + +import org.pcap4j.packet.ArpPacket; +import org.pcap4j.packet.EthernetPacket; +import org.pcap4j.packet.IcmpV4CommonPacket; +import org.pcap4j.packet.IcmpV6CommonPacket; +import org.pcap4j.packet.Packet; +import org.pcap4j.packet.TcpPacket; +import org.pcap4j.packet.UdpPacket; +import org.pcap4j.packet.namednumber.IcmpV4Type; +import org.pcap4j.packet.namednumber.IcmpV6Type; +import org.pcap4j.util.MacAddress; + +import me.itay.packetmanipulator.display.PacketEntry; + +public class ColorEngine { + + // TODO: in the future adding a wireshark expression + // parser and executer will go a long way, since + // it will allow us to take the same rules wireshark + // has. in the meanwhile it is pretty much hard coded + + public static void color(PacketEntry entry) { + Packet packet = entry.original; + + ////////////////// + // Broadcast + ////////////////// + if(packet.contains(EthernetPacket.class)) { + EthernetPacket.EthernetHeader header = packet.get(EthernetPacket.class).getHeader(); + if((header.getDstAddr().getAddress()[0] & 1) != 0 || + (header.getSrcAddr().getAddress()[0] & 1) != 0) { + entry.textColor = Color.parseColor("#babdb6"); + } + } + + ////////////////// + // UDP + ////////////////// + if(packet.contains(UdpPacket.class)) { + entry.backgroundColor = Color.parseColor("#daeeff"); + entry.textColor = Color.parseColor("#12272e"); + } + + if(packet.contains(TcpPacket.class)) { + TcpPacket.TcpHeader header = packet.get(TcpPacket.class).getHeader(); + + ////////////////// + // TCP RST + ////////////////// + if(header.getRst()) { + entry.backgroundColor = Color.parseColor("#a40000"); + entry.textColor = Color.parseColor("#fffc9c"); + + ////////////////// + // TCP SYN/FIN + ////////////////// + } else if(header.getSyn() || header.getFin()) { + entry.backgroundColor = Color.parseColor("#a0a0a0"); + entry.textColor = Color.parseColor("#12272e"); + + ////////////////// + // TCP + ////////////////// + }else { + entry.backgroundColor = Color.parseColor("#e7e6ff"); + entry.textColor = Color.parseColor("#12272e"); + } + } + + ////////////////// + // ARP + ////////////////// + if(packet.contains(ArpPacket.class)) { + entry.backgroundColor = Color.parseColor("#faf0d7"); + entry.textColor = Color.parseColor("#12272e"); + } + + ////////////////// + // ICMP errors + ////////////////// + + if(packet.contains(IcmpV4CommonPacket.class)) { + IcmpV4CommonPacket.IcmpV4CommonHeader header = packet.get(IcmpV4CommonPacket.class).getHeader(); + + if(header.getType() == IcmpV4Type.DESTINATION_UNREACHABLE || + header.getType() == IcmpV4Type.SOURCE_QUENCH || + header.getType() == IcmpV4Type.REDIRECT || + header.getType() == IcmpV4Type.TIME_EXCEEDED) { + entry.backgroundColor = Color.parseColor("#12272e"); + entry.textColor = Color.parseColor("#b7f774"); + }else { + entry.backgroundColor = Color.parseColor("#fce0ff"); + entry.textColor = Color.parseColor("#12272e"); + } + } + + if(packet.contains(IcmpV6CommonPacket.class)) { + IcmpV6CommonPacket.IcmpV6CommonHeader header = packet.get(IcmpV6CommonPacket.class).getHeader(); + + if(header.getType() == IcmpV6Type.DESTINATION_UNREACHABLE || + header.getType() == IcmpV6Type.PACKET_TOO_BIG || + header.getType() == IcmpV6Type.TIME_EXCEEDED || + header.getType() == IcmpV6Type.PARAMETER_PROBLEM) { + entry.backgroundColor = Color.parseColor("#12272e"); + entry.textColor = Color.parseColor("#b7f774"); + }else { + entry.backgroundColor = Color.parseColor("#fce0ff"); + entry.textColor = Color.parseColor("#12272e"); + } + } + } + +} diff --git a/app/src/main/java/me/itay/packetmanipulator/ErrorActivity.java b/app/src/main/java/me/itay/packetmanipulator/ErrorActivity.java index e370d4b..f660e2e 100644 --- a/app/src/main/java/me/itay/packetmanipulator/ErrorActivity.java +++ b/app/src/main/java/me/itay/packetmanipulator/ErrorActivity.java @@ -1,22 +1,22 @@ -package me.itay.packetmanipulator; - -import androidx.appcompat.app.AppCompatActivity; - -import android.os.Bundle; -import android.widget.TextView; - -public class ErrorActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_error); - - // get the controls - TextView txtError = findViewById(R.id.lblError); - - // get the error and set it - String errorString = getIntent().getStringExtra("EXTRA_ERROR_STRING"); - txtError.setText(errorString); - } -} +package me.itay.packetmanipulator; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; +import android.widget.TextView; + +public class ErrorActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_error); + + // get the controls + TextView txtError = findViewById(R.id.lblError); + + // get the error and set it + String errorString = getIntent().getStringExtra("EXTRA_ERROR_STRING"); + txtError.setText(errorString); + } +} diff --git a/app/src/main/java/me/itay/packetmanipulator/MainActivity.java b/app/src/main/java/me/itay/packetmanipulator/MainActivity.java index b8780c2..7bc4379 100644 --- a/app/src/main/java/me/itay/packetmanipulator/MainActivity.java +++ b/app/src/main/java/me/itay/packetmanipulator/MainActivity.java @@ -1,95 +1,94 @@ -package me.itay.packetmanipulator; - -import androidx.appcompat.app.AppCompatActivity; -import me.itay.pcapproxy.PcapProxy; - -import android.annotation.SuppressLint; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.Spinner; - -import com.stericson.RootTools.RootTools; - -import org.pcap4j.core.PcapNetworkInterface; -import org.pcap4j.core.Pcaps; - -import java.net.NetworkInterface; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - -public class MainActivity extends AppCompatActivity { - - public static final String TAG = "MainActivity"; - - @SuppressLint("SetTextI18n") - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // get the controls of the current layout - Spinner spnrInterface = findViewById(R.id.spnrInterface); - Button btnStartSniffer = findViewById(R.id.btnStartSniffer); - - // check we have root - if(!RootTools.isRootAvailable() || !RootTools.isAccessGiven()) { - - Intent intent = new Intent(this, ErrorActivity.class); - intent.putExtra("EXTRA_ERROR_STRING", "This app requires root in order to run!"); - startActivity(intent); - finish(); - - // we have root! - }else { - - // initialize the pcap proxy - try { - PcapProxy.init(this); - }catch(Exception e) { - e.printStackTrace(); - Intent intent = new Intent(this, ErrorActivity.class); - intent.putExtra("EXTRA_ERROR_STRING", e.getMessage()); - startActivity(intent); - finish(); - } - - List pifs = Pcaps.findAllDevs(); - List interfaceNames = new ArrayList<>(); - for(PcapNetworkInterface pif : Pcaps.findAllDevs()) { - StringBuilder sb = new StringBuilder(); - - sb.append(pif.getName()); - - if(pif.getDescription() != null) { - sb.append(" ("); - sb.append(pif.getDescription()); - sb.append(")"); - } - - interfaceNames.add(sb.toString()); - } - - // add them to the spinner so the user can choose - ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, interfaceNames); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spnrInterface.setAdapter(adapter); - - - // on button click send us to the SnifferActivity - btnStartSniffer.setOnClickListener((view) -> { - - // get the interface and send it to the sniffer - PcapNetworkInterface networkInterface = pifs.get(spnrInterface.getSelectedItemPosition()); - Intent intent = new Intent(this, SnifferActivity.class); - intent.putExtra("INTERFACE_NAME", networkInterface.getName()); - startActivity(intent); - finish(); - }); - } - } - -} +package me.itay.packetmanipulator; + +import androidx.appcompat.app.AppCompatActivity; +import me.itay.pcapproxy.PcapProxy; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.Spinner; + +import com.stericson.RootTools.RootTools; + +import org.pcap4j.core.PcapNetworkInterface; +import org.pcap4j.core.Pcaps; + +import java.net.NetworkInterface; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +public class MainActivity extends AppCompatActivity { + + public static final String TAG = "MainActivity"; + + @SuppressLint("SetTextI18n") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + // get the controls of the current layout + Spinner spnrInterface = findViewById(R.id.spnrInterface); + Button btnStartSniffer = findViewById(R.id.btnStartSniffer); + + // check we have root + if(!RootTools.isRootAvailable() || !RootTools.isAccessGiven()) { + + Intent intent = new Intent(this, ErrorActivity.class); + intent.putExtra("EXTRA_ERROR_STRING", "This app requires root in order to run!"); + startActivity(intent); + finish(); + + // we have root! + }else { + + // initialize the pcap proxy + try { + PcapProxy.init(this); + }catch(Exception e) { + e.printStackTrace(); + Intent intent = new Intent(this, ErrorActivity.class); + intent.putExtra("EXTRA_ERROR_STRING", e.getMessage()); + startActivity(intent); + finish(); + } + + List pifs = Pcaps.findAllDevs(); + List interfaceNames = new ArrayList<>(); + for(PcapNetworkInterface pif : Pcaps.findAllDevs()) { + StringBuilder sb = new StringBuilder(); + + sb.append(pif.getName()); + + if(pif.getDescription() != null) { + sb.append(" ("); + sb.append(pif.getDescription()); + sb.append(")"); + } + + interfaceNames.add(sb.toString()); + } + + // add them to the spinner so the user can choose + ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, interfaceNames); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spnrInterface.setAdapter(adapter); + + + // on button click send us to the SnifferActivity + btnStartSniffer.setOnClickListener((view) -> { + + // get the interface and send it to the sniffer + PcapNetworkInterface networkInterface = pifs.get(spnrInterface.getSelectedItemPosition()); + Intent intent = new Intent(this, SnifferActivity.class); + intent.putExtra("INTERFACE_NAME", networkInterface.getName()); + startActivity(intent); + }); + } + } + +} diff --git a/app/src/main/java/me/itay/packetmanipulator/OnClick.java b/app/src/main/java/me/itay/packetmanipulator/OnClick.java index e6bc073..71c3728 100644 --- a/app/src/main/java/me/itay/packetmanipulator/OnClick.java +++ b/app/src/main/java/me/itay/packetmanipulator/OnClick.java @@ -1,7 +1,7 @@ -package me.itay.packetmanipulator; - -public interface OnClick { - - void click(T t); - -} +package me.itay.packetmanipulator; + +public interface OnClick { + + void click(T t); + +} diff --git a/app/src/main/java/me/itay/packetmanipulator/PacketInfoBottomSheet.java b/app/src/main/java/me/itay/packetmanipulator/PacketInfoBottomSheet.java index 703468d..fbeafac 100644 --- a/app/src/main/java/me/itay/packetmanipulator/PacketInfoBottomSheet.java +++ b/app/src/main/java/me/itay/packetmanipulator/PacketInfoBottomSheet.java @@ -1,35 +1,35 @@ -package me.itay.packetmanipulator; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -public class PacketInfoBottomSheet extends BottomSheetDialogFragment { - - private final String text; - private TextView lblPacketInfo; - - public PacketInfoBottomSheet(String text) { - this.text = text; - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.sniffer_packet_info_bottom_sheet, container, false); - - lblPacketInfo = v.findViewById(R.id.lblPacketInfo); - lblPacketInfo.setText(text); - - return v; - } - -} +package me.itay.packetmanipulator; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public class PacketInfoBottomSheet extends BottomSheetDialogFragment { + + private final String text; + private TextView lblPacketInfo; + + public PacketInfoBottomSheet(String text) { + this.text = text; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.sniffer_packet_info_bottom_sheet, container, false); + + lblPacketInfo = v.findViewById(R.id.lblPacketInfo); + lblPacketInfo.setText(text); + + return v; + } + +} diff --git a/app/src/main/java/me/itay/packetmanipulator/RecyclerPacketsAdapter.java b/app/src/main/java/me/itay/packetmanipulator/RecyclerPacketsAdapter.java index 7edf9f6..a53ff15 100644 --- a/app/src/main/java/me/itay/packetmanipulator/RecyclerPacketsAdapter.java +++ b/app/src/main/java/me/itay/packetmanipulator/RecyclerPacketsAdapter.java @@ -1,96 +1,96 @@ -package me.itay.packetmanipulator; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; -import me.itay.packetmanipulator.display.PacketEntry; - -public class RecyclerPacketsAdapter extends RecyclerView.Adapter { - - private final List entries = new ArrayList<>(); - private final OnClick onclick; - - public RecyclerPacketsAdapter(OnClick onclick) { - this.onclick = onclick; - } - - public void add(PacketEntry entry) { - synchronized (entries) { - entries.add(entry); - } - } - - public PacketEntry get(int position) { - synchronized (entries) { - return entries.get(position); - } - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.packet_table_entry, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - PacketEntry entry; - synchronized (entries) { - entry = entries.get(position); - } - - holder.lblSource.setText(entry.source); - holder.lblDestination.setText(entry.destination); - holder.lblProtocol.setText(entry.protocol); - holder.lblInfo.setText(entry.info); - - holder.lblSource.setTextColor(entry.textColor); - holder.lblDestination.setTextColor(entry.textColor); - holder.lblProtocol.setTextColor(entry.textColor); - holder.lblInfo.setTextColor(entry.textColor); - - holder.container.setBackgroundColor(entry.backgroundColor); - holder.container.setOnClickListener((view) -> { - if(onclick != null) { - onclick.click(get(position)); - } - }); - } - - @Override - public int getItemCount() { - synchronized (entries) { - return entries.size(); - } - } - - public class ViewHolder extends RecyclerView.ViewHolder { - - public final TextView lblSource; - public final TextView lblDestination; - public final TextView lblProtocol; - public final TextView lblInfo; - - public final View container; - - public ViewHolder(@NonNull View itemView) { - super(itemView); - - this.lblSource = itemView.findViewById(R.id.lblSource); - this.lblDestination = itemView.findViewById(R.id.lblDestination); - this.lblProtocol = itemView.findViewById(R.id.lblProtocol); - this.lblInfo = itemView.findViewById(R.id.lblInfo); - this.container = itemView.findViewById(R.id.container); - } - } - -} +package me.itay.packetmanipulator; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import me.itay.packetmanipulator.display.PacketEntry; + +public class RecyclerPacketsAdapter extends RecyclerView.Adapter { + + private final List entries = new ArrayList<>(); + private final OnClick onclick; + + public RecyclerPacketsAdapter(OnClick onclick) { + this.onclick = onclick; + } + + public void add(PacketEntry entry) { + synchronized (entries) { + entries.add(entry); + } + } + + public PacketEntry get(int position) { + synchronized (entries) { + return entries.get(position); + } + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.packet_table_entry, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + PacketEntry entry; + synchronized (entries) { + entry = entries.get(position); + } + + holder.lblSource.setText(entry.source); + holder.lblDestination.setText(entry.destination); + holder.lblProtocol.setText(entry.protocol); + holder.lblInfo.setText(entry.info); + + holder.lblSource.setTextColor(entry.textColor); + holder.lblDestination.setTextColor(entry.textColor); + holder.lblProtocol.setTextColor(entry.textColor); + holder.lblInfo.setTextColor(entry.textColor); + + holder.container.setBackgroundColor(entry.backgroundColor); + holder.container.setOnClickListener((view) -> { + if(onclick != null) { + onclick.click(get(position)); + } + }); + } + + @Override + public int getItemCount() { + synchronized (entries) { + return entries.size(); + } + } + + public class ViewHolder extends RecyclerView.ViewHolder { + + public final TextView lblSource; + public final TextView lblDestination; + public final TextView lblProtocol; + public final TextView lblInfo; + + public final View container; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + + this.lblSource = itemView.findViewById(R.id.lblSource); + this.lblDestination = itemView.findViewById(R.id.lblDestination); + this.lblProtocol = itemView.findViewById(R.id.lblProtocol); + this.lblInfo = itemView.findViewById(R.id.lblInfo); + this.container = itemView.findViewById(R.id.container); + } + } + +} diff --git a/app/src/main/java/me/itay/packetmanipulator/SnifferActivity.java b/app/src/main/java/me/itay/packetmanipulator/SnifferActivity.java index 11623cf..b7b68e5 100644 --- a/app/src/main/java/me/itay/packetmanipulator/SnifferActivity.java +++ b/app/src/main/java/me/itay/packetmanipulator/SnifferActivity.java @@ -1,212 +1,354 @@ -package me.itay.packetmanipulator; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.ActionBarDrawerToggle; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; -import androidx.core.view.GravityCompat; -import androidx.drawerlayout.widget.DrawerLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import me.itay.packetmanipulator.display.PacketEntry; -import me.itay.packetmanipulator.display.PacketDissector; - -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; - -import com.google.android.material.navigation.NavigationView; - -import org.pcap4j.core.NotOpenException; -import org.pcap4j.core.PcapHandle; -import org.pcap4j.core.PcapNetworkInterface; -import org.pcap4j.core.Pcaps; -import org.pcap4j.packet.IcmpV4CommonPacket; -import org.pcap4j.packet.Packet; - -import java.io.IOException; -import java.util.concurrent.ConcurrentLinkedQueue; - -public class SnifferActivity extends AppCompatActivity implements Runnable, NavigationView.OnNavigationItemSelectedListener { - - private static final String TAG = "SnifferActivity"; - - private PcapNetworkInterface pif; - private PcapHandle handle; - private boolean autoScroll = true; - - private Thread captureThread; - private ConcurrentLinkedQueue packets = new ConcurrentLinkedQueue<>(); - - private Toolbar toolbar; - private DrawerLayout drawer; - private NavigationView optionsView; - private TextView lblInterfaceName; - private TextView lblInterfaceDescription; - - private Button btnSetFilter; - private EditText txtFilterExpression; - private RecyclerView recyclerPackets; - private RecyclerPacketsAdapter adapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // set layout and get controls - setContentView(R.layout.sniffer_activity); - - ///////////////////////////////////////////////////////////////// - // get the controls - ///////////////////////////////////////////////////////////////// - toolbar = findViewById(R.id.toolbar); - drawer = findViewById(R.id.sniffer_drawer); - optionsView = findViewById(R.id.options_view); - setSupportActionBar(toolbar); - - View headerView = optionsView.getHeaderView(0); - lblInterfaceName = headerView.findViewById(R.id.lblInterfaceName); - lblInterfaceDescription = headerView.findViewById(R.id.lblInterfaceDescription); - optionsView.setNavigationItemSelectedListener(this); - optionsView.setCheckedItem(R.id.option_auto_scroll); - - btnSetFilter = findViewById(R.id.btnSetFilter); - txtFilterExpression = findViewById(R.id.txtFilterExpression); - recyclerPackets = findViewById(R.id.recyclerPackets); - adapter = new RecyclerPacketsAdapter((entry) -> { - new PacketInfoBottomSheet(entry.original.toString()).show(getSupportFragmentManager(), TAG); - }); - recyclerPackets.setAdapter(adapter); - recyclerPackets.setLayoutManager(new LinearLayoutManager(this)); - - ///////////////////////////////////////////////////////////////// - // get the device - ///////////////////////////////////////////////////////////////// - String pifName = getIntent().getStringExtra("INTERFACE_NAME"); - pif = Pcaps.getDevByName(pifName); - assert pif != null; - Log.d(TAG, pif.toString()); - - // attempt to open a live capture - // TODO: Pass PROMISCOUS in an extra of the intent - handle = pif.openLive(1500, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 0); - Log.d(TAG, handle.toString()); - - // start the capturing thread - captureThread = new Thread(this, "SnifferActivityCapture"); - captureThread.start(); - - ///////////////////////////////////////////////////////////////// - // finish setting the layout - ///////////////////////////////////////////////////////////////// - - // set the interface info - lblInterfaceName.setText(String.format("%s (%s)", pif.getName(), handle.getDlt().name())); - if(pif.getDescription() != null) { - lblInterfaceDescription.setText(pif.getDescription()); - }else { - lblInterfaceDescription.setText("No description"); - } - } - - @Override - public void run() { - while(true) { - try { - // get a packet and create the entry - Packet packet = handle.getNextPacket(); - PacketEntry entry = new PacketEntry(); - entry.original = packet; - entry.protocol = packet.getClass().toString(); - entry.info = packet.toString(); - - // transform it if possible - Packet current = packet; - while(current != null) { - if(current instanceof PacketDissector) { - if(((PacketDissector) current).dissect(entry)) { - break; - } - } - current = current.getPayload(); - } - - ColorEngine.color(entry); - - // add to adapter - adapter.add(entry); - recyclerPackets.post(() -> { - adapter.notifyDataSetChanged(); - - if(autoScroll) { - recyclerPackets.scrollToPosition(adapter.getItemCount() - 1); - } - }); - } catch (NotOpenException e) { - e.printStackTrace(); - } - } - } - - - - @Override - protected void onDestroy() { - super.onDestroy(); - - try { - handle.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { - switch(menuItem.getItemId()) { - - case R.id.option_save: - if(handle.isOpen()) { - Toast.makeText(this, "Can not save capture while running", Toast.LENGTH_LONG).show(); - }else { - - } - break; - - case R.id.option_auto_scroll: - autoScroll = !autoScroll; - menuItem.setChecked(autoScroll); - break; - - case R.id.option_go_to_first: - recyclerPackets.scrollToPosition(0); - break; - - case R.id.option_go_to_last: - recyclerPackets.scrollToPosition(adapter.getItemCount() - 1); - break; - - default: - return false; - } - - drawer.closeDrawer(GravityCompat.END); - return true; - } - - @Override - public void onBackPressed() { - if(drawer.isDrawerOpen(GravityCompat.END)) { - drawer.closeDrawer(GravityCompat.END); - }else { - super.onBackPressed(); - } - } -} +package me.itay.packetmanipulator; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import me.itay.packetmanipulator.display.PacketEntry; +import me.itay.packetmanipulator.display.PacketDissector; +import me.itay.pcapproxy.PcapProxy; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Looper; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.material.navigation.NavigationView; + +import org.pcap4j.core.NotOpenException; +import org.pcap4j.core.PcapDumper; +import org.pcap4j.core.PcapHandle; +import org.pcap4j.core.PcapNetworkInterface; +import org.pcap4j.core.Pcaps; +import org.pcap4j.packet.IcmpV4CommonPacket; +import org.pcap4j.packet.Packet; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.ConcurrentLinkedQueue; + +public class SnifferActivity extends AppCompatActivity implements Runnable, NavigationView.OnNavigationItemSelectedListener { + + private static final String TAG = "SnifferActivity"; + + private PcapNetworkInterface pif; + private PcapHandle handle; + private boolean autoScroll = true; + + private Thread captureThread; + private ConcurrentLinkedQueue packets = new ConcurrentLinkedQueue<>(); + + private Toolbar toolbar; + private DrawerLayout drawer; + private NavigationView optionsView; + private TextView lblInterfaceName; + private TextView lblInterfaceDescription; + + private Button btnSetFilter; + private EditText txtFilterExpression; + private RecyclerView recyclerPackets; + private RecyclerPacketsAdapter adapter; + + private boolean running = true; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // set layout and get controls + setContentView(R.layout.sniffer_activity); + + ///////////////////////////////////////////////////////////////// + // get the controls + ///////////////////////////////////////////////////////////////// + toolbar = findViewById(R.id.toolbar); + drawer = findViewById(R.id.sniffer_drawer); + optionsView = findViewById(R.id.options_view); + setSupportActionBar(toolbar); + + View headerView = optionsView.getHeaderView(0); + lblInterfaceName = headerView.findViewById(R.id.lblInterfaceName); + lblInterfaceDescription = headerView.findViewById(R.id.lblInterfaceDescription); + optionsView.setNavigationItemSelectedListener(this); + optionsView.setCheckedItem(R.id.option_auto_scroll); + + btnSetFilter = findViewById(R.id.btnSetFilter); + txtFilterExpression = findViewById(R.id.txtFilterExpression); + recyclerPackets = findViewById(R.id.recyclerPackets); + adapter = new RecyclerPacketsAdapter((entry) -> { + new PacketInfoBottomSheet(entry.original.toString()).show(getSupportFragmentManager(), TAG); + }); + recyclerPackets.setAdapter(adapter); + recyclerPackets.setLayoutManager(new LinearLayoutManager(this)); + + ///////////////////////////////////////////////////////////////// + // get the device + ///////////////////////////////////////////////////////////////// + String pifName = getIntent().getStringExtra("INTERFACE_NAME"); + pif = Pcaps.getDevByName(pifName); + assert pif != null; + Log.d(TAG, pif.toString()); + + // attempt to open a live capture + // TODO: Pass PROMISCOUS in an extra of the intent + handle = pif.openLive(1500, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 0); + Log.d(TAG, handle.toString()); + + // start the capturing thread + captureThread = new Thread(this, "SnifferActivityCapture"); + captureThread.start(); + + ///////////////////////////////////////////////////////////////// + // finish setting the layout + ///////////////////////////////////////////////////////////////// + + // set the interface info + lblInterfaceName.setText(String.format("%s (%s)", pif.getName(), handle.getDlt().name())); + if(pif.getDescription() != null) { + lblInterfaceDescription.setText(pif.getDescription()); + }else { + lblInterfaceDescription.setText("No description"); + } + + // make sure only the needed menu buttons are visible + updateMenu(); + } + + private void updateMenu() { + optionsView.getMenu().findItem(R.id.option_stop).setVisible(running); + optionsView.getMenu().findItem(R.id.option_start).setVisible(!running); + optionsView.getMenu().findItem(R.id.option_save).setVisible(!running); + } + + @Override + public void run() { + while(running) { + try { + // get a packet + Packet packet = handle.getNextPacket(); + + // have this check just in case we were in the middle + // of the get while taking the packet + if(!running) { + return; + } + + // create the entry + PacketEntry entry = new PacketEntry(); + entry.original = packet; + entry.protocol = packet.getClass().toString(); + entry.info = packet.toString(); + + // transform it if possible + Packet current = packet; + while(current != null) { + if(current instanceof PacketDissector) { + if(((PacketDissector) current).dissect(entry)) { + break; + } + } + current = current.getPayload(); + } + + ColorEngine.color(entry); + + // add to adapter + adapter.add(entry); + recyclerPackets.post(() -> { + adapter.notifyDataSetChanged(); + + if(autoScroll) { + recyclerPackets.scrollToPosition(adapter.getItemCount() - 1); + } + }); + } catch (NotOpenException e) { + e.printStackTrace(); + } + } + } + + + + @Override + protected void onDestroy() { + super.onDestroy(); + + stopCapture(); + } + + @SuppressLint("SimpleDateFormat") + private String getFilename() { + String path = Environment.getExternalStorageDirectory().getPath() + File.separator + "pcaps" + File.separator; + File folder = new File(path); + boolean success = true; + if (!folder.exists()) { + success = folder.mkdirs(); + } + if (success) { + return path + pif.getName() + "_" + new SimpleDateFormat("yyyy-MM-dd_hh-mm-ss").format(new Date()) + ".pcap"; + } else { + Log.e(TAG, "Failed to create directory!"); + return null; + } + } + + private void stopCapture() { + running = false; + + // if the capture thread is alive need to stop it + if(captureThread.isAlive()) { + try { + // we are going to try and wait a second for it to exit + Log.i(TAG, "Waiting a second for the capture to finish"); + captureThread.join(1000); + + // the thread is still alive, hard stop it by interrupting and + // and restart the pcapproxy (we might have interrupted the thread + // in the middle of function call which means the stream is in + // unknown context) + if(captureThread.isAlive()) { + Log.w(TAG, "Failed to wait, killing"); + captureThread.interrupt(); + PcapProxy.init(this); + }else { + handle.close(); + } + } catch (InterruptedException | IOException e) { + e.printStackTrace(); + } + } + + } + + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { + switch(menuItem.getItemId()) { + + case R.id.option_save: + // only allow to save when stopped + if(running) { + Toast.makeText(this, "Can not save capture while running", Toast.LENGTH_LONG).show(); + }else { + // TODO: Show a progress dialog instead + Toast.makeText(this, "Please wait while we are saving the capture", Toast.LENGTH_LONG).show(); + + try { + // open a dumper + String filename = getFilename(); + PcapDumper dumper = handle.dumpOpen(filename); + + // do it in the background + new Thread(() -> { + int lastP = 0; + try { + Log.d(TAG, "Starting save"); + + // just go over the packets and add them + for(int i = 0; i < adapter.getItemCount(); i++) { + PacketEntry entry = adapter.get(i); + dumper.dump(entry.original); + + if((i * 100) / adapter.getItemCount() > lastP) { + // flush every 1% just in case + dumper.flush(); + } + } + + } catch (NotOpenException e) { + e.printStackTrace(); + } + + dumper.close(); + + // set the path in the clipboard + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("Capture Path", filename); + assert clipboard != null; + clipboard.setPrimaryClip(clip); + + // finished! + Looper.prepare(); + Toast.makeText(this, String.format("Saved! Path copied to clipboard"), Toast.LENGTH_LONG).show(); + }, "CaptureSave").start(); + + } catch (NotOpenException e) { + e.printStackTrace(); + } + } + break; + + case R.id.option_close: + stopCapture(); + finish(); + break; + + case R.id.option_start: + running = true; + updateMenu(); + + // if the thread is dead wake it up + if(!captureThread.isAlive()) { + captureThread.start(); + } + + break; + + case R.id.option_stop: + // soft stop + running = false; + updateMenu(); + break; + + case R.id.option_auto_scroll: + autoScroll = !autoScroll; + menuItem.setChecked(autoScroll); + break; + + case R.id.option_go_to_first: + recyclerPackets.scrollToPosition(0); + break; + + case R.id.option_go_to_last: + recyclerPackets.scrollToPosition(adapter.getItemCount() - 1); + break; + + default: + return false; + } + + drawer.closeDrawer(GravityCompat.END); + return true; + } + + @Override + public void onBackPressed() { + if(drawer.isDrawerOpen(GravityCompat.END)) { + drawer.closeDrawer(GravityCompat.END); + }else { + super.onBackPressed(); + } + } +} diff --git a/app/src/main/java/me/itay/packetmanipulator/display/PacketDissector.java b/app/src/main/java/me/itay/packetmanipulator/display/PacketDissector.java index e51807b..e268028 100644 --- a/app/src/main/java/me/itay/packetmanipulator/display/PacketDissector.java +++ b/app/src/main/java/me/itay/packetmanipulator/display/PacketDissector.java @@ -1,9 +1,9 @@ -package me.itay.packetmanipulator.display; - -import org.pcap4j.packet.Packet; - -public interface PacketDissector { - - public boolean dissect(PacketEntry entry); - -} +package me.itay.packetmanipulator.display; + +import org.pcap4j.packet.Packet; + +public interface PacketDissector { + + public boolean dissect(PacketEntry entry); + +} diff --git a/app/src/main/java/me/itay/packetmanipulator/display/PacketEntry.java b/app/src/main/java/me/itay/packetmanipulator/display/PacketEntry.java index a846f03..714334d 100644 --- a/app/src/main/java/me/itay/packetmanipulator/display/PacketEntry.java +++ b/app/src/main/java/me/itay/packetmanipulator/display/PacketEntry.java @@ -1,19 +1,19 @@ -package me.itay.packetmanipulator.display; - -import android.graphics.Color; - -import org.pcap4j.packet.Packet; - -public class PacketEntry { - - public Packet original; - - public String source = "?"; - public String destination = "?"; - public String protocol = "?"; - public String info = "?"; - - public int backgroundColor = Color.WHITE; - public int textColor = Color.parseColor("#12272e"); - -} +package me.itay.packetmanipulator.display; + +import android.graphics.Color; + +import org.pcap4j.packet.Packet; + +public class PacketEntry { + + public Packet original; + + public String source = "?"; + public String destination = "?"; + public String protocol = "?"; + public String info = "?"; + + public int backgroundColor = Color.WHITE; + public int textColor = Color.parseColor("#12272e"); + +} diff --git a/app/src/main/java/me/itay/pcapproxy/DataStream.java b/app/src/main/java/me/itay/pcapproxy/DataStream.java index 0d6d8e2..e788e9d 100644 --- a/app/src/main/java/me/itay/pcapproxy/DataStream.java +++ b/app/src/main/java/me/itay/pcapproxy/DataStream.java @@ -1,184 +1,184 @@ -package me.itay.pcapproxy; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class DataStream { - - private InputStream in; - private OutputStream out; - - public DataStream(InputStream in, OutputStream out) { - this.in = in; - this.out = out; - } - - public void checkErr() { - if(!readBool()) { - throw new PcapProxyException(readString()); - } - } - - public boolean readBool() { - try { - return in.read() > 0; - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - } - - public void readBytes(byte[] bytes) { - try { - if(in.read(bytes) != bytes.length) { - throw new PcapProxyException(); - } - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - } - - public void writeBytes(byte[] bytes) { - try { - out.write(bytes); - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - } - - - public short readShort() { - byte[] bytes = new byte[2]; - - try { - if(in.read(bytes) != 2) { - throw new PcapProxyException(); - } - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - - ByteBuffer buffer = ByteBuffer.wrap(bytes); - buffer.order(ByteOrder.nativeOrder()); - return buffer.getShort(); - } - - public int readInt() { - byte[] bytes = new byte[4]; - - try { - if(in.read(bytes) != 4) { - throw new PcapProxyException(); - } - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - - ByteBuffer buffer = ByteBuffer.wrap(bytes); - buffer.order(ByteOrder.nativeOrder()); - return buffer.getInt(); - } - - public long readLong() { - byte[] bytes = new byte[8]; - - try { - if(in.read(bytes) != 8) { - throw new PcapProxyException(); - } - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - - ByteBuffer buffer = ByteBuffer.wrap(bytes); - buffer.order(ByteOrder.nativeOrder()); - return buffer.getLong(); - } - - public void writeInt(int t) { - ByteBuffer buffer = ByteBuffer.allocate(4); - buffer.order(ByteOrder.nativeOrder()); - buffer.putInt(t); - try { - out.write(buffer.array(), buffer.arrayOffset(), 4); - out.flush(); - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - } - - public void writeLong(long t) { - ByteBuffer buffer = ByteBuffer.allocate(8); - buffer.order(ByteOrder.nativeOrder()); - buffer.putLong(t); - try { - out.write(buffer.array(), buffer.arrayOffset(), 8); - out.flush(); - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - } - - public String readString() { - int length = readInt(); - - if(length == 0) { - return null; - } - - byte[] bytes = new byte[length]; - - try { - if(in.read(bytes) != length) { - throw new PcapProxyException(); - } - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - - return new String(bytes); - } - - public void writeString(String str) { - writeInt(str.getBytes().length); - try { - out.write(str.getBytes()); - out.flush(); - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - } - - public void readArray(Runnable iter) { - int count = readInt(); - for(int i = 0; i < count; i++) { - iter.run(); - } - } - - public void writeArray(int count, Runnable iter) { - writeInt(count); - for(int i = 0; i < count; i++) { - iter.run(); - try { - out.flush(); - } catch (IOException e) { - e.printStackTrace(); - throw new PcapProxyException(); - } - } - } - -} +package me.itay.pcapproxy; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +public class DataStream { + + private InputStream in; + private OutputStream out; + + public DataStream(InputStream in, OutputStream out) { + this.in = in; + this.out = out; + } + + public void checkErr() { + if(!readBool()) { + throw new PcapProxyException(readString()); + } + } + + public boolean readBool() { + try { + return in.read() > 0; + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + } + + public void readBytes(byte[] bytes) { + try { + if(in.read(bytes) != bytes.length) { + throw new PcapProxyException(); + } + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + } + + public void writeBytes(byte[] bytes) { + try { + out.write(bytes); + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + } + + + public short readShort() { + byte[] bytes = new byte[2]; + + try { + if(in.read(bytes) != 2) { + throw new PcapProxyException(); + } + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + + ByteBuffer buffer = ByteBuffer.wrap(bytes); + buffer.order(ByteOrder.nativeOrder()); + return buffer.getShort(); + } + + public int readInt() { + byte[] bytes = new byte[4]; + + try { + if(in.read(bytes) != 4) { + throw new PcapProxyException(); + } + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + + ByteBuffer buffer = ByteBuffer.wrap(bytes); + buffer.order(ByteOrder.nativeOrder()); + return buffer.getInt(); + } + + public long readLong() { + byte[] bytes = new byte[8]; + + try { + if(in.read(bytes) != 8) { + throw new PcapProxyException(); + } + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + + ByteBuffer buffer = ByteBuffer.wrap(bytes); + buffer.order(ByteOrder.nativeOrder()); + return buffer.getLong(); + } + + public void writeInt(int t) { + ByteBuffer buffer = ByteBuffer.allocate(4); + buffer.order(ByteOrder.nativeOrder()); + buffer.putInt(t); + try { + out.write(buffer.array(), buffer.arrayOffset(), 4); + out.flush(); + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + } + + public void writeLong(long t) { + ByteBuffer buffer = ByteBuffer.allocate(8); + buffer.order(ByteOrder.nativeOrder()); + buffer.putLong(t); + try { + out.write(buffer.array(), buffer.arrayOffset(), 8); + out.flush(); + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + } + + public String readString() { + int length = readInt(); + + if(length == 0) { + return null; + } + + byte[] bytes = new byte[length]; + + try { + if(in.read(bytes) != length) { + throw new PcapProxyException(); + } + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + + return new String(bytes); + } + + public void writeString(String str) { + writeInt(str.getBytes().length); + try { + out.write(str.getBytes()); + out.flush(); + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + } + + public void readArray(Runnable iter) { + int count = readInt(); + for(int i = 0; i < count; i++) { + iter.run(); + } + } + + public void writeArray(int count, Runnable iter) { + writeInt(count); + for(int i = 0; i < count; i++) { + iter.run(); + try { + out.flush(); + } catch (IOException e) { + e.printStackTrace(); + throw new PcapProxyException(); + } + } + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/PcapProxy.java b/app/src/main/java/me/itay/pcapproxy/PcapProxy.java index ab5cb05..8e2afe4 100644 --- a/app/src/main/java/me/itay/pcapproxy/PcapProxy.java +++ b/app/src/main/java/me/itay/pcapproxy/PcapProxy.java @@ -1,221 +1,235 @@ -package me.itay.pcapproxy; - -import android.content.Context; -import android.util.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import me.itay.pcapproxy.structs.pcap_if; -import me.itay.pcapproxy.structs.pcap_pkthdr; -import me.itay.pcapproxy.structs.pcap_stat; - -public class PcapProxy { - - // function ids - - private static final int PCAP_LIB_VERSION = 1; - private static final int PCAP_FINDALLDEVS = 2; - private static final int PCAP_OPEN_LIVE = 3; - private static final int PCAP_CLOSE = 4; - private static final int PCAP_DATALINK = 5; - private static final int PCAP_NEXT = 6; - private static final int PCAP_SETNONBLOCK = 7; - private static final int PCAP_GETNONBLOCK = 8; - private static final int PCAP_LOOKUPDEV = 9; - private static final int PCAP_STRERROR = 10; - private static final int PCAP_GETERR = 11; - private static final int PCAP_STATS = 12; - private static final int PCAP_DUMP_OPEN = 13; - private static final int PCAP_DUMP = 14; - private static final int PCAP_DUMP_FLUSH = 15; - private static final int PCAP_DUMP_FTELL = 16; - private static final int PCAP_DUMP_CLOSE = 17; - - // global instance - - private static PcapProxy instance; - - public static PcapProxy get() { - assert instance != null; - return instance; - } - - public static void init(Context context) { - instance = new PcapProxy(context); - Log.i("PcapProxy", String.format("successfully loaded the native pcap library: %s", instance.pcap_lib_version())); - } - - // actual implementation - - private DataStream stream; - private Process process; - - private Thread logger_thread; - private InputStream logger_stream; - - public PcapProxy(Context context) { - try { - // TODO: Use root tools maybe? - process = Runtime.getRuntime().exec(new String[] { "su", "-c", String.format("%s/libpcapproxy.so", context.getApplicationInfo().nativeLibraryDir) }); - stream = new DataStream(process.getInputStream(), process.getOutputStream()); - - logger_stream = process.getErrorStream(); - logger_thread = new Thread(() -> { - StringBuilder sb = new StringBuilder(); - while(true) { - int b = 0; - - try { - b = logger_stream.read(); - } catch (IOException e) { - e.printStackTrace(); - break; - } - - if(b == -1) { - Log.w("PcapProxyLogger", "stderr closed! stopping logger"); - break; - } - - if(b == 10) { - Log.d("PcapProxyLogger", sb.toString()); - sb = new StringBuilder(); - }else { - sb.append((char)b); - } - } - - if(!sb.toString().isEmpty()) { - Log.d("PcapProxyLogger", sb.toString()); - } - }, "PcapProxyLogger"); - - logger_thread.start(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public String pcap_lib_version() { - stream.writeInt(PCAP_LIB_VERSION); - return stream.readString(); - } - - public List pcap_findalldevs() { - stream.writeInt(PCAP_FINDALLDEVS); - stream.checkErr(); - - List devices = new ArrayList<>(); - stream.readArray(() -> devices.add(new pcap_if(stream))); - - return devices; - } - - public long pcap_open_live(String device, int spanlen, int promisc, int to_ms) { - stream.writeInt(PCAP_OPEN_LIVE); - stream.writeString(device); - stream.writeInt(spanlen); - stream.writeInt(promisc); - stream.writeInt(to_ms); - - stream.checkErr(); - return stream.readLong(); - } - - public void pcap_close(long handle) { - stream.writeInt(PCAP_CLOSE); - stream.writeLong(handle); - } - - public int pcap_datalink(long handle) { - stream.writeInt(PCAP_DATALINK); - stream.writeLong(handle); - return stream.readInt(); - } - - public pcap_pkthdr pcap_next(long handle) { - stream.writeInt(PCAP_NEXT); - stream.writeLong(handle); - - if(stream.readBool()) { - return new pcap_pkthdr(stream); - }else { - return null; - } - } - - public void pcap_setnonblock(long p, int nonblock) { - stream.writeInt(PCAP_SETNONBLOCK); - stream.writeLong(p); - stream.writeInt(nonblock); - - stream.checkErr(); - } - - public int pcap_getnonblock(long p) { - stream.writeInt(PCAP_GETNONBLOCK); - stream.writeLong(p); - - stream.checkErr(); - return stream.readInt(); - } - - public String pcap_lookupdev() { - stream.writeInt(PCAP_LOOKUPDEV); - stream.checkErr(); - return stream.readString(); - } - - public String pcap_strerror(int error) { - stream.writeInt(PCAP_STRERROR); - stream.writeInt(error); - return stream.readString(); - } - - public String pcap_geterr(long handle) { - stream.writeInt(PCAP_GETERR); - stream.writeLong(handle); - return stream.readString(); - } - - public pcap_stat pcap_stats(long handle) { - stream.writeInt(PCAP_STATS); - stream.writeLong(handle); - return new pcap_stat(stream); - } - - public long pcap_dump_open(long handle, String filepath) { - stream.writeInt(PCAP_DUMP_OPEN); - stream.writeLong(handle); - stream.writeString(filepath); - - return stream.readLong(); - } - - public void pcap_dump(long dumper, pcap_pkthdr packet) { - stream.writeInt(PCAP_DUMP); - stream.writeLong(dumper); - packet.write(stream); - } - - public void pcap_dump_flush(long dumper) { - stream.writeInt(PCAP_DUMP_FLUSH); - stream.writeLong(dumper); - stream.checkErr(); - } - - public long pcap_dump_ftell(long dumper) { - stream.writeInt(PCAP_DUMP_FTELL); - stream.writeLong(dumper); - return stream.readLong(); - } - - public void pcap_dump_close(long dumper) { - stream.writeInt(PCAP_DUMP_CLOSE); - stream.writeLong(dumper); - } - -} +package me.itay.pcapproxy; + +import android.content.Context; +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import me.itay.pcapproxy.structs.pcap_if; +import me.itay.pcapproxy.structs.pcap_pkthdr; +import me.itay.pcapproxy.structs.pcap_stat; + +public class PcapProxy { + + // function ids + + private static final int PCAP_LIB_VERSION = 1; + private static final int PCAP_FINDALLDEVS = 2; + private static final int PCAP_OPEN_LIVE = 3; + private static final int PCAP_CLOSE = 4; + private static final int PCAP_DATALINK = 5; + private static final int PCAP_NEXT = 6; + private static final int PCAP_SETNONBLOCK = 7; + private static final int PCAP_GETNONBLOCK = 8; + private static final int PCAP_LOOKUPDEV = 9; + private static final int PCAP_STRERROR = 10; + private static final int PCAP_GETERR = 11; + private static final int PCAP_STATS = 12; + private static final int PCAP_DUMP_OPEN = 13; + private static final int PCAP_DUMP = 14; + private static final int PCAP_DUMP_FLUSH = 15; + private static final int PCAP_DUMP_FTELL = 16; + private static final int PCAP_DUMP_CLOSE = 17; + private static final int PCAP_OPEN_OFFLINE = 18; + + // global instance + + private static PcapProxy instance; + + public static PcapProxy get() { + assert instance != null; + return instance; + } + + public static void init(Context context) { + if(instance != null) { + Log.i("PcapProxy", "There is already an instance of the proxy running, killing it"); + instance.logger_thread.interrupt(); + instance.process.destroy(); + } + + instance = new PcapProxy(context); + Log.i("PcapProxy", String.format("successfully loaded the native pcap library: %s", instance.pcap_lib_version())); + } + + // actual implementation + + private DataStream stream; + private Process process; + + private Thread logger_thread; + private InputStream logger_stream; + + public PcapProxy(Context context) { + try { + // TODO: Use root tools maybe? + process = Runtime.getRuntime().exec(new String[] { "su", "-c", String.format("%s/libpcapproxy.so", context.getApplicationInfo().nativeLibraryDir) }); + stream = new DataStream(process.getInputStream(), process.getOutputStream()); + + logger_stream = process.getErrorStream(); + logger_thread = new Thread(() -> { + StringBuilder sb = new StringBuilder(); + while(true) { + int b = 0; + + try { + b = logger_stream.read(); + } catch (IOException e) { + e.printStackTrace(); + break; + } + + if(b == -1) { + Log.w("PcapProxyLogger", "stderr closed! stopping logger"); + break; + } + + if(b == 10) { + Log.d("PcapProxyLogger", sb.toString()); + sb = new StringBuilder(); + }else { + sb.append((char)b); + } + } + + if(!sb.toString().isEmpty()) { + Log.d("PcapProxyLogger", sb.toString()); + } + }, "PcapProxyLogger"); + + logger_thread.start(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String pcap_lib_version() { + stream.writeInt(PCAP_LIB_VERSION); + return stream.readString(); + } + + public List pcap_findalldevs() { + stream.writeInt(PCAP_FINDALLDEVS); + stream.checkErr(); + + List devices = new ArrayList<>(); + stream.readArray(() -> devices.add(new pcap_if(stream))); + + return devices; + } + + public long pcap_open_live(String device, int spanlen, int promisc, int to_ms) { + stream.writeInt(PCAP_OPEN_LIVE); + stream.writeString(device); + stream.writeInt(spanlen); + stream.writeInt(promisc); + stream.writeInt(to_ms); + + stream.checkErr(); + return stream.readLong(); + } + + public void pcap_close(long handle) { + stream.writeInt(PCAP_CLOSE); + stream.writeLong(handle); + } + + public int pcap_datalink(long handle) { + stream.writeInt(PCAP_DATALINK); + stream.writeLong(handle); + return stream.readInt(); + } + + public pcap_pkthdr pcap_next(long handle) { + stream.writeInt(PCAP_NEXT); + stream.writeLong(handle); + + if(stream.readBool()) { + return new pcap_pkthdr(stream); + }else { + return null; + } + } + + public void pcap_setnonblock(long p, int nonblock) { + stream.writeInt(PCAP_SETNONBLOCK); + stream.writeLong(p); + stream.writeInt(nonblock); + + stream.checkErr(); + } + + public int pcap_getnonblock(long p) { + stream.writeInt(PCAP_GETNONBLOCK); + stream.writeLong(p); + + stream.checkErr(); + return stream.readInt(); + } + + public String pcap_lookupdev() { + stream.writeInt(PCAP_LOOKUPDEV); + stream.checkErr(); + return stream.readString(); + } + + public String pcap_strerror(int error) { + stream.writeInt(PCAP_STRERROR); + stream.writeInt(error); + return stream.readString(); + } + + public String pcap_geterr(long handle) { + stream.writeInt(PCAP_GETERR); + stream.writeLong(handle); + return stream.readString(); + } + + public pcap_stat pcap_stats(long handle) { + stream.writeInt(PCAP_STATS); + stream.writeLong(handle); + return new pcap_stat(stream); + } + + public long pcap_dump_open(long handle, String filepath) { + stream.writeInt(PCAP_DUMP_OPEN); + stream.writeLong(handle); + stream.writeString(filepath); + + return stream.readLong(); + } + + public void pcap_dump(long dumper, pcap_pkthdr packet) { + stream.writeInt(PCAP_DUMP); + stream.writeLong(dumper); + packet.write(stream); + } + + public void pcap_dump_flush(long dumper) { + stream.writeInt(PCAP_DUMP_FLUSH); + stream.writeLong(dumper); + stream.checkErr(); + } + + public long pcap_dump_ftell(long dumper) { + stream.writeInt(PCAP_DUMP_FTELL); + stream.writeLong(dumper); + return stream.readLong(); + } + + public void pcap_dump_close(long dumper) { + stream.writeInt(PCAP_DUMP_CLOSE); + stream.writeLong(dumper); + } + + public long pcap_open_offline(String filePath) { + stream.writeInt(PCAP_OPEN_OFFLINE); + stream.writeString(filePath); + stream.checkErr(); + return stream.readLong(); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/PcapProxyException.java b/app/src/main/java/me/itay/pcapproxy/PcapProxyException.java index b2553f9..64f9e13 100644 --- a/app/src/main/java/me/itay/pcapproxy/PcapProxyException.java +++ b/app/src/main/java/me/itay/pcapproxy/PcapProxyException.java @@ -1,13 +1,13 @@ -package me.itay.pcapproxy; - -public class PcapProxyException extends RuntimeException { - - public PcapProxyException() { - - } - - public PcapProxyException(String message) { - super(message); - } - -} +package me.itay.pcapproxy; + +public class PcapProxyException extends RuntimeException { + + public PcapProxyException() { + + } + + public PcapProxyException(String message) { + super(message); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/in6_addr.java b/app/src/main/java/me/itay/pcapproxy/structs/in6_addr.java index 95e7ffb..0bcfde9 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/in6_addr.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/in6_addr.java @@ -1,7 +1,7 @@ -package me.itay.pcapproxy.structs; - -public class in6_addr { - - public byte[] s6_addr = new byte[16]; - -} +package me.itay.pcapproxy.structs; + +public class in6_addr { + + public byte[] s6_addr = new byte[16]; + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/in_addr.java b/app/src/main/java/me/itay/pcapproxy/structs/in_addr.java index 0dbea90..6f81b00 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/in_addr.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/in_addr.java @@ -1,7 +1,7 @@ -package me.itay.pcapproxy.structs; - -public class in_addr { - - public int s_addr; - -} +package me.itay.pcapproxy.structs; + +public class in_addr { + + public int s_addr; + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/pcap_addr.java b/app/src/main/java/me/itay/pcapproxy/structs/pcap_addr.java index b0e1ad2..146d85d 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/pcap_addr.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/pcap_addr.java @@ -1,19 +1,19 @@ -package me.itay.pcapproxy.structs; - -import me.itay.pcapproxy.DataStream; - -public class pcap_addr { - - public sockaddr addr; - public sockaddr netmask; - public sockaddr broadaddr; - public sockaddr dstaddr; - - public pcap_addr(DataStream stream) { - addr = new sockaddr(stream); - netmask = new sockaddr(stream); - broadaddr = new sockaddr(stream); - dstaddr = new sockaddr(stream); - } - -} +package me.itay.pcapproxy.structs; + +import me.itay.pcapproxy.DataStream; + +public class pcap_addr { + + public sockaddr addr; + public sockaddr netmask; + public sockaddr broadaddr; + public sockaddr dstaddr; + + public pcap_addr(DataStream stream) { + addr = new sockaddr(stream); + netmask = new sockaddr(stream); + broadaddr = new sockaddr(stream); + dstaddr = new sockaddr(stream); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/pcap_if.java b/app/src/main/java/me/itay/pcapproxy/structs/pcap_if.java index 013d4dc..ce374ed 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/pcap_if.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/pcap_if.java @@ -1,25 +1,25 @@ -package me.itay.pcapproxy.structs; - -import java.util.ArrayList; -import java.util.List; - -import me.itay.pcapproxy.DataStream; - -public class pcap_if { - - public String name; - public String description; - public List addresses; - public int flags; - - public pcap_if(DataStream stream) { - name = stream.readString(); - description = stream.readString(); - - addresses = new ArrayList<>(); - stream.readArray(() -> addresses.add(new pcap_addr(stream))); - - flags = stream.readInt(); - } - -} +package me.itay.pcapproxy.structs; + +import java.util.ArrayList; +import java.util.List; + +import me.itay.pcapproxy.DataStream; + +public class pcap_if { + + public String name; + public String description; + public List addresses; + public int flags; + + public pcap_if(DataStream stream) { + name = stream.readString(); + description = stream.readString(); + + addresses = new ArrayList<>(); + stream.readArray(() -> addresses.add(new pcap_addr(stream))); + + flags = stream.readInt(); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/pcap_pkthdr.java b/app/src/main/java/me/itay/pcapproxy/structs/pcap_pkthdr.java index 68ff5c9..ded60f8 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/pcap_pkthdr.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/pcap_pkthdr.java @@ -1,31 +1,31 @@ -package me.itay.pcapproxy.structs; - -import me.itay.pcapproxy.DataStream; - -public class pcap_pkthdr { - - public timeval ts; - public int caplen; - public int len; - public byte[] data; - - public pcap_pkthdr(DataStream stream) { - ts = new timeval(stream); - this.caplen = stream.readInt(); - this.len = stream.readInt(); - data = new byte[caplen]; - stream.readBytes(data); - } - - public pcap_pkthdr() { - - } - - public void write(DataStream stream) { - this.ts.write(stream); - stream.writeInt(this.caplen); - stream.writeInt(this.len); - stream.readBytes(this.data); - } - -} +package me.itay.pcapproxy.structs; + +import me.itay.pcapproxy.DataStream; + +public class pcap_pkthdr { + + public timeval ts; + public int caplen; + public int len; + public byte[] data; + + public pcap_pkthdr(DataStream stream) { + ts = new timeval(stream); + this.caplen = stream.readInt(); + this.len = stream.readInt(); + data = new byte[caplen]; + stream.readBytes(data); + } + + public pcap_pkthdr() { + + } + + public void write(DataStream stream) { + this.ts.write(stream); + stream.writeInt(this.caplen); + stream.writeInt(this.len); + stream.writeBytes(this.data); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/pcap_stat.java b/app/src/main/java/me/itay/pcapproxy/structs/pcap_stat.java index d998b1b..2d6eaec 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/pcap_stat.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/pcap_stat.java @@ -1,17 +1,17 @@ -package me.itay.pcapproxy.structs; - -import me.itay.pcapproxy.DataStream; - -public class pcap_stat { - - public int ps_recv; - public int ps_drop; - public int ps_ifdrop; - - public pcap_stat(DataStream stream) { - this.ps_recv = stream.readInt(); - this.ps_drop = stream.readInt(); - this.ps_ifdrop = stream.readInt(); - } - -} +package me.itay.pcapproxy.structs; + +import me.itay.pcapproxy.DataStream; + +public class pcap_stat { + + public int ps_recv; + public int ps_drop; + public int ps_ifdrop; + + public pcap_stat(DataStream stream) { + this.ps_recv = stream.readInt(); + this.ps_drop = stream.readInt(); + this.ps_ifdrop = stream.readInt(); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr.java b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr.java index c1b36c6..e446ea5 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr.java @@ -1,30 +1,30 @@ -package me.itay.pcapproxy.structs; - -import java.io.ByteArrayInputStream; -import java.nio.ByteOrder; - -import me.itay.pcapproxy.DataStream; - -public class sockaddr { - - public short sa_family; - public byte[] sa_data = new byte[14]; - - public sockaddr(DataStream stream) { - sa_family = stream.readShort(); - stream.readBytes(sa_data); - } - - public DataStream getSaData() { - return new DataStream(new ByteArrayInputStream(sa_data), null); - } - - public short getSaFamily() { - if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) { - return (short) (0xFF & sa_family); - } else { - return (short) (0xFF & (sa_family >> 8)); - } - } - -} +package me.itay.pcapproxy.structs; + +import java.io.ByteArrayInputStream; +import java.nio.ByteOrder; + +import me.itay.pcapproxy.DataStream; + +public class sockaddr { + + public short sa_family; + public byte[] sa_data = new byte[14]; + + public sockaddr(DataStream stream) { + sa_family = stream.readShort(); + stream.readBytes(sa_data); + } + + public DataStream getSaData() { + return new DataStream(new ByteArrayInputStream(sa_data), null); + } + + public short getSaFamily() { + if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) { + return (short) (0xFF & sa_family); + } else { + return (short) (0xFF & (sa_family >> 8)); + } + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in.java b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in.java index 55d5b1c..ad1808f 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in.java @@ -1,21 +1,21 @@ -package me.itay.pcapproxy.structs; - -import me.itay.pcapproxy.DataStream; - -public class sockaddr_in { - - public short sin_family; - public short sin_port; - public in_addr sin_addr; - public byte[] sin_zero = new byte[8]; - - public sockaddr_in(sockaddr addr) { - this.sin_family = addr.sa_family; - - DataStream stream = addr.getSaData(); - sin_port = stream.readShort(); - sin_addr.s_addr = stream.readInt(); - stream.readBytes(sin_zero); - } - -} +package me.itay.pcapproxy.structs; + +import me.itay.pcapproxy.DataStream; + +public class sockaddr_in { + + public short sin_family; + public short sin_port; + public in_addr sin_addr; + public byte[] sin_zero = new byte[8]; + + public sockaddr_in(sockaddr addr) { + this.sin_family = addr.sa_family; + + DataStream stream = addr.getSaData(); + sin_port = stream.readShort(); + sin_addr.s_addr = stream.readInt(); + stream.readBytes(sin_zero); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in6.java b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in6.java index 53662d1..d8a9d91 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in6.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_in6.java @@ -1,23 +1,23 @@ -package me.itay.pcapproxy.structs; - -import me.itay.pcapproxy.DataStream; - -public class sockaddr_in6 { - - public short sin6_family; - public short sin6_port; - public int sin6_flowinfo; - public in6_addr sin6_addr; - public int sin6_scope_id; - - public sockaddr_in6(sockaddr sa) { - sin6_family = sa.sa_family; - - DataStream stream = sa.getSaData(); - sin6_port = stream.readShort(); - sin6_flowinfo = stream.readInt(); - stream.readBytes(sin6_addr.s6_addr); - sin6_scope_id = stream.readInt(); - } - -} +package me.itay.pcapproxy.structs; + +import me.itay.pcapproxy.DataStream; + +public class sockaddr_in6 { + + public short sin6_family; + public short sin6_port; + public int sin6_flowinfo; + public in6_addr sin6_addr; + public int sin6_scope_id; + + public sockaddr_in6(sockaddr sa) { + sin6_family = sa.sa_family; + + DataStream stream = sa.getSaData(); + sin6_port = stream.readShort(); + sin6_flowinfo = stream.readInt(); + stream.readBytes(sin6_addr.s6_addr); + sin6_scope_id = stream.readInt(); + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_ll.java b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_ll.java index a6d59ad..4dc4c0b 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_ll.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/sockaddr_ll.java @@ -1,37 +1,37 @@ -package me.itay.pcapproxy.structs; - -import java.nio.ByteOrder; - -import me.itay.pcapproxy.DataStream; - -public class sockaddr_ll { - - public short sll_family; - public short sll_protocol; - public short sll_ifindex; - public short sll_hatype; - public short sll_pkttype; - public short sll_halen; - public byte[] sll_addr = new byte[8]; - - public sockaddr_ll(sockaddr sockaddr) { - this.sll_family = sockaddr.sa_family; - - DataStream stream = sockaddr.getSaData(); - sll_protocol = stream.readShort(); - sll_ifindex = stream.readShort(); - sll_hatype = stream.readShort(); - sll_pkttype = stream.readShort(); - sll_halen = stream.readShort(); - stream.readBytes(sll_addr); - } - - public short getSaFamily() { - if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) { - return (short) (0xFF & sll_family); - } else { - return (short) (0xFF & (sll_family >> 8)); - } - } - -} +package me.itay.pcapproxy.structs; + +import java.nio.ByteOrder; + +import me.itay.pcapproxy.DataStream; + +public class sockaddr_ll { + + public short sll_family; + public short sll_protocol; + public short sll_ifindex; + public short sll_hatype; + public short sll_pkttype; + public short sll_halen; + public byte[] sll_addr = new byte[8]; + + public sockaddr_ll(sockaddr sockaddr) { + this.sll_family = sockaddr.sa_family; + + DataStream stream = sockaddr.getSaData(); + sll_protocol = stream.readShort(); + sll_ifindex = stream.readShort(); + sll_hatype = stream.readShort(); + sll_pkttype = stream.readShort(); + sll_halen = stream.readShort(); + stream.readBytes(sll_addr); + } + + public short getSaFamily() { + if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) { + return (short) (0xFF & sll_family); + } else { + return (short) (0xFF & (sll_family >> 8)); + } + } + +} diff --git a/app/src/main/java/me/itay/pcapproxy/structs/timeval.java b/app/src/main/java/me/itay/pcapproxy/structs/timeval.java index e5680ab..f2fb91d 100644 --- a/app/src/main/java/me/itay/pcapproxy/structs/timeval.java +++ b/app/src/main/java/me/itay/pcapproxy/structs/timeval.java @@ -1,24 +1,24 @@ -package me.itay.pcapproxy.structs; - -import me.itay.pcapproxy.DataStream; - -public class timeval { - - public long tv_sec; - public long tv_usec; - - public timeval(DataStream stream) { - this.tv_sec = stream.readLong(); - this.tv_usec = stream.readLong(); - } - - public timeval() { - - } - - public void write(DataStream stream) { - stream.writeLong(this.tv_sec); - stream.writeLong(this.tv_usec); - } - -} +package me.itay.pcapproxy.structs; + +import me.itay.pcapproxy.DataStream; + +public class timeval { + + public long tv_sec; + public long tv_usec; + + public timeval(DataStream stream) { + this.tv_sec = stream.readLong(); + this.tv_usec = stream.readLong(); + } + + public timeval() { + + } + + public void write(DataStream stream) { + stream.writeLong(this.tv_sec); + stream.writeLong(this.tv_usec); + } + +} diff --git a/app/src/main/java/org/pcap4j/LICENSE b/app/src/main/java/org/pcap4j/LICENSE index 30ca242..55404c0 100644 --- a/app/src/main/java/org/pcap4j/LICENSE +++ b/app/src/main/java/org/pcap4j/LICENSE @@ -1,16 +1,16 @@ -Pcap4J is distributed under the MIT license. - -Copyright (c) 2011 Pcap4J.org - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +Pcap4J is distributed under the MIT license. + +Copyright (c) 2011 Pcap4J.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/AbstractPcapAddress.java b/app/src/main/java/org/pcap4j/core/AbstractPcapAddress.java index bac353b..e09e03e 100644 --- a/app/src/main/java/org/pcap4j/core/AbstractPcapAddress.java +++ b/app/src/main/java/org/pcap4j/core/AbstractPcapAddress.java @@ -1,162 +1,162 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2015 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -import android.util.Log; - -import java.net.InetAddress; - -import me.itay.pcapproxy.structs.pcap_addr; -import me.itay.pcapproxy.structs.sockaddr; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.1 - */ -abstract class AbstractPcapAddress implements PcapAddress { - - private static final String TAG = "AbstractPcapAddress"; - - private final InetAddress address; - private final InetAddress netmask; - private final InetAddress broadcastAddr; - private final InetAddress dstAddr; // for point-to-point interface - - protected AbstractPcapAddress(pcap_addr pcapAddr, short saFamily, String devName) { - if (pcapAddr == null) { - throw new NullPointerException(); - } - - if (pcapAddr.addr != null && pcapAddr.addr.getSaFamily() != Inets.AF_UNSPEC) { - if (pcapAddr.addr.getSaFamily() != saFamily) { - warn(pcapAddr.addr.getSaFamily(), saFamily, devName, "addr"); - this.address = null; - } else { - this.address = ntoInetAddress(pcapAddr.addr); - } - } else { - this.address = null; - } - - if (pcapAddr.netmask != null && pcapAddr.netmask.getSaFamily() != Inets.AF_UNSPEC) { - if (pcapAddr.netmask.getSaFamily() != saFamily) { - warn(pcapAddr.netmask.getSaFamily(), saFamily, devName, "netmask"); - this.netmask = null; - } else { - this.netmask = ntoInetAddress(pcapAddr.netmask); - } - } else { - this.netmask = null; - } - - if (pcapAddr.broadaddr != null && pcapAddr.broadaddr.getSaFamily() != Inets.AF_UNSPEC) { - if (pcapAddr.broadaddr.getSaFamily() != saFamily) { - warn(pcapAddr.broadaddr.getSaFamily(), saFamily, devName, "broadaddr"); - this.broadcastAddr = null; - } else { - this.broadcastAddr = ntoInetAddress(pcapAddr.broadaddr); - } - } else { - this.broadcastAddr = null; - } - - if (pcapAddr.dstaddr != null && pcapAddr.dstaddr.getSaFamily() != Inets.AF_UNSPEC) { - if (pcapAddr.dstaddr.getSaFamily() != saFamily) { - warn(pcapAddr.dstaddr.getSaFamily(), saFamily, devName, "dstaddr"); - this.dstAddr = null; - } else { - this.dstAddr = ntoInetAddress(pcapAddr.dstaddr); - } - } else { - this.dstAddr = null; - } - } - - private void warn(short actualSaFamily, short expectedSaFamily, String devName, String field) { - Log.w(TAG, - String.format("Couldn't analyze an address. " - + "devName: %s, field: %s, actual saFamily: %s, expected saFamily: %s", - devName, - field, - actualSaFamily, - expectedSaFamily)); - } - - @Override - public InetAddress getAddress() { - return address; - } - - @Override - public InetAddress getNetmask() { - return netmask; - } - - @Override - public InetAddress getBroadcastAddress() { - return broadcastAddr; - } - - @Override - public InetAddress getDestinationAddress() { - return dstAddr; - } - - protected abstract InetAddress ntoInetAddress(sockaddr sa); - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(190); - - sb.append("address: [") - .append(address) - .append("] netmask: [") - .append(netmask) - .append("] broadcastAddr: [") - .append(broadcastAddr) - .append("] dstAddr [") - .append(dstAddr) - .append("]"); - - return sb.toString(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - AbstractPcapAddress other = (AbstractPcapAddress) obj; - if (address == null) { - if (other.address != null) return false; - } else if (!address.equals(other.address)) return false; - if (broadcastAddr == null) { - if (other.broadcastAddr != null) return false; - } else if (!broadcastAddr.equals(other.broadcastAddr)) return false; - if (dstAddr == null) { - if (other.dstAddr != null) return false; - } else if (!dstAddr.equals(other.dstAddr)) return false; - if (netmask == null) { - if (other.netmask != null) return false; - } else if (!netmask.equals(other.netmask)) return false; - - return true; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((address == null) ? 0 : address.hashCode()); - result = prime * result + ((broadcastAddr == null) ? 0 : broadcastAddr.hashCode()); - result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode()); - result = prime * result + ((netmask == null) ? 0 : netmask.hashCode()); - return result; - } +/*_########################################################################## + _## + _## Copyright (C) 2011-2015 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +import android.util.Log; + +import java.net.InetAddress; + +import me.itay.pcapproxy.structs.pcap_addr; +import me.itay.pcapproxy.structs.sockaddr; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.1 + */ +abstract class AbstractPcapAddress implements PcapAddress { + + private static final String TAG = "AbstractPcapAddress"; + + private final InetAddress address; + private final InetAddress netmask; + private final InetAddress broadcastAddr; + private final InetAddress dstAddr; // for point-to-point interface + + protected AbstractPcapAddress(pcap_addr pcapAddr, short saFamily, String devName) { + if (pcapAddr == null) { + throw new NullPointerException(); + } + + if (pcapAddr.addr != null && pcapAddr.addr.getSaFamily() != Inets.AF_UNSPEC) { + if (pcapAddr.addr.getSaFamily() != saFamily) { + warn(pcapAddr.addr.getSaFamily(), saFamily, devName, "addr"); + this.address = null; + } else { + this.address = ntoInetAddress(pcapAddr.addr); + } + } else { + this.address = null; + } + + if (pcapAddr.netmask != null && pcapAddr.netmask.getSaFamily() != Inets.AF_UNSPEC) { + if (pcapAddr.netmask.getSaFamily() != saFamily) { + warn(pcapAddr.netmask.getSaFamily(), saFamily, devName, "netmask"); + this.netmask = null; + } else { + this.netmask = ntoInetAddress(pcapAddr.netmask); + } + } else { + this.netmask = null; + } + + if (pcapAddr.broadaddr != null && pcapAddr.broadaddr.getSaFamily() != Inets.AF_UNSPEC) { + if (pcapAddr.broadaddr.getSaFamily() != saFamily) { + warn(pcapAddr.broadaddr.getSaFamily(), saFamily, devName, "broadaddr"); + this.broadcastAddr = null; + } else { + this.broadcastAddr = ntoInetAddress(pcapAddr.broadaddr); + } + } else { + this.broadcastAddr = null; + } + + if (pcapAddr.dstaddr != null && pcapAddr.dstaddr.getSaFamily() != Inets.AF_UNSPEC) { + if (pcapAddr.dstaddr.getSaFamily() != saFamily) { + warn(pcapAddr.dstaddr.getSaFamily(), saFamily, devName, "dstaddr"); + this.dstAddr = null; + } else { + this.dstAddr = ntoInetAddress(pcapAddr.dstaddr); + } + } else { + this.dstAddr = null; + } + } + + private void warn(short actualSaFamily, short expectedSaFamily, String devName, String field) { + Log.w(TAG, + String.format("Couldn't analyze an address. " + + "devName: %s, field: %s, actual saFamily: %s, expected saFamily: %s", + devName, + field, + actualSaFamily, + expectedSaFamily)); + } + + @Override + public InetAddress getAddress() { + return address; + } + + @Override + public InetAddress getNetmask() { + return netmask; + } + + @Override + public InetAddress getBroadcastAddress() { + return broadcastAddr; + } + + @Override + public InetAddress getDestinationAddress() { + return dstAddr; + } + + protected abstract InetAddress ntoInetAddress(sockaddr sa); + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(190); + + sb.append("address: [") + .append(address) + .append("] netmask: [") + .append(netmask) + .append("] broadcastAddr: [") + .append(broadcastAddr) + .append("] dstAddr [") + .append(dstAddr) + .append("]"); + + return sb.toString(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + AbstractPcapAddress other = (AbstractPcapAddress) obj; + if (address == null) { + if (other.address != null) return false; + } else if (!address.equals(other.address)) return false; + if (broadcastAddr == null) { + if (other.broadcastAddr != null) return false; + } else if (!broadcastAddr.equals(other.broadcastAddr)) return false; + if (dstAddr == null) { + if (other.dstAddr != null) return false; + } else if (!dstAddr.equals(other.dstAddr)) return false; + if (netmask == null) { + if (other.netmask != null) return false; + } else if (!netmask.equals(other.netmask)) return false; + + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((address == null) ? 0 : address.hashCode()); + result = prime * result + ((broadcastAddr == null) ? 0 : broadcastAddr.hashCode()); + result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode()); + result = prime * result + ((netmask == null) ? 0 : netmask.hashCode()); + return result; + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/Inets.java b/app/src/main/java/org/pcap4j/core/Inets.java index f1092a3..d4abbfb 100644 --- a/app/src/main/java/org/pcap4j/core/Inets.java +++ b/app/src/main/java/org/pcap4j/core/Inets.java @@ -1,99 +1,99 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2016 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteOrder; - -import org.pcap4j.util.ByteArrays; - -import me.itay.pcapproxy.structs.in6_addr; -import me.itay.pcapproxy.structs.in_addr; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.1 - */ -public final class Inets { - - /** - * Unspecified address family. This value is defined in <sys/socket.h> as 0. - */ - public static final short AF_UNSPEC = 0; - - /** - * Address family for IPv4. This value needs to be the same as AF_INET defined in - * <sys/socket.h>. This value may vary depending on OS. This value is set to 2 by - * default and can be changed by setting the property org.pcap4j.af.inet (system - * property or pcap4j-core.jar/org/pcap4j/pcap4j.properties). - */ - public static final short AF_INET; - - /** - * Address family for IPv6. This value needs to be the same as AF_INET6 defined in - * <sys/socket.h>. This value varies depending on OS. By default, this value is set - * to 30 on Mac OS X, 28 on FreeBSD, 10 on Linux, and 23 on the others. This value can be changed - * by setting the property org.pcap4j.af.inet6 (system property or - * pcap4j-core.jar/org/pcap4j/pcap4j.properties). - */ - public static final short AF_INET6; - - /** - * Address family for low level packet interface. This value needs to be the same as AF_PACKET - * defined in <sys/socket.h>. This value may vary depending on OS. This value - * is set to 17 by default and can be changed by setting the property org.pcap4j.af.packet - * (system property or pcap4j-core.jar/org/pcap4j/pcap4j.properties). - */ - public static final short AF_PACKET; - - /** - * Address family for link layer interface. This value needs to be the same as AF_LINK defined in - * <sys/socket.h>. This value may vary depending on OS. This value is set to 18 - * by default and can be changed by setting the property org.pcap4j.af.link (system - * property or pcap4j-core.jar/org/pcap4j/pcap4j.properties). - */ - public static final short AF_LINK; - - static { - AF_INET = 2; - AF_INET6 = 10; - AF_PACKET = 17; - AF_LINK = 18; - } - - private Inets() { - throw new AssertionError(); - } - - static Inet4Address ntoInetAddress(in_addr in) { - if (in == null) { - return null; - } - return itoInetAddress(in.s_addr); - } - - static Inet4Address itoInetAddress(int i) { - return ByteArrays.getInet4Address( - ByteArrays.toByteArray(i, ByteOrder.nativeOrder()), 0); - } - - static Inet6Address ntoInetAddress(in6_addr in6) { - if (in6 == null) { - return null; - } - - try { - return (Inet6Address) InetAddress.getByAddress(in6.s6_addr); - } catch (UnknownHostException e) { - throw new AssertionError(); - } - } +/*_########################################################################## + _## + _## Copyright (C) 2011-2016 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteOrder; + +import org.pcap4j.util.ByteArrays; + +import me.itay.pcapproxy.structs.in6_addr; +import me.itay.pcapproxy.structs.in_addr; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.1 + */ +public final class Inets { + + /** + * Unspecified address family. This value is defined in <sys/socket.h> as 0. + */ + public static final short AF_UNSPEC = 0; + + /** + * Address family for IPv4. This value needs to be the same as AF_INET defined in + * <sys/socket.h>. This value may vary depending on OS. This value is set to 2 by + * default and can be changed by setting the property org.pcap4j.af.inet (system + * property or pcap4j-core.jar/org/pcap4j/pcap4j.properties). + */ + public static final short AF_INET; + + /** + * Address family for IPv6. This value needs to be the same as AF_INET6 defined in + * <sys/socket.h>. This value varies depending on OS. By default, this value is set + * to 30 on Mac OS X, 28 on FreeBSD, 10 on Linux, and 23 on the others. This value can be changed + * by setting the property org.pcap4j.af.inet6 (system property or + * pcap4j-core.jar/org/pcap4j/pcap4j.properties). + */ + public static final short AF_INET6; + + /** + * Address family for low level packet interface. This value needs to be the same as AF_PACKET + * defined in <sys/socket.h>. This value may vary depending on OS. This value + * is set to 17 by default and can be changed by setting the property org.pcap4j.af.packet + * (system property or pcap4j-core.jar/org/pcap4j/pcap4j.properties). + */ + public static final short AF_PACKET; + + /** + * Address family for link layer interface. This value needs to be the same as AF_LINK defined in + * <sys/socket.h>. This value may vary depending on OS. This value is set to 18 + * by default and can be changed by setting the property org.pcap4j.af.link (system + * property or pcap4j-core.jar/org/pcap4j/pcap4j.properties). + */ + public static final short AF_LINK; + + static { + AF_INET = 2; + AF_INET6 = 10; + AF_PACKET = 17; + AF_LINK = 18; + } + + private Inets() { + throw new AssertionError(); + } + + static Inet4Address ntoInetAddress(in_addr in) { + if (in == null) { + return null; + } + return itoInetAddress(in.s_addr); + } + + static Inet4Address itoInetAddress(int i) { + return ByteArrays.getInet4Address( + ByteArrays.toByteArray(i, ByteOrder.nativeOrder()), 0); + } + + static Inet6Address ntoInetAddress(in6_addr in6) { + if (in6 == null) { + return null; + } + + try { + return (Inet6Address) InetAddress.getByAddress(in6.s6_addr); + } catch (UnknownHostException e) { + throw new AssertionError(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/NotOpenException.java b/app/src/main/java/org/pcap4j/core/NotOpenException.java index 122e37e..c6057c5 100644 --- a/app/src/main/java/org/pcap4j/core/NotOpenException.java +++ b/app/src/main/java/org/pcap4j/core/NotOpenException.java @@ -1,28 +1,28 @@ -/*_########################################################################## - _## - _## Copyright (C) 2013 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.16 - */ -public final class NotOpenException extends Exception { - - /** */ - private static final long serialVersionUID = -3852491522682861395L; - - /** */ - public NotOpenException() { - super(); - } - - /** @param message message */ - public NotOpenException(String message) { - super(message); - } +/*_########################################################################## + _## + _## Copyright (C) 2013 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.16 + */ +public final class NotOpenException extends Exception { + + /** */ + private static final long serialVersionUID = -3852491522682861395L; + + /** */ + public NotOpenException() { + super(); + } + + /** @param message message */ + public NotOpenException(String message) { + super(message); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/PcapAddress.java b/app/src/main/java/org/pcap4j/core/PcapAddress.java index 1828984..5d09020 100644 --- a/app/src/main/java/org/pcap4j/core/PcapAddress.java +++ b/app/src/main/java/org/pcap4j/core/PcapAddress.java @@ -1,29 +1,29 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2015 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -import java.net.InetAddress; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.1 - */ -public interface PcapAddress { - - /** @return address or null */ - public InetAddress getAddress(); - - /** @return netmask or null */ - public InetAddress getNetmask(); - - /** @return broadcast address or null */ - public InetAddress getBroadcastAddress(); - - /** @return destination address or null */ - public InetAddress getDestinationAddress(); +/*_########################################################################## + _## + _## Copyright (C) 2011-2015 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +import java.net.InetAddress; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.1 + */ +public interface PcapAddress { + + /** @return address or null */ + public InetAddress getAddress(); + + /** @return netmask or null */ + public InetAddress getNetmask(); + + /** @return broadcast address or null */ + public InetAddress getBroadcastAddress(); + + /** @return destination address or null */ + public InetAddress getDestinationAddress(); } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/PcapDumper.java b/app/src/main/java/org/pcap4j/core/PcapDumper.java index 55811e4..a07ebb2 100644 --- a/app/src/main/java/org/pcap4j/core/PcapDumper.java +++ b/app/src/main/java/org/pcap4j/core/PcapDumper.java @@ -1,193 +1,193 @@ -package org.pcap4j.core; - -import android.util.Log; - -import org.pcap4j.packet.Packet; - -import java.io.Closeable; -import java.io.IOException; -import java.sql.Timestamp; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import me.itay.pcapproxy.PcapProxy; -import me.itay.pcapproxy.PcapProxyException; -import me.itay.pcapproxy.structs.pcap_pkthdr; -import me.itay.pcapproxy.structs.timeval; - -public class PcapDumper implements Closeable { - - private static final String TAG = "PcapDumper"; - - private final long dumper; - private final PcapHandle.TimestampPrecision timestampPrecision; - private final ReentrantReadWriteLock dumperLock = new ReentrantReadWriteLock(true); - - private volatile boolean open = true; - - PcapDumper(long dumper, PcapHandle.TimestampPrecision timestampPrecision) { - this.timestampPrecision = timestampPrecision; - this.dumper = dumper; - } - - public long getDumper() { - return dumper; - } - - /** @return true if this PcapDumper is open; false otherwise. */ - public boolean isOpen() { - return open; - } - - /** - * @param packet packet - * @throws NotOpenException if this PcapHandle is not open. - */ - public void dump(Packet packet) throws NotOpenException { - dump(packet, new Timestamp(System.currentTimeMillis())); - } - - /** - * @param packet packet - * @param timestamp timestamp - * @throws NotOpenException if this PcapHandle is not open. - */ - public void dump(Packet packet, Timestamp timestamp) throws NotOpenException { - if (packet == null || timestamp == null) { - StringBuilder sb = new StringBuilder(); - sb.append("packet: ").append(packet).append(" ts: ").append(timestamp); - throw new NullPointerException(sb.toString()); - } - - dumpRaw(packet.getRawData(), timestamp); - } - - /** - * @param packet packet - * @throws NotOpenException if this PcapHandle is not open. - */ - public void dumpRaw(byte[] packet) throws NotOpenException { - dumpRaw(packet, new Timestamp(System.currentTimeMillis())); - } - - /** - * @param packet packet - * @param timestamp timestamp - * @throws NotOpenException if this PcapHandle is not open. - */ - public void dumpRaw(byte[] packet, Timestamp timestamp) throws NotOpenException { - if (packet == null || timestamp == null) { - StringBuilder sb = new StringBuilder(); - sb.append("packet: ").append(packet).append(" timestamp: ").append(timestamp); - throw new NullPointerException(sb.toString()); - } - - if (!open) { - throw new NotOpenException(); - } - - pcap_pkthdr header = new pcap_pkthdr(); - header.len = header.caplen = packet.length; - header.ts = new timeval(); - header.ts.tv_sec = timestamp.getTime() / 1000L; - switch (timestampPrecision) { - case MICRO: - header.ts.tv_usec = timestamp.getNanos() / 1000L; - break; - case NANO: - header.ts.tv_usec = timestamp.getNanos(); - break; - default: - throw new AssertionError("Never get here."); - } - header.data = packet; - - if (!dumperLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - PcapProxy.get().pcap_dump(dumper, header); - } finally { - dumperLock.readLock().unlock(); - } - } - - /** - * @throws PcapProxyException if an error occurs in the pcap native library. - * @throws NotOpenException if this PcapHandle is not open. - */ - public void flush() throws PcapProxyException, NotOpenException { - if (!open) { - throw new NotOpenException(); - } - - int rc; - if (!dumperLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - PcapProxy.get().pcap_dump_flush(dumper); - } finally { - dumperLock.readLock().unlock(); - } - } - - /** - * @return the file position for a "savefile". - * @throws PcapProxyException if an error occurs in the pcap native library. - * @throws NotOpenException if this PcapHandle is not open. - */ - public long ftell() throws PcapProxyException, NotOpenException { - if (!open) { - throw new NotOpenException(); - } - - long position; - if (!dumperLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - position = PcapProxy.get().pcap_dump_ftell(dumper); - } finally { - dumperLock.readLock().unlock(); - } - - if (position < 0) { - throw new PcapProxyException("Failed to get the file position."); - } - - return position; - } - - /** */ - @Override - public void close() { - if (!open) { - Log.w(TAG, "Already closed."); - return; - } - - dumperLock.writeLock().lock(); - try { - if (!open) { - Log.w(TAG, "Already closed."); - return; - } - open = false; - } finally { - dumperLock.writeLock().unlock(); - } - - PcapProxy.get().pcap_dump_close(dumper); - Log.i(TAG, "Closed."); - } -} +package org.pcap4j.core; + +import android.util.Log; + +import org.pcap4j.packet.Packet; + +import java.io.Closeable; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import me.itay.pcapproxy.PcapProxy; +import me.itay.pcapproxy.PcapProxyException; +import me.itay.pcapproxy.structs.pcap_pkthdr; +import me.itay.pcapproxy.structs.timeval; + +public class PcapDumper implements Closeable { + + private static final String TAG = "PcapDumper"; + + private final long dumper; + private final PcapHandle.TimestampPrecision timestampPrecision; + private final ReentrantReadWriteLock dumperLock = new ReentrantReadWriteLock(true); + + private volatile boolean open = true; + + PcapDumper(long dumper, PcapHandle.TimestampPrecision timestampPrecision) { + this.timestampPrecision = timestampPrecision; + this.dumper = dumper; + } + + public long getDumper() { + return dumper; + } + + /** @return true if this PcapDumper is open; false otherwise. */ + public boolean isOpen() { + return open; + } + + /** + * @param packet packet + * @throws NotOpenException if this PcapHandle is not open. + */ + public void dump(Packet packet) throws NotOpenException { + dump(packet, new Timestamp(System.currentTimeMillis())); + } + + /** + * @param packet packet + * @param timestamp timestamp + * @throws NotOpenException if this PcapHandle is not open. + */ + public void dump(Packet packet, Timestamp timestamp) throws NotOpenException { + if (packet == null || timestamp == null) { + StringBuilder sb = new StringBuilder(); + sb.append("packet: ").append(packet).append(" ts: ").append(timestamp); + throw new NullPointerException(sb.toString()); + } + + dumpRaw(packet.getRawData(), timestamp); + } + + /** + * @param packet packet + * @throws NotOpenException if this PcapHandle is not open. + */ + public void dumpRaw(byte[] packet) throws NotOpenException { + dumpRaw(packet, new Timestamp(System.currentTimeMillis())); + } + + /** + * @param packet packet + * @param timestamp timestamp + * @throws NotOpenException if this PcapHandle is not open. + */ + public void dumpRaw(byte[] packet, Timestamp timestamp) throws NotOpenException { + if (packet == null || timestamp == null) { + StringBuilder sb = new StringBuilder(); + sb.append("packet: ").append(packet).append(" timestamp: ").append(timestamp); + throw new NullPointerException(sb.toString()); + } + + if (!open) { + throw new NotOpenException(); + } + + pcap_pkthdr header = new pcap_pkthdr(); + header.len = header.caplen = packet.length; + header.ts = new timeval(); + header.ts.tv_sec = timestamp.getTime() / 1000L; + switch (timestampPrecision) { + case MICRO: + header.ts.tv_usec = timestamp.getNanos() / 1000L; + break; + case NANO: + header.ts.tv_usec = timestamp.getNanos(); + break; + default: + throw new AssertionError("Never get here."); + } + header.data = packet; + + if (!dumperLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + PcapProxy.get().pcap_dump(dumper, header); + } finally { + dumperLock.readLock().unlock(); + } + } + + /** + * @throws PcapProxyException if an error occurs in the pcap native library. + * @throws NotOpenException if this PcapHandle is not open. + */ + public void flush() throws PcapProxyException, NotOpenException { + if (!open) { + throw new NotOpenException(); + } + + int rc; + if (!dumperLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + PcapProxy.get().pcap_dump_flush(dumper); + } finally { + dumperLock.readLock().unlock(); + } + } + + /** + * @return the file position for a "savefile". + * @throws PcapProxyException if an error occurs in the pcap native library. + * @throws NotOpenException if this PcapHandle is not open. + */ + public long ftell() throws PcapProxyException, NotOpenException { + if (!open) { + throw new NotOpenException(); + } + + long position; + if (!dumperLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + position = PcapProxy.get().pcap_dump_ftell(dumper); + } finally { + dumperLock.readLock().unlock(); + } + + if (position < 0) { + throw new PcapProxyException("Failed to get the file position."); + } + + return position; + } + + /** */ + @Override + public void close() { + if (!open) { + Log.w(TAG, "Already closed."); + return; + } + + dumperLock.writeLock().lock(); + try { + if (!open) { + Log.w(TAG, "Already closed."); + return; + } + open = false; + } finally { + dumperLock.writeLock().unlock(); + } + + PcapProxy.get().pcap_dump_close(dumper); + Log.i(TAG, "Closed."); + } +} diff --git a/app/src/main/java/org/pcap4j/core/PcapHandle.java b/app/src/main/java/org/pcap4j/core/PcapHandle.java index e4273fe..a963a16 100644 --- a/app/src/main/java/org/pcap4j/core/PcapHandle.java +++ b/app/src/main/java/org/pcap4j/core/PcapHandle.java @@ -1,473 +1,473 @@ -package org.pcap4j.core; - -import android.util.Log; - -import org.pcap4j.packet.Packet; -import org.pcap4j.packet.factory.PacketFactories; -import org.pcap4j.packet.namednumber.DataLinkType; - -import java.io.Closeable; -import java.io.IOException; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.sql.Timestamp; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import me.itay.pcapproxy.PcapProxy; -import me.itay.pcapproxy.PcapProxyException; -import me.itay.pcapproxy.structs.pcap_pkthdr; -import me.itay.pcapproxy.structs.pcap_stat; - -public class PcapHandle implements Closeable { - - private static final String TAG = "PcapHandle"; - - private volatile DataLinkType dlt; - private final TimestampPrecision timestampPrecision; - private final long handle; - private final ThreadLocal timestamps = new ThreadLocal(); - private final ThreadLocal originalLengths = new ThreadLocal(); - private final ReentrantReadWriteLock handleLock = new ReentrantReadWriteLock(true); - private static final Object compileLock = new Object(); - - private volatile boolean open = true; - private volatile String filteringExpression = ""; - - /** - * The netmask used for {@link #setFilter(String, BpfProgram.BpfCompileMode, Inet4Address)} or - * {@link #compileFilter(String, BpfProgram.BpfCompileMode, Inet4Address)} when you don't know - * what netmask you should use. - */ - public static final Inet4Address PCAP_NETMASK_UNKNOWN; - - static { - try { - PCAP_NETMASK_UNKNOWN = (Inet4Address) InetAddress.getByName("255.255.255.255"); - } catch (UnknownHostException e) { - throw new AssertionError("never get here"); - } - } - - PcapHandle(long handle, TimestampPrecision timestampPrecision) { - this.handle = handle; - this.dlt = getDltByNative(); - this.timestampPrecision = timestampPrecision; - } - - private DataLinkType getDltByNative() { - return DataLinkType.getInstance(PcapProxy.get().pcap_datalink(handle)); - } - - /** @return the Data Link Type of this PcapHandle */ - public DataLinkType getDlt() { - return dlt; - } - - // TODO setDlt - - /** - * @return true if this PcapHandle object is open (i.e. not yet closed by {@link #close() - * close()}); false otherwise. - */ - public boolean isOpen() { - return open; - } - - /** @return the filtering expression of this PcapHandle */ - public String getFilteringExpression() { - return filteringExpression; - } - - /** @return Timestamp precision */ - public TimestampPrecision getTimestampPrecision() { - return timestampPrecision; - } - - // TODO: setDirection - - /** @return the timestamp of the last packet captured by this handle in the current thread. */ - public Timestamp getTimestamp() { - return timestamps.get(); - } - - /** - * @return the original length of the last packet captured by this handle in the current thread. - */ - public Integer getOriginalLength() { - return originalLengths.get(); - } - - // TODO: getSnapshot - - // TODO: isSwapped - - // TODO: getMajorVersion - - // TODO: getMinorVersion - - // TODO: compileFilter - - // TODO: setFilter - - /** - * @param mode mode - * @throws PcapProxyException if an error occurs in the pcap native library. - * @throws NotOpenException if this PcapHandle is not open. - */ - public void setBlockingMode(BlockingMode mode) throws PcapProxyException, NotOpenException { - if (mode == null) { - StringBuilder sb = new StringBuilder(); - sb.append(" mode: ").append(mode); - throw new NullPointerException(sb.toString()); - } - if (!open) { - throw new NotOpenException(); - } - - if (!handleLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - - PcapProxy.get().pcap_setnonblock(handle, mode.getValue()); - } finally { - handleLock.readLock().unlock(); - } - } - - /** - * @return blocking mode - * @throws PcapProxyException if an error occurs in the pcap native library. - * @throws NotOpenException if this PcapHandle is not open. - */ - public BlockingMode getBlockingMode() throws PcapProxyException, NotOpenException { - if (!open) { - throw new NotOpenException(); - } - - int rc; - if (!handleLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - rc = PcapProxy.get().pcap_getnonblock(handle); - } finally { - handleLock.readLock().unlock(); - } - - if (rc == 0) { - return BlockingMode.BLOCKING; - } else if (rc > 0) { - return BlockingMode.NONBLOCKING; - } else { - throw new PcapProxyException(); - } - } - - /** - * @return a Packet object created from a captured packet using the packet factory. May be null. - * @throws NotOpenException if this PcapHandle is not open. - */ - public Packet getNextPacket() throws NotOpenException { - byte[] ba = getNextRawPacket(); - if (ba == null) { - return null; - } - - return PacketFactories.getFactory(Packet.class, DataLinkType.class) - .newInstance(ba, 0, ba.length, dlt); - } - - /** - * @return a captured packet. May be null. - * @throws NotOpenException if this PcapHandle is not open. - */ - public byte[] getNextRawPacket() throws NotOpenException { - if (!open) { - throw new NotOpenException(); - } - - if (!handleLock.readLock().tryLock()) { - throw new NotOpenException(); - } - - pcap_pkthdr header = null; - try { - if (!open) { - throw new NotOpenException(); - } - header = PcapProxy.get().pcap_next(handle); - } finally { - handleLock.readLock().unlock(); - } - - if (header != null) { - return header.data; - } else { - return null; - } - } - - // TODO: getNextPacketEx - - // TODO: getNextRawPacketEx - - // TODO: loop - - // TODO: dispatch - - /** - * @param filePath "-" means stdout. The dlt of the PcapHandle which captured the packets you want - * to dump must be the same as this dlt. - * @return an opened PcapDumper. - * @throws PcapProxyException if an error occurs in the pcap native library. - * @throws NotOpenException if this PcapHandle is not open. - */ - public PcapDumper dumpOpen(String filePath) throws PcapProxyException, NotOpenException { - if (filePath == null) { - throw new NullPointerException("filePath must not be null."); - } - if (!open) { - throw new NotOpenException(); - } - - long dumper; - if (!handleLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - - dumper = PcapProxy.get().pcap_dump_open(handle, filePath); - if (dumper == 0) { - throw new PcapProxyException(getError()); - } - } finally { - handleLock.readLock().unlock(); - } - - return new PcapDumper(dumper, timestampPrecision); - } - - // TODO: breakLoop - - // TODO: sendPacket - - /** - * @return a {@link org.pcap4j.core.PcapStat PcapStat} object. - * @throws PcapProxyException if an error occurs in the pcap native library. - * @throws NotOpenException if this PcapHandle is not open. - */ - public PcapStat getStats() throws PcapProxyException, NotOpenException { - if (!open) { - throw new NotOpenException(); - } - - if (!handleLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - - pcap_stat ps = PcapProxy.get().pcap_stats(handle); - return new PcapStat(ps); - } finally { - handleLock.readLock().unlock(); - } - } - - // TODO: listDatalinks - - /** - * @return an error message. - * @throws NotOpenException if this PcapHandle is not open. - */ - public String getError() throws NotOpenException { - if (!open) { - throw new NotOpenException(); - } - - if (!handleLock.readLock().tryLock()) { - throw new NotOpenException(); - } - try { - if (!open) { - throw new NotOpenException(); - } - return PcapProxy.get().pcap_geterr(handle); - } finally { - handleLock.readLock().unlock(); - } - } - - @Override - public void close() throws IOException { - if(!open) { - Log.w(TAG, "Already closed"); - return; - } - - handleLock.writeLock().lock(); - try { - if(!open) { - Log.w(TAG, "Already closed"); - return; - } - open = false; - } finally { - handleLock.writeLock().unlock(); - } - - PcapProxy.get().pcap_close(handle); - Log.i(TAG, "Closed."); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(60); - - sb.append("Link type: [") - .append(dlt) - .append("] handle: [") - .append(handle) - .append("] Open: [") - .append(open) - .append("] Filtering Expr: [") - .append(filteringExpression) - .append("]"); - - return sb.toString(); - } - - // TODO: SimpleExecutor - - // TODO: GotPacketFuncExecutor - - // TODO GotRawPacketFuncExecutor - - // TODO: Builder - - /** - * @author Kaito Yamada - * @version pcap4j 0.9.16 - */ - public static enum SwappedType { - - /** */ - NOT_SWAPPED(0), - - /** */ - SWAPPED(1), - - /** */ - MAYBE_SWAPPED(2); - - private final int value; - - private SwappedType(int value) { - this.value = value; - } - - /** @return value */ - public int getValue() { - return value; - } - } - - /** - * @author Kaito Yamada - * @version pcap4j 0.9.15 - */ - public static enum BlockingMode { - - /** */ - BLOCKING(0), - - /** */ - NONBLOCKING(1); - - private final int value; - - private BlockingMode(int value) { - this.value = value; - } - - /** @return value */ - public int getValue() { - return value; - } - } - - /** - * @author Kaito Yamada - * @version pcap4j 1.5.1 - */ - public static enum TimestampPrecision { - - /** use timestamps with microsecond precision, default */ - MICRO(0), - - /** use timestamps with nanosecond precision */ - NANO(1); - - private final int value; - - private TimestampPrecision(int value) { - this.value = value; - } - - /** @return value */ - public int getValue() { - return value; - } - } - - /** - * Direction of packets. - * - *
-     * typedef enum {
-     *   PCAP_D_INOUT = 0,
-     *   PCAP_D_IN,
-     *   PCAP_D_OUT
-     * } pcap_direction_t;
-     * 
- * - * @author Kaito Yamada - * @version pcap4j 1.6.4 - */ - public static enum PcapDirection { - - /** Both inbound and outbound. */ - INOUT(0), - - /** Inbound only. */ - IN(1), - - /** Outbound only, */ - OUT(2); - - private final int value; - - private PcapDirection(int value) { - this.value = value; - } - - /** @return value */ - public int getValue() { - return value; - } - } - -} +package org.pcap4j.core; + +import android.util.Log; + +import org.pcap4j.packet.Packet; +import org.pcap4j.packet.factory.PacketFactories; +import org.pcap4j.packet.namednumber.DataLinkType; + +import java.io.Closeable; +import java.io.IOException; +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.sql.Timestamp; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import me.itay.pcapproxy.PcapProxy; +import me.itay.pcapproxy.PcapProxyException; +import me.itay.pcapproxy.structs.pcap_pkthdr; +import me.itay.pcapproxy.structs.pcap_stat; + +public class PcapHandle implements Closeable { + + private static final String TAG = "PcapHandle"; + + private volatile DataLinkType dlt; + private final TimestampPrecision timestampPrecision; + private final long handle; + private final ThreadLocal timestamps = new ThreadLocal(); + private final ThreadLocal originalLengths = new ThreadLocal(); + private final ReentrantReadWriteLock handleLock = new ReentrantReadWriteLock(true); + private static final Object compileLock = new Object(); + + private volatile boolean open = true; + private volatile String filteringExpression = ""; + + /** + * The netmask used for {@link #setFilter(String, BpfProgram.BpfCompileMode, Inet4Address)} or + * {@link #compileFilter(String, BpfProgram.BpfCompileMode, Inet4Address)} when you don't know + * what netmask you should use. + */ + public static final Inet4Address PCAP_NETMASK_UNKNOWN; + + static { + try { + PCAP_NETMASK_UNKNOWN = (Inet4Address) InetAddress.getByName("255.255.255.255"); + } catch (UnknownHostException e) { + throw new AssertionError("never get here"); + } + } + + PcapHandle(long handle, TimestampPrecision timestampPrecision) { + this.handle = handle; + this.dlt = getDltByNative(); + this.timestampPrecision = timestampPrecision; + } + + private DataLinkType getDltByNative() { + return DataLinkType.getInstance(PcapProxy.get().pcap_datalink(handle)); + } + + /** @return the Data Link Type of this PcapHandle */ + public DataLinkType getDlt() { + return dlt; + } + + // TODO setDlt + + /** + * @return true if this PcapHandle object is open (i.e. not yet closed by {@link #close() + * close()}); false otherwise. + */ + public boolean isOpen() { + return open; + } + + /** @return the filtering expression of this PcapHandle */ + public String getFilteringExpression() { + return filteringExpression; + } + + /** @return Timestamp precision */ + public TimestampPrecision getTimestampPrecision() { + return timestampPrecision; + } + + // TODO: setDirection + + /** @return the timestamp of the last packet captured by this handle in the current thread. */ + public Timestamp getTimestamp() { + return timestamps.get(); + } + + /** + * @return the original length of the last packet captured by this handle in the current thread. + */ + public Integer getOriginalLength() { + return originalLengths.get(); + } + + // TODO: getSnapshot + + // TODO: isSwapped + + // TODO: getMajorVersion + + // TODO: getMinorVersion + + // TODO: compileFilter + + // TODO: setFilter + + /** + * @param mode mode + * @throws PcapProxyException if an error occurs in the pcap native library. + * @throws NotOpenException if this PcapHandle is not open. + */ + public void setBlockingMode(BlockingMode mode) throws PcapProxyException, NotOpenException { + if (mode == null) { + StringBuilder sb = new StringBuilder(); + sb.append(" mode: ").append(mode); + throw new NullPointerException(sb.toString()); + } + if (!open) { + throw new NotOpenException(); + } + + if (!handleLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + + PcapProxy.get().pcap_setnonblock(handle, mode.getValue()); + } finally { + handleLock.readLock().unlock(); + } + } + + /** + * @return blocking mode + * @throws PcapProxyException if an error occurs in the pcap native library. + * @throws NotOpenException if this PcapHandle is not open. + */ + public BlockingMode getBlockingMode() throws PcapProxyException, NotOpenException { + if (!open) { + throw new NotOpenException(); + } + + int rc; + if (!handleLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + rc = PcapProxy.get().pcap_getnonblock(handle); + } finally { + handleLock.readLock().unlock(); + } + + if (rc == 0) { + return BlockingMode.BLOCKING; + } else if (rc > 0) { + return BlockingMode.NONBLOCKING; + } else { + throw new PcapProxyException(); + } + } + + /** + * @return a Packet object created from a captured packet using the packet factory. May be null. + * @throws NotOpenException if this PcapHandle is not open. + */ + public Packet getNextPacket() throws NotOpenException { + byte[] ba = getNextRawPacket(); + if (ba == null) { + return null; + } + + return PacketFactories.getFactory(Packet.class, DataLinkType.class) + .newInstance(ba, 0, ba.length, dlt); + } + + /** + * @return a captured packet. May be null. + * @throws NotOpenException if this PcapHandle is not open. + */ + public byte[] getNextRawPacket() throws NotOpenException { + if (!open) { + throw new NotOpenException(); + } + + if (!handleLock.readLock().tryLock()) { + throw new NotOpenException(); + } + + pcap_pkthdr header = null; + try { + if (!open) { + throw new NotOpenException(); + } + header = PcapProxy.get().pcap_next(handle); + } finally { + handleLock.readLock().unlock(); + } + + if (header != null) { + return header.data; + } else { + return null; + } + } + + // TODO: getNextPacketEx + + // TODO: getNextRawPacketEx + + // TODO: loop + + // TODO: dispatch + + /** + * @param filePath "-" means stdout. The dlt of the PcapHandle which captured the packets you want + * to dump must be the same as this dlt. + * @return an opened PcapDumper. + * @throws PcapProxyException if an error occurs in the pcap native library. + * @throws NotOpenException if this PcapHandle is not open. + */ + public PcapDumper dumpOpen(String filePath) throws PcapProxyException, NotOpenException { + if (filePath == null) { + throw new NullPointerException("filePath must not be null."); + } + if (!open) { + throw new NotOpenException(); + } + + long dumper; + if (!handleLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + + dumper = PcapProxy.get().pcap_dump_open(handle, filePath); + if (dumper == 0) { + throw new PcapProxyException(getError()); + } + } finally { + handleLock.readLock().unlock(); + } + + return new PcapDumper(dumper, timestampPrecision); + } + + // TODO: breakLoop + + // TODO: sendPacket + + /** + * @return a {@link org.pcap4j.core.PcapStat PcapStat} object. + * @throws PcapProxyException if an error occurs in the pcap native library. + * @throws NotOpenException if this PcapHandle is not open. + */ + public PcapStat getStats() throws PcapProxyException, NotOpenException { + if (!open) { + throw new NotOpenException(); + } + + if (!handleLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + + pcap_stat ps = PcapProxy.get().pcap_stats(handle); + return new PcapStat(ps); + } finally { + handleLock.readLock().unlock(); + } + } + + // TODO: listDatalinks + + /** + * @return an error message. + * @throws NotOpenException if this PcapHandle is not open. + */ + public String getError() throws NotOpenException { + if (!open) { + throw new NotOpenException(); + } + + if (!handleLock.readLock().tryLock()) { + throw new NotOpenException(); + } + try { + if (!open) { + throw new NotOpenException(); + } + return PcapProxy.get().pcap_geterr(handle); + } finally { + handleLock.readLock().unlock(); + } + } + + @Override + public void close() throws IOException { + if(!open) { + Log.w(TAG, "Already closed"); + return; + } + + handleLock.writeLock().lock(); + try { + if(!open) { + Log.w(TAG, "Already closed"); + return; + } + open = false; + } finally { + handleLock.writeLock().unlock(); + } + + PcapProxy.get().pcap_close(handle); + Log.i(TAG, "Closed."); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(60); + + sb.append("Link type: [") + .append(dlt) + .append("] handle: [") + .append(handle) + .append("] Open: [") + .append(open) + .append("] Filtering Expr: [") + .append(filteringExpression) + .append("]"); + + return sb.toString(); + } + + // TODO: SimpleExecutor + + // TODO: GotPacketFuncExecutor + + // TODO GotRawPacketFuncExecutor + + // TODO: Builder + + /** + * @author Kaito Yamada + * @version pcap4j 0.9.16 + */ + public static enum SwappedType { + + /** */ + NOT_SWAPPED(0), + + /** */ + SWAPPED(1), + + /** */ + MAYBE_SWAPPED(2); + + private final int value; + + private SwappedType(int value) { + this.value = value; + } + + /** @return value */ + public int getValue() { + return value; + } + } + + /** + * @author Kaito Yamada + * @version pcap4j 0.9.15 + */ + public static enum BlockingMode { + + /** */ + BLOCKING(0), + + /** */ + NONBLOCKING(1); + + private final int value; + + private BlockingMode(int value) { + this.value = value; + } + + /** @return value */ + public int getValue() { + return value; + } + } + + /** + * @author Kaito Yamada + * @version pcap4j 1.5.1 + */ + public static enum TimestampPrecision { + + /** use timestamps with microsecond precision, default */ + MICRO(0), + + /** use timestamps with nanosecond precision */ + NANO(1); + + private final int value; + + private TimestampPrecision(int value) { + this.value = value; + } + + /** @return value */ + public int getValue() { + return value; + } + } + + /** + * Direction of packets. + * + *
+     * typedef enum {
+     *   PCAP_D_INOUT = 0,
+     *   PCAP_D_IN,
+     *   PCAP_D_OUT
+     * } pcap_direction_t;
+     * 
+ * + * @author Kaito Yamada + * @version pcap4j 1.6.4 + */ + public static enum PcapDirection { + + /** Both inbound and outbound. */ + INOUT(0), + + /** Inbound only. */ + IN(1), + + /** Outbound only, */ + OUT(2); + + private final int value; + + private PcapDirection(int value) { + this.value = value; + } + + /** @return value */ + public int getValue() { + return value; + } + } + +} diff --git a/app/src/main/java/org/pcap4j/core/PcapIpV4Address.java b/app/src/main/java/org/pcap4j/core/PcapIpV4Address.java index c4da074..ef76dd2 100644 --- a/app/src/main/java/org/pcap4j/core/PcapIpV4Address.java +++ b/app/src/main/java/org/pcap4j/core/PcapIpV4Address.java @@ -1,55 +1,55 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2015 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -import java.net.Inet4Address; - -import me.itay.pcapproxy.structs.pcap_addr; -import me.itay.pcapproxy.structs.sockaddr; -import me.itay.pcapproxy.structs.sockaddr_in; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.15 - */ -public final class PcapIpV4Address extends AbstractPcapAddress { - - private PcapIpV4Address(pcap_addr pcapAddr, short saFamily, String devName) { - super(pcapAddr, saFamily, devName); - } - - static PcapIpV4Address newInstance(pcap_addr pcapAddr, short saFamily, String devName) { - return new PcapIpV4Address(pcapAddr, saFamily, devName); - } - - @Override - protected Inet4Address ntoInetAddress(sockaddr sa) { - sockaddr_in addr = new sockaddr_in(sa); - return Inets.ntoInetAddress(addr.sin_addr); - } - - @Override - public Inet4Address getAddress() { - return (Inet4Address) super.getAddress(); - } - - @Override - public Inet4Address getNetmask() { - return (Inet4Address) super.getNetmask(); - } - - @Override - public Inet4Address getBroadcastAddress() { - return (Inet4Address) super.getBroadcastAddress(); - } - - @Override - public Inet4Address getDestinationAddress() { - return (Inet4Address) super.getDestinationAddress(); - } +/*_########################################################################## + _## + _## Copyright (C) 2011-2015 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +import java.net.Inet4Address; + +import me.itay.pcapproxy.structs.pcap_addr; +import me.itay.pcapproxy.structs.sockaddr; +import me.itay.pcapproxy.structs.sockaddr_in; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.15 + */ +public final class PcapIpV4Address extends AbstractPcapAddress { + + private PcapIpV4Address(pcap_addr pcapAddr, short saFamily, String devName) { + super(pcapAddr, saFamily, devName); + } + + static PcapIpV4Address newInstance(pcap_addr pcapAddr, short saFamily, String devName) { + return new PcapIpV4Address(pcapAddr, saFamily, devName); + } + + @Override + protected Inet4Address ntoInetAddress(sockaddr sa) { + sockaddr_in addr = new sockaddr_in(sa); + return Inets.ntoInetAddress(addr.sin_addr); + } + + @Override + public Inet4Address getAddress() { + return (Inet4Address) super.getAddress(); + } + + @Override + public Inet4Address getNetmask() { + return (Inet4Address) super.getNetmask(); + } + + @Override + public Inet4Address getBroadcastAddress() { + return (Inet4Address) super.getBroadcastAddress(); + } + + @Override + public Inet4Address getDestinationAddress() { + return (Inet4Address) super.getDestinationAddress(); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/PcapIpV6Address.java b/app/src/main/java/org/pcap4j/core/PcapIpV6Address.java index 2e39cc3..722e5db 100644 --- a/app/src/main/java/org/pcap4j/core/PcapIpV6Address.java +++ b/app/src/main/java/org/pcap4j/core/PcapIpV6Address.java @@ -1,55 +1,55 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2015 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -import java.net.Inet6Address; - -import me.itay.pcapproxy.structs.pcap_addr; -import me.itay.pcapproxy.structs.sockaddr; -import me.itay.pcapproxy.structs.sockaddr_in6; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.15 - */ -public final class PcapIpV6Address extends AbstractPcapAddress { - - private PcapIpV6Address(pcap_addr pcapAddr, short saFamily, String devName) { - super(pcapAddr, saFamily, devName); - } - - static PcapIpV6Address newInstance(pcap_addr pcapAddr, short saFamily, String devName) { - return new PcapIpV6Address(pcapAddr, saFamily, devName); - } - - @Override - protected Inet6Address ntoInetAddress(sockaddr sa) { - sockaddr_in6 addr = new sockaddr_in6(sa); - return Inets.ntoInetAddress(addr.sin6_addr); - } - - @Override - public Inet6Address getAddress() { - return (Inet6Address) super.getAddress(); - } - - @Override - public Inet6Address getNetmask() { - return (Inet6Address) super.getNetmask(); - } - - @Override - public Inet6Address getBroadcastAddress() { - return (Inet6Address) super.getBroadcastAddress(); - } - - @Override - public Inet6Address getDestinationAddress() { - return (Inet6Address) super.getDestinationAddress(); - } +/*_########################################################################## + _## + _## Copyright (C) 2011-2015 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +import java.net.Inet6Address; + +import me.itay.pcapproxy.structs.pcap_addr; +import me.itay.pcapproxy.structs.sockaddr; +import me.itay.pcapproxy.structs.sockaddr_in6; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.15 + */ +public final class PcapIpV6Address extends AbstractPcapAddress { + + private PcapIpV6Address(pcap_addr pcapAddr, short saFamily, String devName) { + super(pcapAddr, saFamily, devName); + } + + static PcapIpV6Address newInstance(pcap_addr pcapAddr, short saFamily, String devName) { + return new PcapIpV6Address(pcapAddr, saFamily, devName); + } + + @Override + protected Inet6Address ntoInetAddress(sockaddr sa) { + sockaddr_in6 addr = new sockaddr_in6(sa); + return Inets.ntoInetAddress(addr.sin6_addr); + } + + @Override + public Inet6Address getAddress() { + return (Inet6Address) super.getAddress(); + } + + @Override + public Inet6Address getNetmask() { + return (Inet6Address) super.getNetmask(); + } + + @Override + public Inet6Address getBroadcastAddress() { + return (Inet6Address) super.getBroadcastAddress(); + } + + @Override + public Inet6Address getDestinationAddress() { + return (Inet6Address) super.getDestinationAddress(); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/PcapNetworkInterface.java b/app/src/main/java/org/pcap4j/core/PcapNetworkInterface.java index 5be31eb..f907c69 100644 --- a/app/src/main/java/org/pcap4j/core/PcapNetworkInterface.java +++ b/app/src/main/java/org/pcap4j/core/PcapNetworkInterface.java @@ -1,322 +1,322 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2018 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -import android.util.Log; - -import org.pcap4j.util.ByteArrays; -import org.pcap4j.util.LinkLayerAddress; - -import java.util.ArrayList; -import java.util.List; - -import me.itay.pcapproxy.PcapProxy; -import me.itay.pcapproxy.PcapProxyException; -import me.itay.pcapproxy.structs.pcap_addr; -import me.itay.pcapproxy.structs.pcap_if; -import me.itay.pcapproxy.structs.sockaddr_ll; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.1 - */ -public final class PcapNetworkInterface { - - private static final String TAG = "PcapNetworkInterface"; - - private static final int PCAP_IF_LOOPBACK = 0x00000001; - private static final int PCAP_IF_UP = 0x00000002; - private static final int PCAP_IF_RUNNING = 0x00000004; - - private final String name; - private final String description; - private final List addresses = new ArrayList(); - private final List linkLayerAddresses = new ArrayList(); - private final boolean loopBack; - private final boolean up; - private final boolean running; - private final boolean local; - - private PcapNetworkInterface(pcap_if pif, boolean local) { - this.name = pif.name; - this.description = pif.description; - - for (pcap_addr pcapAddr : pif.addresses) { - if (pcapAddr.addr == null - && pcapAddr.netmask == null - && pcapAddr.broadaddr == null - && pcapAddr.dstaddr == null) { - Log.w(TAG, String.format("Empty pcap_addr on %s (%s). Ignore it.", name, description)); - continue; - } - - short sa_family = - pcapAddr.addr != null - ? pcapAddr.addr.getSaFamily() - : pcapAddr.netmask != null - ? pcapAddr.netmask.getSaFamily() - : pcapAddr.broadaddr != null - ? pcapAddr.broadaddr.getSaFamily() - : pcapAddr.dstaddr != null - ? pcapAddr.dstaddr.getSaFamily() - : Inets.AF_UNSPEC; // Never get here. - if (sa_family == Inets.AF_INET) { - addresses.add(PcapIpV4Address.newInstance(pcapAddr, sa_family, name)); - } else if (sa_family == Inets.AF_INET6) { - addresses.add(PcapIpV6Address.newInstance(pcapAddr, sa_family, name)); - } else { - if (sa_family == Inets.AF_PACKET) { - sockaddr_ll sll = new sockaddr_ll(pcapAddr.addr); - byte[] addr = sll.sll_addr; - int addrLength = sll.sll_halen & 0xFF; - if (addrLength == 6) { - linkLayerAddresses.add(ByteArrays.getMacAddress(addr, 0)); - } else if (addr.length == 0) { - continue; - } else { - // addrLength (i.e. sll_halen) may exceed addr.length (i.e. sll.sll_addr.length). - // If it's the case, need to shorten addrLength here to avoid - // ArrayIndexOutOfBoundsException in - // the succeeding ByteArrays.getSubArray(). - // https://github.com/kaitoy/pcap4j/issues/228 - addrLength = addrLength <= addr.length ? addrLength : addr.length; - linkLayerAddresses.add( - LinkLayerAddress.getByAddress(ByteArrays.getSubArray(addr, 0, addrLength))); - } - } else { - Log.w(TAG, String.format("%d is not supported address family. Ignore it.", sa_family)); - } - } - } - - this.loopBack = (pif.flags & PCAP_IF_LOOPBACK) != 0; - this.up = (pif.flags & PCAP_IF_UP) != 0; - this.running = (pif.flags & PCAP_IF_RUNNING) != 0; - this.local = local; - } - - static PcapNetworkInterface newInstance(pcap_if pif, boolean local) { - return new PcapNetworkInterface(pif, local); - } - - /** @return name */ - public String getName() { - return name; - } - - /** @return description */ - public String getDescription() { - return description; - } - - /** @return inet addresses */ - public List getAddresses() { - return new ArrayList(addresses); - } - - /** @return link layer addresses */ - public ArrayList getLinkLayerAddresses() { - return new ArrayList(linkLayerAddresses); - } - - /** - * Returns if this network interface is loopback. This method may always return false on some - * environments. - * - * @return true if the network interface represented by this object is a loop back interface; - * false otherwise. - */ - public boolean isLoopBack() { - return loopBack; - } - - /** - * Returns if this network interface is up. This method may always return false on some - * environments. - * - * @return true if the network interface represented by this object is up; false otherwise. - */ - public boolean isUp() { - return up; - } - - /** - * Returns if this network interface is running. This method may always return false on some - * environments. - * - * @return true if the network interface represented by this object is running; false otherwise. - */ - public boolean isRunning() { - return running; - } - - /** - * @return true if the network interface represented by this object is a local interface; false - * otherwise. - */ - public boolean isLocal() { - return local; - } - - /** - * @author Kaito Yamada - * @version pcap4j 0.9.1 - */ - public enum PromiscuousMode { - - /** */ - PROMISCUOUS(1), - - /** */ - NONPROMISCUOUS(0); - - private final int value; - - private PromiscuousMode(int value) { - this.value = value; - } - - /** @return value */ - public int getValue() { - return value; - } - } - - /** - * @param snaplen Snapshot length, which is the number of bytes captured for each packet. - * @param mode mode - * @param timeoutMillis Read timeout. Most OSs buffer packets. The OSs pass the packets to Pcap4j - * after the buffer gets full or the read timeout expires. Must be non-negative. May be - * ignored by some OSs. 0 means infinite. - * @return a new PcapHandle object. - * @throws PcapProxyException if an error occurs in the pcap native library. - */ - public PcapHandle openLive(int snaplen, PromiscuousMode mode, int timeoutMillis) throws PcapProxyException { - if (mode == null) { - StringBuilder sb = new StringBuilder(); - sb.append("mode: ").append(mode); - throw new NullPointerException(sb.toString()); - } - - long handle = PcapProxy.get().pcap_open_live(name, snaplen, mode.getValue(), timeoutMillis); - return new PcapHandle(handle, PcapHandle.TimestampPrecision.MICRO); - } - -// private MacAddress getMacAddress(String nifName) { -// Pointer lpAdapter = NativePacketDllMappings.PacketOpenAdapter(nifName); -// -// long hFile = -1; -// if (lpAdapter != null) { -// if (Native.POINTER_SIZE == 4) { -// hFile = lpAdapter.getInt(0); -// } else { -// hFile = lpAdapter.getLong(0); -// } -// } -// if (hFile == -1L) { -// int err = Native.getLastError(); -// logger.error("Unable to open the NIF {}, Error Code: {}", nifName, err); -// return null; -// } -// -// Memory mem = new Memory(NativePacketDllMappings.PACKET_OID_DATA_SIZE); -// mem.clear(); -// PACKET_OID_DATA oidData = new PACKET_OID_DATA(mem); -// oidData.Length = new NativeLong(6L); -// oidData.Oid = new NativeLong(0x01010102L); -// int status = NativePacketDllMappings.PacketRequest(lpAdapter, 0, oidData); -// NativePacketDllMappings.PacketCloseAdapter(lpAdapter); -// -// if (status == 0) { -// logger.error("Failed to retrieve the link layer address of the NIF: {}", nifName); -// return null; -// } else { -// return MacAddress.getByAddress(oidData.Data); -// } -// } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(250); - - sb.append("name: [").append(name).append("] description: [").append(description); - - for (PcapAddress addr : addresses) { - sb.append("] address: [").append(addr.getAddress()); - } - - for (LinkLayerAddress addr : linkLayerAddresses) { - sb.append("] link layer address: [").append(addr.getAddress()); - } - - sb.append("] loopBack: [").append(loopBack).append("]"); - sb.append("] up: [").append(up).append("]"); - sb.append("] running: [").append(running).append("]"); - sb.append("] local: [").append(local).append("]"); - - return sb.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + addresses.hashCode(); - result = prime * result + ((description == null) ? 0 : description.hashCode()); - result = prime * result + linkLayerAddresses.hashCode(); - result = prime * result + (local ? 1231 : 1237); - result = prime * result + (loopBack ? 1231 : 1237); - result = prime * result + (up ? 1231 : 1237); - result = prime * result + (running ? 1231 : 1237); - result = prime * result + name.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof PcapNetworkInterface)) { - return false; - } - PcapNetworkInterface other = (PcapNetworkInterface) obj; - if (!addresses.equals(other.addresses)) { - return false; - } - if (description == null) { - if (other.description != null) { - return false; - } - } else if (!description.equals(other.description)) { - return false; - } - if (!linkLayerAddresses.equals(other.linkLayerAddresses)) { - return false; - } - if (local != other.local) { - return false; - } - if (loopBack != other.loopBack) { - return false; - } - if (up != other.up) { - return false; - } - if (running != other.running) { - return false; - } - if (!name.equals(other.name)) { - return false; - } - return true; - } +/*_########################################################################## + _## + _## Copyright (C) 2011-2018 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +import android.util.Log; + +import org.pcap4j.util.ByteArrays; +import org.pcap4j.util.LinkLayerAddress; + +import java.util.ArrayList; +import java.util.List; + +import me.itay.pcapproxy.PcapProxy; +import me.itay.pcapproxy.PcapProxyException; +import me.itay.pcapproxy.structs.pcap_addr; +import me.itay.pcapproxy.structs.pcap_if; +import me.itay.pcapproxy.structs.sockaddr_ll; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.1 + */ +public final class PcapNetworkInterface { + + private static final String TAG = "PcapNetworkInterface"; + + private static final int PCAP_IF_LOOPBACK = 0x00000001; + private static final int PCAP_IF_UP = 0x00000002; + private static final int PCAP_IF_RUNNING = 0x00000004; + + private final String name; + private final String description; + private final List addresses = new ArrayList(); + private final List linkLayerAddresses = new ArrayList(); + private final boolean loopBack; + private final boolean up; + private final boolean running; + private final boolean local; + + private PcapNetworkInterface(pcap_if pif, boolean local) { + this.name = pif.name; + this.description = pif.description; + + for (pcap_addr pcapAddr : pif.addresses) { + if (pcapAddr.addr == null + && pcapAddr.netmask == null + && pcapAddr.broadaddr == null + && pcapAddr.dstaddr == null) { + Log.w(TAG, String.format("Empty pcap_addr on %s (%s). Ignore it.", name, description)); + continue; + } + + short sa_family = + pcapAddr.addr != null + ? pcapAddr.addr.getSaFamily() + : pcapAddr.netmask != null + ? pcapAddr.netmask.getSaFamily() + : pcapAddr.broadaddr != null + ? pcapAddr.broadaddr.getSaFamily() + : pcapAddr.dstaddr != null + ? pcapAddr.dstaddr.getSaFamily() + : Inets.AF_UNSPEC; // Never get here. + if (sa_family == Inets.AF_INET) { + addresses.add(PcapIpV4Address.newInstance(pcapAddr, sa_family, name)); + } else if (sa_family == Inets.AF_INET6) { + addresses.add(PcapIpV6Address.newInstance(pcapAddr, sa_family, name)); + } else { + if (sa_family == Inets.AF_PACKET) { + sockaddr_ll sll = new sockaddr_ll(pcapAddr.addr); + byte[] addr = sll.sll_addr; + int addrLength = sll.sll_halen & 0xFF; + if (addrLength == 6) { + linkLayerAddresses.add(ByteArrays.getMacAddress(addr, 0)); + } else if (addr.length == 0) { + continue; + } else { + // addrLength (i.e. sll_halen) may exceed addr.length (i.e. sll.sll_addr.length). + // If it's the case, need to shorten addrLength here to avoid + // ArrayIndexOutOfBoundsException in + // the succeeding ByteArrays.getSubArray(). + // https://github.com/kaitoy/pcap4j/issues/228 + addrLength = addrLength <= addr.length ? addrLength : addr.length; + linkLayerAddresses.add( + LinkLayerAddress.getByAddress(ByteArrays.getSubArray(addr, 0, addrLength))); + } + } else { + Log.w(TAG, String.format("%d is not supported address family. Ignore it.", sa_family)); + } + } + } + + this.loopBack = (pif.flags & PCAP_IF_LOOPBACK) != 0; + this.up = (pif.flags & PCAP_IF_UP) != 0; + this.running = (pif.flags & PCAP_IF_RUNNING) != 0; + this.local = local; + } + + static PcapNetworkInterface newInstance(pcap_if pif, boolean local) { + return new PcapNetworkInterface(pif, local); + } + + /** @return name */ + public String getName() { + return name; + } + + /** @return description */ + public String getDescription() { + return description; + } + + /** @return inet addresses */ + public List getAddresses() { + return new ArrayList(addresses); + } + + /** @return link layer addresses */ + public ArrayList getLinkLayerAddresses() { + return new ArrayList(linkLayerAddresses); + } + + /** + * Returns if this network interface is loopback. This method may always return false on some + * environments. + * + * @return true if the network interface represented by this object is a loop back interface; + * false otherwise. + */ + public boolean isLoopBack() { + return loopBack; + } + + /** + * Returns if this network interface is up. This method may always return false on some + * environments. + * + * @return true if the network interface represented by this object is up; false otherwise. + */ + public boolean isUp() { + return up; + } + + /** + * Returns if this network interface is running. This method may always return false on some + * environments. + * + * @return true if the network interface represented by this object is running; false otherwise. + */ + public boolean isRunning() { + return running; + } + + /** + * @return true if the network interface represented by this object is a local interface; false + * otherwise. + */ + public boolean isLocal() { + return local; + } + + /** + * @author Kaito Yamada + * @version pcap4j 0.9.1 + */ + public enum PromiscuousMode { + + /** */ + PROMISCUOUS(1), + + /** */ + NONPROMISCUOUS(0); + + private final int value; + + private PromiscuousMode(int value) { + this.value = value; + } + + /** @return value */ + public int getValue() { + return value; + } + } + + /** + * @param snaplen Snapshot length, which is the number of bytes captured for each packet. + * @param mode mode + * @param timeoutMillis Read timeout. Most OSs buffer packets. The OSs pass the packets to Pcap4j + * after the buffer gets full or the read timeout expires. Must be non-negative. May be + * ignored by some OSs. 0 means infinite. + * @return a new PcapHandle object. + * @throws PcapProxyException if an error occurs in the pcap native library. + */ + public PcapHandle openLive(int snaplen, PromiscuousMode mode, int timeoutMillis) throws PcapProxyException { + if (mode == null) { + StringBuilder sb = new StringBuilder(); + sb.append("mode: ").append(mode); + throw new NullPointerException(sb.toString()); + } + + long handle = PcapProxy.get().pcap_open_live(name, snaplen, mode.getValue(), timeoutMillis); + return new PcapHandle(handle, PcapHandle.TimestampPrecision.MICRO); + } + +// private MacAddress getMacAddress(String nifName) { +// Pointer lpAdapter = NativePacketDllMappings.PacketOpenAdapter(nifName); +// +// long hFile = -1; +// if (lpAdapter != null) { +// if (Native.POINTER_SIZE == 4) { +// hFile = lpAdapter.getInt(0); +// } else { +// hFile = lpAdapter.getLong(0); +// } +// } +// if (hFile == -1L) { +// int err = Native.getLastError(); +// logger.error("Unable to open the NIF {}, Error Code: {}", nifName, err); +// return null; +// } +// +// Memory mem = new Memory(NativePacketDllMappings.PACKET_OID_DATA_SIZE); +// mem.clear(); +// PACKET_OID_DATA oidData = new PACKET_OID_DATA(mem); +// oidData.Length = new NativeLong(6L); +// oidData.Oid = new NativeLong(0x01010102L); +// int status = NativePacketDllMappings.PacketRequest(lpAdapter, 0, oidData); +// NativePacketDllMappings.PacketCloseAdapter(lpAdapter); +// +// if (status == 0) { +// logger.error("Failed to retrieve the link layer address of the NIF: {}", nifName); +// return null; +// } else { +// return MacAddress.getByAddress(oidData.Data); +// } +// } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(250); + + sb.append("name: [").append(name).append("] description: [").append(description); + + for (PcapAddress addr : addresses) { + sb.append("] address: [").append(addr.getAddress()); + } + + for (LinkLayerAddress addr : linkLayerAddresses) { + sb.append("] link layer address: [").append(addr.getAddress()); + } + + sb.append("] loopBack: [").append(loopBack).append("]"); + sb.append("] up: [").append(up).append("]"); + sb.append("] running: [").append(running).append("]"); + sb.append("] local: [").append(local).append("]"); + + return sb.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + addresses.hashCode(); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + linkLayerAddresses.hashCode(); + result = prime * result + (local ? 1231 : 1237); + result = prime * result + (loopBack ? 1231 : 1237); + result = prime * result + (up ? 1231 : 1237); + result = prime * result + (running ? 1231 : 1237); + result = prime * result + name.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof PcapNetworkInterface)) { + return false; + } + PcapNetworkInterface other = (PcapNetworkInterface) obj; + if (!addresses.equals(other.addresses)) { + return false; + } + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (!linkLayerAddresses.equals(other.linkLayerAddresses)) { + return false; + } + if (local != other.local) { + return false; + } + if (loopBack != other.loopBack) { + return false; + } + if (up != other.up) { + return false; + } + if (running != other.running) { + return false; + } + if (!name.equals(other.name)) { + return false; + } + return true; + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/PcapStat.java b/app/src/main/java/org/pcap4j/core/PcapStat.java index cc73472..b658216 100644 --- a/app/src/main/java/org/pcap4j/core/PcapStat.java +++ b/app/src/main/java/org/pcap4j/core/PcapStat.java @@ -1,50 +1,50 @@ -/*_########################################################################## - _## - _## Copyright (C) 2013-2014 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - - -import me.itay.pcapproxy.structs.pcap_stat; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.16 - */ -public final class PcapStat { - - private final long numPacketsReceived; - private final long numPacketsDropped; - private final long numPacketsDroppedByIf; - private final long numPacketsCaptured; - - PcapStat(pcap_stat stat) { - this.numPacketsReceived = stat.ps_recv & 0xFFFFFFFFL; - this.numPacketsDropped = stat.ps_drop & 0xFFFFFFFFL; - this.numPacketsDroppedByIf = stat.ps_ifdrop & 0xFFFFFFFFL; - this.numPacketsCaptured = 0; - } - - /** @return ps_recv */ - public long getNumPacketsReceived() { - return numPacketsReceived; - } - - /** @return ps_drop */ - public long getNumPacketsDropped() { - return numPacketsDropped; - } - - /** @return ps_ifdrop */ - public long getNumPacketsDroppedByIf() { - return numPacketsDroppedByIf; - } - - /** @return bs_capt, which is valid only on Windows. */ - public long getNumPacketsCaptured() { - return numPacketsCaptured; - } +/*_########################################################################## + _## + _## Copyright (C) 2013-2014 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + + +import me.itay.pcapproxy.structs.pcap_stat; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.16 + */ +public final class PcapStat { + + private final long numPacketsReceived; + private final long numPacketsDropped; + private final long numPacketsDroppedByIf; + private final long numPacketsCaptured; + + PcapStat(pcap_stat stat) { + this.numPacketsReceived = stat.ps_recv & 0xFFFFFFFFL; + this.numPacketsDropped = stat.ps_drop & 0xFFFFFFFFL; + this.numPacketsDroppedByIf = stat.ps_ifdrop & 0xFFFFFFFFL; + this.numPacketsCaptured = 0; + } + + /** @return ps_recv */ + public long getNumPacketsReceived() { + return numPacketsReceived; + } + + /** @return ps_drop */ + public long getNumPacketsDropped() { + return numPacketsDropped; + } + + /** @return ps_ifdrop */ + public long getNumPacketsDroppedByIf() { + return numPacketsDroppedByIf; + } + + /** @return bs_capt, which is valid only on Windows. */ + public long getNumPacketsCaptured() { + return numPacketsCaptured; + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/core/Pcaps.java b/app/src/main/java/org/pcap4j/core/Pcaps.java index 0895741..9ceaf12 100644 --- a/app/src/main/java/org/pcap4j/core/Pcaps.java +++ b/app/src/main/java/org/pcap4j/core/Pcaps.java @@ -1,170 +1,187 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2019 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.core; - -import org.pcap4j.util.MacAddress; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -//import org.pcap4j.core.BpfProgram.BpfCompileMode; -import org.pcap4j.core.PcapHandle.TimestampPrecision; -import org.pcap4j.packet.namednumber.DataLinkType; -import org.pcap4j.util.ByteArrays; -import org.pcap4j.util.Inet4NetworkAddress; -import org.pcap4j.util.MacAddress; - -import me.itay.pcapproxy.PcapProxy; -import me.itay.pcapproxy.PcapProxyException; -import me.itay.pcapproxy.structs.pcap_if; - -public class Pcaps { - - private static final String TAG = "Pcaps"; - - private Pcaps() { - throw new AssertionError(); - } - - /** - * Gets all devices. - * - * @return a list of PcapNetworkInterfaces. - * @throws PcapProxyException if an error occurs in the pcap native library. - */ - public static List findAllDevs() throws PcapProxyException { - List ifList = new ArrayList<>(); - - for(pcap_if pif : PcapProxy.get().pcap_findalldevs()) { - ifList.add(PcapNetworkInterface.newInstance(pif, true)); - } - - return ifList; - } - - /** - * Gets a device by IP address. - * - * @param addr addr - * @return a PcapNetworkInterface. - * @throws PcapProxyException if an error occurs in the pcap native library. - */ - public static PcapNetworkInterface getDevByAddress(InetAddress addr) throws PcapProxyException { - if (addr == null) { - throw new NullPointerException("addr: " + addr); - } - - List allDevs = findAllDevs(); - for (PcapNetworkInterface pif : allDevs) { - for (PcapAddress paddr : pif.getAddresses()) { - if (paddr.getAddress().equals(addr)) { - return pif; - } - } - } - - return null; - } - - /** - * Gets a device by name. - * - * @param name name - * @return a PcapNetworkInterface. - * @throws PcapProxyException if an error occurs in the pcap native library. - */ - public static PcapNetworkInterface getDevByName(String name) throws PcapProxyException { - if (name == null) { - throw new NullPointerException("name: " + name); - } - - List allDevs = findAllDevs(); - for (PcapNetworkInterface pif : allDevs) { - if (pif.getName().equals(name)) { - return pif; - } - } - - return null; - } - - /** - * @return a name of a network interface. - * @throws PcapProxyException if an error occurs in the pcap native library. - */ - public static String lookupDev() throws PcapProxyException { - return PcapProxy.get().pcap_lookupdev(); - } - - // TODO: lookupNet - - // TODO: openOffline - - // TODO: openDead - - // TODO: compileFilter - - // TODO: datalinkNameToVal - - /** - * @param error error - * @return an error message. - */ - public static String strError(int error) { - return PcapProxy.get().pcap_strerror(error); - } - - /** - * @return a string giving information about the version of the libpcap library being used; note - * that it contains more information than just a version number. - */ - public static String libVersion() { - return PcapProxy.get().pcap_lib_version(); - } - - /** - * @param inetAddr Inet4Address or Inet6Address - * @return a string representation of an InetAddress for BPF. - */ - public static String toBpfString(InetAddress inetAddr) { - if (inetAddr == null) { - StringBuilder sb = new StringBuilder(); - sb.append("inetAddr: ").append(inetAddr); - throw new NullPointerException(sb.toString()); - } - - String strAddr = inetAddr.toString(); - return strAddr.substring(strAddr.lastIndexOf("/") + 1); - } - - /** - * @param macAddr macAddr - * @return a string representation of a MAC address for BPF. - */ - public static String toBpfString(MacAddress macAddr) { - if (macAddr == null) { - StringBuilder sb = new StringBuilder(); - sb.append("macAddr: ").append(macAddr); - throw new NullPointerException(sb.toString()); - } - - StringBuilder builder = new StringBuilder(); - byte[] address = macAddr.getAddress(); - - for (int i = 0; i < address.length; i++) { - builder.append(String.format("%02x", address[i])); - builder.append(":"); - } - builder.deleteCharAt(builder.length() - 1); - - return builder.toString(); - } - -} +/*_########################################################################## + _## + _## Copyright (C) 2011-2019 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.core; + +import org.pcap4j.util.MacAddress; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +//import org.pcap4j.core.BpfProgram.BpfCompileMode; +import org.pcap4j.core.PcapHandle.TimestampPrecision; +import org.pcap4j.packet.namednumber.DataLinkType; +import org.pcap4j.util.ByteArrays; +import org.pcap4j.util.Inet4NetworkAddress; +import org.pcap4j.util.MacAddress; + +import me.itay.pcapproxy.PcapProxy; +import me.itay.pcapproxy.PcapProxyException; +import me.itay.pcapproxy.structs.pcap_if; + +public class Pcaps { + + private static final String TAG = "Pcaps"; + + private Pcaps() { + throw new AssertionError(); + } + + /** + * Gets all devices. + * + * @return a list of PcapNetworkInterfaces. + * @throws PcapProxyException if an error occurs in the pcap native library. + */ + public static List findAllDevs() throws PcapProxyException { + List ifList = new ArrayList<>(); + + for(pcap_if pif : PcapProxy.get().pcap_findalldevs()) { + ifList.add(PcapNetworkInterface.newInstance(pif, true)); + } + + return ifList; + } + + /** + * Gets a device by IP address. + * + * @param addr addr + * @return a PcapNetworkInterface. + * @throws PcapProxyException if an error occurs in the pcap native library. + */ + public static PcapNetworkInterface getDevByAddress(InetAddress addr) throws PcapProxyException { + if (addr == null) { + throw new NullPointerException("addr: " + addr); + } + + List allDevs = findAllDevs(); + for (PcapNetworkInterface pif : allDevs) { + for (PcapAddress paddr : pif.getAddresses()) { + if (paddr.getAddress().equals(addr)) { + return pif; + } + } + } + + return null; + } + + /** + * Gets a device by name. + * + * @param name name + * @return a PcapNetworkInterface. + * @throws PcapProxyException if an error occurs in the pcap native library. + */ + public static PcapNetworkInterface getDevByName(String name) throws PcapProxyException { + if (name == null) { + throw new NullPointerException("name: " + name); + } + + List allDevs = findAllDevs(); + for (PcapNetworkInterface pif : allDevs) { + if (pif.getName().equals(name)) { + return pif; + } + } + + return null; + } + + /** + * @return a name of a network interface. + * @throws PcapProxyException if an error occurs in the pcap native library. + */ + public static String lookupDev() throws PcapProxyException { + return PcapProxy.get().pcap_lookupdev(); + } + + // TODO: lookupNet + + /** + * @param filePath "-" means stdin + * @return a new PcapHandle object. + * @throws PcapProxyException if an error occurs in the pcap native library. + */ + public static PcapHandle openOffline(String filePath) throws PcapProxyException { + if (filePath == null) { + StringBuilder sb = new StringBuilder(); + sb.append("filePath: ").append(filePath); + throw new NullPointerException(sb.toString()); + } + + long handle = PcapProxy.get().pcap_open_offline(filePath); + + return new PcapHandle(handle, TimestampPrecision.MICRO); + } + + // TODO: openOffline(String filePath, TimestampPrecision precision) + + // TODO: openDead + + // TODO: compileFilter + + // TODO: datalinkNameToVal + + /** + * @param error error + * @return an error message. + */ + public static String strError(int error) { + return PcapProxy.get().pcap_strerror(error); + } + + /** + * @return a string giving information about the version of the libpcap library being used; note + * that it contains more information than just a version number. + */ + public static String libVersion() { + return PcapProxy.get().pcap_lib_version(); + } + + /** + * @param inetAddr Inet4Address or Inet6Address + * @return a string representation of an InetAddress for BPF. + */ + public static String toBpfString(InetAddress inetAddr) { + if (inetAddr == null) { + StringBuilder sb = new StringBuilder(); + sb.append("inetAddr: ").append(inetAddr); + throw new NullPointerException(sb.toString()); + } + + String strAddr = inetAddr.toString(); + return strAddr.substring(strAddr.lastIndexOf("/") + 1); + } + + /** + * @param macAddr macAddr + * @return a string representation of a MAC address for BPF. + */ + public static String toBpfString(MacAddress macAddr) { + if (macAddr == null) { + StringBuilder sb = new StringBuilder(); + sb.append("macAddr: ").append(macAddr); + throw new NullPointerException(sb.toString()); + } + + StringBuilder builder = new StringBuilder(); + byte[] address = macAddr.getAddress(); + + for (int i = 0; i < address.length; i++) { + builder.append(String.format("%02x", address[i])); + builder.append(":"); + } + builder.deleteCharAt(builder.length() - 1); + + return builder.toString(); + } + +} diff --git a/app/src/main/java/org/pcap4j/packet/factory/PacketFactories.java b/app/src/main/java/org/pcap4j/packet/factory/PacketFactories.java index 9b2c5a1..79c944f 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/PacketFactories.java +++ b/app/src/main/java/org/pcap4j/packet/factory/PacketFactories.java @@ -1,82 +1,82 @@ -/*_########################################################################## - _## - _## Copyright (C) 2012-2019 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.packet.factory; - -import android.util.Log; - -import java.net.URL; -import java.security.ProtectionDomain; -import java.util.Iterator; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; -import org.pcap4j.packet.namednumber.NamedNumber; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.11 - */ -public final class PacketFactories { - - private static final String TAG = "PacketFactories"; - private static final PacketFactoryBinder FACTORY_BINDER; - - static { - PacketFactoryBinder factoryBinder = null; - try { - ServiceLoader loader = - ServiceLoader.load(PacketFactoryBinderProvider.class); - Iterator iter = loader.iterator(); - if (iter.hasNext()) { - PacketFactoryBinderProvider packetFactoryBinderProvider = iter.next(); - ProtectionDomain pd = packetFactoryBinderProvider.getClass().getProtectionDomain(); - URL codeSrcLocation = null; - if (pd != null) { - codeSrcLocation = pd.getCodeSource().getLocation(); - } - Log.i(TAG, - String.format("A PacketFactoryBinderProvider implementation is found. ClassLoader: %s, URL: %s", - packetFactoryBinderProvider.getClass().getClassLoader().toString(), - codeSrcLocation)); - factoryBinder = packetFactoryBinderProvider.getBinder(); - Log.i(TAG, "Succeeded in PacketFactoryBinderProvider.getBinder()"); - } else { - Log.w(TAG, - "No PacketFactoryBinder is available. All packets will be captured as UnknownPacket."); - } - } catch (ServiceConfigurationError e) { - Log.w(TAG, e.getClass().getName() + ": " + e.getMessage()); - } - FACTORY_BINDER = factoryBinder; - } - - private PacketFactories() { - throw new AssertionError(); - } - - /** - * @param target - * @param number - * @param targetClass targetClass - * @param numberClass numberClass - * @return a {@link org.pcap4j.packet.factory.PacketFactory PacketFactory} object. - */ - public static > PacketFactory getFactory( - Class targetClass, Class numberClass) { - if (numberClass == null || targetClass == null) { - StringBuilder sb = new StringBuilder(); - sb.append("numberClass: ").append(numberClass).append(" targetClass: ").append(targetClass); - throw new NullPointerException(sb.toString()); - } - - if (FACTORY_BINDER != null) { - return FACTORY_BINDER.getPacketFactory(targetClass, numberClass); - } else { - return SimplePacketFactoryBinder.getInstance().getPacketFactory(targetClass, numberClass); - } - } +/*_########################################################################## + _## + _## Copyright (C) 2012-2019 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.packet.factory; + +import android.util.Log; + +import java.net.URL; +import java.security.ProtectionDomain; +import java.util.Iterator; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; +import org.pcap4j.packet.namednumber.NamedNumber; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.11 + */ +public final class PacketFactories { + + private static final String TAG = "PacketFactories"; + private static final PacketFactoryBinder FACTORY_BINDER; + + static { + PacketFactoryBinder factoryBinder = null; + try { + ServiceLoader loader = + ServiceLoader.load(PacketFactoryBinderProvider.class); + Iterator iter = loader.iterator(); + if (iter.hasNext()) { + PacketFactoryBinderProvider packetFactoryBinderProvider = iter.next(); + ProtectionDomain pd = packetFactoryBinderProvider.getClass().getProtectionDomain(); + URL codeSrcLocation = null; + if (pd != null) { + codeSrcLocation = pd.getCodeSource().getLocation(); + } + Log.i(TAG, + String.format("A PacketFactoryBinderProvider implementation is found. ClassLoader: %s, URL: %s", + packetFactoryBinderProvider.getClass().getClassLoader().toString(), + codeSrcLocation)); + factoryBinder = packetFactoryBinderProvider.getBinder(); + Log.i(TAG, "Succeeded in PacketFactoryBinderProvider.getBinder()"); + } else { + Log.w(TAG, + "No PacketFactoryBinder is available. All packets will be captured as UnknownPacket."); + } + } catch (ServiceConfigurationError e) { + Log.w(TAG, e.getClass().getName() + ": " + e.getMessage()); + } + FACTORY_BINDER = factoryBinder; + } + + private PacketFactories() { + throw new AssertionError(); + } + + /** + * @param target + * @param number + * @param targetClass targetClass + * @param numberClass numberClass + * @return a {@link org.pcap4j.packet.factory.PacketFactory PacketFactory} object. + */ + public static > PacketFactory getFactory( + Class targetClass, Class numberClass) { + if (numberClass == null || targetClass == null) { + StringBuilder sb = new StringBuilder(); + sb.append("numberClass: ").append(numberClass).append(" targetClass: ").append(targetClass); + throw new NullPointerException(sb.toString()); + } + + if (FACTORY_BINDER != null) { + return FACTORY_BINDER.getPacketFactory(targetClass, numberClass); + } else { + return SimplePacketFactoryBinder.getInstance().getPacketFactory(targetClass, numberClass); + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/packet/factory/PacketFactory.java b/app/src/main/java/org/pcap4j/packet/factory/PacketFactory.java index 4260731..c949af6 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/PacketFactory.java +++ b/app/src/main/java/org/pcap4j/packet/factory/PacketFactory.java @@ -1,49 +1,49 @@ -/*_########################################################################## - _## - _## Copyright (C) 2012-2014 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.packet.factory; - -import org.pcap4j.packet.namednumber.NamedNumber; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.11 - * @param target - * @param number - */ -public interface PacketFactory> { - - /** - * @param rawData rawData - * @param offset offset - * @param length length - * @param number number - * @return a new data object. - */ - public T newInstance(byte[] rawData, int offset, int length, N number); - - /** - * @param rawData rawData - * @param offset offset - * @param length length - * @return a new data object. - */ - public T newInstance(byte[] rawData, int offset, int length); - - /** - * @param number number - * @return a {@link java.lang.Class Class} object this factory instantiates by {@link - * #newInstance(byte[], int, int, NamedNumber)} with the number argument. - */ - public Class getTargetClass(N number); - - /** - * @return a {@link java.lang.Class Class} object this factory instantiates by {@link - * #newInstance(byte[], int, int)}. - */ - public Class getTargetClass(); +/*_########################################################################## + _## + _## Copyright (C) 2012-2014 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.packet.factory; + +import org.pcap4j.packet.namednumber.NamedNumber; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.11 + * @param target + * @param number + */ +public interface PacketFactory> { + + /** + * @param rawData rawData + * @param offset offset + * @param length length + * @param number number + * @return a new data object. + */ + public T newInstance(byte[] rawData, int offset, int length, N number); + + /** + * @param rawData rawData + * @param offset offset + * @param length length + * @return a new data object. + */ + public T newInstance(byte[] rawData, int offset, int length); + + /** + * @param number number + * @return a {@link java.lang.Class Class} object this factory instantiates by {@link + * #newInstance(byte[], int, int, NamedNumber)} with the number argument. + */ + public Class getTargetClass(N number); + + /** + * @return a {@link java.lang.Class Class} object this factory instantiates by {@link + * #newInstance(byte[], int, int)}. + */ + public Class getTargetClass(); } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinder.java b/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinder.java index 2606d27..482e2d1 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinder.java +++ b/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinder.java @@ -1,31 +1,31 @@ -/*_########################################################################## - _## - _## Copyright (C) 2019 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.packet.factory; - -import org.pcap4j.packet.namednumber.NamedNumber; - -/** - * Pcap4J modules can provide a factory to build new packets as they are received.
- * The implementing modules must also provide a {@link PacketFactoryBinderProvider} - * - * @author Jordan Dubie - * @since pcap4j 1.8.0 - */ -public interface PacketFactoryBinder { - /** - * Provides a {@link PacketFactory} to build the received packets. - * - * @param targetClass targetClass - * @param numberClass numberClass - * @param the type of object the factory method returns. - * @param the type of object that is given to the factory method. - * @return the factory - */ - public > PacketFactory getPacketFactory( - Class targetClass, Class numberClass); +/*_########################################################################## + _## + _## Copyright (C) 2019 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.packet.factory; + +import org.pcap4j.packet.namednumber.NamedNumber; + +/** + * Pcap4J modules can provide a factory to build new packets as they are received.
+ * The implementing modules must also provide a {@link PacketFactoryBinderProvider} + * + * @author Jordan Dubie + * @since pcap4j 1.8.0 + */ +public interface PacketFactoryBinder { + /** + * Provides a {@link PacketFactory} to build the received packets. + * + * @param targetClass targetClass + * @param numberClass numberClass + * @param the type of object the factory method returns. + * @param the type of object that is given to the factory method. + * @return the factory + */ + public > PacketFactory getPacketFactory( + Class targetClass, Class numberClass); } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinderProvider.java b/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinderProvider.java index cb70508..6ca8cd9 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinderProvider.java +++ b/app/src/main/java/org/pcap4j/packet/factory/PacketFactoryBinderProvider.java @@ -1,34 +1,34 @@ -/*_########################################################################## - _## - _## Copyright (C) 2019 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.packet.factory; - -/** - * Provides an instance of {@link PacketFactoryBinder} - * - *

Implementing modules must declare themselves to the core module by: - * - *

    - *
  • creating the file - * src/main/resources/META-INF/services/org.pcap4j.packet.factory.PacketFactoryBinderProvider - *
  • adding a line in the file '<package>.<className>' for the name of the class - * implementing this {@link PacketFactoryBinderProvider} - *
- * - *

See {@link java.util.ServiceLoader} for more information. - * - * @author Jordan Dubie - * @since pcap4j 1.8.0 - */ -public interface PacketFactoryBinderProvider { - /** - * The instance of the {@link PacketFactoryBinder} to use to build the packets. - * - * @return a {@link PacketFactoryBinder} - */ - public PacketFactoryBinder getBinder(); +/*_########################################################################## + _## + _## Copyright (C) 2019 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.packet.factory; + +/** + * Provides an instance of {@link PacketFactoryBinder} + * + *

Implementing modules must declare themselves to the core module by: + * + *

    + *
  • creating the file + * src/main/resources/META-INF/services/org.pcap4j.packet.factory.PacketFactoryBinderProvider + *
  • adding a line in the file '<package>.<className>' for the name of the class + * implementing this {@link PacketFactoryBinderProvider} + *
+ * + *

See {@link java.util.ServiceLoader} for more information. + * + * @author Jordan Dubie + * @since pcap4j 1.8.0 + */ +public interface PacketFactoryBinderProvider { + /** + * The instance of the {@link PacketFactoryBinder} to use to build the packets. + * + * @return a {@link PacketFactoryBinder} + */ + public PacketFactoryBinder getBinder(); } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/packet/factory/SimplePacketFactoryBinder.java b/app/src/main/java/org/pcap4j/packet/factory/SimplePacketFactoryBinder.java index 134b4f3..446892e 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/SimplePacketFactoryBinder.java +++ b/app/src/main/java/org/pcap4j/packet/factory/SimplePacketFactoryBinder.java @@ -1,38 +1,38 @@ -/*_########################################################################## - _## - _## Copyright (C) 2013-2014 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.packet.factory; - -import org.pcap4j.packet.Packet; -import org.pcap4j.packet.namednumber.NamedNumber; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.16 - */ -final class SimplePacketFactoryBinder { - - private static final SimplePacketFactoryBinder INSTANCE = new SimplePacketFactoryBinder(); - - private SimplePacketFactoryBinder() {} - - public static SimplePacketFactoryBinder getInstance() { - return INSTANCE; - } - - @SuppressWarnings("unchecked") - public > PacketFactory getPacketFactory( - Class targetClass, Class numberClass) { - if (Packet.class.isAssignableFrom(targetClass)) { - return (PacketFactory) StaticUnknownPacketFactory.getInstance(); - } else { - StringBuilder sb = new StringBuilder(100); - sb.append("targetClass: ").append(targetClass).append(" numberClass: ").append(numberClass); - throw new IllegalArgumentException(sb.toString()); - } - } +/*_########################################################################## + _## + _## Copyright (C) 2013-2014 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.packet.factory; + +import org.pcap4j.packet.Packet; +import org.pcap4j.packet.namednumber.NamedNumber; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.16 + */ +final class SimplePacketFactoryBinder { + + private static final SimplePacketFactoryBinder INSTANCE = new SimplePacketFactoryBinder(); + + private SimplePacketFactoryBinder() {} + + public static SimplePacketFactoryBinder getInstance() { + return INSTANCE; + } + + @SuppressWarnings("unchecked") + public > PacketFactory getPacketFactory( + Class targetClass, Class numberClass) { + if (Packet.class.isAssignableFrom(targetClass)) { + return (PacketFactory) StaticUnknownPacketFactory.getInstance(); + } else { + StringBuilder sb = new StringBuilder(100); + sb.append("targetClass: ").append(targetClass).append(" numberClass: ").append(numberClass); + throw new IllegalArgumentException(sb.toString()); + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/packet/factory/StaticUnknownPacketFactory.java b/app/src/main/java/org/pcap4j/packet/factory/StaticUnknownPacketFactory.java index 8c7ba32..b5370ee 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/StaticUnknownPacketFactory.java +++ b/app/src/main/java/org/pcap4j/packet/factory/StaticUnknownPacketFactory.java @@ -1,46 +1,46 @@ -/*_########################################################################## - _## - _## Copyright (C) 2012-2014 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.packet.factory; - -import org.pcap4j.packet.Packet; -import org.pcap4j.packet.UnknownPacket; -import org.pcap4j.packet.namednumber.NamedNumber; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.14 - */ -public final class StaticUnknownPacketFactory implements PacketFactory> { - - private static final StaticUnknownPacketFactory INSTANCE = new StaticUnknownPacketFactory(); - - private StaticUnknownPacketFactory() {}; - - /** @return the singleton instance of StaticUnknownPacketFactory. */ - public static StaticUnknownPacketFactory getInstance() { - return INSTANCE; - } - - public Packet newInstance(byte[] rawData, int offset, int length, NamedNumber number) { - return newInstance(rawData, offset, length); - } - - public Packet newInstance(byte[] rawData, int offset, int length) { - return UnknownPacket.newPacket(rawData, offset, length); - } - - @Override - public Class getTargetClass(NamedNumber number) { - return getTargetClass(); - } - - @Override - public Class getTargetClass() { - return UnknownPacket.class; - } +/*_########################################################################## + _## + _## Copyright (C) 2012-2014 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.packet.factory; + +import org.pcap4j.packet.Packet; +import org.pcap4j.packet.UnknownPacket; +import org.pcap4j.packet.namednumber.NamedNumber; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.14 + */ +public final class StaticUnknownPacketFactory implements PacketFactory> { + + private static final StaticUnknownPacketFactory INSTANCE = new StaticUnknownPacketFactory(); + + private StaticUnknownPacketFactory() {}; + + /** @return the singleton instance of StaticUnknownPacketFactory. */ + public static StaticUnknownPacketFactory getInstance() { + return INSTANCE; + } + + public Packet newInstance(byte[] rawData, int offset, int length, NamedNumber number) { + return newInstance(rawData, offset, length); + } + + public Packet newInstance(byte[] rawData, int offset, int length) { + return UnknownPacket.newPacket(rawData, offset, length); + } + + @Override + public Class getTargetClass(NamedNumber number) { + return getTargetClass(); + } + + @Override + public Class getTargetClass() { + return UnknownPacket.class; + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinder.java b/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinder.java index 5ba6922..325d7bc 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinder.java +++ b/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinder.java @@ -1,131 +1,131 @@ -/*_########################################################################## - _## - _## Copyright (C) 2013-2019 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.packet.factory.statik.services; - -import java.util.HashMap; -import java.util.Map; -import org.pcap4j.packet.DnsResourceRecord.DnsRData; -import org.pcap4j.packet.IcmpV6CommonPacket.IpV6NeighborDiscoveryOption; -import org.pcap4j.packet.IpV4InternetTimestampOption; -import org.pcap4j.packet.IpV4Packet.IpV4Option; -import org.pcap4j.packet.IpV4Packet.IpV4Tos; -import org.pcap4j.packet.IpV6ExtOptionsPacket.IpV6Option; -import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6RoutingData; -import org.pcap4j.packet.IpV6Packet.IpV6FlowLabel; -import org.pcap4j.packet.IpV6Packet.IpV6TrafficClass; -import org.pcap4j.packet.Packet; -import org.pcap4j.packet.RadiotapPacket.RadiotapData; -import org.pcap4j.packet.SctpPacket.SctpChunk; -import org.pcap4j.packet.TcpPacket.TcpOption; -import org.pcap4j.packet.factory.PacketFactory; -import org.pcap4j.packet.factory.PacketFactoryBinder; -import org.pcap4j.packet.factory.StaticUnknownPacketFactory; -import org.pcap4j.packet.factory.statik.StaticDataLinkTypePacketFactory; -import org.pcap4j.packet.factory.statik.StaticDnsRDataFactory; -import org.pcap4j.packet.factory.statik.StaticDot11FrameTypePacketFactory; -import org.pcap4j.packet.factory.statik.StaticEtherTypePacketFactory; -import org.pcap4j.packet.factory.statik.StaticIcmpV4TypePacketFactory; -import org.pcap4j.packet.factory.statik.StaticIcmpV6TypePacketFactory; -import org.pcap4j.packet.factory.statik.StaticIpNumberPacketFactory; -import org.pcap4j.packet.factory.statik.StaticIpV4InternetTimestampOptionDataFactory; -import org.pcap4j.packet.factory.statik.StaticIpV4OptionFactory; -import org.pcap4j.packet.factory.statik.StaticIpV4TosFactory; -import org.pcap4j.packet.factory.statik.StaticIpV6FlowLabelFactory; -import org.pcap4j.packet.factory.statik.StaticIpV6NeighborDiscoveryOptionFactory; -import org.pcap4j.packet.factory.statik.StaticIpV6OptionFactory; -import org.pcap4j.packet.factory.statik.StaticIpV6RoutingDataFactory; -import org.pcap4j.packet.factory.statik.StaticIpV6TrafficClassFactory; -import org.pcap4j.packet.factory.statik.StaticLlcNumberPacketFactory; -import org.pcap4j.packet.factory.statik.StaticNotApplicablePacketFactory; -import org.pcap4j.packet.factory.statik.StaticPppDllProtocolPacketFactory; -import org.pcap4j.packet.factory.statik.StaticProtocolFamilyPacketFactory; -import org.pcap4j.packet.factory.statik.StaticRadiotapDataFieldFactory; -import org.pcap4j.packet.factory.statik.StaticSctpChunkFactory; -import org.pcap4j.packet.factory.statik.StaticSctpPortPacketFactory; -import org.pcap4j.packet.factory.statik.StaticTcpOptionFactory; -import org.pcap4j.packet.factory.statik.StaticTcpPortPacketFactory; -import org.pcap4j.packet.factory.statik.StaticUdpPortPacketFactory; -import org.pcap4j.packet.namednumber.DataLinkType; -import org.pcap4j.packet.namednumber.Dot11FrameType; -import org.pcap4j.packet.namednumber.EtherType; -import org.pcap4j.packet.namednumber.IcmpV4Type; -import org.pcap4j.packet.namednumber.IcmpV6Type; -import org.pcap4j.packet.namednumber.IpNumber; -import org.pcap4j.packet.namednumber.LlcNumber; -import org.pcap4j.packet.namednumber.NamedNumber; -import org.pcap4j.packet.namednumber.NotApplicable; -import org.pcap4j.packet.namednumber.PppDllProtocol; -import org.pcap4j.packet.namednumber.ProtocolFamily; -import org.pcap4j.packet.namednumber.SctpPort; -import org.pcap4j.packet.namednumber.TcpPort; -import org.pcap4j.packet.namednumber.UdpPort; - -/** - * @author Kaito Yamada - * @since pcap4j 1.8.0 - */ -final class StaticPacketFactoryBinder implements PacketFactoryBinder { - - private static final PacketFactoryBinder INSTANCE = new StaticPacketFactoryBinder(); - - private final Map>, PacketFactory> packetFactories = - new HashMap>, PacketFactory>(); - private final Map, PacketFactory> packetpPieceFactories = - new HashMap, PacketFactory>(); - - private StaticPacketFactoryBinder() { - packetFactories.put(DataLinkType.class, StaticDataLinkTypePacketFactory.getInstance()); - packetFactories.put(EtherType.class, StaticEtherTypePacketFactory.getInstance()); - packetFactories.put(LlcNumber.class, StaticLlcNumberPacketFactory.getInstance()); - packetFactories.put(IcmpV4Type.class, StaticIcmpV4TypePacketFactory.getInstance()); - packetFactories.put(IcmpV6Type.class, StaticIcmpV6TypePacketFactory.getInstance()); - packetFactories.put(IpNumber.class, StaticIpNumberPacketFactory.getInstance()); - packetFactories.put(TcpPort.class, StaticTcpPortPacketFactory.getInstance()); - packetFactories.put(UdpPort.class, StaticUdpPortPacketFactory.getInstance()); - packetFactories.put(SctpPort.class, StaticSctpPortPacketFactory.getInstance()); - packetFactories.put(NotApplicable.class, StaticNotApplicablePacketFactory.getInstance()); - packetFactories.put(PppDllProtocol.class, StaticPppDllProtocolPacketFactory.getInstance()); - packetFactories.put(ProtocolFamily.class, StaticProtocolFamilyPacketFactory.getInstance()); - packetFactories.put(Dot11FrameType.class, StaticDot11FrameTypePacketFactory.getInstance()); - - packetpPieceFactories.put(IpV4Option.class, StaticIpV4OptionFactory.getInstance()); - packetpPieceFactories.put( - IpV4InternetTimestampOption.class, - StaticIpV4InternetTimestampOptionDataFactory.getInstance()); - packetpPieceFactories.put(TcpOption.class, StaticTcpOptionFactory.getInstance()); - packetpPieceFactories.put(IpV6Option.class, StaticIpV6OptionFactory.getInstance()); - packetpPieceFactories.put(IpV6RoutingData.class, StaticIpV6RoutingDataFactory.getInstance()); - packetpPieceFactories.put( - IpV6NeighborDiscoveryOption.class, StaticIpV6NeighborDiscoveryOptionFactory.getInstance()); - packetpPieceFactories.put(IpV4Tos.class, StaticIpV4TosFactory.getInstance()); - packetpPieceFactories.put(IpV6TrafficClass.class, StaticIpV6TrafficClassFactory.getInstance()); - packetpPieceFactories.put(IpV6FlowLabel.class, StaticIpV6FlowLabelFactory.getInstance()); - packetpPieceFactories.put(RadiotapData.class, StaticRadiotapDataFieldFactory.getInstance()); - packetpPieceFactories.put(SctpChunk.class, StaticSctpChunkFactory.getInstance()); - packetpPieceFactories.put(DnsRData.class, StaticDnsRDataFactory.getInstance()); - } - - public static PacketFactoryBinder getInstance() { - return INSTANCE; - } - - @Override - @SuppressWarnings("unchecked") - public > PacketFactory getPacketFactory( - Class targetClass, Class numberClass) { - if (Packet.class.isAssignableFrom(targetClass)) { - PacketFactory factory = (PacketFactory) packetFactories.get(numberClass); - if (factory != null) { - return factory; - } else { - return (PacketFactory) StaticUnknownPacketFactory.getInstance(); - } - } - return (PacketFactory) packetpPieceFactories.get(targetClass); - } +/*_########################################################################## + _## + _## Copyright (C) 2013-2019 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.packet.factory.statik.services; + +import java.util.HashMap; +import java.util.Map; +import org.pcap4j.packet.DnsResourceRecord.DnsRData; +import org.pcap4j.packet.IcmpV6CommonPacket.IpV6NeighborDiscoveryOption; +import org.pcap4j.packet.IpV4InternetTimestampOption; +import org.pcap4j.packet.IpV4Packet.IpV4Option; +import org.pcap4j.packet.IpV4Packet.IpV4Tos; +import org.pcap4j.packet.IpV6ExtOptionsPacket.IpV6Option; +import org.pcap4j.packet.IpV6ExtRoutingPacket.IpV6RoutingData; +import org.pcap4j.packet.IpV6Packet.IpV6FlowLabel; +import org.pcap4j.packet.IpV6Packet.IpV6TrafficClass; +import org.pcap4j.packet.Packet; +import org.pcap4j.packet.RadiotapPacket.RadiotapData; +import org.pcap4j.packet.SctpPacket.SctpChunk; +import org.pcap4j.packet.TcpPacket.TcpOption; +import org.pcap4j.packet.factory.PacketFactory; +import org.pcap4j.packet.factory.PacketFactoryBinder; +import org.pcap4j.packet.factory.StaticUnknownPacketFactory; +import org.pcap4j.packet.factory.statik.StaticDataLinkTypePacketFactory; +import org.pcap4j.packet.factory.statik.StaticDnsRDataFactory; +import org.pcap4j.packet.factory.statik.StaticDot11FrameTypePacketFactory; +import org.pcap4j.packet.factory.statik.StaticEtherTypePacketFactory; +import org.pcap4j.packet.factory.statik.StaticIcmpV4TypePacketFactory; +import org.pcap4j.packet.factory.statik.StaticIcmpV6TypePacketFactory; +import org.pcap4j.packet.factory.statik.StaticIpNumberPacketFactory; +import org.pcap4j.packet.factory.statik.StaticIpV4InternetTimestampOptionDataFactory; +import org.pcap4j.packet.factory.statik.StaticIpV4OptionFactory; +import org.pcap4j.packet.factory.statik.StaticIpV4TosFactory; +import org.pcap4j.packet.factory.statik.StaticIpV6FlowLabelFactory; +import org.pcap4j.packet.factory.statik.StaticIpV6NeighborDiscoveryOptionFactory; +import org.pcap4j.packet.factory.statik.StaticIpV6OptionFactory; +import org.pcap4j.packet.factory.statik.StaticIpV6RoutingDataFactory; +import org.pcap4j.packet.factory.statik.StaticIpV6TrafficClassFactory; +import org.pcap4j.packet.factory.statik.StaticLlcNumberPacketFactory; +import org.pcap4j.packet.factory.statik.StaticNotApplicablePacketFactory; +import org.pcap4j.packet.factory.statik.StaticPppDllProtocolPacketFactory; +import org.pcap4j.packet.factory.statik.StaticProtocolFamilyPacketFactory; +import org.pcap4j.packet.factory.statik.StaticRadiotapDataFieldFactory; +import org.pcap4j.packet.factory.statik.StaticSctpChunkFactory; +import org.pcap4j.packet.factory.statik.StaticSctpPortPacketFactory; +import org.pcap4j.packet.factory.statik.StaticTcpOptionFactory; +import org.pcap4j.packet.factory.statik.StaticTcpPortPacketFactory; +import org.pcap4j.packet.factory.statik.StaticUdpPortPacketFactory; +import org.pcap4j.packet.namednumber.DataLinkType; +import org.pcap4j.packet.namednumber.Dot11FrameType; +import org.pcap4j.packet.namednumber.EtherType; +import org.pcap4j.packet.namednumber.IcmpV4Type; +import org.pcap4j.packet.namednumber.IcmpV6Type; +import org.pcap4j.packet.namednumber.IpNumber; +import org.pcap4j.packet.namednumber.LlcNumber; +import org.pcap4j.packet.namednumber.NamedNumber; +import org.pcap4j.packet.namednumber.NotApplicable; +import org.pcap4j.packet.namednumber.PppDllProtocol; +import org.pcap4j.packet.namednumber.ProtocolFamily; +import org.pcap4j.packet.namednumber.SctpPort; +import org.pcap4j.packet.namednumber.TcpPort; +import org.pcap4j.packet.namednumber.UdpPort; + +/** + * @author Kaito Yamada + * @since pcap4j 1.8.0 + */ +final class StaticPacketFactoryBinder implements PacketFactoryBinder { + + private static final PacketFactoryBinder INSTANCE = new StaticPacketFactoryBinder(); + + private final Map>, PacketFactory> packetFactories = + new HashMap>, PacketFactory>(); + private final Map, PacketFactory> packetpPieceFactories = + new HashMap, PacketFactory>(); + + private StaticPacketFactoryBinder() { + packetFactories.put(DataLinkType.class, StaticDataLinkTypePacketFactory.getInstance()); + packetFactories.put(EtherType.class, StaticEtherTypePacketFactory.getInstance()); + packetFactories.put(LlcNumber.class, StaticLlcNumberPacketFactory.getInstance()); + packetFactories.put(IcmpV4Type.class, StaticIcmpV4TypePacketFactory.getInstance()); + packetFactories.put(IcmpV6Type.class, StaticIcmpV6TypePacketFactory.getInstance()); + packetFactories.put(IpNumber.class, StaticIpNumberPacketFactory.getInstance()); + packetFactories.put(TcpPort.class, StaticTcpPortPacketFactory.getInstance()); + packetFactories.put(UdpPort.class, StaticUdpPortPacketFactory.getInstance()); + packetFactories.put(SctpPort.class, StaticSctpPortPacketFactory.getInstance()); + packetFactories.put(NotApplicable.class, StaticNotApplicablePacketFactory.getInstance()); + packetFactories.put(PppDllProtocol.class, StaticPppDllProtocolPacketFactory.getInstance()); + packetFactories.put(ProtocolFamily.class, StaticProtocolFamilyPacketFactory.getInstance()); + packetFactories.put(Dot11FrameType.class, StaticDot11FrameTypePacketFactory.getInstance()); + + packetpPieceFactories.put(IpV4Option.class, StaticIpV4OptionFactory.getInstance()); + packetpPieceFactories.put( + IpV4InternetTimestampOption.class, + StaticIpV4InternetTimestampOptionDataFactory.getInstance()); + packetpPieceFactories.put(TcpOption.class, StaticTcpOptionFactory.getInstance()); + packetpPieceFactories.put(IpV6Option.class, StaticIpV6OptionFactory.getInstance()); + packetpPieceFactories.put(IpV6RoutingData.class, StaticIpV6RoutingDataFactory.getInstance()); + packetpPieceFactories.put( + IpV6NeighborDiscoveryOption.class, StaticIpV6NeighborDiscoveryOptionFactory.getInstance()); + packetpPieceFactories.put(IpV4Tos.class, StaticIpV4TosFactory.getInstance()); + packetpPieceFactories.put(IpV6TrafficClass.class, StaticIpV6TrafficClassFactory.getInstance()); + packetpPieceFactories.put(IpV6FlowLabel.class, StaticIpV6FlowLabelFactory.getInstance()); + packetpPieceFactories.put(RadiotapData.class, StaticRadiotapDataFieldFactory.getInstance()); + packetpPieceFactories.put(SctpChunk.class, StaticSctpChunkFactory.getInstance()); + packetpPieceFactories.put(DnsRData.class, StaticDnsRDataFactory.getInstance()); + } + + public static PacketFactoryBinder getInstance() { + return INSTANCE; + } + + @Override + @SuppressWarnings("unchecked") + public > PacketFactory getPacketFactory( + Class targetClass, Class numberClass) { + if (Packet.class.isAssignableFrom(targetClass)) { + PacketFactory factory = (PacketFactory) packetFactories.get(numberClass); + if (factory != null) { + return factory; + } else { + return (PacketFactory) StaticUnknownPacketFactory.getInstance(); + } + } + return (PacketFactory) packetpPieceFactories.get(targetClass); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinderProvider.java b/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinderProvider.java index 4c9e5ca..4a2b1c5 100644 --- a/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinderProvider.java +++ b/app/src/main/java/org/pcap4j/packet/factory/statik/services/StaticPacketFactoryBinderProvider.java @@ -1,21 +1,21 @@ -/* - * *************************************************************************** - * Copyright (C) 2019 Thales AVS, All Rights Reserved. * - * *************************************************************************** - */ -package org.pcap4j.packet.factory.statik.services; - -import org.pcap4j.packet.factory.PacketFactoryBinder; -import org.pcap4j.packet.factory.PacketFactoryBinderProvider; - -/** - * @author Jordan Dubie - * @since pcap4j 1.8.0 - */ -public class StaticPacketFactoryBinderProvider implements PacketFactoryBinderProvider { - - @Override - public PacketFactoryBinder getBinder() { - return StaticPacketFactoryBinder.getInstance(); - } +/* + * *************************************************************************** + * Copyright (C) 2019 Thales AVS, All Rights Reserved. * + * *************************************************************************** + */ +package org.pcap4j.packet.factory.statik.services; + +import org.pcap4j.packet.factory.PacketFactoryBinder; +import org.pcap4j.packet.factory.PacketFactoryBinderProvider; + +/** + * @author Jordan Dubie + * @since pcap4j 1.8.0 + */ +public class StaticPacketFactoryBinderProvider implements PacketFactoryBinderProvider { + + @Override + public PacketFactoryBinder getBinder() { + return StaticPacketFactoryBinder.getInstance(); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/util/ByteArrays.java b/app/src/main/java/org/pcap4j/util/ByteArrays.java index c5ad17a..88baf62 100644 --- a/app/src/main/java/org/pcap4j/util/ByteArrays.java +++ b/app/src/main/java/org/pcap4j/util/ByteArrays.java @@ -1,1032 +1,1032 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2019 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.util; - -import static java.nio.ByteOrder.*; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteOrder; -import java.util.List; -import java.util.regex.Pattern; -import java.util.zip.Adler32; -import java.util.zip.CRC32; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.1 - */ -public final class ByteArrays { - - /** */ - public static final int BYTE_SIZE_IN_BYTES = 1; - - /** */ - public static final int SHORT_SIZE_IN_BYTES = 2; - - /** */ - public static final int INT_SIZE_IN_BYTES = 4; - - /** */ - public static final int LONG_SIZE_IN_BYTES = 8; - - /** */ - public static final int INET4_ADDRESS_SIZE_IN_BYTES = 4; - - /** */ - public static final int INET6_ADDRESS_SIZE_IN_BYTES = 16; - - /** */ - public static final int BYTE_SIZE_IN_BITS = 8; - - private static final Pattern NO_SEPARATOR_HEX_STRING_PATTERN = - Pattern.compile("\\A([0-9a-fA-F][0-9a-fA-F])+\\z"); - - private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); - - private static final int[] CRC32C_TABLE = - new int[] { - 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, - 0xd4ca64eb, - 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, - 0x5e133c24, - 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, - 0xc494a384, - 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848, - 0x4e4dfb4b, - 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936, - 0xf477ea35, - 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, - 0x7eaeb2fa, - 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59, - 0xe4292d5a, - 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696, - 0x6ef07595, - 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, - 0x95b17957, - 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b, - 0x1f682198, - 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, - 0x85efbe38, - 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, - 0x0f36e6f7, - 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a, - 0xb50cf789, - 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, - 0x3fd5af46, - 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, - 0xa55230e6, - 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, - 0x2f8b6829, - 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90, - 0x563c5f93, - 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, - 0xdce5075c, - 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff, - 0x466298fc, - 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, - 0xccbbc033, - 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, - 0x7681d14d, - 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81, - 0xfc588982, - 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521, - 0x66df1622, - 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, - 0xec064eed, - 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c, - 0x1747422f, - 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3, - 0x9d9e1ae0, - 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, - 0x07198540, - 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, - 0x8dc0dd8f, - 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, - 0x37faccf1, - 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, - 0xbd23943e, - 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, - 0x27a40b9e, - 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, - 0xad7d5351, - }; - - private ByteArrays() { - throw new AssertionError(); - } - - /** - * @param array array - * @return a new array containing specified array's elements in reverse order. - */ - public static byte[] reverse(byte[] array) { - byte[] rarray = new byte[array.length]; - for (int i = 0; i < array.length; i++) { - rarray[i] = array[array.length - i - 1]; - } - return rarray; - } - - /** - * @param array array - * @param offset offset - * @return byte value. - */ - public static byte getByte(byte[] array, int offset) { - validateBounds(array, offset, BYTE_SIZE_IN_BYTES); - return array[offset]; - } - - /** - * @param value value - * @return byte array - */ - public static byte[] toByteArray(byte value) { - return new byte[] {value}; - } - - /** - * @param value value - * @param separator separator - * @return hex string - */ - public static String toHexString(byte value, String separator) { - return toHexString(toByteArray(value), separator); - } - - /** - * @param array array - * @param offset offset - * @return short value - */ - public static short getShort(byte[] array, int offset) { - return getShort(array, offset, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param bo bo - * @return short value - */ - public static short getShort(byte[] array, int offset, ByteOrder bo) { - validateBounds(array, offset, SHORT_SIZE_IN_BYTES); - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - if (bo.equals(LITTLE_ENDIAN)) { - return (short) (((array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) | ((0xFF & array[offset]))); - } else { - return (short) (((array[offset]) << (BYTE_SIZE_IN_BITS * 1)) | ((0xFF & array[offset + 1]))); - } - } - - /** - * @param value value - * @return byte array - */ - public static byte[] toByteArray(short value) { - return toByteArray(value, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param bo bo - * @return byte array - */ - public static byte[] toByteArray(short value, ByteOrder bo) { - if (bo.equals(LITTLE_ENDIAN)) { - return new byte[] {(byte) (value), (byte) (value >> BYTE_SIZE_IN_BITS * 1)}; - } else { - return new byte[] {(byte) (value >> BYTE_SIZE_IN_BITS * 1), (byte) (value)}; - } - } - - /** - * @param value value - * @param separator separator - * @return hex string - */ - public static String toHexString(short value, String separator) { - return toHexString(value, separator, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param separator separator - * @param bo bo - * @return hex string - */ - public static String toHexString(short value, String separator, ByteOrder bo) { - return toHexString(toByteArray(value, bo), separator); - } - - /** - * @param array array - * @param offset offset - * @return int value. - */ - public static int getInt(byte[] array, int offset) { - return getInt(array, offset, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param bo bo - * @return int value. - */ - public static int getInt(byte[] array, int offset, ByteOrder bo) { - validateBounds(array, offset, INT_SIZE_IN_BYTES); - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - if (bo.equals(LITTLE_ENDIAN)) { - return ((array[offset + 3]) << (BYTE_SIZE_IN_BITS * 3)) - | ((0xFF & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 2)) - | ((0xFF & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) - | ((0xFF & array[offset])); - } else { - return ((array[offset]) << (BYTE_SIZE_IN_BITS * 3)) - | ((0xFF & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 2)) - | ((0xFF & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 1)) - | ((0xFF & array[offset + 3])); - } - } - - /** - * @param array array - * @param offset offset - * @param length length - * @return int value. - */ - public static int getInt(byte[] array, int offset, int length) { - return getInt(array, offset, length, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param length length - * @param bo bo - * @return int value. - */ - public static int getInt(byte[] array, int offset, int length, ByteOrder bo) { - validateBounds(array, offset, length); - if (length > INT_SIZE_IN_BYTES) { - StringBuilder sb = - new StringBuilder(30) - .append("length must be equal or less than ") - .append(INT_SIZE_IN_BYTES) - .append(", but is: ") - .append(length); - throw new IllegalArgumentException(sb.toString()); - } - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - int value = 0; - if (bo.equals(LITTLE_ENDIAN)) { - for (int i = offset + length - 1; i >= offset; i--) { - value <<= BYTE_SIZE_IN_BITS; - value |= 0xFF & array[i]; - } - } else { - for (int i = offset; i < offset + length; i++) { - value <<= BYTE_SIZE_IN_BITS; - value |= 0xFF & array[i]; - } - } - return value; - } - - /** - * @param value value - * @return byte array - */ - public static byte[] toByteArray(int value) { - return toByteArray(value, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param bo bo - * @return byte array - */ - public static byte[] toByteArray(int value, ByteOrder bo) { - if (bo.equals(LITTLE_ENDIAN)) { - return new byte[] { - (byte) (value), - (byte) (value >> BYTE_SIZE_IN_BITS * 1), - (byte) (value >> BYTE_SIZE_IN_BITS * 2), - (byte) (value >> BYTE_SIZE_IN_BITS * 3), - }; - } else { - return new byte[] { - (byte) (value >> BYTE_SIZE_IN_BITS * 3), - (byte) (value >> BYTE_SIZE_IN_BITS * 2), - (byte) (value >> BYTE_SIZE_IN_BITS * 1), - (byte) (value) - }; - } - } - - /** - * @param value value - * @param length length - * @return byte array - */ - public static byte[] toByteArray(int value, int length) { - return toByteArray(value, length, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param length length - * @param bo bo - * @return byte array - */ - public static byte[] toByteArray(int value, int length, ByteOrder bo) { - if (length > INT_SIZE_IN_BYTES) { - StringBuilder sb = - new StringBuilder(30) - .append("length must be equal or less than ") - .append(INT_SIZE_IN_BYTES) - .append(", but is: ") - .append(length); - throw new IllegalArgumentException(sb.toString()); - } - - byte[] arr = new byte[length]; - if (bo.equals(LITTLE_ENDIAN)) { - for (int i = 0; i < length; i++) { - arr[length - i - 1] = (byte) (value >> BYTE_SIZE_IN_BITS * i); - } - } else { - for (int i = 0; i < length; i++) { - arr[i] = (byte) (value >> BYTE_SIZE_IN_BITS * i); - } - } - - return arr; - } - - /** - * @param value value - * @param separator separator - * @return hex string - */ - public static String toHexString(int value, String separator) { - return toHexString(value, separator, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param separator separator - * @param bo bo - * @return hex string - */ - public static String toHexString(int value, String separator, ByteOrder bo) { - return toHexString(toByteArray(value, bo), separator); - } - - /** - * @param array array - * @param offset offset - * @return long value - */ - public static long getLong(byte[] array, int offset) { - return getLong(array, offset, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param bo bo - * @return long value - */ - public static long getLong(byte[] array, int offset, ByteOrder bo) { - validateBounds(array, offset, LONG_SIZE_IN_BYTES); - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - if (bo.equals(LITTLE_ENDIAN)) { - return (((long) array[offset + 7]) << (BYTE_SIZE_IN_BITS * 7)) - | ((0xFFL & array[offset + 6]) << (BYTE_SIZE_IN_BITS * 6)) - | ((0xFFL & array[offset + 5]) << (BYTE_SIZE_IN_BITS * 5)) - | ((0xFFL & array[offset + 4]) << (BYTE_SIZE_IN_BITS * 4)) - | ((0xFFL & array[offset + 3]) << (BYTE_SIZE_IN_BITS * 3)) - | ((0xFFL & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 2)) - | ((0xFFL & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) - | ((0xFFL & array[offset])); - } else { - return (((long) array[offset]) << (BYTE_SIZE_IN_BITS * 7)) - | ((0xFFL & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 6)) - | ((0xFFL & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 5)) - | ((0xFFL & array[offset + 3]) << (BYTE_SIZE_IN_BITS * 4)) - | ((0xFFL & array[offset + 4]) << (BYTE_SIZE_IN_BITS * 3)) - | ((0xFFL & array[offset + 5]) << (BYTE_SIZE_IN_BITS * 2)) - | ((0xFFL & array[offset + 6]) << (BYTE_SIZE_IN_BITS * 1)) - | ((0xFFL & array[offset + 7])); - } - } - - /** - * @param value value - * @return byte array - */ - public static byte[] toByteArray(long value) { - return toByteArray(value, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param bo bo - * @return byte array - */ - public static byte[] toByteArray(long value, ByteOrder bo) { - if (bo.equals(LITTLE_ENDIAN)) { - return new byte[] { - (byte) (value), - (byte) (value >> BYTE_SIZE_IN_BITS * 1), - (byte) (value >> BYTE_SIZE_IN_BITS * 2), - (byte) (value >> BYTE_SIZE_IN_BITS * 3), - (byte) (value >> BYTE_SIZE_IN_BITS * 4), - (byte) (value >> BYTE_SIZE_IN_BITS * 5), - (byte) (value >> BYTE_SIZE_IN_BITS * 6), - (byte) (value >> BYTE_SIZE_IN_BITS * 7) - }; - } else { - return new byte[] { - (byte) (value >> BYTE_SIZE_IN_BITS * 7), - (byte) (value >> BYTE_SIZE_IN_BITS * 6), - (byte) (value >> BYTE_SIZE_IN_BITS * 5), - (byte) (value >> BYTE_SIZE_IN_BITS * 4), - (byte) (value >> BYTE_SIZE_IN_BITS * 3), - (byte) (value >> BYTE_SIZE_IN_BITS * 2), - (byte) (value >> BYTE_SIZE_IN_BITS * 1), - (byte) (value) - }; - } - } - - /** - * @param value value - * @param separator separator - * @return hex string - */ - public static String toHexString(long value, String separator) { - return toHexString(value, separator, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param separator separator - * @param bo bo - * @return hex string - */ - public static String toHexString(long value, String separator, ByteOrder bo) { - return toHexString(toByteArray(value, bo), separator); - } - - /** - * @param array array - * @param offset offset - * @return a new MacAddress object. - */ - public static MacAddress getMacAddress(byte[] array, int offset) { - return getMacAddress(array, offset, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param bo bo - * @return a new MacAddress object. - */ - public static MacAddress getMacAddress(byte[] array, int offset, ByteOrder bo) { - validateBounds(array, offset, MacAddress.SIZE_IN_BYTES); - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - if (bo.equals(LITTLE_ENDIAN)) { - return MacAddress.getByAddress(reverse(getSubArray(array, offset, MacAddress.SIZE_IN_BYTES))); - } else { - return MacAddress.getByAddress(getSubArray(array, offset, MacAddress.SIZE_IN_BYTES)); - } - } - - /** - * @param value value - * @return byte array - */ - public static byte[] toByteArray(MacAddress value) { - return toByteArray(value, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param bo bo - * @return byte array - */ - public static byte[] toByteArray(MacAddress value, ByteOrder bo) { - if (bo.equals(LITTLE_ENDIAN)) { - return reverse(value.getAddress()); - } else { - return value.getAddress(); - } - } - - /** - * @param array array - * @param offset offset - * @param length length - * @return a new LinkLayerAddress object. - */ - public static LinkLayerAddress getLinkLayerAddress(byte[] array, int offset, int length) { - return getLinkLayerAddress(array, offset, length, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param length length - * @param bo bo - * @return a new LinkLayerAddress object. - */ - public static LinkLayerAddress getLinkLayerAddress( - byte[] array, int offset, int length, ByteOrder bo) { - validateBounds(array, offset, length); - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - if (bo.equals(LITTLE_ENDIAN)) { - return LinkLayerAddress.getByAddress(reverse(getSubArray(array, offset, length))); - } else { - return LinkLayerAddress.getByAddress(getSubArray(array, offset, length)); - } - } - - /** - * @param value value - * @return byte array - */ - public static byte[] toByteArray(LinkLayerAddress value) { - return toByteArray(value, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param bo bo - * @return byte array - */ - public static byte[] toByteArray(LinkLayerAddress value, ByteOrder bo) { - if (bo.equals(LITTLE_ENDIAN)) { - return reverse(value.getAddress()); - } else { - return value.getAddress(); - } - } - - /** - * @param array array - * @param offset offset - * @return a new Inet4Address object. - */ - public static Inet4Address getInet4Address(byte[] array, int offset) { - return getInet4Address(array, offset, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param bo bo - * @return a new Inet4Address object. - */ - public static Inet4Address getInet4Address(byte[] array, int offset, ByteOrder bo) { - validateBounds(array, offset, INET4_ADDRESS_SIZE_IN_BYTES); - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - try { - if (bo.equals(LITTLE_ENDIAN)) { - return (Inet4Address) - InetAddress.getByAddress( - reverse(getSubArray(array, offset, INET4_ADDRESS_SIZE_IN_BYTES))); - } else { - return (Inet4Address) - InetAddress.getByAddress(getSubArray(array, offset, INET4_ADDRESS_SIZE_IN_BYTES)); - } - } catch (UnknownHostException e) { - throw new AssertionError(e); - } - } - - /** - * @param addr a string representation of an IPv4 address. (e.g. "192.168.0.100") - * @return a byte array representation of the IPv4 address. - * @throws IllegalArgumentException if failed to parse addr. - */ - public static byte[] parseInet4Address(String addr) { - String[] octetStrs = addr.split("\\.", 4); - if (octetStrs.length != INET4_ADDRESS_SIZE_IN_BYTES) { - throw new IllegalArgumentException("Couldn't get an Inet4Address from " + addr); - } - - byte[] octets = new byte[4]; - for (int i = 0; i < octets.length; i++) { - String octetStr = octetStrs[i]; - try { - int octet = Integer.parseInt(octetStr); - if (octet < 0 || octet > 255) { - throw new IllegalArgumentException("Couldn't get an Inet4Address from " + addr); - } - octets[i] = (byte) octet; - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Couldn't get an Inet4Address from " + addr); - } - } - - return octets; - } - - /** - * @param array array - * @param offset offset - * @return a new Inet6Address object. - */ - public static Inet6Address getInet6Address(byte[] array, int offset) { - return getInet6Address(array, offset, ByteOrder.BIG_ENDIAN); - } - - /** - * @param array array - * @param offset offset - * @param bo bo - * @return a new Inet6Address object. - */ - public static Inet6Address getInet6Address(byte[] array, int offset, ByteOrder bo) { - validateBounds(array, offset, INET6_ADDRESS_SIZE_IN_BYTES); - - if (bo == null) { - throw new NullPointerException(" bo: " + bo); - } - - try { - if (bo.equals(LITTLE_ENDIAN)) { - return Inet6Address.getByAddress( - null, reverse(getSubArray(array, offset, INET6_ADDRESS_SIZE_IN_BYTES)), -1); - } else { - return Inet6Address.getByAddress( - null, getSubArray(array, offset, INET6_ADDRESS_SIZE_IN_BYTES), -1); - } - } catch (UnknownHostException e) { - throw new AssertionError(e); - } - } - - /** - * @param value value - * @return byte array - */ - public static byte[] toByteArray(InetAddress value) { - return toByteArray(value, ByteOrder.BIG_ENDIAN); - } - - /** - * @param value value - * @param bo bo - * @return byte array - */ - public static byte[] toByteArray(InetAddress value, ByteOrder bo) { - if (bo.equals(LITTLE_ENDIAN)) { - return reverse(value.getAddress()); - } else { - return value.getAddress(); - } - } - - /** - * @param array array - * @param offset offset - * @param length length - * @return sub array - */ - public static byte[] getSubArray(byte[] array, int offset, int length) { - validateBounds(array, offset, length); - - byte[] subArray = new byte[length]; - System.arraycopy(array, offset, subArray, 0, length); - return subArray; - } - - /** - * @param array array - * @param offset offset - * @return sub array - */ - public static byte[] getSubArray(byte[] array, int offset) { - return getSubArray(array, offset, array.length - offset); - } - - /** - * @param array array - * @param separator separator - * @return hex string - */ - public static String toHexString(byte[] array, String separator) { - return toHexString(array, separator, 0, array.length); - } - - /** - * @param array array - * @param separator separator - * @param offset offset - * @param length length - * @return hex string - */ - public static String toHexString(byte[] array, String separator, int offset, int length) { - validateBounds(array, offset, length); - - char[] hexChars; - if (separator.length() != 0) { - char[] sepChars = separator.toCharArray(); - hexChars = new char[length * 2 + sepChars.length * (length - 1)]; - int cur = 0; - int i = 0; - for (; i < length - 1; i++) { - int v = array[offset + i] & 0xFF; - hexChars[cur] = HEX_CHARS[v >>> 4]; - cur++; - hexChars[cur] = HEX_CHARS[v & 0x0F]; - cur++; - for (int j = 0; j < sepChars.length; j++) { - hexChars[cur] = sepChars[j]; - cur++; - } - } - int v = array[offset + i] & 0xFF; - hexChars[cur] = HEX_CHARS[v >>> 4]; - hexChars[cur + 1] = HEX_CHARS[v & 0x0F]; - } else { - hexChars = new char[length * 2]; - int cur = 0; - for (int i = 0; i < length; i++) { - int v = array[offset + i] & 0xFF; - hexChars[cur] = HEX_CHARS[v >>> 4]; - cur++; - hexChars[cur] = HEX_CHARS[v & 0x0F]; - cur++; - } - } - - return new String(hexChars); - } - - /** - * A utility method to calculate the Internet checksum. - * - * @see RFC 1071 - * @param data data - * @return checksum - */ - public static short calcChecksum(byte[] data) { - long sum = 0; - for (int i = 1; i < data.length; i += SHORT_SIZE_IN_BYTES) { - sum += 0xFFFFL & getShort(data, i - 1); - } - if (data.length % 2 != 0) { - sum += 0xFFFFL & (data[data.length - 1] << BYTE_SIZE_IN_BITS); - } - - while ((sum >> (BYTE_SIZE_IN_BITS * SHORT_SIZE_IN_BYTES)) != 0) { - sum = (0xFFFFL & sum) + (sum >>> (BYTE_SIZE_IN_BITS * SHORT_SIZE_IN_BYTES)); - } - - return (short) ~sum; - } - - /** - * A utility method to calculate CRC-32 checksum. - * - * @param data data - * @return checksum - */ - public static int calcCrc32Checksum(byte[] data) { - CRC32 crc32 = new CRC32(); - crc32.update(data); - return (int) crc32.getValue(); - } - - /** - * A utility method to calculate CRC-32C checksum. - * - * @param data data - * @return checksum - */ - public static int calcCrc32cChecksum(byte[] data) { - int c = 0xFFFFFFFF; - for (int i = 0; i < data.length; i++) { - c = CRC32C_TABLE[(c ^ data[i]) & 0xFF] ^ (c >>> 8); - } - return c ^ 0xFFFFFFFF; - } - - /** - * A utility method to calculate Adler-32 checksum. - * - * @param data data - * @return checksum - */ - public static int calcAdler32Checksum(byte[] data) { - Adler32 adler32 = new Adler32(); - adler32.update(data); - return (int) adler32.getValue(); - } - - /** - * @param hexString hexString - * @param separator separator - * @return a new byte array. - */ - public static byte[] parseByteArray(String hexString, String separator) { - if (hexString == null || separator == null) { - StringBuilder sb = new StringBuilder(); - sb.append("hexString: ").append(hexString).append(" separator: ").append(separator); - throw new NullPointerException(sb.toString()); - } - - if (hexString.startsWith("0x")) { - hexString = hexString.substring(2); - } - - String noSeparatorHexString; - if (separator.length() == 0) { - if (!NO_SEPARATOR_HEX_STRING_PATTERN.matcher(hexString).matches()) { - StringBuilder sb = new StringBuilder(100); - sb.append("invalid hex string(") - .append(hexString) - .append("), not match pattern(") - .append(NO_SEPARATOR_HEX_STRING_PATTERN.pattern()) - .append(")"); - throw new IllegalArgumentException(sb.toString()); - } - noSeparatorHexString = hexString; - } else { - StringBuilder patternSb = new StringBuilder(60); - patternSb - .append("\\A[0-9a-fA-F][0-9a-fA-F](") - .append(Pattern.quote(separator)) - .append("[0-9a-fA-F][0-9a-fA-F])*\\z"); - String patternString = patternSb.toString(); - - Pattern pattern = Pattern.compile(patternString); - if (!pattern.matcher(hexString).matches()) { - StringBuilder sb = new StringBuilder(150); - sb.append("invalid hex string(") - .append(hexString) - .append("), not match pattern(") - .append(patternString) - .append(")"); - throw new IllegalArgumentException(sb.toString()); - } - noSeparatorHexString = hexString.replaceAll(Pattern.quote(separator), ""); - } - - int arrayLength = noSeparatorHexString.length() / 2; - byte[] array = new byte[arrayLength]; - for (int i = 0; i < arrayLength; i++) { - array[i] = (byte) Integer.parseInt(noSeparatorHexString.substring(i * 2, i * 2 + 2), 16); - } - - return array; - } - - /** - * @param array array - * @return a clone of array - */ - public static byte[] clone(byte[] array) { - byte[] clone = new byte[array.length]; - System.arraycopy(array, 0, clone, 0, array.length); - return clone; - } - - /** - * A utility method to validate arguments which indicate a part of an array. - * - * @param arr arr - * @param offset offset - * @param len len - * @throws NullPointerException if the {@code arr} is null. - * @throws IllegalArgumentException if {@code arr} is empty or {@code len} is zero. - * @throws ArrayIndexOutOfBoundsException if {@code offset} or {@code len} is negative, or ({@code - * offset} + {@code len}) is greater than or equal to {@code arr.length}. - */ - public static void validateBounds(byte[] arr, int offset, int len) { - if (arr == null) { - throw new NullPointerException("arr must not be null."); - } - if (arr.length == 0) { - throw new IllegalArgumentException("arr is empty."); - } - if (len == 0) { - StringBuilder sb = new StringBuilder(100); - sb.append("length is zero. offset: ") - .append(offset) - .append(", arr: ") - .append(toHexString(arr, "")); - throw new IllegalArgumentException(sb.toString()); - } - if (offset < 0 || len < 0 || offset + len > arr.length) { - StringBuilder sb = new StringBuilder(100); - sb.append("arr.length: ") - .append(arr.length) - .append(", offset: ") - .append(offset) - .append(", len: ") - .append(len) - .append(", arr: ") - .append(toHexString(arr, "")); - throw new ArrayIndexOutOfBoundsException(sb.toString()); - } - } - - /** - * @param arr1 arr1 - * @param arr2 arr2 - * @return arr1 xor arr2 - */ - public static byte[] xor(byte[] arr1, byte[] arr2) { - if (arr1 == null) { - throw new NullPointerException("arr1 must not be null."); - } - if (arr2 == null) { - throw new NullPointerException("arr2 must not be null."); - } - if (arr1.length != arr2.length) { - throw new IllegalArgumentException("arr1.length must equal to arr2.length."); - } - - byte[] result = new byte[arr1.length]; - for (int i = 0; i < arr1.length; i++) { - result[i] = (byte) (arr1[i] ^ arr2[i]); - } - - return result; - } - - /** - * @param arr1 arr1 - * @param arr2 arr2 - * @return arr1 + arr2 - */ - public static byte[] concatenate(byte[] arr1, byte[] arr2) { - byte[] result = new byte[arr1.length + arr2.length]; - System.arraycopy(arr1, 0, result, 0, arr1.length); - System.arraycopy(arr2, 0, result, arr1.length, arr2.length); - return result; - } - - /** - * @param arrs arrays - * @return the concatenated array. - */ - public static byte[] concatenate(List arrs) { - int length = 0; - for (byte[] arr : arrs) { - length += arr.length; - } - - byte[] result = new byte[length]; - int destPos = 0; - for (byte[] arr : arrs) { - System.arraycopy(arr, 0, result, destPos, arr.length); - destPos += arr.length; - } - - return result; - } +/*_########################################################################## + _## + _## Copyright (C) 2011-2019 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.util; + +import static java.nio.ByteOrder.*; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteOrder; +import java.util.List; +import java.util.regex.Pattern; +import java.util.zip.Adler32; +import java.util.zip.CRC32; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.1 + */ +public final class ByteArrays { + + /** */ + public static final int BYTE_SIZE_IN_BYTES = 1; + + /** */ + public static final int SHORT_SIZE_IN_BYTES = 2; + + /** */ + public static final int INT_SIZE_IN_BYTES = 4; + + /** */ + public static final int LONG_SIZE_IN_BYTES = 8; + + /** */ + public static final int INET4_ADDRESS_SIZE_IN_BYTES = 4; + + /** */ + public static final int INET6_ADDRESS_SIZE_IN_BYTES = 16; + + /** */ + public static final int BYTE_SIZE_IN_BITS = 8; + + private static final Pattern NO_SEPARATOR_HEX_STRING_PATTERN = + Pattern.compile("\\A([0-9a-fA-F][0-9a-fA-F])+\\z"); + + private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); + + private static final int[] CRC32C_TABLE = + new int[] { + 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, + 0xd4ca64eb, + 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, + 0x5e133c24, + 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, + 0xc494a384, + 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848, + 0x4e4dfb4b, + 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936, + 0xf477ea35, + 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, + 0x7eaeb2fa, + 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59, + 0xe4292d5a, + 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696, + 0x6ef07595, + 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, + 0x95b17957, + 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b, + 0x1f682198, + 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, + 0x85efbe38, + 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, + 0x0f36e6f7, + 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a, + 0xb50cf789, + 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, + 0x3fd5af46, + 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, + 0xa55230e6, + 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, + 0x2f8b6829, + 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90, + 0x563c5f93, + 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, + 0xdce5075c, + 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff, + 0x466298fc, + 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, + 0xccbbc033, + 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, + 0x7681d14d, + 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81, + 0xfc588982, + 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521, + 0x66df1622, + 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, + 0xec064eed, + 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c, + 0x1747422f, + 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3, + 0x9d9e1ae0, + 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, + 0x07198540, + 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, + 0x8dc0dd8f, + 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, + 0x37faccf1, + 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, + 0xbd23943e, + 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, + 0x27a40b9e, + 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, + 0xad7d5351, + }; + + private ByteArrays() { + throw new AssertionError(); + } + + /** + * @param array array + * @return a new array containing specified array's elements in reverse order. + */ + public static byte[] reverse(byte[] array) { + byte[] rarray = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + rarray[i] = array[array.length - i - 1]; + } + return rarray; + } + + /** + * @param array array + * @param offset offset + * @return byte value. + */ + public static byte getByte(byte[] array, int offset) { + validateBounds(array, offset, BYTE_SIZE_IN_BYTES); + return array[offset]; + } + + /** + * @param value value + * @return byte array + */ + public static byte[] toByteArray(byte value) { + return new byte[] {value}; + } + + /** + * @param value value + * @param separator separator + * @return hex string + */ + public static String toHexString(byte value, String separator) { + return toHexString(toByteArray(value), separator); + } + + /** + * @param array array + * @param offset offset + * @return short value + */ + public static short getShort(byte[] array, int offset) { + return getShort(array, offset, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param bo bo + * @return short value + */ + public static short getShort(byte[] array, int offset, ByteOrder bo) { + validateBounds(array, offset, SHORT_SIZE_IN_BYTES); + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + if (bo.equals(LITTLE_ENDIAN)) { + return (short) (((array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) | ((0xFF & array[offset]))); + } else { + return (short) (((array[offset]) << (BYTE_SIZE_IN_BITS * 1)) | ((0xFF & array[offset + 1]))); + } + } + + /** + * @param value value + * @return byte array + */ + public static byte[] toByteArray(short value) { + return toByteArray(value, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param bo bo + * @return byte array + */ + public static byte[] toByteArray(short value, ByteOrder bo) { + if (bo.equals(LITTLE_ENDIAN)) { + return new byte[] {(byte) (value), (byte) (value >> BYTE_SIZE_IN_BITS * 1)}; + } else { + return new byte[] {(byte) (value >> BYTE_SIZE_IN_BITS * 1), (byte) (value)}; + } + } + + /** + * @param value value + * @param separator separator + * @return hex string + */ + public static String toHexString(short value, String separator) { + return toHexString(value, separator, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param separator separator + * @param bo bo + * @return hex string + */ + public static String toHexString(short value, String separator, ByteOrder bo) { + return toHexString(toByteArray(value, bo), separator); + } + + /** + * @param array array + * @param offset offset + * @return int value. + */ + public static int getInt(byte[] array, int offset) { + return getInt(array, offset, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param bo bo + * @return int value. + */ + public static int getInt(byte[] array, int offset, ByteOrder bo) { + validateBounds(array, offset, INT_SIZE_IN_BYTES); + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + if (bo.equals(LITTLE_ENDIAN)) { + return ((array[offset + 3]) << (BYTE_SIZE_IN_BITS * 3)) + | ((0xFF & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 2)) + | ((0xFF & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) + | ((0xFF & array[offset])); + } else { + return ((array[offset]) << (BYTE_SIZE_IN_BITS * 3)) + | ((0xFF & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 2)) + | ((0xFF & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 1)) + | ((0xFF & array[offset + 3])); + } + } + + /** + * @param array array + * @param offset offset + * @param length length + * @return int value. + */ + public static int getInt(byte[] array, int offset, int length) { + return getInt(array, offset, length, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param length length + * @param bo bo + * @return int value. + */ + public static int getInt(byte[] array, int offset, int length, ByteOrder bo) { + validateBounds(array, offset, length); + if (length > INT_SIZE_IN_BYTES) { + StringBuilder sb = + new StringBuilder(30) + .append("length must be equal or less than ") + .append(INT_SIZE_IN_BYTES) + .append(", but is: ") + .append(length); + throw new IllegalArgumentException(sb.toString()); + } + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + int value = 0; + if (bo.equals(LITTLE_ENDIAN)) { + for (int i = offset + length - 1; i >= offset; i--) { + value <<= BYTE_SIZE_IN_BITS; + value |= 0xFF & array[i]; + } + } else { + for (int i = offset; i < offset + length; i++) { + value <<= BYTE_SIZE_IN_BITS; + value |= 0xFF & array[i]; + } + } + return value; + } + + /** + * @param value value + * @return byte array + */ + public static byte[] toByteArray(int value) { + return toByteArray(value, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param bo bo + * @return byte array + */ + public static byte[] toByteArray(int value, ByteOrder bo) { + if (bo.equals(LITTLE_ENDIAN)) { + return new byte[] { + (byte) (value), + (byte) (value >> BYTE_SIZE_IN_BITS * 1), + (byte) (value >> BYTE_SIZE_IN_BITS * 2), + (byte) (value >> BYTE_SIZE_IN_BITS * 3), + }; + } else { + return new byte[] { + (byte) (value >> BYTE_SIZE_IN_BITS * 3), + (byte) (value >> BYTE_SIZE_IN_BITS * 2), + (byte) (value >> BYTE_SIZE_IN_BITS * 1), + (byte) (value) + }; + } + } + + /** + * @param value value + * @param length length + * @return byte array + */ + public static byte[] toByteArray(int value, int length) { + return toByteArray(value, length, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param length length + * @param bo bo + * @return byte array + */ + public static byte[] toByteArray(int value, int length, ByteOrder bo) { + if (length > INT_SIZE_IN_BYTES) { + StringBuilder sb = + new StringBuilder(30) + .append("length must be equal or less than ") + .append(INT_SIZE_IN_BYTES) + .append(", but is: ") + .append(length); + throw new IllegalArgumentException(sb.toString()); + } + + byte[] arr = new byte[length]; + if (bo.equals(LITTLE_ENDIAN)) { + for (int i = 0; i < length; i++) { + arr[length - i - 1] = (byte) (value >> BYTE_SIZE_IN_BITS * i); + } + } else { + for (int i = 0; i < length; i++) { + arr[i] = (byte) (value >> BYTE_SIZE_IN_BITS * i); + } + } + + return arr; + } + + /** + * @param value value + * @param separator separator + * @return hex string + */ + public static String toHexString(int value, String separator) { + return toHexString(value, separator, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param separator separator + * @param bo bo + * @return hex string + */ + public static String toHexString(int value, String separator, ByteOrder bo) { + return toHexString(toByteArray(value, bo), separator); + } + + /** + * @param array array + * @param offset offset + * @return long value + */ + public static long getLong(byte[] array, int offset) { + return getLong(array, offset, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param bo bo + * @return long value + */ + public static long getLong(byte[] array, int offset, ByteOrder bo) { + validateBounds(array, offset, LONG_SIZE_IN_BYTES); + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + if (bo.equals(LITTLE_ENDIAN)) { + return (((long) array[offset + 7]) << (BYTE_SIZE_IN_BITS * 7)) + | ((0xFFL & array[offset + 6]) << (BYTE_SIZE_IN_BITS * 6)) + | ((0xFFL & array[offset + 5]) << (BYTE_SIZE_IN_BITS * 5)) + | ((0xFFL & array[offset + 4]) << (BYTE_SIZE_IN_BITS * 4)) + | ((0xFFL & array[offset + 3]) << (BYTE_SIZE_IN_BITS * 3)) + | ((0xFFL & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 2)) + | ((0xFFL & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) + | ((0xFFL & array[offset])); + } else { + return (((long) array[offset]) << (BYTE_SIZE_IN_BITS * 7)) + | ((0xFFL & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 6)) + | ((0xFFL & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 5)) + | ((0xFFL & array[offset + 3]) << (BYTE_SIZE_IN_BITS * 4)) + | ((0xFFL & array[offset + 4]) << (BYTE_SIZE_IN_BITS * 3)) + | ((0xFFL & array[offset + 5]) << (BYTE_SIZE_IN_BITS * 2)) + | ((0xFFL & array[offset + 6]) << (BYTE_SIZE_IN_BITS * 1)) + | ((0xFFL & array[offset + 7])); + } + } + + /** + * @param value value + * @return byte array + */ + public static byte[] toByteArray(long value) { + return toByteArray(value, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param bo bo + * @return byte array + */ + public static byte[] toByteArray(long value, ByteOrder bo) { + if (bo.equals(LITTLE_ENDIAN)) { + return new byte[] { + (byte) (value), + (byte) (value >> BYTE_SIZE_IN_BITS * 1), + (byte) (value >> BYTE_SIZE_IN_BITS * 2), + (byte) (value >> BYTE_SIZE_IN_BITS * 3), + (byte) (value >> BYTE_SIZE_IN_BITS * 4), + (byte) (value >> BYTE_SIZE_IN_BITS * 5), + (byte) (value >> BYTE_SIZE_IN_BITS * 6), + (byte) (value >> BYTE_SIZE_IN_BITS * 7) + }; + } else { + return new byte[] { + (byte) (value >> BYTE_SIZE_IN_BITS * 7), + (byte) (value >> BYTE_SIZE_IN_BITS * 6), + (byte) (value >> BYTE_SIZE_IN_BITS * 5), + (byte) (value >> BYTE_SIZE_IN_BITS * 4), + (byte) (value >> BYTE_SIZE_IN_BITS * 3), + (byte) (value >> BYTE_SIZE_IN_BITS * 2), + (byte) (value >> BYTE_SIZE_IN_BITS * 1), + (byte) (value) + }; + } + } + + /** + * @param value value + * @param separator separator + * @return hex string + */ + public static String toHexString(long value, String separator) { + return toHexString(value, separator, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param separator separator + * @param bo bo + * @return hex string + */ + public static String toHexString(long value, String separator, ByteOrder bo) { + return toHexString(toByteArray(value, bo), separator); + } + + /** + * @param array array + * @param offset offset + * @return a new MacAddress object. + */ + public static MacAddress getMacAddress(byte[] array, int offset) { + return getMacAddress(array, offset, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param bo bo + * @return a new MacAddress object. + */ + public static MacAddress getMacAddress(byte[] array, int offset, ByteOrder bo) { + validateBounds(array, offset, MacAddress.SIZE_IN_BYTES); + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + if (bo.equals(LITTLE_ENDIAN)) { + return MacAddress.getByAddress(reverse(getSubArray(array, offset, MacAddress.SIZE_IN_BYTES))); + } else { + return MacAddress.getByAddress(getSubArray(array, offset, MacAddress.SIZE_IN_BYTES)); + } + } + + /** + * @param value value + * @return byte array + */ + public static byte[] toByteArray(MacAddress value) { + return toByteArray(value, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param bo bo + * @return byte array + */ + public static byte[] toByteArray(MacAddress value, ByteOrder bo) { + if (bo.equals(LITTLE_ENDIAN)) { + return reverse(value.getAddress()); + } else { + return value.getAddress(); + } + } + + /** + * @param array array + * @param offset offset + * @param length length + * @return a new LinkLayerAddress object. + */ + public static LinkLayerAddress getLinkLayerAddress(byte[] array, int offset, int length) { + return getLinkLayerAddress(array, offset, length, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param length length + * @param bo bo + * @return a new LinkLayerAddress object. + */ + public static LinkLayerAddress getLinkLayerAddress( + byte[] array, int offset, int length, ByteOrder bo) { + validateBounds(array, offset, length); + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + if (bo.equals(LITTLE_ENDIAN)) { + return LinkLayerAddress.getByAddress(reverse(getSubArray(array, offset, length))); + } else { + return LinkLayerAddress.getByAddress(getSubArray(array, offset, length)); + } + } + + /** + * @param value value + * @return byte array + */ + public static byte[] toByteArray(LinkLayerAddress value) { + return toByteArray(value, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param bo bo + * @return byte array + */ + public static byte[] toByteArray(LinkLayerAddress value, ByteOrder bo) { + if (bo.equals(LITTLE_ENDIAN)) { + return reverse(value.getAddress()); + } else { + return value.getAddress(); + } + } + + /** + * @param array array + * @param offset offset + * @return a new Inet4Address object. + */ + public static Inet4Address getInet4Address(byte[] array, int offset) { + return getInet4Address(array, offset, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param bo bo + * @return a new Inet4Address object. + */ + public static Inet4Address getInet4Address(byte[] array, int offset, ByteOrder bo) { + validateBounds(array, offset, INET4_ADDRESS_SIZE_IN_BYTES); + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + try { + if (bo.equals(LITTLE_ENDIAN)) { + return (Inet4Address) + InetAddress.getByAddress( + reverse(getSubArray(array, offset, INET4_ADDRESS_SIZE_IN_BYTES))); + } else { + return (Inet4Address) + InetAddress.getByAddress(getSubArray(array, offset, INET4_ADDRESS_SIZE_IN_BYTES)); + } + } catch (UnknownHostException e) { + throw new AssertionError(e); + } + } + + /** + * @param addr a string representation of an IPv4 address. (e.g. "192.168.0.100") + * @return a byte array representation of the IPv4 address. + * @throws IllegalArgumentException if failed to parse addr. + */ + public static byte[] parseInet4Address(String addr) { + String[] octetStrs = addr.split("\\.", 4); + if (octetStrs.length != INET4_ADDRESS_SIZE_IN_BYTES) { + throw new IllegalArgumentException("Couldn't get an Inet4Address from " + addr); + } + + byte[] octets = new byte[4]; + for (int i = 0; i < octets.length; i++) { + String octetStr = octetStrs[i]; + try { + int octet = Integer.parseInt(octetStr); + if (octet < 0 || octet > 255) { + throw new IllegalArgumentException("Couldn't get an Inet4Address from " + addr); + } + octets[i] = (byte) octet; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Couldn't get an Inet4Address from " + addr); + } + } + + return octets; + } + + /** + * @param array array + * @param offset offset + * @return a new Inet6Address object. + */ + public static Inet6Address getInet6Address(byte[] array, int offset) { + return getInet6Address(array, offset, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param bo bo + * @return a new Inet6Address object. + */ + public static Inet6Address getInet6Address(byte[] array, int offset, ByteOrder bo) { + validateBounds(array, offset, INET6_ADDRESS_SIZE_IN_BYTES); + + if (bo == null) { + throw new NullPointerException(" bo: " + bo); + } + + try { + if (bo.equals(LITTLE_ENDIAN)) { + return Inet6Address.getByAddress( + null, reverse(getSubArray(array, offset, INET6_ADDRESS_SIZE_IN_BYTES)), -1); + } else { + return Inet6Address.getByAddress( + null, getSubArray(array, offset, INET6_ADDRESS_SIZE_IN_BYTES), -1); + } + } catch (UnknownHostException e) { + throw new AssertionError(e); + } + } + + /** + * @param value value + * @return byte array + */ + public static byte[] toByteArray(InetAddress value) { + return toByteArray(value, ByteOrder.BIG_ENDIAN); + } + + /** + * @param value value + * @param bo bo + * @return byte array + */ + public static byte[] toByteArray(InetAddress value, ByteOrder bo) { + if (bo.equals(LITTLE_ENDIAN)) { + return reverse(value.getAddress()); + } else { + return value.getAddress(); + } + } + + /** + * @param array array + * @param offset offset + * @param length length + * @return sub array + */ + public static byte[] getSubArray(byte[] array, int offset, int length) { + validateBounds(array, offset, length); + + byte[] subArray = new byte[length]; + System.arraycopy(array, offset, subArray, 0, length); + return subArray; + } + + /** + * @param array array + * @param offset offset + * @return sub array + */ + public static byte[] getSubArray(byte[] array, int offset) { + return getSubArray(array, offset, array.length - offset); + } + + /** + * @param array array + * @param separator separator + * @return hex string + */ + public static String toHexString(byte[] array, String separator) { + return toHexString(array, separator, 0, array.length); + } + + /** + * @param array array + * @param separator separator + * @param offset offset + * @param length length + * @return hex string + */ + public static String toHexString(byte[] array, String separator, int offset, int length) { + validateBounds(array, offset, length); + + char[] hexChars; + if (separator.length() != 0) { + char[] sepChars = separator.toCharArray(); + hexChars = new char[length * 2 + sepChars.length * (length - 1)]; + int cur = 0; + int i = 0; + for (; i < length - 1; i++) { + int v = array[offset + i] & 0xFF; + hexChars[cur] = HEX_CHARS[v >>> 4]; + cur++; + hexChars[cur] = HEX_CHARS[v & 0x0F]; + cur++; + for (int j = 0; j < sepChars.length; j++) { + hexChars[cur] = sepChars[j]; + cur++; + } + } + int v = array[offset + i] & 0xFF; + hexChars[cur] = HEX_CHARS[v >>> 4]; + hexChars[cur + 1] = HEX_CHARS[v & 0x0F]; + } else { + hexChars = new char[length * 2]; + int cur = 0; + for (int i = 0; i < length; i++) { + int v = array[offset + i] & 0xFF; + hexChars[cur] = HEX_CHARS[v >>> 4]; + cur++; + hexChars[cur] = HEX_CHARS[v & 0x0F]; + cur++; + } + } + + return new String(hexChars); + } + + /** + * A utility method to calculate the Internet checksum. + * + * @see RFC 1071 + * @param data data + * @return checksum + */ + public static short calcChecksum(byte[] data) { + long sum = 0; + for (int i = 1; i < data.length; i += SHORT_SIZE_IN_BYTES) { + sum += 0xFFFFL & getShort(data, i - 1); + } + if (data.length % 2 != 0) { + sum += 0xFFFFL & (data[data.length - 1] << BYTE_SIZE_IN_BITS); + } + + while ((sum >> (BYTE_SIZE_IN_BITS * SHORT_SIZE_IN_BYTES)) != 0) { + sum = (0xFFFFL & sum) + (sum >>> (BYTE_SIZE_IN_BITS * SHORT_SIZE_IN_BYTES)); + } + + return (short) ~sum; + } + + /** + * A utility method to calculate CRC-32 checksum. + * + * @param data data + * @return checksum + */ + public static int calcCrc32Checksum(byte[] data) { + CRC32 crc32 = new CRC32(); + crc32.update(data); + return (int) crc32.getValue(); + } + + /** + * A utility method to calculate CRC-32C checksum. + * + * @param data data + * @return checksum + */ + public static int calcCrc32cChecksum(byte[] data) { + int c = 0xFFFFFFFF; + for (int i = 0; i < data.length; i++) { + c = CRC32C_TABLE[(c ^ data[i]) & 0xFF] ^ (c >>> 8); + } + return c ^ 0xFFFFFFFF; + } + + /** + * A utility method to calculate Adler-32 checksum. + * + * @param data data + * @return checksum + */ + public static int calcAdler32Checksum(byte[] data) { + Adler32 adler32 = new Adler32(); + adler32.update(data); + return (int) adler32.getValue(); + } + + /** + * @param hexString hexString + * @param separator separator + * @return a new byte array. + */ + public static byte[] parseByteArray(String hexString, String separator) { + if (hexString == null || separator == null) { + StringBuilder sb = new StringBuilder(); + sb.append("hexString: ").append(hexString).append(" separator: ").append(separator); + throw new NullPointerException(sb.toString()); + } + + if (hexString.startsWith("0x")) { + hexString = hexString.substring(2); + } + + String noSeparatorHexString; + if (separator.length() == 0) { + if (!NO_SEPARATOR_HEX_STRING_PATTERN.matcher(hexString).matches()) { + StringBuilder sb = new StringBuilder(100); + sb.append("invalid hex string(") + .append(hexString) + .append("), not match pattern(") + .append(NO_SEPARATOR_HEX_STRING_PATTERN.pattern()) + .append(")"); + throw new IllegalArgumentException(sb.toString()); + } + noSeparatorHexString = hexString; + } else { + StringBuilder patternSb = new StringBuilder(60); + patternSb + .append("\\A[0-9a-fA-F][0-9a-fA-F](") + .append(Pattern.quote(separator)) + .append("[0-9a-fA-F][0-9a-fA-F])*\\z"); + String patternString = patternSb.toString(); + + Pattern pattern = Pattern.compile(patternString); + if (!pattern.matcher(hexString).matches()) { + StringBuilder sb = new StringBuilder(150); + sb.append("invalid hex string(") + .append(hexString) + .append("), not match pattern(") + .append(patternString) + .append(")"); + throw new IllegalArgumentException(sb.toString()); + } + noSeparatorHexString = hexString.replaceAll(Pattern.quote(separator), ""); + } + + int arrayLength = noSeparatorHexString.length() / 2; + byte[] array = new byte[arrayLength]; + for (int i = 0; i < arrayLength; i++) { + array[i] = (byte) Integer.parseInt(noSeparatorHexString.substring(i * 2, i * 2 + 2), 16); + } + + return array; + } + + /** + * @param array array + * @return a clone of array + */ + public static byte[] clone(byte[] array) { + byte[] clone = new byte[array.length]; + System.arraycopy(array, 0, clone, 0, array.length); + return clone; + } + + /** + * A utility method to validate arguments which indicate a part of an array. + * + * @param arr arr + * @param offset offset + * @param len len + * @throws NullPointerException if the {@code arr} is null. + * @throws IllegalArgumentException if {@code arr} is empty or {@code len} is zero. + * @throws ArrayIndexOutOfBoundsException if {@code offset} or {@code len} is negative, or ({@code + * offset} + {@code len}) is greater than or equal to {@code arr.length}. + */ + public static void validateBounds(byte[] arr, int offset, int len) { + if (arr == null) { + throw new NullPointerException("arr must not be null."); + } + if (arr.length == 0) { + throw new IllegalArgumentException("arr is empty."); + } + if (len == 0) { + StringBuilder sb = new StringBuilder(100); + sb.append("length is zero. offset: ") + .append(offset) + .append(", arr: ") + .append(toHexString(arr, "")); + throw new IllegalArgumentException(sb.toString()); + } + if (offset < 0 || len < 0 || offset + len > arr.length) { + StringBuilder sb = new StringBuilder(100); + sb.append("arr.length: ") + .append(arr.length) + .append(", offset: ") + .append(offset) + .append(", len: ") + .append(len) + .append(", arr: ") + .append(toHexString(arr, "")); + throw new ArrayIndexOutOfBoundsException(sb.toString()); + } + } + + /** + * @param arr1 arr1 + * @param arr2 arr2 + * @return arr1 xor arr2 + */ + public static byte[] xor(byte[] arr1, byte[] arr2) { + if (arr1 == null) { + throw new NullPointerException("arr1 must not be null."); + } + if (arr2 == null) { + throw new NullPointerException("arr2 must not be null."); + } + if (arr1.length != arr2.length) { + throw new IllegalArgumentException("arr1.length must equal to arr2.length."); + } + + byte[] result = new byte[arr1.length]; + for (int i = 0; i < arr1.length; i++) { + result[i] = (byte) (arr1[i] ^ arr2[i]); + } + + return result; + } + + /** + * @param arr1 arr1 + * @param arr2 arr2 + * @return arr1 + arr2 + */ + public static byte[] concatenate(byte[] arr1, byte[] arr2) { + byte[] result = new byte[arr1.length + arr2.length]; + System.arraycopy(arr1, 0, result, 0, arr1.length); + System.arraycopy(arr2, 0, result, arr1.length, arr2.length); + return result; + } + + /** + * @param arrs arrays + * @return the concatenated array. + */ + public static byte[] concatenate(List arrs) { + int length = 0; + for (byte[] arr : arrs) { + length += arr.length; + } + + byte[] result = new byte[length]; + int destPos = 0; + for (byte[] arr : arrs) { + System.arraycopy(arr, 0, result, destPos, arr.length); + destPos += arr.length; + } + + return result; + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/util/Inet4NetworkAddress.java b/app/src/main/java/org/pcap4j/util/Inet4NetworkAddress.java index ce96cbd..20260da 100644 --- a/app/src/main/java/org/pcap4j/util/Inet4NetworkAddress.java +++ b/app/src/main/java/org/pcap4j/util/Inet4NetworkAddress.java @@ -1,43 +1,43 @@ -/*_########################################################################## - _## - _## Copyright (C) 2013 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.util; - -import java.io.Serializable; -import java.net.Inet4Address; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.15 - */ -public final class Inet4NetworkAddress implements Serializable { - - /** */ - private static final long serialVersionUID = -8599700451783666420L; - - private final Inet4Address networkAddress; - private final Inet4Address mask; - - /** - * @param networkAddress networkAddress - * @param mask mask - */ - public Inet4NetworkAddress(Inet4Address networkAddress, Inet4Address mask) { - this.networkAddress = networkAddress; - this.mask = mask; - } - - /** @return networkAddress */ - public Inet4Address getNetworkAddress() { - return networkAddress; - } - - /** @return mask */ - public Inet4Address getMask() { - return mask; - } +/*_########################################################################## + _## + _## Copyright (C) 2013 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.util; + +import java.io.Serializable; +import java.net.Inet4Address; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.15 + */ +public final class Inet4NetworkAddress implements Serializable { + + /** */ + private static final long serialVersionUID = -8599700451783666420L; + + private final Inet4Address networkAddress; + private final Inet4Address mask; + + /** + * @param networkAddress networkAddress + * @param mask mask + */ + public Inet4NetworkAddress(Inet4Address networkAddress, Inet4Address mask) { + this.networkAddress = networkAddress; + this.mask = mask; + } + + /** @return networkAddress */ + public Inet4Address getNetworkAddress() { + return networkAddress; + } + + /** @return mask */ + public Inet4Address getMask() { + return mask; + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/util/LazyValue.java b/app/src/main/java/org/pcap4j/util/LazyValue.java index a131202..0ed7011 100644 --- a/app/src/main/java/org/pcap4j/util/LazyValue.java +++ b/app/src/main/java/org/pcap4j/util/LazyValue.java @@ -1,66 +1,66 @@ -/*_########################################################################## - _## - _## Copyright (C) 2012 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.util; - -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.6 - * @param the type of value this class returns. - */ -public final class LazyValue implements Serializable { - - /** */ - private static final long serialVersionUID = 1379102837076225509L; - - private final transient BuildValueCommand command; - private final transient Object thisLock = new Object(); - - private volatile T1 value = null; - - /** @param command command */ - public LazyValue(BuildValueCommand command) { - this.command = command; - } - - /** @return value */ - public T1 getValue() { - T1 result = value; - if (result == null) { - synchronized (thisLock) { - result = value; - if (result == null) { - value = command.buildValue(); - } - } - } - return value; - } - - private void writeObject(ObjectOutputStream out) throws IOException { - getValue(); - if (value == null) { - throw new AssertionError(); - } - out.defaultWriteObject(); - } - - /** - * @author Kaito Yamada - * @since pcap4j 0.9.6 - * @param the type of value to build. - */ - public interface BuildValueCommand { - - /** @return value */ - public T2 buildValue(); - } +/*_########################################################################## + _## + _## Copyright (C) 2012 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.util; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.6 + * @param the type of value this class returns. + */ +public final class LazyValue implements Serializable { + + /** */ + private static final long serialVersionUID = 1379102837076225509L; + + private final transient BuildValueCommand command; + private final transient Object thisLock = new Object(); + + private volatile T1 value = null; + + /** @param command command */ + public LazyValue(BuildValueCommand command) { + this.command = command; + } + + /** @return value */ + public T1 getValue() { + T1 result = value; + if (result == null) { + synchronized (thisLock) { + result = value; + if (result == null) { + value = command.buildValue(); + } + } + } + return value; + } + + private void writeObject(ObjectOutputStream out) throws IOException { + getValue(); + if (value == null) { + throw new AssertionError(); + } + out.defaultWriteObject(); + } + + /** + * @author Kaito Yamada + * @since pcap4j 0.9.6 + * @param the type of value to build. + */ + public interface BuildValueCommand { + + /** @return value */ + public T2 buildValue(); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/util/LinkLayerAddress.java b/app/src/main/java/org/pcap4j/util/LinkLayerAddress.java index e7eb02f..2d4dc0a 100644 --- a/app/src/main/java/org/pcap4j/util/LinkLayerAddress.java +++ b/app/src/main/java/org/pcap4j/util/LinkLayerAddress.java @@ -1,91 +1,91 @@ -/*_########################################################################## - _## - _## Copyright (C) 2014 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.util; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author Kaito Yamada - * @since pcap4j 1.0.1 - */ -public class LinkLayerAddress implements Serializable { - - /** */ - private static final long serialVersionUID = -2832879271594305200L; - - /** */ - protected static final Pattern HEX_SEPARATOR_PATTERN = Pattern.compile("([^0-9a-fA-F])"); - - private final byte[] address; - - /** @param address address */ - protected LinkLayerAddress(byte[] address) { - this.address = address; - } - - /** - * @param address address - * @return a new LinkLayerAddress object. - */ - public static LinkLayerAddress getByAddress(byte[] address) { - return new LinkLayerAddress(ByteArrays.clone(address)); - } - - /** - * @param name name - * @return a new LinkLayerAddress object. - */ - public static LinkLayerAddress getByName(String name) { - Matcher m = HEX_SEPARATOR_PATTERN.matcher(name); - m.find(); - return getByName(name, m.group(1)); - } - - /** - * @param name name - * @param separator separator - * @return a new LinkLayerAddress object. - */ - public static LinkLayerAddress getByName(String name, String separator) { - return getByAddress(ByteArrays.parseByteArray(name, separator)); - } - - /** @return address */ - public byte[] getAddress() { - return ByteArrays.clone(address); - } - - /** @return length */ - public int length() { - return address.length; - } - - @Override - public String toString() { - return ByteArrays.toHexString(address, ":"); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof LinkLayerAddress)) { - return false; - } - return Arrays.equals(((LinkLayerAddress) obj).getAddress(), address); - } - - @Override - public int hashCode() { - return Arrays.hashCode(address); - } +/*_########################################################################## + _## + _## Copyright (C) 2014 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.util; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Kaito Yamada + * @since pcap4j 1.0.1 + */ +public class LinkLayerAddress implements Serializable { + + /** */ + private static final long serialVersionUID = -2832879271594305200L; + + /** */ + protected static final Pattern HEX_SEPARATOR_PATTERN = Pattern.compile("([^0-9a-fA-F])"); + + private final byte[] address; + + /** @param address address */ + protected LinkLayerAddress(byte[] address) { + this.address = address; + } + + /** + * @param address address + * @return a new LinkLayerAddress object. + */ + public static LinkLayerAddress getByAddress(byte[] address) { + return new LinkLayerAddress(ByteArrays.clone(address)); + } + + /** + * @param name name + * @return a new LinkLayerAddress object. + */ + public static LinkLayerAddress getByName(String name) { + Matcher m = HEX_SEPARATOR_PATTERN.matcher(name); + m.find(); + return getByName(name, m.group(1)); + } + + /** + * @param name name + * @param separator separator + * @return a new LinkLayerAddress object. + */ + public static LinkLayerAddress getByName(String name, String separator) { + return getByAddress(ByteArrays.parseByteArray(name, separator)); + } + + /** @return address */ + public byte[] getAddress() { + return ByteArrays.clone(address); + } + + /** @return length */ + public int length() { + return address.length; + } + + @Override + public String toString() { + return ByteArrays.toHexString(address, ":"); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof LinkLayerAddress)) { + return false; + } + return Arrays.equals(((LinkLayerAddress) obj).getAddress(), address); + } + + @Override + public int hashCode() { + return Arrays.hashCode(address); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/util/MacAddress.java b/app/src/main/java/org/pcap4j/util/MacAddress.java index 3ede17f..c8b7a08 100644 --- a/app/src/main/java/org/pcap4j/util/MacAddress.java +++ b/app/src/main/java/org/pcap4j/util/MacAddress.java @@ -1,95 +1,95 @@ -/*_########################################################################## - _## - _## Copyright (C) 2011-2014 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.util; - -import java.util.regex.Matcher; -import org.pcap4j.packet.namednumber.Oui; - -/** - * @author Kaito Yamada - * @since pcap4j 0.9.1 - */ -public final class MacAddress extends LinkLayerAddress { - - /** */ - private static final long serialVersionUID = -8222662646993989547L; - - /** */ - public static final MacAddress ETHER_BROADCAST_ADDRESS = - MacAddress.getByAddress( - new byte[] {(byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255}); - - /** */ - public static final int SIZE_IN_BYTES = 6; - - private MacAddress(byte[] address) { - super(address); - } - - /** - * @param address address - * @return a new MacAddress object. - */ - public static MacAddress getByAddress(byte[] address) { - if (address.length != SIZE_IN_BYTES) { - throw new IllegalArgumentException( - ByteArrays.toHexString(address, ":") - + " is invalid for address. The length must be " - + SIZE_IN_BYTES); - } - return new MacAddress(ByteArrays.clone(address)); - } - - /** - * @param name name - * @return a new MacAddress object. - */ - public static MacAddress getByName(String name) { - Matcher m = HEX_SEPARATOR_PATTERN.matcher(name); - m.find(); - return getByName(name, m.group(1)); - } - - /** - * @param name name - * @param separator separator - * @return a new MacAddress object. - */ - public static MacAddress getByName(String name, String separator) { - return getByAddress(ByteArrays.parseByteArray(name, separator)); - } - - /** @return OUI */ - public Oui getOui() { - return Oui.getInstance(ByteArrays.getInt(getAddress(), 0) >>> 8); - } - - /** - * @return true if the MAC address represented by this object is a unicast address; otherwise - * false. - */ - public boolean isUnicast() { - return (getAddress()[0] & 1) == 0; - } - - /** - * @return true if the MAC address represented by this object is a globally unique address; - * otherwise false. - */ - public boolean isGloballyUnique() { - return (getAddress()[0] & 2) == 0; - } - - @Override - public String toString() { - if(this.equals(ETHER_BROADCAST_ADDRESS)) { - return "Broadcast"; - } - return super.toString(); - } +/*_########################################################################## + _## + _## Copyright (C) 2011-2014 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.util; + +import java.util.regex.Matcher; +import org.pcap4j.packet.namednumber.Oui; + +/** + * @author Kaito Yamada + * @since pcap4j 0.9.1 + */ +public final class MacAddress extends LinkLayerAddress { + + /** */ + private static final long serialVersionUID = -8222662646993989547L; + + /** */ + public static final MacAddress ETHER_BROADCAST_ADDRESS = + MacAddress.getByAddress( + new byte[] {(byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255}); + + /** */ + public static final int SIZE_IN_BYTES = 6; + + private MacAddress(byte[] address) { + super(address); + } + + /** + * @param address address + * @return a new MacAddress object. + */ + public static MacAddress getByAddress(byte[] address) { + if (address.length != SIZE_IN_BYTES) { + throw new IllegalArgumentException( + ByteArrays.toHexString(address, ":") + + " is invalid for address. The length must be " + + SIZE_IN_BYTES); + } + return new MacAddress(ByteArrays.clone(address)); + } + + /** + * @param name name + * @return a new MacAddress object. + */ + public static MacAddress getByName(String name) { + Matcher m = HEX_SEPARATOR_PATTERN.matcher(name); + m.find(); + return getByName(name, m.group(1)); + } + + /** + * @param name name + * @param separator separator + * @return a new MacAddress object. + */ + public static MacAddress getByName(String name, String separator) { + return getByAddress(ByteArrays.parseByteArray(name, separator)); + } + + /** @return OUI */ + public Oui getOui() { + return Oui.getInstance(ByteArrays.getInt(getAddress(), 0) >>> 8); + } + + /** + * @return true if the MAC address represented by this object is a unicast address; otherwise + * false. + */ + public boolean isUnicast() { + return (getAddress()[0] & 1) == 0; + } + + /** + * @return true if the MAC address represented by this object is a globally unique address; + * otherwise false. + */ + public boolean isGloballyUnique() { + return (getAddress()[0] & 2) == 0; + } + + @Override + public String toString() { + if(this.equals(ETHER_BROADCAST_ADDRESS)) { + return "Broadcast"; + } + return super.toString(); + } } \ No newline at end of file diff --git a/app/src/main/java/org/pcap4j/util/Packets.java b/app/src/main/java/org/pcap4j/util/Packets.java index 1e95758..61bdb43 100644 --- a/app/src/main/java/org/pcap4j/util/Packets.java +++ b/app/src/main/java/org/pcap4j/util/Packets.java @@ -1,89 +1,89 @@ -/*_########################################################################## - _## - _## Copyright (C) 2017 Pcap4J.org - _## - _########################################################################## -*/ - -package org.pcap4j.util; - -import org.pcap4j.packet.EthernetPacket; -//import org.pcap4j.packet.IpPacket; -//import org.pcap4j.packet.IpV4Packet; -//import org.pcap4j.packet.IpV6Packet; -import org.pcap4j.packet.Packet; -//import org.pcap4j.packet.TcpPacket; -//import org.pcap4j.packet.UdpPacket; - -/** - * A utility class for operating on packets. - * - * @author Kaito Yamada - * @since pcap4j 1.7.2 - */ -public final class Packets { - - private Packets() { - throw new AssertionError(); - } - -// /** -// * Checks if the given packet contains a TCP packet ({@link TcpPacket}). -// * -// * @param packet packet -// * @return true if the packet contains a TCP packet; false otherwise. -// */ -// public static boolean containsTcpPacket(Packet packet) { -// return packet.contains(TcpPacket.class); -// } -// -// /** -// * Checks if the given packet contains a Udp packet ({@link UdpPacket}). -// * -// * @param packet packet -// * @return true if the packet contains a UDP packet; false otherwise. -// */ -// public static boolean containsUdpPacket(Packet packet) { -// return packet.contains(UdpPacket.class); -// } -// -// /** -// * Checks if the given packet contains an IPv4 packet ({@link IpV4Packet}). -// * -// * @param packet packet -// * @return true if the packet contains an IPv4 packet; false otherwise. -// */ -// public static boolean containsIpV4Packet(Packet packet) { -// return packet.contains(IpV4Packet.class); -// } -// -// /** -// * Checks if the given packet contains an IPv6 packet ({@link IpV6Packet}). -// * -// * @param packet packet -// * @return true if the packet contains an IPv6 packet; false otherwise. -// */ -// public static boolean containsIpV6Packet(Packet packet) { -// return packet.contains(IpV6Packet.class); -// } -// -// /** -// * Checks if the given packet contains an IP packet ({@link IpPacket}). -// * -// * @param packet packet -// * @return true if the packet contains an IP packet; false otherwise. -// */ -// public static boolean containsIpPacket(Packet packet) { -// return packet.contains(IpPacket.class); -// } - - /** - * Checks if the given packet contains an Ethernet packet ({@link EthernetPacket}). - * - * @param packet packet - * @return true if the packet contains an Ethernet packet; false otherwise. - */ - public static boolean containsEthernetPacket(Packet packet) { - return packet.contains(EthernetPacket.class); - } +/*_########################################################################## + _## + _## Copyright (C) 2017 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.util; + +import org.pcap4j.packet.EthernetPacket; +//import org.pcap4j.packet.IpPacket; +//import org.pcap4j.packet.IpV4Packet; +//import org.pcap4j.packet.IpV6Packet; +import org.pcap4j.packet.Packet; +//import org.pcap4j.packet.TcpPacket; +//import org.pcap4j.packet.UdpPacket; + +/** + * A utility class for operating on packets. + * + * @author Kaito Yamada + * @since pcap4j 1.7.2 + */ +public final class Packets { + + private Packets() { + throw new AssertionError(); + } + +// /** +// * Checks if the given packet contains a TCP packet ({@link TcpPacket}). +// * +// * @param packet packet +// * @return true if the packet contains a TCP packet; false otherwise. +// */ +// public static boolean containsTcpPacket(Packet packet) { +// return packet.contains(TcpPacket.class); +// } +// +// /** +// * Checks if the given packet contains a Udp packet ({@link UdpPacket}). +// * +// * @param packet packet +// * @return true if the packet contains a UDP packet; false otherwise. +// */ +// public static boolean containsUdpPacket(Packet packet) { +// return packet.contains(UdpPacket.class); +// } +// +// /** +// * Checks if the given packet contains an IPv4 packet ({@link IpV4Packet}). +// * +// * @param packet packet +// * @return true if the packet contains an IPv4 packet; false otherwise. +// */ +// public static boolean containsIpV4Packet(Packet packet) { +// return packet.contains(IpV4Packet.class); +// } +// +// /** +// * Checks if the given packet contains an IPv6 packet ({@link IpV6Packet}). +// * +// * @param packet packet +// * @return true if the packet contains an IPv6 packet; false otherwise. +// */ +// public static boolean containsIpV6Packet(Packet packet) { +// return packet.contains(IpV6Packet.class); +// } +// +// /** +// * Checks if the given packet contains an IP packet ({@link IpPacket}). +// * +// * @param packet packet +// * @return true if the packet contains an IP packet; false otherwise. +// */ +// public static boolean containsIpPacket(Packet packet) { +// return packet.contains(IpPacket.class); +// } + + /** + * Checks if the given packet contains an Ethernet packet ({@link EthernetPacket}). + * + * @param packet packet + * @return true if the packet contains an Ethernet packet; false otherwise. + */ + public static boolean containsEthernetPacket(Packet packet) { + return packet.contains(EthernetPacket.class); + } } \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml index 1f6bb29..971add5 100644 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,34 +1,34 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/app/src/main/res/drawable/border.xml b/app/src/main/res/drawable/border.xml index 46c96b6..d1330ce 100644 --- a/app/src/main/res/drawable/border.xml +++ b/app/src/main/res/drawable/border.xml @@ -1,7 +1,7 @@ - - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml new file mode 100644 index 0000000..ede4b71 --- /dev/null +++ b/app/src/main/res/drawable/ic_close.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index 0d025f9..eed7a42 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_restart.xml b/app/src/main/res/drawable/ic_restart.xml new file mode 100644 index 0000000..794ca6a --- /dev/null +++ b/app/src/main/res/drawable/ic_restart.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_start.xml b/app/src/main/res/drawable/ic_start.xml new file mode 100644 index 0000000..bf9b895 --- /dev/null +++ b/app/src/main/res/drawable/ic_start.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_error.xml b/app/src/main/res/layout/activity_error.xml index 01e7989..0ffafab 100644 --- a/app/src/main/res/layout/activity_error.xml +++ b/app/src/main/res/layout/activity_error.xml @@ -1,20 +1,20 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 72bf22b..4ac3057 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,31 +1,31 @@ - - - - - - - - - -