diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..e236489d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.js linguist-vendored +/Dockerfile linguist-vendored +/release.py linguist-vendored +/**/*.js linguist-vendored \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..05551636 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Bettercap Documentation + url: https://www.bettercap.org/ + about: Please read the instructions before asking for help. diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/default_issue.md similarity index 94% rename from ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/default_issue.md index 5c23a58c..8fc3c85c 100644 --- a/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/default_issue.md @@ -1,3 +1,8 @@ +--- +name: General Issue +about: Write a general issue or bug report. +--- + # Prerequisites Please, before creating this issue make sure that you read the [README](https://github.com/bettercap/bettercap/blob/master/README.md), that you are running the [latest stable version](https://github.com/bettercap/bettercap/releases) and that you already searched [other issues](https://github.com/bettercap/bettercap/issues?q=is%3Aopen+is%3Aissue+label%3Abug) to see if your problem or request was already reported. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..c78a0857 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + # GitHub Actions + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index a989673d..a9a770f0 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -8,58 +8,57 @@ on: jobs: build: - runs-on: ${{ matrix.os }} + name: ${{ matrix.os.pretty }} ${{ matrix.arch }} + runs-on: ${{ matrix.os.runs-on }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - go-version: ['1.22.x'] - include: - - os: ubuntu-latest - arch: amd64 - target_os: linux - target_arch: amd64 - - os: ubuntu-latest - arch: arm64 - target_os: linux - target_arch: aarch64 - - os: macos-latest - arch: arm64 - target_os: darwin - target_arch: arm64 - - os: windows-latest - arch: amd64 - target_os: windows - target_arch: amd64 + os: + - name: darwin + runs-on: [macos-latest] + pretty: 🍎 macOS + - name: linux + runs-on: [ubuntu-latest] + pretty: 🐧 Linux + - name: windows + runs-on: [windows-latest] + pretty: 🪟 Windows output: bettercap.exe + arch: [amd64, arm64] + go: [1.24.x] + exclude: + - os: + name: darwin + arch: amd64 + # Linux ARM64 images are not yet publicly available (https://github.com/actions/runner-images) + - os: + name: linux + arch: arm64 + - os: + name: windows + arch: arm64 env: - TARGET_OS: ${{ matrix.target_os }} - TARGET_ARCH: ${{ matrix.target_arch }} - GO_VERSION: ${{ matrix.go-version }} - OUTPUT: ${{ matrix.output || 'bettercap' }} + OUTPUT: ${{ matrix.os.output || 'bettercap' }} steps: - name: Checkout Code - uses: actions/checkout@v2 - with: - submodules: true + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: - go-version: ${{ matrix.go-version }} + go-version: ${{ matrix.go }} - name: Install Dependencies - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os.name == 'linux' }} run: sudo apt-get update && sudo apt-get install -y p7zip-full libpcap-dev libnetfilter-queue-dev libusb-1.0-0-dev - name: Install Dependencies (macOS) - if: ${{ matrix.os == 'macos-latest' }} + if: ${{ matrix.os.name == 'macos' }} run: brew install libpcap libusb p7zip - - name: Install libusb via mingw (Windows) - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ matrix.os.name == 'windows' }} uses: msys2/setup-msys2@v2 with: install: |- @@ -67,7 +66,7 @@ jobs: mingw64/mingw-w64-x86_64-pkg-config - name: Install other Dependencies (Windows) - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ matrix.os.name == 'windows' }} run: | choco install openssl.light -y choco install make -y @@ -83,25 +82,36 @@ jobs: - name: Verify Build run: | file "${{ env.OUTPUT }}" - openssl dgst -sha256 "${{ env.OUTPUT }}" | tee bettercap_${{ matrix.target_os }}_${{ matrix.target_arch }}_${{ env.VERSION }}.sha256 - 7z a "bettercap_${{ matrix.target_os }}_${{ matrix.target_arch }}_${{ env.VERSION }}.zip" "${{ env.OUTPUT }}" "bettercap_${{ matrix.target_os }}_${{ matrix.target_arch }}_${{ env.VERSION }}.sha256" + openssl dgst -sha256 "${{ env.OUTPUT }}" | tee bettercap_${{ matrix.os.name }}_${{ matrix.arch }}.sha256 + 7z a "bettercap_${{ matrix.os.name }}_${{ matrix.arch }}.zip" "${{ env.OUTPUT }}" "bettercap_${{ matrix.os.name }}_${{ matrix.arch }}.sha256" + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: release-artifacts-${{ matrix.os.name }}-${{ matrix.arch }} + path: | + bettercap_*.zip + bettercap_*.sha256 deploy: needs: [build] - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') name: Release runs-on: ubuntu-latest steps: - - name: Checkout Code - uses: actions/checkout@v2 + - name: Download Artifacts + uses: actions/download-artifact@v5 with: - submodules: true + pattern: release-artifacts-* + merge-multiple: true + path: dist/ + + - name: Release Assets + run: ls -l dist - name: Upload Release Assets - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') with: - files: | - bettercap_*.zip - bettercap_*.sha256 + files: dist/bettercap_* env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/build-and-push-docker.yml b/.github/workflows/build-and-push-docker.yml index 062b9a47..c9ad06f1 100644 --- a/.github/workflows/build-and-push-docker.yml +++ b/.github/workflows/build-and-push-docker.yml @@ -12,8 +12,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - with: - submodules: true + - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx @@ -24,7 +23,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: platforms: linux/amd64,linux/arm64 push: true diff --git a/.github/workflows/test-on-linux.yml b/.github/workflows/test-on-linux.yml index d85a7913..e920f281 100644 --- a/.github/workflows/test-on-linux.yml +++ b/.github/workflows/test-on-linux.yml @@ -13,16 +13,14 @@ jobs: strategy: matrix: os: [ubuntu-latest] - go-version: ['1.22.x'] + go-version: ['1.24.x'] steps: - name: Checkout Code - uses: actions/checkout@v2 - with: - submodules: true + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} diff --git a/.github/workflows/test-on-macos.yml b/.github/workflows/test-on-macos.yml index e7d0dfbf..b48c57cd 100644 --- a/.github/workflows/test-on-macos.yml +++ b/.github/workflows/test-on-macos.yml @@ -13,16 +13,14 @@ jobs: strategy: matrix: os: [macos-latest] - go-version: ['1.22.x'] + go-version: ['1.24.x'] steps: - name: Checkout Code - uses: actions/checkout@v2 - with: - submodules: true + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} diff --git a/.github/workflows/test-on-windows.yml b/.github/workflows/test-on-windows.yml index 201f85d7..b5e6a6e2 100644 --- a/.github/workflows/test-on-windows.yml +++ b/.github/workflows/test-on-windows.yml @@ -13,16 +13,14 @@ jobs: strategy: matrix: os: [windows-latest] - go-version: ['1.22.x'] + go-version: ['1.24.x'] steps: - name: Checkout Code - uses: actions/checkout@v2 - with: - submodules: true + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} diff --git a/.gitignore b/.gitignore index 54d34c48..8b655142 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,6 @@ stage/ /snap .idea /cover.out -/can-data \ No newline at end of file +/can-data +/test*.yml +/zerochaos.js \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 7d518695..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "ui"] - path = modules/ui/ui - url = https://github.com/bettercap/ui.git diff --git a/Dockerfile b/Dockerfile index 414cc8c4..362ff471 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # build stage -FROM golang:1.22-alpine3.20 AS build-env +FROM golang:1.24-alpine AS build-env RUN apk add --no-cache ca-certificates RUN apk add --no-cache bash gcc g++ binutils-gold iptables wireless-tools build-base libpcap-dev libusb-dev linux-headers libnetfilter_queue-dev git @@ -13,9 +13,9 @@ RUN mkdir -p /usr/local/share/bettercap RUN git clone https://github.com/bettercap/caplets /usr/local/share/bettercap/caplets # final stage -FROM alpine:3.20 +FROM alpine RUN apk add --no-cache ca-certificates -RUN apk add --no-cache bash iproute2 libpcap libusb-dev libnetfilter_queue wireless-tools +RUN apk add --no-cache bash iproute2 libpcap libusb-dev libnetfilter_queue wireless-tools iw COPY --from=build-env /go/src/github.com/bettercap/bettercap/bettercap /app/ COPY --from=build-env /usr/local/share/bettercap/caplets /app/ WORKDIR /app diff --git a/Makefile b/Makefile index f0b66583..3ec8e6cc 100644 --- a/Makefile +++ b/Makefile @@ -5,19 +5,14 @@ GO ?= go all: build -build: resources ui - $(GOFLAGS) $(GO) build -o $(TARGET) . +build: resources + $(GO) build $(GOFLAGS) -o $(TARGET) . build_with_race_detector: resources - $(GOFLAGS) $(GO) build -race -o $(TARGET) . + $(GO) build $(GOFLAGS) -race -o $(TARGET) . resources: network/manuf.go -ui: ./modules/ui/ui/dist/ui/index.html - -./modules/ui/ui/dist/ui/index.html: - @cd modules/ui/ui && make build - network/manuf.go: @python3 ./network/make_manuf.py @@ -29,13 +24,13 @@ docker: @docker build -t bettercap:latest . test: - $(GOFLAGS) $(GO) test -covermode=atomic -coverprofile=cover.out ./... + $(GO) test -covermode=atomic -coverprofile=cover.out ./... html_coverage: test - $(GOFLAGS) $(GO) tool cover -html=cover.out -o cover.out.html + $(GO) tool cover -html=cover.out -o cover.out.html benchmark: server_deps - $(GOFLAGS) $(GO) test -v -run=doNotRunTests -bench=. -benchmem ./... + $(GO) test -v -run=doNotRunTests -bench=. -benchmem ./... fmt: $(GO) fmt -s -w $(PACKAGES) diff --git a/README.md b/README.md index fae10d87..299e1d78 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@
-bettercap is a powerful, easily extensible and portable framework written in Go which aims to offer to security researchers, red teamers and reverse engineers an **easy to use**, **all-in-one solution** with all the features they might possibly need for performing reconnaissance and attacking [WiFi](https://www.bettercap.org/modules/wifi/) networks, [Bluetooth Low Energy](https://www.bettercap.org/modules/ble/) devices, [CAN-bus](https://www.bettercap.org/modules/can/), wireless [HID](https://www.bettercap.org/modules/hid/) devices and [Ethernet](https://www.bettercap.org/modules/ethernet) networks. +bettercap is a powerful, easily extensible and portable framework written in Go which aims to offer to security researchers, red teamers and reverse engineers an **easy to use**, **all-in-one solution** with all the features they might possibly need for performing reconnaissance and attacking [WiFi](https://www.bettercap.org/modules/wifi/) networks, [Bluetooth Low Energy](https://www.bettercap.org/modules/ble/) devices, [CAN-bus](https://www.bettercap.org/modules/canbus/), wireless [HID](https://www.bettercap.org/modules/hid/) devices and [Ethernet](https://www.bettercap.org/modules/ethernet) networks.  @@ -38,9 +38,15 @@ bettercap is a powerful, easily extensible and portable framework written in Go * **A very convenient [web UI](https://www.bettercap.org/usage/#web-ui).** * [More!](https://www.bettercap.org/modules/) +## Contributors + + +p[2])m=[r+q*Math.ceil((p[0]-r)/q),a[1]]}p=b.layerStatesArray;for(q=p.length-1;0<=q;--q){var u=p[q];r=u.layer;if(yg(u,n)&&f.call(g,r)&&(u=ij(this,r),r.ha()&&(l=u.wa(r.ha().D?m:a,b,c,h,e)),l))return l}};
+k.Ui=function(a,b,c,d,e){return void 0!==this.wa(a,b,c,Re,this,d,e)};function ij(a,b){var c=x(b).toString();if(c in a.c)return a.c[c];for(var d,e=a.S(),f=0,g=pg.length;f
+
+
+
diff --git a/modules/ui/ui/fa-brands-400.ttf b/modules/ui/ui/fa-brands-400.ttf
new file mode 100644
index 00000000..328c0526
Binary files /dev/null and b/modules/ui/ui/fa-brands-400.ttf differ
diff --git a/modules/ui/ui/fa-brands-400.woff b/modules/ui/ui/fa-brands-400.woff
new file mode 100644
index 00000000..2b0861f8
Binary files /dev/null and b/modules/ui/ui/fa-brands-400.woff differ
diff --git a/modules/ui/ui/fa-brands-400.woff2 b/modules/ui/ui/fa-brands-400.woff2
new file mode 100644
index 00000000..b5f9e08f
Binary files /dev/null and b/modules/ui/ui/fa-brands-400.woff2 differ
diff --git a/modules/ui/ui/fa-regular-400.eot b/modules/ui/ui/fa-regular-400.eot
new file mode 100644
index 00000000..8f820c7e
Binary files /dev/null and b/modules/ui/ui/fa-regular-400.eot differ
diff --git a/modules/ui/ui/fa-regular-400.svg b/modules/ui/ui/fa-regular-400.svg
new file mode 100644
index 00000000..f4774621
--- /dev/null
+++ b/modules/ui/ui/fa-regular-400.svg
@@ -0,0 +1,803 @@
+
+
+
+
diff --git a/modules/ui/ui/fa-regular-400.ttf b/modules/ui/ui/fa-regular-400.ttf
new file mode 100644
index 00000000..9f81d9e9
Binary files /dev/null and b/modules/ui/ui/fa-regular-400.ttf differ
diff --git a/modules/ui/ui/fa-regular-400.woff b/modules/ui/ui/fa-regular-400.woff
new file mode 100644
index 00000000..ed70421c
Binary files /dev/null and b/modules/ui/ui/fa-regular-400.woff differ
diff --git a/modules/ui/ui/fa-regular-400.woff2 b/modules/ui/ui/fa-regular-400.woff2
new file mode 100644
index 00000000..5da4177f
Binary files /dev/null and b/modules/ui/ui/fa-regular-400.woff2 differ
diff --git a/modules/ui/ui/fa-solid-900.eot b/modules/ui/ui/fa-solid-900.eot
new file mode 100644
index 00000000..ae0eaad4
Binary files /dev/null and b/modules/ui/ui/fa-solid-900.eot differ
diff --git a/modules/ui/ui/fa-solid-900.svg b/modules/ui/ui/fa-solid-900.svg
new file mode 100644
index 00000000..02ad6d36
--- /dev/null
+++ b/modules/ui/ui/fa-solid-900.svg
@@ -0,0 +1,4527 @@
+
+
+
+
diff --git a/modules/ui/ui/fa-solid-900.ttf b/modules/ui/ui/fa-solid-900.ttf
new file mode 100644
index 00000000..52739b55
Binary files /dev/null and b/modules/ui/ui/fa-solid-900.ttf differ
diff --git a/modules/ui/ui/fa-solid-900.woff b/modules/ui/ui/fa-solid-900.woff
new file mode 100644
index 00000000..990c8be5
Binary files /dev/null and b/modules/ui/ui/fa-solid-900.woff differ
diff --git a/modules/ui/ui/fa-solid-900.woff2 b/modules/ui/ui/fa-solid-900.woff2
new file mode 100644
index 00000000..a0fb9f03
Binary files /dev/null and b/modules/ui/ui/fa-solid-900.woff2 differ
diff --git a/modules/ui/ui/favicon.ico b/modules/ui/ui/favicon.ico
new file mode 100644
index 00000000..8081c7ce
Binary files /dev/null and b/modules/ui/ui/favicon.ico differ
diff --git a/modules/ui/ui/index.html b/modules/ui/ui/index.html
new file mode 100644
index 00000000..91e6202a
--- /dev/null
+++ b/modules/ui/ui/index.html
@@ -0,0 +1,15 @@
+
+
+ No commands available for this module. {{ cmd.description }} No parameters available for this module. {{ p.value.description }} \n No caplets installed so far.\n \n {{ sessionError.message }}\n \n {{ api.settings.URL() }} is using an insecure connection, refer to the documentation to configure the api.rest module to use SSL. No commands available for this module. {{ cmd.description }} No parameters available for this module. {{ p.value.description }} \\n No caplets installed so far.\\n \\n {{ sessionError.message }}\\n \\n {{ api.settings.URL() }} is using an insecure connection, refer to the documentation to configure the api.rest module to use SSL.Status
\n\n \n \n
\n \n \n UI Version \n \n {{ environment.version }}\n \n requires API {{ environment.requires }}\n \n \n \n \n Connected To \n \n {{ api.settings.URL() }}\n \n polled every {{ api.settings.interval }}ms with a ping of {{ api.ping }}ms\n \n (paused)\n \n \n \n \n \n\n API Version \n \n {{ api.session.version }} \n \n compiled with {{ api.session.goversion }} for {{ api.session.os }} {{ api.session.arch }}\n \n \n \n \n CPU \n Using {{ api.session.resources.max_cpus }} of {{ api.session.resources.cpus }} logical CPUs \n ({{ api.session.resources.goroutines }} goroutines)\n \n \n \n\n \n MEM \n \n Heap: {{ api.session.resources.alloc | size }} Sys: {{ api.session.resources.sys | size }} \n \n gc cycles: {{ api.session.resources.gcs }}\n \n \n Options
\n\n \n \n
\n \n \n \n {{ arg.key }} \n \n \n Variables
\n\n \n \n
\n \n \n \n {{ val.key }} \n \n \n Interfaces
\n\n \n \n
\n\n \n \n \n {{ iface.name }} \n {{ iface.flags }}\n \n \n \n {{ iface.mac | uppercase }} \n {{ iface.vendor }}\n \n \n \n \n \n not connected\n \n \n \n \n {{ a.address }} {{ a.type }}\n \n Packets per Protocol
\n\n \n \n
\n \n \n \n {{ proto.key }} \n \n \n Commands
\n\n Parameters
\n\n \n \n
\n\n \n \n \n \n\n RSSI \n MAC \n Name \n Vendor \n Flags \n Connectable \n Services \n Seen \n \n \n\n \n empty\n \n \n \n \n \n \n \n \n \n {{ (device.name ? device.name : device.alias ? '' : 'none') | unbash }}\n \n {{ device.alias }}\n \n \n\n {{ device.vendor ? device.vendor : 'unknown' }} \n {{ device.flags ? device.flags : 'none' }} \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n 0\">\n \n {{ device.services.length }}\n \n \n \n \n\n \n \n 0\" ngbTooltip=\"Refresh\" class=\"fas fa-sync-alt\">\n \n \n {{ device.last_seen | date: 'HH:mm:ss' }} \n \n \n
\n\n \n \n \n Handles \n \n \n Service\n \n \n \n Characteristics\n \n \n Properties \n Data \n \n \n \n \n {{ svc.handle }}\n \n {{ svc.end_handle }}\n \n \n \n \n {{ svc.name }}\n \n {{ svc.uuid }}\n \n \n {{ svc.uuid }}\n \n \n \n \n \n \n \n {{ ch.handle }}\n \n \n \n \n {{ ch.name }}\n \n {{ ch.uuid }}\n \n \n {{ ch.uuid }}\n \n \n \n {{ ch.properties.join(', ') | unbash }}\n \n \n \n {{ ch.data | unbash }}\n \n \n \n \n \n
\n \n
\n
\n
\n \n \n
\n\n \n \n \n Muted\n \n \n \n\n \n \n \n \n
\n\n \n \n \n\n Time \n Type \n \n \n \n\n \n empty\n \n \n \n \n {{ event.time | date: 'short' }} \n \n \n \n \n \n \n \n
\n\n \n \n \n\n Address \n Type \n Data \n Channels \n Seen \n \n \n\n \n empty\n \n \n \n \n \n \n {{ device.address | uppercase }}\n\n \n {{ device.alias }}\n \n\n \n \n \n injecting ...\n \n \n sniffing ...\n \n \n \n \n \n \n\n \n \n {{ device.type ? device.type : 'unknown'}}\n \n \n 0\n\n \n {{ device.channels.join(', ') }} \n {{ device.last_seen | date: 'HH:mm:ss' }} \n \n \n
\n\n \n \n \n IP \n MAC \n Hostname \n Vendor \n Sent \n Recvd \n Seen \n Info \n \n \n\n \n empty\n \n \n \n \n \n \n \n \n \n {{ host.hostname }}\n \n \n {{ host.alias }}\n \n \n {{ host.vendor ? host.vendor : 'unknown' }} \n {{ host.sent | size }} \n {{ host.received | size }} \n {{ host.last_seen | date: 'HH:mm:ss'}} \n \n\n interface\n gateway\n\n \n\n \n ERROR
\n WARNING
\n
\n \n \n
\n\n \n\n \n \n \n \n Not running\n \n \n\n \n \n No satellites\n \n \n\n 0\">Updated \n 0\">\n {{ api.session.gps.Updated | date:'HH:mm:ss' }} \n \n\n {{ gps.key }} \n {{ gps.value }} \n \n \n
\n \n \n \n \n \n\n RSSI \n BSSID \n ESSID \n Vendor \n Encryption \n\n Ch \n \n \n \n\n Clients \n Sent \n Recvd \n Seen \n \n \n\n \n empty\n \n \n \n \n \n \n \n\n '\">\n {{ ap.hostname }}\n {{ ap.alias }}\n \n\n \n {{ ap.vendor ? ap.vendor : 'unknown' }}\n \n\n \n \n\n \n \n {{ ap.encryption }}\n \n\n \n \n \n \n \n \n {{ ap.channel }}\n \n\n \n 0\n 0\">\n \n {{ ap.clients.length }}\n \n \n \n \n \n\n {{ ap.sent | size }} \n {{ ap.received | size }} \n {{ ap.last_seen | date: 'HH:mm:ss' }} \n\n \n \n
\n\n \n \n \n RSSI \n MAC \n Vendor \n Sent \n Recvd \n First Seen \n Last Seen \n \n \n\n \n empty\n \n \n \n \n \n \n \n \n \n \n\n \n \n {{ client.alias }}\n \n \n \n {{ client.vendor ? client.vendor : 'unknown' }}\n \n {{ client.sent | size }} \n {{ client.received | size }} \n \n {{ client.first_seen | date: 'HH:mm:ss' }}\n \n \n {{ client.last_seen | date: 'HH:mm:ss' }}\n \n Status
\\n\\n \\n \\n
\\n \\n \\n UI Version \\n \\n {{ environment.version }}\\n \\n requires API {{ environment.requires }}\\n \\n \\n \\n \\n Connected To \\n \\n {{ api.settings.URL() }}\\n \\n polled every {{ api.settings.interval }}ms with a ping of {{ api.ping }}ms\\n \\n (paused)\\n \\n \\n \\n \\n \\n\\n API Version \\n \\n {{ api.session.version }} \\n \\n compiled with {{ api.session.goversion }} for {{ api.session.os }} {{ api.session.arch }}\\n \\n \\n \\n \\n CPU \\n Using {{ api.session.resources.max_cpus }} of {{ api.session.resources.cpus }} logical CPUs \\n ({{ api.session.resources.goroutines }} goroutines)\\n \\n \\n \\n\\n \\n MEM \\n \\n Heap: {{ api.session.resources.alloc | size }} Sys: {{ api.session.resources.sys | size }} \\n \\n gc cycles: {{ api.session.resources.gcs }}\\n \\n \\n Options
\\n\\n \\n \\n
\\n \\n \\n \\n {{ arg.key }} \\n \\n \\n Variables
\\n\\n \\n \\n
\\n \\n \\n \\n {{ val.key }} \\n \\n \\n Interfaces
\\n\\n \\n \\n
\\n\\n \\n \\n \\n {{ iface.name }} \\n {{ iface.flags }}\\n \\n \\n \\n {{ iface.mac | uppercase }} \\n {{ iface.vendor }}\\n \\n \\n \\n \\n \\n not connected\\n \\n \\n \\n \\n {{ a.address }} {{ a.type }}\\n \\n Packets per Protocol
\\n\\n \\n \\n
\\n \\n \\n \\n {{ proto.key }} \\n \\n \\n Commands
\\n\\n Parameters
\\n\\n \\n \\n
\\n\\n \\n \\n \\n \\n\\n RSSI \\n MAC \\n Name \\n Vendor \\n Flags \\n Connectable \\n Services \\n Seen \\n \\n \\n\\n \\n empty\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n {{ (device.name ? device.name : device.alias ? '' : 'none') | unbash }}\\n \\n {{ device.alias }}\\n \\n \\n\\n {{ device.vendor ? device.vendor : 'unknown' }} \\n {{ device.flags ? device.flags : 'none' }} \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n\\n 0\\\">\\n \\n {{ device.services.length }}\\n \\n \\n \\n \\n\\n \\n \\n 0\\\" ngbTooltip=\\\"Refresh\\\" class=\\\"fas fa-sync-alt\\\">\\n \\n \\n {{ device.last_seen | date: 'HH:mm:ss' }} \\n \\n \\n
\\n\\n \\n \\n \\n Handles \\n \\n \\n Service\\n \\n \\n \\n Characteristics\\n \\n \\n Properties \\n Data \\n \\n \\n \\n \\n {{ svc.handle }}\\n \\n {{ svc.end_handle }}\\n \\n \\n \\n \\n {{ svc.name }}\\n \\n {{ svc.uuid }}\\n \\n \\n {{ svc.uuid }}\\n \\n \\n \\n \\n \\n \\n \\n {{ ch.handle }}\\n \\n \\n \\n \\n {{ ch.name }}\\n \\n {{ ch.uuid }}\\n \\n \\n {{ ch.uuid }}\\n \\n \\n \\n {{ ch.properties.join(', ') | unbash }}\\n \\n \\n \\n {{ ch.data | unbash }}\\n \\n \\n \\n \\n \\n
\\n \\n
\\n
\\n
\\n \\n \\n
\\n\\n \\n \\n \\n Muted\\n \\n \\n \\n\\n \\n \\n \\n \\n
\\n\\n \\n \\n \\n\\n Time \\n Type \\n \\n \\n \\n\\n \\n empty\\n \\n \\n \\n \\n {{ event.time | date: 'short' }} \\n \\n \\n \\n \\n \\n \\n \\n
\\n\\n \\n \\n \\n\\n Address \\n Type \\n Data \\n Channels \\n Seen \\n \\n \\n\\n \\n empty\\n \\n \\n \\n \\n \\n \\n {{ device.address | uppercase }}\\n\\n \\n {{ device.alias }}\\n \\n\\n \\n \\n \\n injecting ...\\n \\n \\n sniffing ...\\n \\n \\n \\n \\n \\n \\n\\n \\n \\n {{ device.type ? device.type : 'unknown'}}\\n \\n \\n 0\\n\\n \\n {{ device.channels.join(', ') }} \\n {{ device.last_seen | date: 'HH:mm:ss' }} \\n \\n \\n
\\n\\n \\n \\n \\n IP \\n MAC \\n Hostname \\n Vendor \\n Sent \\n Recvd \\n Seen \\n Info \\n \\n \\n\\n \\n empty\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n {{ host.hostname }}\\n \\n \\n {{ host.alias }}\\n \\n \\n {{ host.vendor ? host.vendor : 'unknown' }} \\n {{ host.sent | size }} \\n {{ host.received | size }} \\n {{ host.last_seen | date: 'HH:mm:ss'}} \\n \\n\\n interface\\n gateway\\n\\n \\n\\n \\n ERROR
\\n WARNING
\\n
\\n \\n \\n
\\n\\n \\n\\n \\n \\n \\n \\n Not running\\n \\n \\n\\n \\n \\n No satellites\\n \\n \\n\\n 0\\\">Updated \\n 0\\\">\\n {{ api.session.gps.Updated | date:'HH:mm:ss' }} \\n \\n\\n {{ gps.key }} \\n {{ gps.value }} \\n \\n \\n
\\n \\n \\n \\n \\n \\n\\n RSSI \\n BSSID \\n ESSID \\n Vendor \\n Encryption \\n\\n Ch \\n \\n \\n \\n\\n Clients \\n Sent \\n Recvd \\n Seen \\n \\n \\n\\n \\n empty\\n \\n \\n \\n \\n \\n \\n \\n\\n '\\\">\\n {{ ap.hostname }}\\n {{ ap.alias }}\\n \\n\\n \\n {{ ap.vendor ? ap.vendor : 'unknown' }}\\n \\n\\n \\n \\n\\n \\n \\n {{ ap.encryption }}\\n \\n\\n \\n \\n \\n \\n \\n \\n {{ ap.channel }}\\n \\n\\n \\n 0\\n 0\\\">\\n \\n {{ ap.clients.length }}\\n \\n \\n \\n \\n \\n\\n {{ ap.sent | size }} \\n {{ ap.received | size }} \\n {{ ap.last_seen | date: 'HH:mm:ss' }} \\n\\n \\n \\n
\\n\\n \\n \\n \\n RSSI \\n MAC \\n Vendor \\n Sent \\n Recvd \\n First Seen \\n Last Seen \\n \\n \\n\\n \\n empty\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n\\n \\n \\n {{ client.alias }}\\n \\n \\n \\n {{ client.vendor ? client.vendor : 'unknown' }}\\n \\n {{ client.sent | size }} \\n {{ client.received | size }} \\n \\n {{ client.first_seen | date: 'HH:mm:ss' }}\\n \\n \\n {{ client.last_seen | date: 'HH:mm:ss' }}\\n \\n ","
"],col:[2,"
"],tr:[2,"","
"],td:[3,"
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n","